From dc0e09caea5d77720d2caad57cb42f162e6c929e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 21:00:53 +0000 Subject: [PATCH 001/165] rebase: bump github.com/aws/aws-sdk-go from 1.44.195 to 1.44.205 Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.44.195 to 1.44.205. - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.44.195...v1.44.205) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 +- .../aws/credentials/processcreds/provider.go | 24 +- .../aws/aws-sdk-go/aws/endpoints/defaults.go | 230 ++++++- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../aws/aws-sdk-go/service/ec2/api.go | 591 +++++++++++------- .../aws/aws-sdk-go/service/ec2/waiters.go | 51 ++ vendor/modules.txt | 2 +- 8 files changed, 630 insertions(+), 276 deletions(-) diff --git a/go.mod b/go.mod index 40f20834b..9120e6f6b 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( github.com/IBM/keyprotect-go-client v0.9.2 - github.com/aws/aws-sdk-go v1.44.195 + github.com/aws/aws-sdk-go v1.44.205 github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000 // TODO: API for managing subvolume metadata and snapshot metadata requires `ceph_ci_untested` build-tag diff --git a/go.sum b/go.sum index 3ab1f0098..03c1a8ffe 100644 --- a/go.sum +++ b/go.sum @@ -131,8 +131,8 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.44.195 h1:d5xFL0N83Fpsq2LFiHgtBUHknCRUPGHdOlCWt/jtOJs= -github.com/aws/aws-sdk-go v1.44.195/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.205 h1:q23NJXgLPIuBMn4zaluWWz57HPP5z7Ut8ZtK1D3N9bs= +github.com/aws/aws-sdk-go v1.44.205/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.17.4 h1:wyC6p9Yfq6V2y98wfDsj6OnNQa4w2BLGCLIxzNhwOGY= github.com/aws/aws-sdk-go-v2 v1.17.4/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 h1:r+XwaCLpIvCKjBIYy/HVZujQS9tsz5ohHG3ZIe0wKoE= diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go index e62483600..18694f07f 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go @@ -226,12 +226,24 @@ func NewCredentialsCommand(command *exec.Cmd, options ...func(*ProcessProvider)) return credentials.NewCredentials(p) } -type credentialProcessResponse struct { - Version int - AccessKeyID string `json:"AccessKeyId"` +// A CredentialProcessResponse is the AWS credentials format that must be +// returned when executing an external credential_process. +type CredentialProcessResponse struct { + // As of this writing, the Version key must be set to 1. This might + // increment over time as the structure evolves. + Version int + + // The access key ID that identifies the temporary security credentials. + AccessKeyID string `json:"AccessKeyId"` + + // The secret access key that can be used to sign requests. SecretAccessKey string - SessionToken string - Expiration *time.Time + + // The token that users must pass to the service API to use the temporary credentials. + SessionToken string + + // The date on which the current credentials expire. + Expiration *time.Time } // Retrieve executes the 'credential_process' and returns the credentials. @@ -242,7 +254,7 @@ func (p *ProcessProvider) Retrieve() (credentials.Value, error) { } // Serialize and validate response - resp := &credentialProcessResponse{} + resp := &CredentialProcessResponse{} if err = json.Unmarshal(out, resp); err != nil { return credentials.Value{ProviderName: ProviderName}, awserr.New( ErrCodeProcessProviderParse, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index 3eea5472e..6f4ad8ef1 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -2605,6 +2605,9 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -3221,6 +3224,9 @@ var awsPartition = partition{ endpointKey{ Region: "ap-northeast-1", }: endpoint{}, + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, endpointKey{ Region: "ap-southeast-2", }: endpoint{}, @@ -4057,6 +4063,21 @@ var awsPartition = partition{ }, "cases": service{ Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-southeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-southeast-2", + }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, + endpointKey{ + Region: "eu-west-2", + }: endpoint{}, endpointKey{ Region: "fips-us-east-1", }: endpoint{ @@ -6585,6 +6606,9 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, + endpointKey{ + Region: "ca-central-1", + }: endpoint{}, endpointKey{ Region: "eu-west-2", }: endpoint{}, @@ -7275,6 +7299,9 @@ var awsPartition = partition{ endpointKey{ Region: "ap-south-1", }: endpoint{}, + endpointKey{ + Region: "ap-south-2", + }: endpoint{}, endpointKey{ Region: "ap-southeast-1", }: endpoint{}, @@ -7296,12 +7323,18 @@ var awsPartition = partition{ endpointKey{ Region: "eu-central-1", }: endpoint{}, + endpointKey{ + Region: "eu-central-2", + }: endpoint{}, endpointKey{ Region: "eu-north-1", }: endpoint{}, endpointKey{ Region: "eu-south-1", }: endpoint{}, + endpointKey{ + Region: "eu-south-2", + }: endpoint{}, endpointKey{ Region: "eu-west-1", }: endpoint{}, @@ -9049,6 +9082,9 @@ var awsPartition = partition{ endpointKey{ Region: "ap-south-1", }: endpoint{}, + endpointKey{ + Region: "ap-south-2", + }: endpoint{}, endpointKey{ Region: "ap-southeast-1", }: endpoint{}, @@ -9064,12 +9100,18 @@ var awsPartition = partition{ endpointKey{ Region: "eu-central-1", }: endpoint{}, + endpointKey{ + Region: "eu-central-2", + }: endpoint{}, endpointKey{ Region: "eu-north-1", }: endpoint{}, endpointKey{ Region: "eu-south-1", }: endpoint{}, + endpointKey{ + Region: "eu-south-2", + }: endpoint{}, endpointKey{ Region: "eu-west-1", }: endpoint{}, @@ -9502,6 +9544,15 @@ var awsPartition = partition{ }: endpoint{ Hostname: "elasticfilesystem-fips.ap-south-1.amazonaws.com", }, + endpointKey{ + Region: "ap-south-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-south-2.amazonaws.com", + }, endpointKey{ Region: "ap-southeast-1", }: endpoint{}, @@ -9664,6 +9715,15 @@ var awsPartition = partition{ }, Deprecated: boxedTrue, }, + endpointKey{ + Region: "fips-ap-south-2", + }: endpoint{ + Hostname: "elasticfilesystem-fips.ap-south-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-2", + }, + Deprecated: boxedTrue, + }, endpointKey{ Region: "fips-ap-southeast-1", }: endpoint{ @@ -12612,6 +12672,9 @@ var awsPartition = partition{ endpointKey{ Region: "ap-south-1", }: endpoint{}, + endpointKey{ + Region: "ap-south-2", + }: endpoint{}, endpointKey{ Region: "ap-southeast-1", }: endpoint{}, @@ -12636,6 +12699,9 @@ var awsPartition = partition{ endpointKey{ Region: "eu-south-1", }: endpoint{}, + endpointKey{ + Region: "eu-south-2", + }: endpoint{}, endpointKey{ Region: "eu-west-1", }: endpoint{}, @@ -14198,6 +14264,9 @@ var awsPartition = partition{ }, "kendra": service{ Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, endpointKey{ Region: "ap-south-1", }: endpoint{}, @@ -14292,6 +14361,11 @@ var awsPartition = partition{ }: endpoint{ Hostname: "kendra-ranking.ap-east-1.api.aws", }, + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{ + Hostname: "kendra-ranking.ap-northeast-1.api.aws", + }, endpointKey{ Region: "ap-northeast-2", }: endpoint{ @@ -14302,6 +14376,11 @@ var awsPartition = partition{ }: endpoint{ Hostname: "kendra-ranking.ap-northeast-3.api.aws", }, + endpointKey{ + Region: "ap-south-1", + }: endpoint{ + Hostname: "kendra-ranking.ap-south-1.api.aws", + }, endpointKey{ Region: "ap-south-2", }: endpoint{ @@ -19728,6 +19807,9 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-3", }: endpoint{}, + endpointKey{ + Region: "ap-southeast-4", + }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -30279,6 +30361,21 @@ var awscnPartition = partition{ }, }, }, + "servicequotas": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{ + Protocols: []string{"https"}, + }, + }, + Endpoints: serviceEndpoints{ + endpointKey{ + Region: "cn-north-1", + }: endpoint{}, + endpointKey{ + Region: "cn-northwest-1", + }: endpoint{}, + }, + }, "sms": service{ Endpoints: serviceEndpoints{ endpointKey{ @@ -32444,6 +32541,24 @@ var awsusgovPartition = partition{ Region: "us-gov-east-1", }, }, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticbeanstalk.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + endpointKey{ + Region: "us-gov-east-1-fips", + }: endpoint{ + Hostname: "elasticbeanstalk.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + Deprecated: boxedTrue, + }, endpointKey{ Region: "us-gov-west-1", }: endpoint{ @@ -32452,6 +32567,24 @@ var awsusgovPartition = partition{ Region: "us-gov-west-1", }, }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "elasticbeanstalk.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + endpointKey{ + Region: "us-gov-west-1-fips", + }: endpoint{ + Hostname: "elasticbeanstalk.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, }, }, "elasticfilesystem": service{ @@ -32889,21 +33022,43 @@ var awsusgovPartition = partition{ "glacier": service{ Endpoints: serviceEndpoints{ endpointKey{ - Region: "us-gov-east-1", + Region: "fips-us-gov-east-1", }: endpoint{ Hostname: "glacier.us-gov-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-east-1", }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-gov-west-1", + }: endpoint{ + Hostname: "glacier.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "glacier.us-gov-east-1.amazonaws.com", }, endpointKey{ Region: "us-gov-west-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, }: endpoint{ Hostname: "glacier.us-gov-west-1.amazonaws.com", Protocols: []string{"http", "https"}, - CredentialScope: credentialScope{ - Region: "us-gov-west-1", - }, }, }, }, @@ -32974,36 +33129,38 @@ var awsusgovPartition = partition{ endpointKey{ Region: "fips-us-gov-east-1", }: endpoint{ - Hostname: "greengrass-fips.us-gov-east-1.amazonaws.com", + Hostname: "greengrass.us-gov-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-east-1", }, Deprecated: boxedTrue, }, endpointKey{ - Region: "us-gov-east-1", - }: endpoint{ - Hostname: "greengrass.us-gov-east-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-gov-east-1", - }, - }, - endpointKey{ - Region: "us-gov-east-1", - Variant: fipsVariant, - }: endpoint{ - Hostname: "greengrass-fips.us-gov-east-1.amazonaws.com", - CredentialScope: credentialScope{ - Region: "us-gov-east-1", - }, - }, - endpointKey{ - Region: "us-gov-west-1", + Region: "fips-us-gov-west-1", }: endpoint{ Hostname: "greengrass.us-gov-west-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-west-1", }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "greengrass.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "greengrass.us-gov-west-1.amazonaws.com", }, }, }, @@ -34122,20 +34279,40 @@ var awsusgovPartition = partition{ "outposts": service{ Endpoints: serviceEndpoints{ endpointKey{ - Region: "us-gov-east-1", + Region: "fips-us-gov-east-1", }: endpoint{ Hostname: "outposts.us-gov-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-east-1", }, + Deprecated: boxedTrue, }, endpointKey{ - Region: "us-gov-west-1", + Region: "fips-us-gov-west-1", }: endpoint{ Hostname: "outposts.us-gov-west-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-west-1", }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "outposts.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "outposts.us-gov-west-1.amazonaws.com", }, }, }, @@ -34650,6 +34827,9 @@ var awsusgovPartition = partition{ }, }, Endpoints: serviceEndpoints{ + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, endpointKey{ Region: "us-gov-west-1", }: endpoint{}, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index 0d1e26e51..a9e3cca1a 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.44.195" +const SDKVersion = "1.44.205" diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index e90ac8634..3d4d25336 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -3705,8 +3705,8 @@ func (c *EC2) CancelImageLaunchPermissionRequest(input *CancelImageLaunchPermiss // // Removes your Amazon Web Services account from the launch permissions for // the specified AMI. For more information, see Cancel having an AMI shared -// with your Amazon Web Services account (https://docs.aws.amazon.com/) in the -// Amazon EC2 User Guide. +// with your Amazon Web Services account (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/cancel-sharing-an-AMI.html) +// in the Amazon EC2 User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -28714,11 +28714,8 @@ func (c *EC2) DescribeSnapshotsRequest(input *DescribeSnapshotsInput) (req *requ // own or have explicit permissions, or all for public snapshots. // // If you are describing a long list of snapshots, we recommend that you paginate -// the output to make the list more manageable. The MaxResults parameter sets -// the maximum number of results returned in a single page. If the list of results -// exceeds your MaxResults value, then that number of results is returned along -// with a NextToken value that can be passed to a subsequent DescribeSnapshots -// request to retrieve the remaining results. +// the output to make the list more manageable. For more information, see Pagination +// (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). // // To get the state of fast snapshot restores for a snapshot, use DescribeFastSnapshotRestores. // @@ -32769,11 +32766,8 @@ func (c *EC2) DescribeVolumesRequest(input *DescribeVolumesInput) (req *request. // Describes the specified EBS volumes or all of your EBS volumes. // // If you are describing a long list of volumes, we recommend that you paginate -// the output to make the list more manageable. The MaxResults parameter sets -// the maximum number of results returned in a single page. If the list of results -// exceeds your MaxResults value, then that number of results is returned along -// with a NextToken value that can be passed to a subsequent DescribeVolumes -// request to retrieve the remaining results. +// the output to make the list more manageable. For more information, see Pagination +// (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). // // For more information about EBS volumes, see Amazon EBS volumes (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumes.html) // in the Amazon Elastic Compute Cloud User Guide. @@ -53742,9 +53736,9 @@ func (c *EC2) UnassignPrivateNatGatewayAddressRequest(input *UnassignPrivateNatG // UnassignPrivateNatGatewayAddress API operation for Amazon Elastic Compute Cloud. // -// Unassigns secondary private NAT gateway IPv4 addresses from a private NAT -// gateway. You cannot unassign your primary private IP. For more information, -// see Edit secondary IP address associations (https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html#nat-gateway-edit-secondary) +// Unassigns secondary private IPv4 addresses from a private NAT gateway. You +// cannot unassign your primary private IP. For more information, see Edit secondary +// IP address associations (https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html#nat-gateway-edit-secondary) // in the Amazon Virtual Private Cloud User Guide. // // While unassigning is in progress, you cannot assign/unassign additional IP @@ -56042,6 +56036,13 @@ type AllocateHostsInput struct { // of the request. For more information, see Ensuring Idempotency (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). ClientToken *string `locationName:"clientToken" type:"string"` + // Indicates whether to enable or disable host maintenance for the Dedicated + // Host. For more information, see Host maintenance (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-hosts-maintenance.html) + // in the Amazon EC2 User Guide. + // + // Default: on + HostMaintenance *string `type:"string" enum:"HostMaintenance"` + // Indicates whether to enable or disable host recovery for the Dedicated Host. // Host recovery is disabled by default. For more information, see Host recovery // (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-hosts-recovery.html) @@ -56133,6 +56134,12 @@ func (s *AllocateHostsInput) SetClientToken(v string) *AllocateHostsInput { return s } +// SetHostMaintenance sets the HostMaintenance field's value. +func (s *AllocateHostsInput) SetHostMaintenance(v string) *AllocateHostsInput { + s.HostMaintenance = &v + return s +} + // SetHostRecovery sets the HostRecovery field's value. func (s *AllocateHostsInput) SetHostRecovery(v string) *AllocateHostsInput { s.HostRecovery = &v @@ -87661,7 +87668,7 @@ type DescribeAvailabilityZonesInput struct { // // * message - The Zone message. // - // * opt-in-status - The opt-in status (opted-in, and not-opted-in | opt-in-not-required). + // * opt-in-status - The opt-in status (opted-in | not-opted-in | opt-in-not-required). // // * parent-zoneID - The ID of the zone that handles some of the Local Zone // and Wavelength Zone control plane operations, such as API calls. @@ -87678,13 +87685,11 @@ type DescribeAvailabilityZonesInput struct { // Local Zone (for example, usw2-lax1-az1), or the Wavelength Zone (for example, // us-east-1-wl1-bos-wlz-1). // - // * zone-type - The type of zone, for example, local-zone. - // // * zone-name - The name of the Availability Zone (for example, us-east-1a), // the Local Zone (for example, us-west-2-lax-1a), or the Wavelength Zone // (for example, us-east-1-wl1-bos-wlz-1). // - // * zone-type - The type of zone, for example, local-zone. + // * zone-type - The type of zone (availability-zone | local-zone | wavelength-zone). Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // The IDs of the Availability Zones, Local Zones, and Wavelength Zones. @@ -88598,13 +88603,15 @@ type DescribeClassicLinkInstancesInput struct { // One or more instance IDs. Must be instances linked to a VPC through ClassicLink. InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). // // Constraint: If the value is greater than 1000, we return only 1000 items. MaxResults *int64 `locationName:"maxResults" min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `locationName:"nextToken" type:"string"` } @@ -88675,8 +88682,8 @@ type DescribeClassicLinkInstancesOutput struct { // Information about one or more linked EC2-Classic instances. Instances []*ClassicLinkInstance `locationName:"instancesSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -89750,11 +89757,13 @@ type DescribeDhcpOptionsInput struct { // the tag value. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -89825,8 +89834,8 @@ type DescribeDhcpOptionsOutput struct { // Information about one or more DHCP options sets. DhcpOptions []*DhcpOptions `locationName:"dhcpOptionsSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -89885,11 +89894,13 @@ type DescribeEgressOnlyInternetGatewaysInput struct { // the tag value. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -89960,8 +89971,8 @@ type DescribeEgressOnlyInternetGatewaysOutput struct { // Information about the egress-only internet gateways. EgressOnlyInternetGateways []*EgressOnlyInternetGateway `locationName:"egressOnlyInternetGatewaySet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -90728,11 +90739,13 @@ type DescribeFastSnapshotRestoresInput struct { // | optimizing | enabled | disabling | disabled). Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -90784,8 +90797,8 @@ type DescribeFastSnapshotRestoresOutput struct { // Information about the state of fast snapshot restores. FastSnapshotRestores []*DescribeFastSnapshotRestoreSuccessItem `locationName:"fastSnapshotRestoreSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -91434,11 +91447,13 @@ type DescribeFlowLogsInput struct { // Constraint: Maximum of 1000 flow log IDs. FlowLogIds []*string `locationName:"FlowLogId" locationNameList:"item" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `type:"integer"` - // The token for the next page of results. + // The token to request the next page of items. Pagination continues from the + // end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -91496,8 +91511,8 @@ type DescribeFlowLogsOutput struct { // Information about the flow logs. FlowLogs []*FlowLog `locationName:"flowLogSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to request the next page of items. This value is null when there + // are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -92201,11 +92216,13 @@ type DescribeIamInstanceProfileAssociationsInput struct { // * state - The state of the association (associating | associated | disassociating). Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return in a single call. To retrieve the - // remaining results, make another call with the returned NextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token to request the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -92270,8 +92287,8 @@ type DescribeIamInstanceProfileAssociationsOutput struct { // Information about the IAM instance profile associations. IamInstanceProfileAssociations []*IamInstanceProfileAssociation `locationName:"iamInstanceProfileAssociationSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -93453,13 +93470,15 @@ type DescribeInstanceCreditSpecificationsInput struct { // Constraints: Maximum 1000 explicitly specified instance IDs. InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` - // The maximum number of results to return in a single call. To retrieve the - // remaining results, make another call with the returned NextToken value. This + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. This // value can be between 5 and 1000. You cannot specify this parameter and the - // instance IDs parameter in the same call. + // instance IDs parameter in the same call. For more information, see Pagination + // (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token to retrieve the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -93530,8 +93549,8 @@ type DescribeInstanceCreditSpecificationsOutput struct { // Information about the credit option for CPU usage of an instance. InstanceCreditSpecifications []*InstanceCreditSpecification `locationName:"instanceCreditSpecificationSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -93855,13 +93874,15 @@ type DescribeInstanceStatusInput struct { // Constraints: Maximum 100 explicitly specified instance IDs. InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` - // The maximum number of results to return in a single call. To retrieve the - // remaining results, make another call with the returned NextToken value. This - // value can be between 5 and 1000. You cannot specify this parameter and the - // instance IDs parameter in the same call. + // The maximum number of items to return for this request. To retrieve the next + // page of items, make another request with the token returned in the output. + // This value can be between 5 and 1000. You cannot specify this parameter and + // the instance IDs parameter in the same call. For more information, see Pagination + // (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `type:"integer"` - // The token to retrieve the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -93925,8 +93946,8 @@ type DescribeInstanceStatusOutput struct { // Information about the status of the instances. InstanceStatuses []*InstanceStatus `locationName:"instanceStatusSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -93981,12 +94002,13 @@ type DescribeInstanceTypeOfferingsInput struct { // The location type. LocationType *string `type:"string" enum:"LocationType"` - // The maximum number of results to return for the request in a single page. - // The remaining results can be seen by sending another request with the next - // token value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token to retrieve the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -94057,8 +94079,8 @@ type DescribeInstanceTypeOfferingsOutput struct { // The instance types offered. InstanceTypeOfferings []*InstanceTypeOffering `locationName:"instanceTypeOfferingSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -94240,12 +94262,13 @@ type DescribeInstanceTypesInput struct { // in the Amazon EC2 User Guide. InstanceTypes []*string `locationName:"InstanceType" type:"list" enum:"InstanceType"` - // The maximum number of results to return for the request in a single page. - // The remaining results can be seen by sending another request with the next - // token value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token to retrieve the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -94317,8 +94340,8 @@ type DescribeInstanceTypesOutput struct { // in the Amazon EC2 User Guide. InstanceTypes []*InstanceTypeInfo `locationName:"instanceTypeSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -94627,13 +94650,15 @@ type DescribeInstancesInput struct { // Default: Describes all your instances. InstanceIds []*string `locationName:"InstanceId" locationNameList:"InstanceId" type:"list"` - // The maximum number of results to return in a single call. To retrieve the - // remaining results, make another call with the returned NextToken value. This + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. This // value can be between 5 and 1000. You cannot specify this parameter and the - // instance IDs parameter in the same call. + // instance IDs parameter in the same request. For more information, see Pagination + // (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `locationName:"maxResults" type:"integer"` - // The token to request the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `locationName:"nextToken" type:"string"` } @@ -94688,8 +94713,8 @@ func (s *DescribeInstancesInput) SetNextToken(v string) *DescribeInstancesInput type DescribeInstancesOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the reservations. @@ -94763,11 +94788,13 @@ type DescribeInternetGatewaysInput struct { // Default: Describes all your internet gateways. InternetGatewayIds []*string `locationName:"internetGatewayId" locationNameList:"item" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -94838,8 +94865,8 @@ type DescribeInternetGatewaysOutput struct { // Information about one or more internet gateways. InternetGateways []*InternetGateway `locationName:"internetGatewaySet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -97271,14 +97298,16 @@ type DescribeNatGatewaysInput struct { // * vpc-id - The ID of the VPC in which the NAT gateway resides. Filter []*Filter `locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` // One or more NAT gateway IDs. NatGatewayIds []*string `locationName:"NatGatewayId" locationNameList:"item" type:"list"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -97349,8 +97378,8 @@ type DescribeNatGatewaysOutput struct { // Information about the NAT gateways. NatGateways []*NatGateway `locationName:"natGatewaySet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -97447,8 +97476,9 @@ type DescribeNetworkAclsInput struct { // * vpc-id - The ID of the VPC for the network ACL. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` // One or more network ACL IDs. @@ -97456,7 +97486,8 @@ type DescribeNetworkAclsInput struct { // Default: Describes all your network ACLs. NetworkAclIds []*string `locationName:"NetworkAclId" locationNameList:"item" type:"list"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -97527,8 +97558,8 @@ type DescribeNetworkAclsOutput struct { // Information about one or more network ACLs. NetworkAcls []*NetworkAcl `locationName:"networkAclSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -98289,15 +98320,17 @@ type DescribeNetworkInterfacePermissionsInput struct { // | EIP-ASSOCIATE). Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return in a single call. To retrieve the - // remaining results, make another call with the returned NextToken value. If + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. If // this parameter is not specified, up to 50 results are returned by default. + // For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` // The network interface permission IDs. NetworkInterfacePermissionIds []*string `locationName:"NetworkInterfacePermissionId" type:"list"` - // The token to request the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -98363,7 +98396,8 @@ type DescribeNetworkInterfacePermissionsOutput struct { // The network interface permissions. NetworkInterfacePermissions []*NetworkInterfacePermission `locationName:"networkInterfacePermissions" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -98518,10 +98552,10 @@ type DescribeNetworkInterfacesInput struct { // * vpc-id - The ID of the VPC for the network interface. Filters []*Filter `locationName:"filter" locationNameList:"Filter" type:"list"` - // The maximum number of items to return for this request. The request returns - // a token that you can specify in a subsequent call to get the next set of - // results. You cannot specify this parameter and the network interface IDs - // parameter in the same request. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. You + // cannot specify this parameter and the network interface IDs parameter in + // the same request. For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` // The network interface IDs. @@ -98529,7 +98563,8 @@ type DescribeNetworkInterfacesInput struct { // Default: Describes all your network interfaces. NetworkInterfaceIds []*string `locationName:"NetworkInterfaceId" locationNameList:"item" type:"list"` - // The token to retrieve the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -98594,15 +98629,14 @@ func (s *DescribeNetworkInterfacesInput) SetNextToken(v string) *DescribeNetwork return s } -// Contains the output of DescribeNetworkInterfaces. type DescribeNetworkInterfacesOutput struct { _ struct{} `type:"structure"` // Information about one or more network interfaces. NetworkInterfaces []*NetworkInterface `locationName:"networkInterfaceSet" locationNameList:"item" type:"list"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` } @@ -99228,11 +99262,13 @@ type DescribeReplaceRootVolumeTasksInput struct { // task was created. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"1" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // The ID of the root volume replacement task to view. @@ -99303,8 +99339,8 @@ func (s *DescribeReplaceRootVolumeTasksInput) SetReplaceRootVolumeTaskIds(v []*s type DescribeReplaceRootVolumeTasksOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the root volume replacement task. @@ -100046,11 +100082,13 @@ type DescribeRouteTablesInput struct { // * vpc-id - The ID of the VPC for the route table. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // One or more route table IDs. @@ -100124,8 +100162,8 @@ func (s *DescribeRouteTablesInput) SetRouteTableIds(v []*string) *DescribeRouteT type DescribeRouteTablesOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about one or more route tables. @@ -100587,13 +100625,14 @@ type DescribeSecurityGroupRulesInput struct { // the filter value. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return in a single call. To retrieve the - // remaining results, make another request with the returned NextToken value. - // This value can be between 5 and 1000. If this parameter is not specified, - // then all results are returned. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. This + // value can be between 5 and 1000. If this parameter is not specified, then + // all items are returned. For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // The IDs of the security group rules. @@ -100664,8 +100703,8 @@ func (s *DescribeSecurityGroupRulesInput) SetSecurityGroupRuleIds(v []*string) * type DescribeSecurityGroupRulesOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about security group rules. @@ -100805,13 +100844,14 @@ type DescribeSecurityGroupsInput struct { // Default: Describes all of your security groups. GroupNames []*string `locationName:"GroupName" locationNameList:"GroupName" type:"list"` - // The maximum number of results to return in a single call. To retrieve the - // remaining results, make another request with the returned NextToken value. - // This value can be between 5 and 1000. If this parameter is not specified, - // then all results are returned. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. This + // value can be between 5 and 1000. If this parameter is not specified, then + // all items are returned. For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token to request the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -100885,8 +100925,8 @@ func (s *DescribeSecurityGroupsInput) SetNextToken(v string) *DescribeSecurityGr type DescribeSecurityGroupsOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the security groups. @@ -101066,11 +101106,13 @@ type DescribeSnapshotTierStatusInput struct { // | temporary-restore-completed | temporary-restore-failed) Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` } @@ -101119,8 +101161,8 @@ func (s *DescribeSnapshotTierStatusInput) SetNextToken(v string) *DescribeSnapsh type DescribeSnapshotTierStatusOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the snapshot's storage tier. @@ -101206,22 +101248,15 @@ type DescribeSnapshotsInput struct { // * volume-size - The size of the volume, in GiB. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of snapshot results returned by DescribeSnapshots in paginated - // output. When this parameter is used, DescribeSnapshots only returns MaxResults - // results in a single page along with a NextToken response element. The remaining - // results of the initial request can be seen by sending another DescribeSnapshots - // request with the returned NextToken value. This value can be between 5 and - // 1,000; if MaxResults is given a value larger than 1,000, only 1,000 results - // are returned. If this parameter is not used, then DescribeSnapshots returns - // all results. You cannot specify this parameter and the snapshot IDs parameter - // in the same request. + // The maximum number of snapshots to return for this request. This value can + // be between 5 and 1,000; if this value is larger than 1,000, only 1,000 results + // are returned. If this parameter is not used, then the request returns all + // snapshots. You cannot specify this parameter and the snapshot IDs parameter + // in the same request. For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `type:"integer"` - // The NextToken value returned from a previous paginated DescribeSnapshots - // request where MaxResults was used and the results exceeded the value of that - // parameter. Pagination continues from the end of the previous results that - // returned the NextToken value. This value is null when there are no more results - // to return. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // Scopes the results to snapshots with the specified owners. You can specify @@ -101301,10 +101336,8 @@ func (s *DescribeSnapshotsInput) SetSnapshotIds(v []*string) *DescribeSnapshotsI type DescribeSnapshotsOutput struct { _ struct{} `type:"structure"` - // The NextToken value to include in a future DescribeSnapshots request. When - // the results of a DescribeSnapshots request exceed MaxResults, this value - // can be used to retrieve the next page of results. This value is null when - // there are no more results to return. + // The token to include in another request to return the next page of snapshots. + // This value is null when there are no more snapshots to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the snapshots. @@ -102225,13 +102258,13 @@ type DescribeStaleSecurityGroupsInput struct { // it is UnauthorizedOperation. DryRun *bool `type:"boolean"` - // The maximum number of items to return for this request. The request returns - // a token that you can specify in a subsequent call to get the next set of - // results. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next set of items to return. (You received this token from - // a prior call.) + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `min:"1" type:"string"` // The ID of the VPC. @@ -102304,8 +102337,8 @@ func (s *DescribeStaleSecurityGroupsInput) SetVpcId(v string) *DescribeStaleSecu type DescribeStaleSecurityGroupsOutput struct { _ struct{} `type:"structure"` - // The token to use when requesting the next set of items. If there are no additional - // items to return, the string is empty. + // The token to include in another request to get the next page of items. If + // there are no additional items to return, the string is empty. NextToken *string `locationName:"nextToken" type:"string"` // Information about the stale security groups. @@ -102571,11 +102604,13 @@ type DescribeSubnetsInput struct { // * vpc-id - The ID of the VPC for the subnet. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // One or more subnet IDs. @@ -102648,8 +102683,8 @@ func (s *DescribeSubnetsInput) SetSubnetIds(v []*string) *DescribeSubnetsInput { type DescribeSubnetsOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about one or more subnets. @@ -102716,12 +102751,13 @@ type DescribeTagsInput struct { // * value - The tag value. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return in a single call. This value can - // be between 5 and 1000. To retrieve the remaining results, make another call - // with the returned NextToken value. + // The maximum number of items to return for this request. This value can be + // between 5 and 1000. To get the next page of items, make another request with + // the token returned in the output. For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `locationName:"maxResults" type:"integer"` - // The token to retrieve the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `locationName:"nextToken" type:"string"` } @@ -102770,8 +102806,8 @@ func (s *DescribeTagsInput) SetNextToken(v string) *DescribeTagsInput { type DescribeTagsOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // The tags. @@ -105545,20 +105581,16 @@ type DescribeVolumeStatusInput struct { // | insufficient-data). Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of volume results returned by DescribeVolumeStatus in - // paginated output. When this parameter is used, the request only returns MaxResults - // results in a single page along with a NextToken response element. The remaining - // results of the initial request can be seen by sending another request with - // the returned NextToken value. This value can be between 5 and 1,000; if MaxResults - // is given a value larger than 1,000, only 1,000 results are returned. If this - // parameter is not used, then DescribeVolumeStatus returns all results. You - // cannot specify this parameter and the volume IDs parameter in the same request. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. This + // value can be between 5 and 1,000; if the value is larger than 1,000, only + // 1,000 results are returned. If this parameter is not used, then all items + // are returned. You cannot specify this parameter and the volume IDs parameter + // in the same request. For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `type:"integer"` - // The NextToken value to include in a future DescribeVolumeStatus request. - // When the results of the request exceed MaxResults, this value can be used - // to retrieve the next page of results. This value is null when there are no - // more results to return. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // The IDs of the volumes. @@ -105618,8 +105650,8 @@ func (s *DescribeVolumeStatusInput) SetVolumeIds(v []*string) *DescribeVolumeSta type DescribeVolumeStatusOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the status of the volumes. @@ -105715,21 +105747,15 @@ type DescribeVolumesInput struct { // | sc1| standard) Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of volume results returned by DescribeVolumes in paginated - // output. When this parameter is used, DescribeVolumes only returns MaxResults - // results in a single page along with a NextToken response element. The remaining - // results of the initial request can be seen by sending another DescribeVolumes - // request with the returned NextToken value. This value can be between 5 and - // 500; if MaxResults is given a value larger than 500, only 500 results are - // returned. If this parameter is not used, then DescribeVolumes returns all - // results. You cannot specify this parameter and the volume IDs parameter in - // the same request. + // The maximum number of volumes to return for this request. This value can + // be between 5 and 500; if you specify a value larger than 500, only 500 items + // are returned. If this parameter is not used, then all items are returned. + // You cannot specify this parameter and the volume IDs parameter in the same + // request. For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `locationName:"maxResults" type:"integer"` - // The NextToken value returned from a previous paginated DescribeVolumes request - // where MaxResults was used and the results exceeded the value of that parameter. - // Pagination continues from the end of the previous results that returned the - // NextToken value. This value is null when there are no more results to return. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned from the previous request. NextToken *string `locationName:"nextToken" type:"string"` // The volume IDs. @@ -105824,10 +105850,11 @@ type DescribeVolumesModificationsInput struct { Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // The maximum number of results (up to a limit of 500) to be returned in a - // paginated request. + // paginated request. For more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `type:"integer"` - // The nextToken value returned by a previous paginated request. + // The token returned by a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // The IDs of the volumes. @@ -105885,7 +105912,8 @@ func (s *DescribeVolumesModificationsInput) SetVolumeIds(v []*string) *DescribeV type DescribeVolumesModificationsOutput struct { _ struct{} `type:"structure"` - // Token for pagination, null if there are no more results + // The token to include in another request to get the next page of items. This + // value is null if there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the volume modifications. @@ -105925,10 +105953,8 @@ func (s *DescribeVolumesModificationsOutput) SetVolumesModifications(v []*Volume type DescribeVolumesOutput struct { _ struct{} `type:"structure"` - // The NextToken value to include in a future DescribeVolumes request. When - // the results of a DescribeVolumes request exceed MaxResults, this value can - // be used to retrieve the next page of results. This value is null when there - // are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the volumes. @@ -106102,11 +106128,13 @@ func (s *DescribeVpcAttributeOutput) SetVpcId(v string) *DescribeVpcAttributeOut type DescribeVpcClassicLinkDnsSupportInput struct { _ struct{} `type:"structure"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `locationName:"maxResults" min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `locationName:"nextToken" min:"1" type:"string"` // One or more VPC IDs. @@ -106168,8 +106196,8 @@ func (s *DescribeVpcClassicLinkDnsSupportInput) SetVpcIds(v []*string) *Describe type DescribeVpcClassicLinkDnsSupportOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" min:"1" type:"string"` // Information about the ClassicLink DNS support status of the VPCs. @@ -107145,11 +107173,13 @@ type DescribeVpcPeeringConnectionsInput struct { // * vpc-peering-connection-id - The ID of the VPC peering connection. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // One or more VPC peering connection IDs. @@ -107222,8 +107252,8 @@ func (s *DescribeVpcPeeringConnectionsInput) SetVpcPeeringConnectionIds(v []*str type DescribeVpcPeeringConnectionsOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the VPC peering connections. @@ -107318,11 +107348,13 @@ type DescribeVpcsInput struct { // * vpc-id - The ID of the VPC. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // One or more VPC IDs. @@ -107395,8 +107427,8 @@ func (s *DescribeVpcsInput) SetVpcIds(v []*string) *DescribeVpcsInput { type DescribeVpcsOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about one or more VPCs. @@ -111845,14 +111877,32 @@ type EbsBlockDevice struct { // Encrypted volumes can only be attached to instances that support Amazon EBS // encryption. For more information, see Supported instance types (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances). // - // This parameter is not returned by DescribeImageAttribute (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImageAttribute.html). + // This parameter is not returned by DescribeImageAttribute. // - // For CreateImage and RegisterImage, you can specify this parameter only for - // block device mappings that result in new, empty volumes when instances are - // launched from the image. Omit this parameter on block device mappings that - // include an existing volume or snapshot. If you include this parameter, and - // specify an encryption setting that is different from the existing volume - // or snapshot, the request will fail. + // For CreateImage and RegisterImage, whether you can include this parameter, + // and the allowed values differ depending on the type of block device mapping + // you are creating. + // + // * If you are creating a block device mapping for a new (empty) volume, + // you can include this parameter, and specify either true for an encrypted + // volume, or false for an unencrypted volume. If you omit this parameter, + // it defaults to false (unencrypted). + // + // * If you are creating a block device mapping from an existing encrypted + // or unencrypted snapshot, you must omit this parameter. If you include + // this parameter, the request will fail, regardless of the value that you + // specify. + // + // * If you are creating a block device mapping from an existing unencrypted + // volume, you can include this parameter, but you must specify false. If + // you specify true, the request will fail. In this case, we recommend that + // you omit the parameter. + // + // * If you are creating a block device mapping from an existing encrypted + // volume, you can include this parameter, and specify either true or false. + // However, if you specify false, the parameter is ignored and the block + // device mapping is always encrypted. In this case, we recommend that you + // omit the parameter. Encrypted *bool `locationName:"encrypted" type:"boolean"` // The number of I/O operations per second (IOPS). For gp3, io1, and io2 volumes, @@ -123888,6 +123938,10 @@ type Host struct { // The ID of the Dedicated Host. HostId *string `locationName:"hostId" type:"string"` + // Indicates whether host maintenance is enabled or disabled for the Dedicated + // Host. + HostMaintenance *string `locationName:"hostMaintenance" type:"string" enum:"HostMaintenance"` + // The hardware specifications of the Dedicated Host. HostProperties *HostProperties `locationName:"hostProperties" type:"structure"` @@ -123989,6 +124043,12 @@ func (s *Host) SetHostId(v string) *Host { return s } +// SetHostMaintenance sets the HostMaintenance field's value. +func (s *Host) SetHostMaintenance(v string) *Host { + s.HostMaintenance = &v + return s +} + // SetHostProperties sets the HostProperties field's value. func (s *Host) SetHostProperties(v *HostProperties) *Host { s.HostProperties = v @@ -134117,7 +134177,11 @@ type LaunchSpecification struct { SubnetId *string `locationName:"subnetId" type:"string"` // The Base64-encoded user data for the instance. - UserData *string `locationName:"userData" type:"string"` + // + // UserData is a sensitive parameter and its value will be + // replaced with "sensitive" in string returned by LaunchSpecification's + // String and GoString methods. + UserData *string `locationName:"userData" type:"string" sensitive:"true"` } // String returns the string representation. @@ -137217,11 +137281,13 @@ type ListSnapshotsInRecycleBinInput struct { // it is UnauthorizedOperation. DryRun *bool `type:"boolean"` - // The maximum number of results to return with a single call. To retrieve the - // remaining results, make another call with the returned nextToken value. + // The maximum number of items to return for this request. To get the next page + // of items, make another request with the token returned in the output. For + // more information, see Pagination (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html#api-pagination). MaxResults *int64 `min:"5" type:"integer"` - // The token for the next page of results. + // The token returned from a previous paginated request. Pagination continues + // from the end of the items returned by the previous request. NextToken *string `type:"string"` // The IDs of the snapshots to list. Omit this parameter to list all of the @@ -137287,8 +137353,8 @@ func (s *ListSnapshotsInRecycleBinInput) SetSnapshotIds(v []*string) *ListSnapsh type ListSnapshotsInRecycleBinOutput struct { _ struct{} `type:"structure"` - // The token to use to retrieve the next page of results. This value is null - // when there are no more results to return. + // The token to include in another request to get the next page of items. This + // value is null when there are no more items to return. NextToken *string `locationName:"nextToken" type:"string"` // Information about the snapshots. @@ -139816,6 +139882,11 @@ type ModifyHostsInput struct { // HostIds is a required field HostIds []*string `locationName:"hostId" locationNameList:"item" type:"list" required:"true"` + // Indicates whether to enable or disable host maintenance for the Dedicated + // Host. For more information, see Host maintenance (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-hosts-maintenance.html) + // in the Amazon EC2 User Guide. + HostMaintenance *string `type:"string" enum:"HostMaintenance"` + // Indicates whether to enable or disable host recovery for the Dedicated Host. // For more information, see Host recovery (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-hosts-recovery.html) // in the Amazon EC2 User Guide. @@ -139883,6 +139954,12 @@ func (s *ModifyHostsInput) SetHostIds(v []*string) *ModifyHostsInput { return s } +// SetHostMaintenance sets the HostMaintenance field's value. +func (s *ModifyHostsInput) SetHostMaintenance(v string) *ModifyHostsInput { + s.HostMaintenance = &v + return s +} + // SetHostRecovery sets the HostRecovery field's value. func (s *ModifyHostsInput) SetHostRecovery(v string) *ModifyHostsInput { s.HostRecovery = &v @@ -157710,7 +157787,11 @@ type RequestSpotLaunchSpecification struct { // The Base64-encoded user data for the instance. User data is limited to 16 // KB. - UserData *string `locationName:"userData" type:"string"` + // + // UserData is a sensitive parameter and its value will be + // replaced with "sensitive" in string returned by RequestSpotLaunchSpecification's + // String and GoString methods. + UserData *string `locationName:"userData" type:"string" sensitive:"true"` } // String returns the string representation. @@ -159781,7 +159862,11 @@ type ResponseLaunchTemplateData struct { TagSpecifications []*LaunchTemplateTagSpecification `locationName:"tagSpecificationSet" locationNameList:"item" type:"list"` // The user data for the instance. - UserData *string `locationName:"userData" type:"string"` + // + // UserData is a sensitive parameter and its value will be + // replaced with "sensitive" in string returned by ResponseLaunchTemplateData's + // String and GoString methods. + UserData *string `locationName:"userData" type:"string" sensitive:"true"` } // String returns the string representation. @@ -162130,8 +162215,12 @@ type RunScheduledInstancesInput struct { // The launch specification. You must match the instance type, Availability // Zone, network, and platform of the schedule that you purchased. // + // LaunchSpecification is a sensitive parameter and its value will be + // replaced with "sensitive" in string returned by RunScheduledInstancesInput's + // String and GoString methods. + // // LaunchSpecification is a required field - LaunchSpecification *ScheduledInstancesLaunchSpecification `type:"structure" required:"true"` + LaunchSpecification *ScheduledInstancesLaunchSpecification `type:"structure" required:"true" sensitive:"true"` // The Scheduled Instance ID. // @@ -163053,7 +163142,7 @@ func (s *ScheduledInstancesIpv6Address) SetIpv6Address(v string) *ScheduledInsta // the ID of the subnet. You can specify the subnet using either SubnetId or // NetworkInterface. type ScheduledInstancesLaunchSpecification struct { - _ struct{} `type:"structure"` + _ struct{} `type:"structure" sensitive:"true"` // The block device mapping entries. BlockDeviceMappings []*ScheduledInstancesBlockDeviceMapping `locationName:"BlockDeviceMapping" locationNameList:"BlockDeviceMapping" type:"list"` @@ -166061,7 +166150,11 @@ type SpotFleetLaunchSpecification struct { TagSpecifications []*SpotFleetTagSpecification `locationName:"tagSpecificationSet" locationNameList:"item" type:"list"` // The Base64-encoded user data that instances use when starting up. - UserData *string `locationName:"userData" type:"string"` + // + // UserData is a sensitive parameter and its value will be + // replaced with "sensitive" in string returned by SpotFleetLaunchSpecification's + // String and GoString methods. + UserData *string `locationName:"userData" type:"string" sensitive:"true"` // The number of units provided by the specified instance type. These are the // same units that you chose to set the target capacity in terms of instances, @@ -169373,7 +169466,9 @@ func (s *TagDescription) SetValue(v string) *TagDescription { return s } -// The tags to apply to a resource when the resource is being created. +// The tags to apply to a resource when the resource is being created. When +// you specify a tag, you must specify the resource type to tag, otherwise the +// request will fail. // // The Valid Values lists all the resource types that can be tagged. However, // the action you're using might not support tagging all of these resource types. @@ -181657,6 +181752,22 @@ func GatewayType_Values() []string { } } +const ( + // HostMaintenanceOn is a HostMaintenance enum value + HostMaintenanceOn = "on" + + // HostMaintenanceOff is a HostMaintenance enum value + HostMaintenanceOff = "off" +) + +// HostMaintenance_Values returns all elements of the HostMaintenance enum +func HostMaintenance_Values() []string { + return []string{ + HostMaintenanceOn, + HostMaintenanceOff, + } +} + const ( // HostRecoveryOn is a HostRecovery enum value HostRecoveryOn = "on" diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go index a10de4f3f..a970f12fb 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/waiters.go @@ -1156,6 +1156,57 @@ func (c *EC2) WaitUntilSnapshotCompletedWithContext(ctx aws.Context, input *Desc return w.WaitWithContext(ctx) } +// WaitUntilSnapshotImported uses the Amazon EC2 API operation +// DescribeImportSnapshotTasks to wait for a condition to be met before returning. +// If the condition is not met within the max attempt window, an error will +// be returned. +func (c *EC2) WaitUntilSnapshotImported(input *DescribeImportSnapshotTasksInput) error { + return c.WaitUntilSnapshotImportedWithContext(aws.BackgroundContext(), input) +} + +// WaitUntilSnapshotImportedWithContext is an extended version of WaitUntilSnapshotImported. +// With the support for passing in a context and options to configure the +// Waiter and the underlying request options. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *EC2) WaitUntilSnapshotImportedWithContext(ctx aws.Context, input *DescribeImportSnapshotTasksInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "WaitUntilSnapshotImported", + MaxAttempts: 40, + Delay: request.ConstantWaiterDelay(15 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, Argument: "ImportSnapshotTasks[].SnapshotTaskDetail.Status", + Expected: "completed", + }, + { + State: request.FailureWaiterState, + Matcher: request.PathAnyWaiterMatch, Argument: "ImportSnapshotTasks[].SnapshotTaskDetail.Status", + Expected: "error", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *DescribeImportSnapshotTasksInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeImportSnapshotTasksRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + w.ApplyOptions(opts...) + + return w.WaitWithContext(ctx) +} + // WaitUntilSpotInstanceRequestFulfilled uses the Amazon EC2 API operation // DescribeSpotInstanceRequests to wait for a condition to be met before returning. // If the condition is not met within the max attempt window, an error will diff --git a/vendor/modules.txt b/vendor/modules.txt index a9454736c..28ba246c4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -8,7 +8,7 @@ github.com/ansel1/merry # github.com/ansel1/merry/v2 v2.0.1 ## explicit; go 1.12 github.com/ansel1/merry/v2 -# github.com/aws/aws-sdk-go v1.44.195 +# github.com/aws/aws-sdk-go v1.44.205 ## explicit; go 1.11 github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws/awserr From ef6aabbfb00ecb7da49b7d0d21bcdd485db583d8 Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Wed, 22 Feb 2023 08:25:54 +0100 Subject: [PATCH 002/165] doc: update README for 3.8.0 release updated README to deprecate 3.6.x release and pin latest release to 3.8.0 Signed-off-by: Madhu Rajanna --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b3393e316..5c5f9a34b 100644 --- a/README.md +++ b/README.md @@ -56,11 +56,10 @@ environments. | Ceph CSI Version | Container Orchestrator Name | Version Tested| | -----------------| --------------------------- | --------------| +| v3.8.0 | Kubernetes | v1.24, v1.25, v1.26| | v3.7.2 | Kubernetes | v1.22, v1.23, v1.24| | v3.7.1 | Kubernetes | v1.22, v1.23, v1.24| | v3.7.0 | Kubernetes | v1.22, v1.23, v1.24| -| v3.6.1 | Kubernetes | v1.21, v1.22, v1.23| -| v3.6.0 | Kubernetes | v1.21, v1.22, v1.23| There is work in progress to make this CO-independent and thus support other orchestration environments (Nomad, Mesos..etc). @@ -70,8 +69,8 @@ NOTE: The supported window of Ceph CSI versions is "N.(x-1)": (N (Latest major release) . (x (Latest minor release) - 1)). -For example, if the Ceph CSI latest major version is `3.7.0` today, support is -provided for the versions above `3.6.0`. If users are running an unsupported +For example, if the Ceph CSI latest major version is `3.8.0` today, support is +provided for the versions above `3.7.0`. If users are running an unsupported Ceph CSI version, they will be asked to upgrade when requesting support. ## Support Matrix @@ -131,14 +130,15 @@ in the Kubernetes documentation. | Ceph CSI Release/Branch | Container image name | Image Tag | | ----------------------- | ---------------------------- | --------- | | devel (Branch) | quay.io/cephcsi/cephcsi | canary | +| v3.8.0 (Release) | quay.io/cephcsi/cephcsi | v3.8.0 | | v3.7.2 (Release) | quay.io/cephcsi/cephcsi | v3.7.2 | | v3.7.1 (Release) | quay.io/cephcsi/cephcsi | v3.7.1 | | v3.7.0 (Release) | quay.io/cephcsi/cephcsi | v3.7.0 | -| v3.6.1 (Release) | quay.io/cephcsi/cephcsi | v3.6.1 | -| v3.6.0 (Release) | quay.io/cephcsi/cephcsi | v3.6.0 | | Deprecated Ceph CSI Release/Branch | Container image name | Image Tag | | ----------------------- | --------------------------------| --------- | +| v3.6.1 (Release) | quay.io/cephcsi/cephcsi | v3.6.1 | +| v3.6.0 (Release) | quay.io/cephcsi/cephcsi | v3.6.0 | | v3.5.1 (Release) | quay.io/cephcsi/cephcsi | v3.5.1 | | v3.5.0 (Release) | quay.io/cephcsi/cephcsi | v3.5.0 | | v3.4.0 (Release) | quay.io/cephcsi/cephcsi | v3.4.0 | From 5de4c2a970aa3d5d6c50c85ea49856905c681313 Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Wed, 22 Feb 2023 08:31:35 +0100 Subject: [PATCH 003/165] doc: upgrade doc from 3.7 to 3.8 updating upgrade document from 3.7 to 3.8.0 Signed-off-by: Madhu Rajanna --- docs/ceph-csi-upgrade.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/ceph-csi-upgrade.md b/docs/ceph-csi-upgrade.md index d62d1fae0..491e8aefd 100644 --- a/docs/ceph-csi-upgrade.md +++ b/docs/ceph-csi-upgrade.md @@ -9,6 +9,7 @@ - [Upgrading from v3.4 to v3.5](#upgrading-from-v34-to-v35) - [Upgrading from v3.5 to v3.6](#upgrading-from-v35-to-v36) - [Upgrading from v3.6 to v3.7](#upgrading-from-v36-to-v37) + - [Upgrading from v3.7 to v3.8](#upgrading-from-v37-to-v38) - [Upgrading CephFS](#upgrading-cephfs) - [1. Upgrade CephFS Provisioner resources](#1-upgrade-cephfs-provisioner-resources) - [1.1 Update the CephFS Provisioner RBAC](#11-update-the-cephfs-provisioner-rbac) @@ -55,7 +56,7 @@ To avoid this issue in future upgrades, we recommend that you do not use the fuse client as of now. This guide will walk you through the steps to upgrade the software in a cluster -from v3.4 to v3.5 +from v3.7 to v3.8 ### Snapshot-controller and snapshot crd @@ -94,6 +95,11 @@ to upgrade from cephcsi v3.5 to v3.6 ## Upgrading from v3.6 to v3.7 +Refer [upgrade-from-v3.6-v3.7](https://github.com/ceph/ceph-csi/blob/v3.7.2/docs/ceph-csi-upgrade.md) +to upgrade from cephcsi v3.6 to v3.7 + +## Upgrading from v3.7 to v3.8 + **Ceph-csi releases from devel are expressly unsupported.** It is strongly recommended that you use [official releases](https://github.com/ceph/ceph-csi/releases) of Ceph-csi. Unreleased @@ -102,15 +108,15 @@ that will not be supported in the official releases. Builds from the devel branch can have functionality changed and even removed at any time without compatibility support and without prior notice. -**Also, we do not recommend any direct upgrades to 3.7 except from 3.6 to 3.7.** -For example, upgrading from 3.5 to 3.7 is not recommended. +**Also, we do not recommend any direct upgrades to 3.8 except from 3.7 to 3.8.** +For example, upgrading from 3.6 to 3.8 is not recommended. -git checkout v3.7.2 tag +git checkout v3.8.0 tag ```bash git clone https://github.com/ceph/ceph-csi.git cd ./ceph-csi -git checkout v3.7.2 +git checkout v3.8.0 ``` ```console @@ -246,7 +252,7 @@ kubectl delete role cephfs-csi-nodeplugin-psp --ignore-not-found kubectl delete rolebinding cephfs-csi-nodeplugin-psp --ignore-not-found ``` -we have successfully upgraded cephfs csi from v3.6 to v3.7 +we have successfully upgraded cephfs csi from v3.7 to v3.8 ### Upgrading RBD @@ -329,7 +335,7 @@ kubectl delete role rbd-csi-vault-token-review-psp --ignore-not-found kubectl delete rolebinding rbd-csi-vault-token-review-psp --ignore-not-found ``` -we have successfully upgraded RBD csi from v3.6 to v3.7 +we have successfully upgraded RBD csi from v3.7 to v3.8 ### Upgrading NFS @@ -391,7 +397,7 @@ daemonset.apps/csi-nfsplugin configured service/csi-metrics-nfsplugin configured ``` -we have successfully upgraded nfs csi from v3.6 to v3.7 +we have successfully upgraded nfs csi from v3.7 to v3.8 ### CSI Sidecar containers consideration From 991c21f7fdeacef76ac08911d219435d89a1c119 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 22 Feb 2023 12:56:59 +0100 Subject: [PATCH 004/165] ci: do not add `ok-to-test` if CentOS jobs were successful Mergify does not add the `ok-to-test` label immediately anymore. But once the CentOS CI jobs have finished, the label still gets added. With the additional check, this should not be the case anymore. Signed-off-by: Niels de Vos --- .mergify.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index 9b5a2281a..730335411 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -52,6 +52,8 @@ pull_request_rules: - "check-pending=Queue: Embarked in merge train" - not: check-pending~=^ci/centos + - not: + status-success~=^ci/centos actions: label: add: From f84d43c6d18b54dcb90287cea408ffa37a9df60c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:30:55 +0000 Subject: [PATCH 005/165] rebase: bump github.com/google/fscrypt from 0.3.3 to 0.3.4 Bumps [github.com/google/fscrypt](https://github.com/google/fscrypt) from 0.3.3 to 0.3.4. - [Release notes](https://github.com/google/fscrypt/releases) - [Changelog](https://github.com/google/fscrypt/blob/master/NEWS.md) - [Commits](https://github.com/google/fscrypt/compare/v0.3.3...v0.3.4) --- updated-dependencies: - dependency-name: github.com/google/fscrypt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 13 +- .../google/fscrypt/actions/config.go | 26 +- .../google/fscrypt/actions/policy.go | 2 +- .../google/fscrypt/actions/recovery.go | 6 +- .../google/fscrypt/filesystem/filesystem.go | 11 +- .../google/fscrypt/filesystem/mountpoint.go | 9 +- .../google/fscrypt/metadata/checks.go | 36 +- .../google/fscrypt/metadata/config.go | 36 +- .../google/fscrypt/metadata/metadata.pb.go | 1115 +++++++++++------ .../google/fscrypt/metadata/metadata.proto | 8 +- .../google/fscrypt/metadata/policy.go | 25 +- vendor/modules.txt | 4 +- 13 files changed, 852 insertions(+), 441 deletions(-) diff --git a/go.mod b/go.mod index 9120e6f6b..44c2d528c 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/csi-addons/spec v0.1.2-0.20221101132540-98eff76b0ff8 github.com/gemalto/kmip-go v0.0.8 github.com/golang/protobuf v1.5.2 - github.com/google/fscrypt v0.3.3 + github.com/google/fscrypt v0.3.4 github.com/google/uuid v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 diff --git a/go.sum b/go.sum index 03c1a8ffe..9820c4794 100644 --- a/go.sum +++ b/go.sum @@ -67,6 +67,7 @@ github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRY github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= @@ -220,6 +221,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -422,8 +424,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= -github.com/google/fscrypt v0.3.3 h1:qwx9OCR/xZE68VGr/r0/yugFhlGpIOGsH9JHrttP7vc= -github.com/google/fscrypt v0.3.3/go.mod h1:H1JHtH8BVe0dYNhzx1Ztkn3azQ0OBdoOmM828vEWAXc= +github.com/google/fscrypt v0.3.4 h1:XGSVMIsQFooj82aRRfYn3JpgU/4fOTnzXPnjhxC8uH8= +github.com/google/fscrypt v0.3.4/go.mod h1:BRpw7vaeDitXGRvXa281i/ivQszAdBIiUYDWHjVTkcs= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= @@ -1010,6 +1012,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= @@ -1114,6 +1117,7 @@ golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= @@ -1128,6 +1132,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1343,7 +1348,6 @@ golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -1395,7 +1399,6 @@ golang.org/x/tools v0.0.0-20190718200317-82a3ea8a504c/go.mod h1:jcCCGcm9btYwXyDq golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191025023517-2077df36852e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1440,6 +1443,7 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1673,6 +1677,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.3.0/go.mod h1:vlRD9XErLMGT+mDuofSr0mMMquscM/1nQqtRSsh6m70= k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI= diff --git a/vendor/github.com/google/fscrypt/actions/config.go b/vendor/github.com/google/fscrypt/actions/config.go index a8eb029db..7c7c0e619 100644 --- a/vendor/github.com/google/fscrypt/actions/config.go +++ b/vendor/github.com/google/fscrypt/actions/config.go @@ -29,6 +29,7 @@ import ( "time" "golang.org/x/sys/unix" + "google.golang.org/protobuf/proto" "github.com/google/fscrypt/crypto" "github.com/google/fscrypt/filesystem" @@ -186,11 +187,17 @@ func getHashingCosts(target time.Duration) (*metadata.HashingCosts, error) { log.Printf("Finding hashing costs that take %v\n", target) // Start out with the minimal possible costs that use all the CPUs. - nCPUs := int64(runtime.NumCPU()) + parallelism := int64(runtime.NumCPU()) + // golang.org/x/crypto/argon2 only supports parallelism up to 255. + // For compatibility, don't use more than that amount. + if parallelism > metadata.MaxParallelism { + parallelism = metadata.MaxParallelism + } costs := &metadata.HashingCosts{ - Time: 1, - Memory: 8 * nCPUs, - Parallelism: nCPUs, + Time: 1, + Memory: 8 * parallelism, + Parallelism: parallelism, + TruncationFixed: true, } // If even the minimal costs are not fast enough, just return the @@ -210,7 +217,7 @@ func getHashingCosts(target time.Duration) (*metadata.HashingCosts, error) { memoryKiBLimit := memoryBytesLimit() / 1024 for { // Store a copy of the previous costs - costsPrev := *costs + costsPrev := proto.Clone(costs).(*metadata.HashingCosts) tPrev := t // Double the memory up to the max, then double the time. @@ -223,7 +230,7 @@ func getHashingCosts(target time.Duration) (*metadata.HashingCosts, error) { // If our hashing failed, return the last good set of costs. if t, err = timeHashingCosts(costs); err != nil { log.Printf("Hashing with costs={%v} failed: %v\n", costs, err) - return &costsPrev, nil + return costsPrev, nil } log.Printf("Costs={%v}\t-> %v\n", costs, t) @@ -232,9 +239,10 @@ func getHashingCosts(target time.Duration) (*metadata.HashingCosts, error) { if t >= target { f := float64(target-tPrev) / float64(t-tPrev) return &metadata.HashingCosts{ - Time: betweenCosts(costsPrev.Time, costs.Time, f), - Memory: betweenCosts(costsPrev.Memory, costs.Memory, f), - Parallelism: costs.Parallelism, + Time: betweenCosts(costsPrev.Time, costs.Time, f), + Memory: betweenCosts(costsPrev.Memory, costs.Memory, f), + Parallelism: costs.Parallelism, + TruncationFixed: costs.TruncationFixed, }, nil } } diff --git a/vendor/github.com/google/fscrypt/actions/policy.go b/vendor/github.com/google/fscrypt/actions/policy.go index 3b2017693..c62172562 100644 --- a/vendor/github.com/google/fscrypt/actions/policy.go +++ b/vendor/github.com/google/fscrypt/actions/policy.go @@ -25,8 +25,8 @@ import ( "os" "os/user" - "github.com/golang/protobuf/proto" "github.com/pkg/errors" + "google.golang.org/protobuf/proto" "github.com/google/fscrypt/crypto" "github.com/google/fscrypt/filesystem" diff --git a/vendor/github.com/google/fscrypt/actions/recovery.go b/vendor/github.com/google/fscrypt/actions/recovery.go index 8a769cc7e..2bb8a23d3 100644 --- a/vendor/github.com/google/fscrypt/actions/recovery.go +++ b/vendor/github.com/google/fscrypt/actions/recovery.go @@ -23,6 +23,8 @@ import ( "os" "strconv" + "google.golang.org/protobuf/proto" + "github.com/google/fscrypt/crypto" "github.com/google/fscrypt/metadata" "github.com/google/fscrypt/util" @@ -31,10 +33,10 @@ import ( // modifiedContextWithSource returns a copy of ctx with the protector source // replaced by source. func modifiedContextWithSource(ctx *Context, source metadata.SourceType) *Context { - modifiedConfig := *ctx.Config + modifiedConfig := proto.Clone(ctx.Config).(*metadata.Config) modifiedConfig.Source = source modifiedCtx := *ctx - modifiedCtx.Config = &modifiedConfig + modifiedCtx.Config = modifiedConfig return &modifiedCtx } diff --git a/vendor/github.com/google/fscrypt/filesystem/filesystem.go b/vendor/github.com/google/fscrypt/filesystem/filesystem.go index 27bfa2415..0e1f0c822 100644 --- a/vendor/github.com/google/fscrypt/filesystem/filesystem.go +++ b/vendor/github.com/google/fscrypt/filesystem/filesystem.go @@ -35,7 +35,6 @@ package filesystem import ( "fmt" "io" - "io/ioutil" "log" "os" "os/user" @@ -45,9 +44,9 @@ import ( "syscall" "time" - "github.com/golang/protobuf/proto" "github.com/pkg/errors" "golang.org/x/sys/unix" + "google.golang.org/protobuf/proto" "github.com/google/fscrypt/metadata" "github.com/google/fscrypt/util" @@ -335,7 +334,7 @@ func (m *Mount) PolicyPath(descriptor string) string { // directory and returns a temporary Mount which represents this temporary // directory. The caller is responsible for removing this temporary directory. func (m *Mount) tempMount() (*Mount, error) { - tempDir, err := ioutil.TempDir(filepath.Dir(m.BaseDir()), tempPrefix) + tempDir, err := os.MkdirTemp(filepath.Dir(m.BaseDir()), tempPrefix) return &Mount{Path: tempDir}, err } @@ -393,7 +392,7 @@ func (m *Mount) isFscryptSetupAllowed() bool { return true } switch m.FilesystemType { - case "ext4", "f2fs", "ubifs", "btrfs", "ceph", "xfs": + case "ext4", "f2fs", "ubifs", "btrfs", "ceph", "xfs", "lustre": return true default: return false @@ -635,7 +634,7 @@ func (m *Mount) writeData(path string, data []byte, owner *user.User, mode os.Fi // Write the data to a temporary file, sync it, then rename into place // so that the operation will be atomic. dirPath := filepath.Dir(path) - tempFile, err := ioutil.TempFile(dirPath, tempPrefix) + tempFile, err := os.CreateTemp(dirPath, tempPrefix) if err != nil { log.Print(err) if os.IsPermission(err) { @@ -767,7 +766,7 @@ func readMetadataFileSafe(path string, trustedUser *user.User) ([]byte, int64, e } // Read the file contents, allowing at most maxMetadataFileSize bytes. reader := &io.LimitedReader{R: file, N: maxMetadataFileSize + 1} - data, err := ioutil.ReadAll(reader) + data, err := io.ReadAll(reader) if err != nil { return nil, -1, err } diff --git a/vendor/github.com/google/fscrypt/filesystem/mountpoint.go b/vendor/github.com/google/fscrypt/filesystem/mountpoint.go index 0b0693b2b..0abae06f0 100644 --- a/vendor/github.com/google/fscrypt/filesystem/mountpoint.go +++ b/vendor/github.com/google/fscrypt/filesystem/mountpoint.go @@ -25,7 +25,6 @@ import ( "bufio" "fmt" "io" - "io/ioutil" "log" "os" "path/filepath" @@ -537,11 +536,15 @@ func getMountFromLink(link string) (*Mount, error) { } func (mnt *Mount) getFilesystemUUID() (string, error) { - dirContents, err := ioutil.ReadDir(uuidDirectory) + dirEntries, err := os.ReadDir(uuidDirectory) if err != nil { return "", err } - for _, fileInfo := range dirContents { + for _, dirEntry := range dirEntries { + fileInfo, err := dirEntry.Info() + if err != nil { + continue + } if fileInfo.Mode()&os.ModeSymlink == 0 { continue // Only interested in UUID symlinks } diff --git a/vendor/github.com/google/fscrypt/metadata/checks.go b/vendor/github.com/google/fscrypt/metadata/checks.go index 84fd208c8..d7dea4165 100644 --- a/vendor/github.com/google/fscrypt/metadata/checks.go +++ b/vendor/github.com/google/fscrypt/metadata/checks.go @@ -20,8 +20,11 @@ package metadata import ( - "github.com/golang/protobuf/proto" + "log" + "math" + "github.com/pkg/errors" + "google.golang.org/protobuf/proto" "github.com/google/fscrypt/util" ) @@ -57,20 +60,37 @@ func (s SourceType) CheckValidity() error { return nil } +// MaxParallelism is the maximum allowed value for HashingCosts.Parallelism. +const MaxParallelism = math.MaxUint8 + // CheckValidity ensures the hash costs will be accepted by Argon2. func (h *HashingCosts) CheckValidity() error { if h == nil { return errNotInitialized } - if h.Time <= 0 { - return errors.Errorf("time=%d is not positive", h.Time) + + minP := int64(1) + p := uint8(h.Parallelism) + if h.Parallelism < minP || h.Parallelism > MaxParallelism { + if h.TruncationFixed || p == 0 { + return errors.Errorf("parallelism cost %d is not in range [%d, %d]", + h.Parallelism, minP, MaxParallelism) + } + // Previously we unconditionally casted costs.Parallelism to a uint8, + // so we replicate this behavior for backwards compatibility. + log.Printf("WARNING: Truncating parallelism cost of %d to %d", h.Parallelism, p) } - if h.Parallelism <= 0 { - return errors.Errorf("parallelism=%d is not positive", h.Parallelism) + + minT := int64(1) + maxT := int64(math.MaxUint32) + if h.Time < minT || h.Time > maxT { + return errors.Errorf("time cost %d is not in range [%d, %d]", h.Time, minT, maxT) } - minMemory := 8 * h.Parallelism - if h.Memory < minMemory { - return errors.Errorf("memory=%d is less than minimum (%d)", h.Memory, minMemory) + + minM := 8 * int64(p) + maxM := int64(math.MaxUint32) + if h.Memory < minM || h.Memory > maxM { + return errors.Errorf("memory cost %d KiB is not in range [%d, %d]", h.Memory, minM, maxM) } return nil } diff --git a/vendor/github.com/google/fscrypt/metadata/config.go b/vendor/github.com/google/fscrypt/metadata/config.go index b3c872693..1d93d7497 100644 --- a/vendor/github.com/google/fscrypt/metadata/config.go +++ b/vendor/github.com/google/fscrypt/metadata/config.go @@ -29,31 +29,39 @@ package metadata import ( "io" - "github.com/golang/protobuf/jsonpb" + "google.golang.org/protobuf/encoding/protojson" ) // WriteConfig outputs the Config data as nicely formatted JSON func WriteConfig(config *Config, out io.Writer) error { - m := jsonpb.Marshaler{ - EmitDefaults: true, - EnumsAsInts: false, - Indent: "\t", - OrigName: true, + m := protojson.MarshalOptions{ + Multiline: true, + Indent: "\t", + UseProtoNames: true, + UseEnumNumbers: false, + EmitUnpopulated: true, } - if err := m.Marshal(out, config); err != nil { + bytes, err := m.Marshal(config) + if err != nil { return err } - - _, err := out.Write([]byte{'\n'}) + if _, err = out.Write(bytes); err != nil { + return err + } + _, err = out.Write([]byte{'\n'}) return err } // ReadConfig writes the JSON data into the config structure func ReadConfig(in io.Reader) (*Config, error) { - config := new(Config) - // Allow (and ignore) unknown fields for forwards compatibility. - u := jsonpb.Unmarshaler{ - AllowUnknownFields: true, + bytes, err := io.ReadAll(in) + if err != nil { + return nil, err } - return config, u.Unmarshal(in, config) + config := new(Config) + // Discard unknown fields for forwards compatibility. + u := protojson.UnmarshalOptions{ + DiscardUnknown: true, + } + return config, u.Unmarshal(bytes, config) } diff --git a/vendor/github.com/google/fscrypt/metadata/metadata.pb.go b/vendor/github.com/google/fscrypt/metadata/metadata.pb.go index 67098043c..6a335f949 100644 --- a/vendor/github.com/google/fscrypt/metadata/metadata.pb.go +++ b/vendor/github.com/google/fscrypt/metadata/metadata.pb.go @@ -1,22 +1,47 @@ +// +// metadata.proto - File which contains all of the metadata structures which we +// write to metadata files. Must be compiled with protoc to use the library. +// Compilation can be invoked with go generate. +// +// Copyright 2017 Google Inc. +// Author: Joe Richey (joerichey@google.com) +// +// 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. + +// If the *.proto file is modified, be sure to run "make gen" (at the project +// root) to recreate the *.pb.go file. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.6.1 // source: metadata/metadata.proto package metadata -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +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) +) // Specifies the method in which an outside secret is obtained for a Protector type SourceType int32 @@ -28,562 +53,884 @@ const ( SourceType_raw_key SourceType = 3 ) -var SourceType_name = map[int32]string{ - 0: "default", - 1: "pam_passphrase", - 2: "custom_passphrase", - 3: "raw_key", -} -var SourceType_value = map[string]int32{ - "default": 0, - "pam_passphrase": 1, - "custom_passphrase": 2, - "raw_key": 3, +// Enum value maps for SourceType. +var ( + SourceType_name = map[int32]string{ + 0: "default", + 1: "pam_passphrase", + 2: "custom_passphrase", + 3: "raw_key", + } + SourceType_value = map[string]int32{ + "default": 0, + "pam_passphrase": 1, + "custom_passphrase": 2, + "raw_key": 3, + } +) + +func (x SourceType) Enum() *SourceType { + p := new(SourceType) + *p = x + return p } func (x SourceType) String() string { - return proto.EnumName(SourceType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } + +func (SourceType) Descriptor() protoreflect.EnumDescriptor { + return file_metadata_metadata_proto_enumTypes[0].Descriptor() +} + +func (SourceType) Type() protoreflect.EnumType { + return &file_metadata_metadata_proto_enumTypes[0] +} + +func (x SourceType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SourceType.Descriptor instead. func (SourceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{0} + return file_metadata_metadata_proto_rawDescGZIP(), []int{0} } // Type of encryption; should match declarations of unix.FSCRYPT_MODE type EncryptionOptions_Mode int32 const ( - EncryptionOptions_default EncryptionOptions_Mode = 0 - EncryptionOptions_AES_256_XTS EncryptionOptions_Mode = 1 - EncryptionOptions_AES_256_GCM EncryptionOptions_Mode = 2 - EncryptionOptions_AES_256_CBC EncryptionOptions_Mode = 3 - EncryptionOptions_AES_256_CTS EncryptionOptions_Mode = 4 - EncryptionOptions_AES_128_CBC EncryptionOptions_Mode = 5 - EncryptionOptions_AES_128_CTS EncryptionOptions_Mode = 6 - EncryptionOptions_Adiantum EncryptionOptions_Mode = 9 + EncryptionOptions_default EncryptionOptions_Mode = 0 + EncryptionOptions_AES_256_XTS EncryptionOptions_Mode = 1 + EncryptionOptions_AES_256_GCM EncryptionOptions_Mode = 2 + EncryptionOptions_AES_256_CBC EncryptionOptions_Mode = 3 + EncryptionOptions_AES_256_CTS EncryptionOptions_Mode = 4 + EncryptionOptions_AES_128_CBC EncryptionOptions_Mode = 5 + EncryptionOptions_AES_128_CTS EncryptionOptions_Mode = 6 + EncryptionOptions_Adiantum EncryptionOptions_Mode = 9 + EncryptionOptions_AES_256_HCTR2 EncryptionOptions_Mode = 10 ) -var EncryptionOptions_Mode_name = map[int32]string{ - 0: "default", - 1: "AES_256_XTS", - 2: "AES_256_GCM", - 3: "AES_256_CBC", - 4: "AES_256_CTS", - 5: "AES_128_CBC", - 6: "AES_128_CTS", - 9: "Adiantum", -} -var EncryptionOptions_Mode_value = map[string]int32{ - "default": 0, - "AES_256_XTS": 1, - "AES_256_GCM": 2, - "AES_256_CBC": 3, - "AES_256_CTS": 4, - "AES_128_CBC": 5, - "AES_128_CTS": 6, - "Adiantum": 9, +// Enum value maps for EncryptionOptions_Mode. +var ( + EncryptionOptions_Mode_name = map[int32]string{ + 0: "default", + 1: "AES_256_XTS", + 2: "AES_256_GCM", + 3: "AES_256_CBC", + 4: "AES_256_CTS", + 5: "AES_128_CBC", + 6: "AES_128_CTS", + 9: "Adiantum", + 10: "AES_256_HCTR2", + } + EncryptionOptions_Mode_value = map[string]int32{ + "default": 0, + "AES_256_XTS": 1, + "AES_256_GCM": 2, + "AES_256_CBC": 3, + "AES_256_CTS": 4, + "AES_128_CBC": 5, + "AES_128_CTS": 6, + "Adiantum": 9, + "AES_256_HCTR2": 10, + } +) + +func (x EncryptionOptions_Mode) Enum() *EncryptionOptions_Mode { + p := new(EncryptionOptions_Mode) + *p = x + return p } func (x EncryptionOptions_Mode) String() string { - return proto.EnumName(EncryptionOptions_Mode_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } + +func (EncryptionOptions_Mode) Descriptor() protoreflect.EnumDescriptor { + return file_metadata_metadata_proto_enumTypes[1].Descriptor() +} + +func (EncryptionOptions_Mode) Type() protoreflect.EnumType { + return &file_metadata_metadata_proto_enumTypes[1] +} + +func (x EncryptionOptions_Mode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use EncryptionOptions_Mode.Descriptor instead. func (EncryptionOptions_Mode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{3, 0} + return file_metadata_metadata_proto_rawDescGZIP(), []int{3, 0} } // Cost parameters to be used in our hashing functions. type HashingCosts struct { - Time int64 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"` - Memory int64 `protobuf:"varint,3,opt,name=memory,proto3" json:"memory,omitempty"` - Parallelism int64 `protobuf:"varint,4,opt,name=parallelism,proto3" json:"parallelism,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Time int64 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"` + Memory int64 `protobuf:"varint,3,opt,name=memory,proto3" json:"memory,omitempty"` + Parallelism int64 `protobuf:"varint,4,opt,name=parallelism,proto3" json:"parallelism,omitempty"` + // If true, parallelism should no longer be truncated to 8 bits. + TruncationFixed bool `protobuf:"varint,5,opt,name=truncation_fixed,json=truncationFixed,proto3" json:"truncation_fixed,omitempty"` } -func (m *HashingCosts) Reset() { *m = HashingCosts{} } -func (m *HashingCosts) String() string { return proto.CompactTextString(m) } -func (*HashingCosts) ProtoMessage() {} +func (x *HashingCosts) Reset() { + *x = HashingCosts{} + if protoimpl.UnsafeEnabled { + mi := &file_metadata_metadata_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HashingCosts) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HashingCosts) ProtoMessage() {} + +func (x *HashingCosts) ProtoReflect() protoreflect.Message { + mi := &file_metadata_metadata_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HashingCosts.ProtoReflect.Descriptor instead. func (*HashingCosts) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{0} -} -func (m *HashingCosts) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_HashingCosts.Unmarshal(m, b) -} -func (m *HashingCosts) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_HashingCosts.Marshal(b, m, deterministic) -} -func (dst *HashingCosts) XXX_Merge(src proto.Message) { - xxx_messageInfo_HashingCosts.Merge(dst, src) -} -func (m *HashingCosts) XXX_Size() int { - return xxx_messageInfo_HashingCosts.Size(m) -} -func (m *HashingCosts) XXX_DiscardUnknown() { - xxx_messageInfo_HashingCosts.DiscardUnknown(m) + return file_metadata_metadata_proto_rawDescGZIP(), []int{0} } -var xxx_messageInfo_HashingCosts proto.InternalMessageInfo - -func (m *HashingCosts) GetTime() int64 { - if m != nil { - return m.Time +func (x *HashingCosts) GetTime() int64 { + if x != nil { + return x.Time } return 0 } -func (m *HashingCosts) GetMemory() int64 { - if m != nil { - return m.Memory +func (x *HashingCosts) GetMemory() int64 { + if x != nil { + return x.Memory } return 0 } -func (m *HashingCosts) GetParallelism() int64 { - if m != nil { - return m.Parallelism +func (x *HashingCosts) GetParallelism() int64 { + if x != nil { + return x.Parallelism } return 0 } +func (x *HashingCosts) GetTruncationFixed() bool { + if x != nil { + return x.TruncationFixed + } + return false +} + // This structure is used for our authenticated wrapping/unwrapping of keys. type WrappedKeyData struct { - IV []byte `protobuf:"bytes,1,opt,name=IV,proto3" json:"IV,omitempty"` - EncryptedKey []byte `protobuf:"bytes,2,opt,name=encrypted_key,json=encryptedKey,proto3" json:"encrypted_key,omitempty"` - Hmac []byte `protobuf:"bytes,3,opt,name=hmac,proto3" json:"hmac,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IV []byte `protobuf:"bytes,1,opt,name=IV,proto3" json:"IV,omitempty"` + EncryptedKey []byte `protobuf:"bytes,2,opt,name=encrypted_key,json=encryptedKey,proto3" json:"encrypted_key,omitempty"` + Hmac []byte `protobuf:"bytes,3,opt,name=hmac,proto3" json:"hmac,omitempty"` } -func (m *WrappedKeyData) Reset() { *m = WrappedKeyData{} } -func (m *WrappedKeyData) String() string { return proto.CompactTextString(m) } -func (*WrappedKeyData) ProtoMessage() {} +func (x *WrappedKeyData) Reset() { + *x = WrappedKeyData{} + if protoimpl.UnsafeEnabled { + mi := &file_metadata_metadata_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WrappedKeyData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WrappedKeyData) ProtoMessage() {} + +func (x *WrappedKeyData) ProtoReflect() protoreflect.Message { + mi := &file_metadata_metadata_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WrappedKeyData.ProtoReflect.Descriptor instead. func (*WrappedKeyData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{1} -} -func (m *WrappedKeyData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WrappedKeyData.Unmarshal(m, b) -} -func (m *WrappedKeyData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WrappedKeyData.Marshal(b, m, deterministic) -} -func (dst *WrappedKeyData) XXX_Merge(src proto.Message) { - xxx_messageInfo_WrappedKeyData.Merge(dst, src) -} -func (m *WrappedKeyData) XXX_Size() int { - return xxx_messageInfo_WrappedKeyData.Size(m) -} -func (m *WrappedKeyData) XXX_DiscardUnknown() { - xxx_messageInfo_WrappedKeyData.DiscardUnknown(m) + return file_metadata_metadata_proto_rawDescGZIP(), []int{1} } -var xxx_messageInfo_WrappedKeyData proto.InternalMessageInfo - -func (m *WrappedKeyData) GetIV() []byte { - if m != nil { - return m.IV +func (x *WrappedKeyData) GetIV() []byte { + if x != nil { + return x.IV } return nil } -func (m *WrappedKeyData) GetEncryptedKey() []byte { - if m != nil { - return m.EncryptedKey +func (x *WrappedKeyData) GetEncryptedKey() []byte { + if x != nil { + return x.EncryptedKey } return nil } -func (m *WrappedKeyData) GetHmac() []byte { - if m != nil { - return m.Hmac +func (x *WrappedKeyData) GetHmac() []byte { + if x != nil { + return x.Hmac } return nil } // The associated data for each protector type ProtectorData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + ProtectorDescriptor string `protobuf:"bytes,1,opt,name=protector_descriptor,json=protectorDescriptor,proto3" json:"protector_descriptor,omitempty"` Source SourceType `protobuf:"varint,2,opt,name=source,proto3,enum=metadata.SourceType" json:"source,omitempty"` // These are only used by some of the protector types - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - Costs *HashingCosts `protobuf:"bytes,4,opt,name=costs,proto3" json:"costs,omitempty"` - Salt []byte `protobuf:"bytes,5,opt,name=salt,proto3" json:"salt,omitempty"` - Uid int64 `protobuf:"varint,6,opt,name=uid,proto3" json:"uid,omitempty"` - WrappedKey *WrappedKeyData `protobuf:"bytes,7,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Costs *HashingCosts `protobuf:"bytes,4,opt,name=costs,proto3" json:"costs,omitempty"` + Salt []byte `protobuf:"bytes,5,opt,name=salt,proto3" json:"salt,omitempty"` + Uid int64 `protobuf:"varint,6,opt,name=uid,proto3" json:"uid,omitempty"` + WrappedKey *WrappedKeyData `protobuf:"bytes,7,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` } -func (m *ProtectorData) Reset() { *m = ProtectorData{} } -func (m *ProtectorData) String() string { return proto.CompactTextString(m) } -func (*ProtectorData) ProtoMessage() {} +func (x *ProtectorData) Reset() { + *x = ProtectorData{} + if protoimpl.UnsafeEnabled { + mi := &file_metadata_metadata_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProtectorData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProtectorData) ProtoMessage() {} + +func (x *ProtectorData) ProtoReflect() protoreflect.Message { + mi := &file_metadata_metadata_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProtectorData.ProtoReflect.Descriptor instead. func (*ProtectorData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{2} -} -func (m *ProtectorData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ProtectorData.Unmarshal(m, b) -} -func (m *ProtectorData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ProtectorData.Marshal(b, m, deterministic) -} -func (dst *ProtectorData) XXX_Merge(src proto.Message) { - xxx_messageInfo_ProtectorData.Merge(dst, src) -} -func (m *ProtectorData) XXX_Size() int { - return xxx_messageInfo_ProtectorData.Size(m) -} -func (m *ProtectorData) XXX_DiscardUnknown() { - xxx_messageInfo_ProtectorData.DiscardUnknown(m) + return file_metadata_metadata_proto_rawDescGZIP(), []int{2} } -var xxx_messageInfo_ProtectorData proto.InternalMessageInfo - -func (m *ProtectorData) GetProtectorDescriptor() string { - if m != nil { - return m.ProtectorDescriptor +func (x *ProtectorData) GetProtectorDescriptor() string { + if x != nil { + return x.ProtectorDescriptor } return "" } -func (m *ProtectorData) GetSource() SourceType { - if m != nil { - return m.Source +func (x *ProtectorData) GetSource() SourceType { + if x != nil { + return x.Source } return SourceType_default } -func (m *ProtectorData) GetName() string { - if m != nil { - return m.Name +func (x *ProtectorData) GetName() string { + if x != nil { + return x.Name } return "" } -func (m *ProtectorData) GetCosts() *HashingCosts { - if m != nil { - return m.Costs +func (x *ProtectorData) GetCosts() *HashingCosts { + if x != nil { + return x.Costs } return nil } -func (m *ProtectorData) GetSalt() []byte { - if m != nil { - return m.Salt +func (x *ProtectorData) GetSalt() []byte { + if x != nil { + return x.Salt } return nil } -func (m *ProtectorData) GetUid() int64 { - if m != nil { - return m.Uid +func (x *ProtectorData) GetUid() int64 { + if x != nil { + return x.Uid } return 0 } -func (m *ProtectorData) GetWrappedKey() *WrappedKeyData { - if m != nil { - return m.WrappedKey +func (x *ProtectorData) GetWrappedKey() *WrappedKeyData { + if x != nil { + return x.WrappedKey } return nil } // Encryption policy specifics, corresponds to the fscrypt_policy struct type EncryptionOptions struct { - Padding int64 `protobuf:"varint,1,opt,name=padding,proto3" json:"padding,omitempty"` - Contents EncryptionOptions_Mode `protobuf:"varint,2,opt,name=contents,proto3,enum=metadata.EncryptionOptions_Mode" json:"contents,omitempty"` - Filenames EncryptionOptions_Mode `protobuf:"varint,3,opt,name=filenames,proto3,enum=metadata.EncryptionOptions_Mode" json:"filenames,omitempty"` - PolicyVersion int64 `protobuf:"varint,4,opt,name=policy_version,json=policyVersion,proto3" json:"policy_version,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Padding int64 `protobuf:"varint,1,opt,name=padding,proto3" json:"padding,omitempty"` + Contents EncryptionOptions_Mode `protobuf:"varint,2,opt,name=contents,proto3,enum=metadata.EncryptionOptions_Mode" json:"contents,omitempty"` + Filenames EncryptionOptions_Mode `protobuf:"varint,3,opt,name=filenames,proto3,enum=metadata.EncryptionOptions_Mode" json:"filenames,omitempty"` + PolicyVersion int64 `protobuf:"varint,4,opt,name=policy_version,json=policyVersion,proto3" json:"policy_version,omitempty"` } -func (m *EncryptionOptions) Reset() { *m = EncryptionOptions{} } -func (m *EncryptionOptions) String() string { return proto.CompactTextString(m) } -func (*EncryptionOptions) ProtoMessage() {} +func (x *EncryptionOptions) Reset() { + *x = EncryptionOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_metadata_metadata_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EncryptionOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EncryptionOptions) ProtoMessage() {} + +func (x *EncryptionOptions) ProtoReflect() protoreflect.Message { + mi := &file_metadata_metadata_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EncryptionOptions.ProtoReflect.Descriptor instead. func (*EncryptionOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{3} -} -func (m *EncryptionOptions) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EncryptionOptions.Unmarshal(m, b) -} -func (m *EncryptionOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EncryptionOptions.Marshal(b, m, deterministic) -} -func (dst *EncryptionOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_EncryptionOptions.Merge(dst, src) -} -func (m *EncryptionOptions) XXX_Size() int { - return xxx_messageInfo_EncryptionOptions.Size(m) -} -func (m *EncryptionOptions) XXX_DiscardUnknown() { - xxx_messageInfo_EncryptionOptions.DiscardUnknown(m) + return file_metadata_metadata_proto_rawDescGZIP(), []int{3} } -var xxx_messageInfo_EncryptionOptions proto.InternalMessageInfo - -func (m *EncryptionOptions) GetPadding() int64 { - if m != nil { - return m.Padding +func (x *EncryptionOptions) GetPadding() int64 { + if x != nil { + return x.Padding } return 0 } -func (m *EncryptionOptions) GetContents() EncryptionOptions_Mode { - if m != nil { - return m.Contents +func (x *EncryptionOptions) GetContents() EncryptionOptions_Mode { + if x != nil { + return x.Contents } return EncryptionOptions_default } -func (m *EncryptionOptions) GetFilenames() EncryptionOptions_Mode { - if m != nil { - return m.Filenames +func (x *EncryptionOptions) GetFilenames() EncryptionOptions_Mode { + if x != nil { + return x.Filenames } return EncryptionOptions_default } -func (m *EncryptionOptions) GetPolicyVersion() int64 { - if m != nil { - return m.PolicyVersion +func (x *EncryptionOptions) GetPolicyVersion() int64 { + if x != nil { + return x.PolicyVersion } return 0 } type WrappedPolicyKey struct { - ProtectorDescriptor string `protobuf:"bytes,1,opt,name=protector_descriptor,json=protectorDescriptor,proto3" json:"protector_descriptor,omitempty"` - WrappedKey *WrappedKeyData `protobuf:"bytes,2,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProtectorDescriptor string `protobuf:"bytes,1,opt,name=protector_descriptor,json=protectorDescriptor,proto3" json:"protector_descriptor,omitempty"` + WrappedKey *WrappedKeyData `protobuf:"bytes,2,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` } -func (m *WrappedPolicyKey) Reset() { *m = WrappedPolicyKey{} } -func (m *WrappedPolicyKey) String() string { return proto.CompactTextString(m) } -func (*WrappedPolicyKey) ProtoMessage() {} +func (x *WrappedPolicyKey) Reset() { + *x = WrappedPolicyKey{} + if protoimpl.UnsafeEnabled { + mi := &file_metadata_metadata_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WrappedPolicyKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WrappedPolicyKey) ProtoMessage() {} + +func (x *WrappedPolicyKey) ProtoReflect() protoreflect.Message { + mi := &file_metadata_metadata_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WrappedPolicyKey.ProtoReflect.Descriptor instead. func (*WrappedPolicyKey) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{4} -} -func (m *WrappedPolicyKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WrappedPolicyKey.Unmarshal(m, b) -} -func (m *WrappedPolicyKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WrappedPolicyKey.Marshal(b, m, deterministic) -} -func (dst *WrappedPolicyKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_WrappedPolicyKey.Merge(dst, src) -} -func (m *WrappedPolicyKey) XXX_Size() int { - return xxx_messageInfo_WrappedPolicyKey.Size(m) -} -func (m *WrappedPolicyKey) XXX_DiscardUnknown() { - xxx_messageInfo_WrappedPolicyKey.DiscardUnknown(m) + return file_metadata_metadata_proto_rawDescGZIP(), []int{4} } -var xxx_messageInfo_WrappedPolicyKey proto.InternalMessageInfo - -func (m *WrappedPolicyKey) GetProtectorDescriptor() string { - if m != nil { - return m.ProtectorDescriptor +func (x *WrappedPolicyKey) GetProtectorDescriptor() string { + if x != nil { + return x.ProtectorDescriptor } return "" } -func (m *WrappedPolicyKey) GetWrappedKey() *WrappedKeyData { - if m != nil { - return m.WrappedKey +func (x *WrappedPolicyKey) GetWrappedKey() *WrappedKeyData { + if x != nil { + return x.WrappedKey } return nil } // The associated data for each policy type PolicyData struct { - KeyDescriptor string `protobuf:"bytes,1,opt,name=key_descriptor,json=keyDescriptor,proto3" json:"key_descriptor,omitempty"` - Options *EncryptionOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` - WrappedPolicyKeys []*WrappedPolicyKey `protobuf:"bytes,3,rep,name=wrapped_policy_keys,json=wrappedPolicyKeys,proto3" json:"wrapped_policy_keys,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyDescriptor string `protobuf:"bytes,1,opt,name=key_descriptor,json=keyDescriptor,proto3" json:"key_descriptor,omitempty"` + Options *EncryptionOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` + WrappedPolicyKeys []*WrappedPolicyKey `protobuf:"bytes,3,rep,name=wrapped_policy_keys,json=wrappedPolicyKeys,proto3" json:"wrapped_policy_keys,omitempty"` } -func (m *PolicyData) Reset() { *m = PolicyData{} } -func (m *PolicyData) String() string { return proto.CompactTextString(m) } -func (*PolicyData) ProtoMessage() {} +func (x *PolicyData) Reset() { + *x = PolicyData{} + if protoimpl.UnsafeEnabled { + mi := &file_metadata_metadata_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PolicyData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PolicyData) ProtoMessage() {} + +func (x *PolicyData) ProtoReflect() protoreflect.Message { + mi := &file_metadata_metadata_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PolicyData.ProtoReflect.Descriptor instead. func (*PolicyData) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{5} -} -func (m *PolicyData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PolicyData.Unmarshal(m, b) -} -func (m *PolicyData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PolicyData.Marshal(b, m, deterministic) -} -func (dst *PolicyData) XXX_Merge(src proto.Message) { - xxx_messageInfo_PolicyData.Merge(dst, src) -} -func (m *PolicyData) XXX_Size() int { - return xxx_messageInfo_PolicyData.Size(m) -} -func (m *PolicyData) XXX_DiscardUnknown() { - xxx_messageInfo_PolicyData.DiscardUnknown(m) + return file_metadata_metadata_proto_rawDescGZIP(), []int{5} } -var xxx_messageInfo_PolicyData proto.InternalMessageInfo - -func (m *PolicyData) GetKeyDescriptor() string { - if m != nil { - return m.KeyDescriptor +func (x *PolicyData) GetKeyDescriptor() string { + if x != nil { + return x.KeyDescriptor } return "" } -func (m *PolicyData) GetOptions() *EncryptionOptions { - if m != nil { - return m.Options +func (x *PolicyData) GetOptions() *EncryptionOptions { + if x != nil { + return x.Options } return nil } -func (m *PolicyData) GetWrappedPolicyKeys() []*WrappedPolicyKey { - if m != nil { - return m.WrappedPolicyKeys +func (x *PolicyData) GetWrappedPolicyKeys() []*WrappedPolicyKey { + if x != nil { + return x.WrappedPolicyKeys } return nil } // Data stored in the config file type Config struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + Source SourceType `protobuf:"varint,1,opt,name=source,proto3,enum=metadata.SourceType" json:"source,omitempty"` HashCosts *HashingCosts `protobuf:"bytes,2,opt,name=hash_costs,json=hashCosts,proto3" json:"hash_costs,omitempty"` Options *EncryptionOptions `protobuf:"bytes,4,opt,name=options,proto3" json:"options,omitempty"` UseFsKeyringForV1Policies bool `protobuf:"varint,5,opt,name=use_fs_keyring_for_v1_policies,json=useFsKeyringForV1Policies,proto3" json:"use_fs_keyring_for_v1_policies,omitempty"` AllowCrossUserMetadata bool `protobuf:"varint,6,opt,name=allow_cross_user_metadata,json=allowCrossUserMetadata,proto3" json:"allow_cross_user_metadata,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` } -func (m *Config) Reset() { *m = Config{} } -func (m *Config) String() string { return proto.CompactTextString(m) } -func (*Config) ProtoMessage() {} +func (x *Config) Reset() { + *x = Config{} + if protoimpl.UnsafeEnabled { + mi := &file_metadata_metadata_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Config) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Config) ProtoMessage() {} + +func (x *Config) ProtoReflect() protoreflect.Message { + mi := &file_metadata_metadata_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return fileDescriptor_metadata_31965d2849cb292a, []int{6} -} -func (m *Config) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Config.Unmarshal(m, b) -} -func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Config.Marshal(b, m, deterministic) -} -func (dst *Config) XXX_Merge(src proto.Message) { - xxx_messageInfo_Config.Merge(dst, src) -} -func (m *Config) XXX_Size() int { - return xxx_messageInfo_Config.Size(m) -} -func (m *Config) XXX_DiscardUnknown() { - xxx_messageInfo_Config.DiscardUnknown(m) + return file_metadata_metadata_proto_rawDescGZIP(), []int{6} } -var xxx_messageInfo_Config proto.InternalMessageInfo - -func (m *Config) GetSource() SourceType { - if m != nil { - return m.Source +func (x *Config) GetSource() SourceType { + if x != nil { + return x.Source } return SourceType_default } -func (m *Config) GetHashCosts() *HashingCosts { - if m != nil { - return m.HashCosts +func (x *Config) GetHashCosts() *HashingCosts { + if x != nil { + return x.HashCosts } return nil } -func (m *Config) GetOptions() *EncryptionOptions { - if m != nil { - return m.Options +func (x *Config) GetOptions() *EncryptionOptions { + if x != nil { + return x.Options } return nil } -func (m *Config) GetUseFsKeyringForV1Policies() bool { - if m != nil { - return m.UseFsKeyringForV1Policies +func (x *Config) GetUseFsKeyringForV1Policies() bool { + if x != nil { + return x.UseFsKeyringForV1Policies } return false } -func (m *Config) GetAllowCrossUserMetadata() bool { - if m != nil { - return m.AllowCrossUserMetadata +func (x *Config) GetAllowCrossUserMetadata() bool { + if x != nil { + return x.AllowCrossUserMetadata } return false } -func init() { - proto.RegisterType((*HashingCosts)(nil), "metadata.HashingCosts") - proto.RegisterType((*WrappedKeyData)(nil), "metadata.WrappedKeyData") - proto.RegisterType((*ProtectorData)(nil), "metadata.ProtectorData") - proto.RegisterType((*EncryptionOptions)(nil), "metadata.EncryptionOptions") - proto.RegisterType((*WrappedPolicyKey)(nil), "metadata.WrappedPolicyKey") - proto.RegisterType((*PolicyData)(nil), "metadata.PolicyData") - proto.RegisterType((*Config)(nil), "metadata.Config") - proto.RegisterEnum("metadata.SourceType", SourceType_name, SourceType_value) - proto.RegisterEnum("metadata.EncryptionOptions_Mode", EncryptionOptions_Mode_name, EncryptionOptions_Mode_value) +var File_metadata_metadata_proto protoreflect.FileDescriptor + +var file_metadata_metadata_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x22, 0x87, 0x01, 0x0a, 0x0c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x43, + 0x6f, 0x73, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, + 0x73, 0x6d, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x72, + 0x75, 0x6e, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x22, 0x59, 0x0a, + 0x0e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x0e, 0x0a, 0x02, 0x49, 0x56, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x49, 0x56, 0x12, + 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, + 0x64, 0x4b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6d, 0x61, 0x63, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x68, 0x6d, 0x61, 0x63, 0x22, 0x93, 0x02, 0x0a, 0x0d, 0x50, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x14, 0x70, 0x72, + 0x6f, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x2c, 0x0a, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x2c, 0x0a, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x73, 0x74, 0x73, 0x52, 0x05, 0x63, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x61, 0x6c, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, + 0x75, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0b, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, + 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x0a, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x22, 0xef, + 0x02, 0x0a, 0x11, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x3c, + 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x20, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x6e, 0x63, 0x72, + 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4d, 0x6f, + 0x64, 0x65, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3e, 0x0a, 0x09, + 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x20, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4d, 0x6f, 0x64, + 0x65, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x22, 0x9a, 0x01, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, + 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x58, 0x54, 0x53, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, + 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, 0x4d, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x41, + 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x43, 0x42, 0x43, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, + 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x43, 0x54, 0x53, 0x10, 0x04, 0x12, 0x0f, 0x0a, + 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x43, 0x42, 0x43, 0x10, 0x05, 0x12, 0x0f, + 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x31, 0x32, 0x38, 0x5f, 0x43, 0x54, 0x53, 0x10, 0x06, 0x12, + 0x0c, 0x0a, 0x08, 0x41, 0x64, 0x69, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x10, 0x09, 0x12, 0x11, 0x0a, + 0x0d, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, 0x36, 0x5f, 0x48, 0x43, 0x54, 0x52, 0x32, 0x10, 0x0a, + 0x22, 0x80, 0x01, 0x0a, 0x10, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x39, 0x0a, 0x0b, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x22, 0xb6, 0x01, 0x0a, 0x0a, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x65, 0x79, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x35, 0x0a, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x4a, 0x0a, 0x13, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4b, 0x65, 0x79, 0x52, 0x11, 0x77, 0x72, 0x61, 0x70, 0x70, + 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x22, 0xb7, 0x02, 0x0a, + 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x0a, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x63, 0x6f, + 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x73, 0x74, + 0x73, 0x52, 0x09, 0x68, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x1e, 0x75, 0x73, 0x65, 0x5f, 0x66, 0x73, 0x5f, 0x6b, 0x65, + 0x79, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x5f, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x19, 0x75, 0x73, 0x65, + 0x46, 0x73, 0x4b, 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x6f, 0x72, 0x56, 0x31, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, + 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x43, 0x72, 0x6f, 0x73, 0x73, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x2a, 0x51, 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, + 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x70, 0x61, 0x6d, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, + 0x61, 0x73, 0x65, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, + 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, + 0x72, 0x61, 0x77, 0x5f, 0x6b, 0x65, 0x79, 0x10, 0x03, 0x42, 0x24, 0x5a, 0x22, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x66, + 0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } -func init() { proto.RegisterFile("metadata/metadata.proto", fileDescriptor_metadata_31965d2849cb292a) } +var ( + file_metadata_metadata_proto_rawDescOnce sync.Once + file_metadata_metadata_proto_rawDescData = file_metadata_metadata_proto_rawDesc +) -var fileDescriptor_metadata_31965d2849cb292a = []byte{ - // 748 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdb, 0x6a, 0xf3, 0x46, - 0x10, 0xae, 0x24, 0xc7, 0x87, 0xf1, 0xa1, 0xca, 0xfe, 0x69, 0xaa, 0xb4, 0x50, 0x8c, 0x4b, 0x20, - 0x94, 0x90, 0x62, 0x97, 0x94, 0x06, 0x4a, 0x21, 0x75, 0x92, 0x36, 0x09, 0xa1, 0xe9, 0xda, 0x75, - 0x5b, 0x28, 0x88, 0x8d, 0xb4, 0xb6, 0x17, 0x4b, 0x5a, 0xb1, 0xbb, 0x8a, 0xd1, 0x5d, 0xef, 0xfa, - 0x00, 0x7d, 0x97, 0xf6, 0x65, 0xfa, 0x30, 0x45, 0x2b, 0xc9, 0x87, 0x04, 0x42, 0xf2, 0xdf, 0x98, - 0xd9, 0x6f, 0x67, 0xe6, 0x9b, 0xf9, 0x66, 0xc7, 0x82, 0x8f, 0x43, 0xaa, 0x88, 0x4f, 0x14, 0xf9, - 0xb2, 0x34, 0x4e, 0x62, 0xc1, 0x15, 0x47, 0xf5, 0xf2, 0xdc, 0xfb, 0x03, 0x5a, 0x3f, 0x12, 0x39, - 0x67, 0xd1, 0x6c, 0xc8, 0xa5, 0x92, 0x08, 0x41, 0x45, 0xb1, 0x90, 0x3a, 0x66, 0xd7, 0x38, 0xb2, - 0xb0, 0xb6, 0xd1, 0x3e, 0x54, 0x43, 0x1a, 0x72, 0x91, 0x3a, 0x96, 0x46, 0x8b, 0x13, 0xea, 0x42, - 0x33, 0x26, 0x82, 0x04, 0x01, 0x0d, 0x98, 0x0c, 0x9d, 0x8a, 0xbe, 0xdc, 0x84, 0x7a, 0xbf, 0x43, - 0xe7, 0x57, 0x41, 0xe2, 0x98, 0xfa, 0xb7, 0x34, 0xbd, 0x20, 0x8a, 0xa0, 0x0e, 0x98, 0xd7, 0x13, - 0xc7, 0xe8, 0x1a, 0x47, 0x2d, 0x6c, 0x5e, 0x4f, 0xd0, 0xe7, 0xd0, 0xa6, 0x91, 0x27, 0xd2, 0x58, - 0x51, 0xdf, 0x5d, 0xd0, 0x54, 0x13, 0xb7, 0x70, 0x6b, 0x05, 0xde, 0xd2, 0x34, 0x2b, 0x6a, 0x1e, - 0x12, 0x4f, 0xd3, 0xb7, 0xb0, 0xb6, 0x7b, 0x7f, 0x9b, 0xd0, 0xbe, 0x17, 0x5c, 0x51, 0x4f, 0x71, - 0xa1, 0x53, 0xf7, 0x61, 0x2f, 0x2e, 0x01, 0xd7, 0xa7, 0xd2, 0x13, 0x2c, 0x56, 0x5c, 0x68, 0xb2, - 0x06, 0x7e, 0xb7, 0xba, 0xbb, 0x58, 0x5d, 0xa1, 0x63, 0xa8, 0x4a, 0x9e, 0x08, 0x2f, 0xef, 0xb7, - 0x33, 0xd8, 0x3b, 0x59, 0x09, 0x35, 0xd2, 0xf8, 0x38, 0x8d, 0x29, 0x2e, 0x7c, 0xb2, 0x32, 0x22, - 0x12, 0x52, 0x5d, 0x46, 0x03, 0x6b, 0x1b, 0x1d, 0xc3, 0x8e, 0x97, 0x09, 0xa7, 0xbb, 0x6f, 0x0e, - 0xf6, 0xd7, 0x09, 0x36, 0x65, 0xc5, 0xb9, 0x53, 0x96, 0x41, 0x92, 0x40, 0x39, 0x3b, 0x79, 0x23, - 0x99, 0x8d, 0x6c, 0xb0, 0x12, 0xe6, 0x3b, 0x55, 0xad, 0x5e, 0x66, 0xa2, 0x33, 0x68, 0x2e, 0x73, - 0xd5, 0xb4, 0x22, 0x35, 0x9d, 0xd9, 0x59, 0x67, 0xde, 0x96, 0x14, 0xc3, 0x72, 0x75, 0xee, 0xfd, - 0x67, 0xc2, 0xee, 0x65, 0x2e, 0x1d, 0xe3, 0xd1, 0x4f, 0xfa, 0x57, 0x22, 0x07, 0x6a, 0x31, 0xf1, - 0x7d, 0x16, 0xcd, 0xb4, 0x18, 0x16, 0x2e, 0x8f, 0xe8, 0x5b, 0xa8, 0x7b, 0x3c, 0x52, 0x34, 0x52, - 0xb2, 0x90, 0xa0, 0xbb, 0xe6, 0x79, 0x96, 0xe8, 0xe4, 0x8e, 0xfb, 0x14, 0xaf, 0x22, 0xd0, 0x77, - 0xd0, 0x98, 0xb2, 0x80, 0x66, 0x42, 0x48, 0xad, 0xca, 0x6b, 0xc2, 0xd7, 0x21, 0xe8, 0x10, 0x3a, - 0x31, 0x0f, 0x98, 0x97, 0xba, 0x8f, 0x54, 0x48, 0xc6, 0xa3, 0xe2, 0x0d, 0xb5, 0x73, 0x74, 0x92, - 0x83, 0xbd, 0xbf, 0x0c, 0xa8, 0x64, 0xa1, 0xa8, 0x09, 0x35, 0x9f, 0x4e, 0x49, 0x12, 0x28, 0xfb, - 0x03, 0xf4, 0x21, 0x34, 0xcf, 0x2f, 0x47, 0xee, 0xe0, 0xf4, 0x6b, 0xf7, 0xb7, 0xf1, 0xc8, 0x36, - 0x36, 0x81, 0x1f, 0x86, 0x77, 0xb6, 0xb9, 0x09, 0x0c, 0xbf, 0x1f, 0xda, 0xd6, 0x16, 0x30, 0x1e, - 0xd9, 0x95, 0x12, 0xe8, 0x0f, 0xbe, 0xd1, 0x1e, 0x3b, 0x5b, 0xc0, 0x78, 0x64, 0x57, 0x51, 0x0b, - 0xea, 0xe7, 0x3e, 0x23, 0x91, 0x4a, 0x42, 0xbb, 0xd1, 0xfb, 0xd3, 0x00, 0xbb, 0x50, 0xff, 0x5e, - 0x97, 0x98, 0xbd, 0xce, 0xf7, 0x78, 0x77, 0x4f, 0x26, 0x6c, 0xbe, 0x61, 0xc2, 0xff, 0x18, 0x00, - 0x39, 0xb7, 0x7e, 0xf4, 0x87, 0xd0, 0x59, 0xd0, 0xf4, 0x39, 0x6d, 0x7b, 0x41, 0xd3, 0x0d, 0xc2, - 0x53, 0xa8, 0xf1, 0x7c, 0x08, 0x05, 0xd9, 0xa7, 0x2f, 0xcc, 0x09, 0x97, 0xbe, 0xe8, 0x06, 0xde, - 0x95, 0x75, 0x16, 0x83, 0x5a, 0xd0, 0x34, 0x1b, 0xb5, 0x75, 0xd4, 0x1c, 0x7c, 0xf2, 0xac, 0xde, - 0x95, 0x26, 0x78, 0x77, 0xf9, 0x04, 0x91, 0xbd, 0x7f, 0x4d, 0xa8, 0x0e, 0x79, 0x34, 0x65, 0xb3, - 0x8d, 0xb5, 0x33, 0x5e, 0xb1, 0x76, 0xa7, 0x00, 0x73, 0x22, 0xe7, 0x6e, 0xbe, 0x67, 0xe6, 0x8b, - 0x7b, 0xd6, 0xc8, 0x3c, 0xf3, 0x7f, 0xb2, 0x8d, 0x96, 0x2b, 0x6f, 0x68, 0xf9, 0x1c, 0x3e, 0x4b, - 0x24, 0x75, 0xa7, 0x32, 0x6b, 0x55, 0xb0, 0x68, 0xe6, 0x4e, 0xb9, 0x70, 0x1f, 0xfb, 0xb9, 0x00, - 0x8c, 0x4a, 0xbd, 0xbc, 0x75, 0x7c, 0x90, 0x48, 0x7a, 0x25, 0x6f, 0x73, 0x9f, 0x2b, 0x2e, 0x26, - 0xfd, 0xfb, 0xc2, 0x01, 0x9d, 0xc1, 0x01, 0x09, 0x02, 0xbe, 0x74, 0x3d, 0xc1, 0xa5, 0x74, 0x13, - 0x49, 0x85, 0x5b, 0x52, 0xeb, 0x3d, 0xaf, 0xe3, 0x7d, 0xed, 0x30, 0xcc, 0xee, 0x7f, 0x91, 0x54, - 0xdc, 0x15, 0xb7, 0x37, 0x95, 0xba, 0x65, 0x57, 0x70, 0xdb, 0xe3, 0x61, 0x4c, 0x14, 0x7b, 0x60, - 0x01, 0x53, 0xe9, 0x17, 0x3f, 0x03, 0xac, 0x65, 0xd9, 0x5e, 0x02, 0x04, 0x9d, 0x98, 0x84, 0x6e, - 0x4c, 0xa4, 0x8c, 0xe7, 0x82, 0x48, 0x6a, 0x1b, 0xe8, 0x23, 0xd8, 0xf5, 0x12, 0xa9, 0xf8, 0x16, - 0x6c, 0x66, 0x71, 0x82, 0x2c, 0xb3, 0xae, 0x6c, 0xeb, 0xa1, 0xaa, 0xbf, 0x03, 0x5f, 0xfd, 0x1f, - 0x00, 0x00, 0xff, 0xff, 0xe2, 0x78, 0x9e, 0x2e, 0x22, 0x06, 0x00, 0x00, +func file_metadata_metadata_proto_rawDescGZIP() []byte { + file_metadata_metadata_proto_rawDescOnce.Do(func() { + file_metadata_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_metadata_metadata_proto_rawDescData) + }) + return file_metadata_metadata_proto_rawDescData +} + +var file_metadata_metadata_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_metadata_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_metadata_metadata_proto_goTypes = []interface{}{ + (SourceType)(0), // 0: metadata.SourceType + (EncryptionOptions_Mode)(0), // 1: metadata.EncryptionOptions.Mode + (*HashingCosts)(nil), // 2: metadata.HashingCosts + (*WrappedKeyData)(nil), // 3: metadata.WrappedKeyData + (*ProtectorData)(nil), // 4: metadata.ProtectorData + (*EncryptionOptions)(nil), // 5: metadata.EncryptionOptions + (*WrappedPolicyKey)(nil), // 6: metadata.WrappedPolicyKey + (*PolicyData)(nil), // 7: metadata.PolicyData + (*Config)(nil), // 8: metadata.Config +} +var file_metadata_metadata_proto_depIdxs = []int32{ + 0, // 0: metadata.ProtectorData.source:type_name -> metadata.SourceType + 2, // 1: metadata.ProtectorData.costs:type_name -> metadata.HashingCosts + 3, // 2: metadata.ProtectorData.wrapped_key:type_name -> metadata.WrappedKeyData + 1, // 3: metadata.EncryptionOptions.contents:type_name -> metadata.EncryptionOptions.Mode + 1, // 4: metadata.EncryptionOptions.filenames:type_name -> metadata.EncryptionOptions.Mode + 3, // 5: metadata.WrappedPolicyKey.wrapped_key:type_name -> metadata.WrappedKeyData + 5, // 6: metadata.PolicyData.options:type_name -> metadata.EncryptionOptions + 6, // 7: metadata.PolicyData.wrapped_policy_keys:type_name -> metadata.WrappedPolicyKey + 0, // 8: metadata.Config.source:type_name -> metadata.SourceType + 2, // 9: metadata.Config.hash_costs:type_name -> metadata.HashingCosts + 5, // 10: metadata.Config.options:type_name -> metadata.EncryptionOptions + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name +} + +func init() { file_metadata_metadata_proto_init() } +func file_metadata_metadata_proto_init() { + if File_metadata_metadata_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_metadata_metadata_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HashingCosts); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_metadata_metadata_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WrappedKeyData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_metadata_metadata_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProtectorData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_metadata_metadata_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EncryptionOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_metadata_metadata_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WrappedPolicyKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_metadata_metadata_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicyData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_metadata_metadata_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Config); 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{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_metadata_metadata_proto_rawDesc, + NumEnums: 2, + NumMessages: 7, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_metadata_metadata_proto_goTypes, + DependencyIndexes: file_metadata_metadata_proto_depIdxs, + EnumInfos: file_metadata_metadata_proto_enumTypes, + MessageInfos: file_metadata_metadata_proto_msgTypes, + }.Build() + File_metadata_metadata_proto = out.File + file_metadata_metadata_proto_rawDesc = nil + file_metadata_metadata_proto_goTypes = nil + file_metadata_metadata_proto_depIdxs = nil } diff --git a/vendor/github.com/google/fscrypt/metadata/metadata.proto b/vendor/github.com/google/fscrypt/metadata/metadata.proto index 84245e020..f2dd78fe7 100644 --- a/vendor/github.com/google/fscrypt/metadata/metadata.proto +++ b/vendor/github.com/google/fscrypt/metadata/metadata.proto @@ -19,15 +19,20 @@ * the License. */ -// If you modify this file, be sure to run "go generate" on this package. +// If the *.proto file is modified, be sure to run "make gen" (at the project +// root) to recreate the *.pb.go file. syntax = "proto3"; package metadata; +option go_package = "github.com/google/fscrypt/metadata"; + // Cost parameters to be used in our hashing functions. message HashingCosts { int64 time = 2; int64 memory = 3; int64 parallelism = 4; + // If true, parallelism should no longer be truncated to 8 bits. + bool truncation_fixed = 5; } // This structure is used for our authenticated wrapping/unwrapping of keys. @@ -73,6 +78,7 @@ message EncryptionOptions { AES_128_CBC = 5; AES_128_CTS = 6; Adiantum = 9; + AES_256_HCTR2 = 10; } Mode contents = 2; diff --git a/vendor/github.com/google/fscrypt/metadata/policy.go b/vendor/github.com/google/fscrypt/metadata/policy.go index e218a0814..7831e53a6 100644 --- a/vendor/github.com/google/fscrypt/metadata/policy.go +++ b/vendor/github.com/google/fscrypt/metadata/policy.go @@ -94,7 +94,7 @@ func (err *ErrNotEncrypted) Error() string { return fmt.Sprintf("file or directory %q is not encrypted", err.Path) } -func policyIoctl(file *os.File, request uintptr, arg unsafe.Pointer) error { +func getPolicyIoctl(file *os.File, request uintptr, arg unsafe.Pointer) error { _, _, errno := unix.Syscall(unix.SYS_IOCTL, file.Fd(), request, uintptr(arg)) if errno == 0 { return nil @@ -102,6 +102,19 @@ func policyIoctl(file *os.File, request uintptr, arg unsafe.Pointer) error { return errno } +func setPolicy(file *os.File, arg unsafe.Pointer) error { + _, _, errno := unix.Syscall(unix.SYS_IOCTL, file.Fd(), unix.FS_IOC_SET_ENCRYPTION_POLICY, uintptr(arg)) + if errno != 0 { + return errno + } + + if err := file.Sync(); err != nil { + return err + } + + return nil +} + // Maps EncryptionOptions.Padding <-> FSCRYPT_POLICY_FLAGS var ( paddingArray = []int64{4, 8, 16, 32} @@ -159,10 +172,10 @@ func GetPolicy(path string) (*PolicyData, error) { var arg unix.FscryptGetPolicyExArg arg.Size = uint64(unsafe.Sizeof(arg.Policy)) policyPtr := util.Ptr(arg.Policy[:]) - err = policyIoctl(file, unix.FS_IOC_GET_ENCRYPTION_POLICY_EX, unsafe.Pointer(&arg)) + err = getPolicyIoctl(file, unix.FS_IOC_GET_ENCRYPTION_POLICY_EX, unsafe.Pointer(&arg)) if err == unix.ENOTTY { // Fall back to the old version of the ioctl. This works for v1 policies only. - err = policyIoctl(file, unix.FS_IOC_GET_ENCRYPTION_POLICY, policyPtr) + err = getPolicyIoctl(file, unix.FS_IOC_GET_ENCRYPTION_POLICY, policyPtr) arg.Size = uint64(unsafe.Sizeof(unix.FscryptPolicyV1{})) } switch err { @@ -235,7 +248,7 @@ func setV1Policy(file *os.File, options *EncryptionOptions, descriptorBytes []by } copy(policy.Master_key_descriptor[:], descriptorBytes) - return policyIoctl(file, unix.FS_IOC_SET_ENCRYPTION_POLICY, unsafe.Pointer(&policy)) + return setPolicy(file, unsafe.Pointer(&policy)) } func setV2Policy(file *os.File, options *EncryptionOptions, descriptorBytes []byte) error { @@ -252,7 +265,7 @@ func setV2Policy(file *os.File, options *EncryptionOptions, descriptorBytes []by } copy(policy.Master_key_identifier[:], descriptorBytes) - return policyIoctl(file, unix.FS_IOC_SET_ENCRYPTION_POLICY, unsafe.Pointer(&policy)) + return setPolicy(file, unsafe.Pointer(&policy)) } // SetPolicy sets up the specified directory to be encrypted with the specified @@ -332,7 +345,7 @@ func CheckSupport(path string) error { Flags: math.MaxUint8, } - err = policyIoctl(file, unix.FS_IOC_SET_ENCRYPTION_POLICY, unsafe.Pointer(&badPolicy)) + err = setPolicy(file, unsafe.Pointer(&badPolicy)) switch err { case nil: log.Panicf(`FS_IOC_SET_ENCRYPTION_POLICY succeeded when it should have failed. diff --git a/vendor/modules.txt b/vendor/modules.txt index 28ba246c4..b704118fc 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -228,8 +228,8 @@ github.com/golang/protobuf/ptypes/wrappers # github.com/golang/snappy v0.0.4 ## explicit github.com/golang/snappy -# github.com/google/fscrypt v0.3.3 -## explicit; go 1.11 +# github.com/google/fscrypt v0.3.4 +## explicit; go 1.16 github.com/google/fscrypt/actions github.com/google/fscrypt/crypto github.com/google/fscrypt/filesystem From cfa173d6ff388fa40c7d304f1a365167d748f4ea Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Thu, 23 Feb 2023 08:59:36 +0100 Subject: [PATCH 006/165] ci: update mergify rules for Kubernetes 1.26 removed mergify rules for Kubernetes 1.23 and update the rules to consider Kubernetes 1.26 Signed-off-by: Madhu Rajanna --- .mergify.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 730335411..4d9253661 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -29,15 +29,15 @@ queue_rules: - "status-success=golangci-lint" - "status-success=mod-check" - "status-success=lint-extras" - - "status-success=ci/centos/k8s-e2e-external-storage/1.23" - "status-success=ci/centos/k8s-e2e-external-storage/1.24" - "status-success=ci/centos/k8s-e2e-external-storage/1.25" - - "status-success=ci/centos/mini-e2e-helm/k8s-1.23" + - "status-success=ci/centos/k8s-e2e-external-storage/1.26" - "status-success=ci/centos/mini-e2e-helm/k8s-1.24" - "status-success=ci/centos/mini-e2e-helm/k8s-1.25" - - "status-success=ci/centos/mini-e2e/k8s-1.23" + - "status-success=ci/centos/mini-e2e-helm/k8s-1.26" - "status-success=ci/centos/mini-e2e/k8s-1.24" - "status-success=ci/centos/mini-e2e/k8s-1.25" + - "status-success=ci/centos/mini-e2e/k8s-1.26" - "status-success=ci/centos/upgrade-tests-cephfs" - "status-success=ci/centos/upgrade-tests-rbd" - and: @@ -93,15 +93,15 @@ pull_request_rules: - "status-success=golangci-lint" - "status-success=mod-check" - "status-success=lint-extras" - - "status-success=ci/centos/k8s-e2e-external-storage/1.23" - "status-success=ci/centos/k8s-e2e-external-storage/1.24" - "status-success=ci/centos/k8s-e2e-external-storage/1.25" - - "status-success=ci/centos/mini-e2e-helm/k8s-1.23" + - "status-success=ci/centos/k8s-e2e-external-storage/1.26" - "status-success=ci/centos/mini-e2e-helm/k8s-1.24" - "status-success=ci/centos/mini-e2e-helm/k8s-1.25" - - "status-success=ci/centos/mini-e2e/k8s-1.23" + - "status-success=ci/centos/mini-e2e-helm/k8s-1.26" - "status-success=ci/centos/mini-e2e/k8s-1.24" - "status-success=ci/centos/mini-e2e/k8s-1.25" + - "status-success=ci/centos/mini-e2e/k8s-1.26" - "status-success=ci/centos/upgrade-tests-cephfs" - "status-success=ci/centos/upgrade-tests-rbd" - "status-success=DCO" @@ -132,15 +132,15 @@ pull_request_rules: - "status-success=commitlint" - "status-success=mod-check" - "status-success=lint-extras" - - "status-success=ci/centos/k8s-e2e-external-storage/1.23" - "status-success=ci/centos/k8s-e2e-external-storage/1.24" - "status-success=ci/centos/k8s-e2e-external-storage/1.25" - - "status-success=ci/centos/mini-e2e-helm/k8s-1.23" + - "status-success=ci/centos/k8s-e2e-external-storage/1.26" - "status-success=ci/centos/mini-e2e-helm/k8s-1.24" - "status-success=ci/centos/mini-e2e-helm/k8s-1.25" - - "status-success=ci/centos/mini-e2e/k8s-1.23" + - "status-success=ci/centos/mini-e2e-helm/k8s-1.26" - "status-success=ci/centos/mini-e2e/k8s-1.24" - "status-success=ci/centos/mini-e2e/k8s-1.25" + - "status-success=ci/centos/mini-e2e/k8s-1.26" - "status-success=ci/centos/upgrade-tests-cephfs" - "status-success=ci/centos/upgrade-tests-rbd" - "status-success=DCO" @@ -163,15 +163,15 @@ pull_request_rules: - "status-success=mod-check" - "status-success=lint-extras" - "#changes-requested-reviews-by=0" - - "status-success=ci/centos/k8s-e2e-external-storage/1.23" - "status-success=ci/centos/k8s-e2e-external-storage/1.24" - "status-success=ci/centos/k8s-e2e-external-storage/1.25" - - "status-success=ci/centos/mini-e2e-helm/k8s-1.23" + - "status-success=ci/centos/k8s-e2e-external-storage/1.26" - "status-success=ci/centos/mini-e2e-helm/k8s-1.24" - "status-success=ci/centos/mini-e2e-helm/k8s-1.25" - - "status-success=ci/centos/mini-e2e/k8s-1.23" + - "status-success=ci/centos/mini-e2e-helm/k8s-1.26" - "status-success=ci/centos/mini-e2e/k8s-1.24" - "status-success=ci/centos/mini-e2e/k8s-1.25" + - "status-success=ci/centos/mini-e2e/k8s-1.26" - "status-success=ci/centos/upgrade-tests-cephfs" - "status-success=ci/centos/upgrade-tests-rbd" - "status-success=DCO" From f5d24628dcacb38a35ffff67b991e11244256abc Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Thu, 23 Feb 2023 09:02:19 +0100 Subject: [PATCH 007/165] ci: add mergify rules for release-v3.8 added mergify rules to backport PR to release-v3.8 branch. Signed-off-by: Madhu Rajanna --- .mergify.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.mergify.yml b/.mergify.yml index 4d9253661..9bc3e7e74 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -198,6 +198,15 @@ pull_request_rules: branches: - release-v3.7 + - name: backport patches to release-v3.8 branch + conditions: + - base=devel + - label=backport-to-release-v3.8 + actions: + backport: + branches: + - release-v3.8 + - name: remove outdated approvals on ci/centos conditions: - base=ci/centos From 8fd0383cbede79658ae2391102a2b397317df7e0 Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Thu, 23 Feb 2023 09:03:13 +0100 Subject: [PATCH 008/165] ci: remove rules for release-v3.6 As release 3.6 is deprecated and not supported anymore removing its rules from mergify Signed-off-by: Madhu Rajanna --- .mergify.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 9bc3e7e74..d7384cf67 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -180,15 +180,6 @@ pull_request_rules: name: default delete_head_branch: {} - - name: backport patches to release-v3.6 branch - conditions: - - base=devel - - label=backport-to-release-v3.6 - actions: - backport: - branches: - - release-v3.6 - - name: backport patches to release-v3.7 branch conditions: - base=devel From 4685fc07cde9cf013d8c265f296b74122b8129a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:13:31 +0000 Subject: [PATCH 009/165] rebase: Bump github.com/aws/aws-sdk-go-v2/service/sts Bumps [github.com/aws/aws-sdk-go-v2/service/sts](https://github.com/aws/aws-sdk-go-v2) from 1.18.3 to 1.18.5. - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.18.3...config/v1.18.5) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/service/sts dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 10 +++++----- go.sum | 20 +++++++++---------- .../aws-sdk-go-v2/aws/go_module_metadata.go | 2 +- .../internal/configsources/CHANGELOG.md | 4 ++++ .../configsources/go_module_metadata.go | 2 +- .../internal/endpoints/v2/CHANGELOG.md | 4 ++++ .../endpoints/v2/go_module_metadata.go | 2 +- .../internal/presigned-url/CHANGELOG.md | 4 ++++ .../presigned-url/go_module_metadata.go | 2 +- .../aws-sdk-go-v2/service/sts/CHANGELOG.md | 8 ++++++++ .../service/sts/go_module_metadata.go | 2 +- .../aws-sdk-go-v2/service/sts/types/errors.go | 16 +++++++-------- vendor/modules.txt | 10 +++++----- 13 files changed, 53 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index 44c2d528c..c99f90f08 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/IBM/keyprotect-go-client v0.9.2 github.com/aws/aws-sdk-go v1.44.205 - github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 + github.com/aws/aws-sdk-go-v2/service/sts v1.18.5 github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000 // TODO: API for managing subvolume metadata and snapshot metadata requires `ceph_ci_untested` build-tag github.com/ceph/go-ceph v0.20.0 @@ -50,10 +50,10 @@ require ( require ( github.com/ansel1/merry v1.6.2 // indirect github.com/ansel1/merry/v2 v2.0.1 // indirect - github.com/aws/aws-sdk-go-v2 v1.17.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22 // indirect + github.com/aws/aws-sdk-go-v2 v1.17.5 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.23 // indirect github.com/aws/smithy-go v1.13.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect diff --git a/go.sum b/go.sum index 9820c4794..766db022e 100644 --- a/go.sum +++ b/go.sum @@ -134,16 +134,16 @@ github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.44.205 h1:q23NJXgLPIuBMn4zaluWWz57HPP5z7Ut8ZtK1D3N9bs= github.com/aws/aws-sdk-go v1.44.205/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aws/aws-sdk-go-v2 v1.17.4 h1:wyC6p9Yfq6V2y98wfDsj6OnNQa4w2BLGCLIxzNhwOGY= -github.com/aws/aws-sdk-go-v2 v1.17.4/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 h1:r+XwaCLpIvCKjBIYy/HVZujQS9tsz5ohHG3ZIe0wKoE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28/go.mod h1:3lwChorpIM/BhImY/hy+Z6jekmN92cXGPI1QJasVPYY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 h1:7AwGYXDdqRQYsluvKFmWoqpcOQJ4bH634SkYf3FNj/A= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22/go.mod h1:EqK7gVrIGAHyZItrD1D8B0ilgwMD1GiWAmbU4u/JHNk= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22 h1:LjFQf8hFuMO22HkV5VWGLBvmCLBCLPivUAmpdpnp4Vs= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22/go.mod h1:xt0Au8yPIwYXf/GYPy/vl4K3CgwhfQMYbrH7DlUUIws= -github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 h1:s49mSnsBZEXjfGBkRfmK+nPqzT7Lt3+t2SmAKNyHblw= -github.com/aws/aws-sdk-go-v2/service/sts v1.18.3/go.mod h1:b+psTJn33Q4qGoDaM7ZiOVVG8uVjGI6HaZ8WBHdgDgU= +github.com/aws/aws-sdk-go-v2 v1.17.5 h1:TzCUW1Nq4H8Xscph5M/skINUitxM5UBAyvm2s7XBzL4= +github.com/aws/aws-sdk-go-v2 v1.17.5/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 h1:9/aKwwus0TQxppPXFmf010DFrE+ssSbzroLVYINA+xE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29/go.mod h1:Dip3sIGv485+xerzVv24emnjX5Sg88utCL8fwGmCeWg= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 h1:b/Vn141DBuLVgXbhRWIrl9g+ww7G+ScV5SzniWR13jQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23/go.mod h1:mr6c4cHC+S/MMkrjtSlG4QA36kOznDep+0fga5L/fGQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.23 h1:QoOybhwRfciWUBbZ0gp9S7XaDnCuSTeK/fySB99V1ls= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.23/go.mod h1:9uPh+Hrz2Vn6oMnQYiUi/zbh3ovbnQk19YKINkQny44= +github.com/aws/aws-sdk-go-v2/service/sts v1.18.5 h1:L1600eLr0YvTT7gNh3Ni24yGI7NSHkq9Gp62vijPRCs= +github.com/aws/aws-sdk-go-v2/service/sts v1.18.5/go.mod h1:1mKZHLLpDMHTNSYPJ7qrcnCQdHCWsNQaT0xRvq2u80s= github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go index 39abc2e24..a85dd1450 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go @@ -3,4 +3,4 @@ package aws // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.17.4" +const goModuleVersion = "1.17.5" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md index 8412c43d5..01d7a2eab 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md @@ -1,3 +1,7 @@ +# v1.1.29 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.1.28 (2023-02-03) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go index dfd4e2eea..1d100e6c0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go @@ -3,4 +3,4 @@ package configsources // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.1.28" +const goModuleVersion = "1.1.29" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md index 7d8e325fd..1662bba60 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md @@ -1,3 +1,7 @@ +# v2.4.23 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + # v2.4.22 (2023-02-03) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go index eb6a19509..7349a2875 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go @@ -3,4 +3,4 @@ package endpoints // goModuleVersion is the tagged release for this module -const goModuleVersion = "2.4.22" +const goModuleVersion = "2.4.23" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md index 37d72a51e..aed3e8c09 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md @@ -1,3 +1,7 @@ +# v1.9.23 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.9.22 (2023-02-03) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go index 494ae82fc..5a43e1386 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go @@ -3,4 +3,4 @@ package presignedurl // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.9.22" +const goModuleVersion = "1.9.23" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md index a9ed5300f..2e072a23b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md @@ -1,3 +1,11 @@ +# v1.18.5 (2023-02-22) + +* **Bug Fix**: Prevent nil pointer dereference when retrieving error codes. + +# v1.18.4 (2023-02-20) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.18.3 (2023-02-03) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go index dc11195ec..c78b771e0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go @@ -3,4 +3,4 @@ package sts // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.18.3" +const goModuleVersion = "1.18.5" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go index 88d3e6c69..9e3adaa9a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go @@ -27,7 +27,7 @@ func (e *ExpiredTokenException) ErrorMessage() string { return *e.Message } func (e *ExpiredTokenException) ErrorCode() string { - if e.ErrorCodeOverride == nil { + if e == nil || e.ErrorCodeOverride == nil { return "ExpiredTokenException" } return *e.ErrorCodeOverride @@ -57,7 +57,7 @@ func (e *IDPCommunicationErrorException) ErrorMessage() string { return *e.Message } func (e *IDPCommunicationErrorException) ErrorCode() string { - if e.ErrorCodeOverride == nil { + if e == nil || e.ErrorCodeOverride == nil { return "IDPCommunicationError" } return *e.ErrorCodeOverride @@ -86,7 +86,7 @@ func (e *IDPRejectedClaimException) ErrorMessage() string { return *e.Message } func (e *IDPRejectedClaimException) ErrorCode() string { - if e.ErrorCodeOverride == nil { + if e == nil || e.ErrorCodeOverride == nil { return "IDPRejectedClaim" } return *e.ErrorCodeOverride @@ -114,7 +114,7 @@ func (e *InvalidAuthorizationMessageException) ErrorMessage() string { return *e.Message } func (e *InvalidAuthorizationMessageException) ErrorCode() string { - if e.ErrorCodeOverride == nil { + if e == nil || e.ErrorCodeOverride == nil { return "InvalidAuthorizationMessageException" } return *e.ErrorCodeOverride @@ -144,7 +144,7 @@ func (e *InvalidIdentityTokenException) ErrorMessage() string { return *e.Message } func (e *InvalidIdentityTokenException) ErrorCode() string { - if e.ErrorCodeOverride == nil { + if e == nil || e.ErrorCodeOverride == nil { return "InvalidIdentityToken" } return *e.ErrorCodeOverride @@ -171,7 +171,7 @@ func (e *MalformedPolicyDocumentException) ErrorMessage() string { return *e.Message } func (e *MalformedPolicyDocumentException) ErrorCode() string { - if e.ErrorCodeOverride == nil { + if e == nil || e.ErrorCodeOverride == nil { return "MalformedPolicyDocument" } return *e.ErrorCodeOverride @@ -208,7 +208,7 @@ func (e *PackedPolicyTooLargeException) ErrorMessage() string { return *e.Message } func (e *PackedPolicyTooLargeException) ErrorCode() string { - if e.ErrorCodeOverride == nil { + if e == nil || e.ErrorCodeOverride == nil { return "PackedPolicyTooLarge" } return *e.ErrorCodeOverride @@ -239,7 +239,7 @@ func (e *RegionDisabledException) ErrorMessage() string { return *e.Message } func (e *RegionDisabledException) ErrorCode() string { - if e.ErrorCodeOverride == nil { + if e == nil || e.ErrorCodeOverride == nil { return "RegionDisabledException" } return *e.ErrorCodeOverride diff --git a/vendor/modules.txt b/vendor/modules.txt index b704118fc..7f791ea3b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -53,7 +53,7 @@ github.com/aws/aws-sdk-go/service/sso github.com/aws/aws-sdk-go/service/sso/ssoiface github.com/aws/aws-sdk-go/service/sts github.com/aws/aws-sdk-go/service/sts/stsiface -# github.com/aws/aws-sdk-go-v2 v1.17.4 +# github.com/aws/aws-sdk-go-v2 v1.17.5 ## explicit; go 1.15 github.com/aws/aws-sdk-go-v2/aws github.com/aws/aws-sdk-go-v2/aws/defaults @@ -70,16 +70,16 @@ github.com/aws/aws-sdk-go-v2/internal/sdk github.com/aws/aws-sdk-go-v2/internal/strings github.com/aws/aws-sdk-go-v2/internal/sync/singleflight github.com/aws/aws-sdk-go-v2/internal/timeconv -# github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.28 +# github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.29 ## explicit; go 1.15 github.com/aws/aws-sdk-go-v2/internal/configsources -# github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.22 +# github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.23 ## explicit; go 1.15 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 -# github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.22 +# github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.23 ## explicit; go 1.15 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url -# github.com/aws/aws-sdk-go-v2/service/sts v1.18.3 +# github.com/aws/aws-sdk-go-v2/service/sts v1.18.5 ## explicit; go 1.15 github.com/aws/aws-sdk-go-v2/service/sts github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints From 0c3d3c116a13c3ce391a916259a9558363869c62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:13:43 +0000 Subject: [PATCH 010/165] rebase: Bump golang.org/x/oauth2 from 0.5.0 to 0.6.0 in /actions/retest Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.5.0 to 0.6.0. - [Release notes](https://github.com/golang/oauth2/releases) - [Commits](https://github.com/golang/oauth2/compare/v0.5.0...v0.6.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- actions/retest/go.mod | 4 ++-- actions/retest/go.sum | 8 ++++---- actions/retest/vendor/modules.txt | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/actions/retest/go.mod b/actions/retest/go.mod index 5b82e919b..d55ec3525 100644 --- a/actions/retest/go.mod +++ b/actions/retest/go.mod @@ -4,13 +4,13 @@ go 1.18 require ( github.com/google/go-github v17.0.0+incompatible - golang.org/x/oauth2 v0.5.0 + golang.org/x/oauth2 v0.6.0 ) require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-querystring v1.1.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/net v0.8.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.1 // indirect ) diff --git a/actions/retest/go.sum b/actions/retest/go.sum index fa57cc2b0..e81e888f4 100644 --- a/actions/retest/go.sum +++ b/actions/retest/go.sum @@ -11,10 +11,10 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/actions/retest/vendor/modules.txt b/actions/retest/vendor/modules.txt index 3776cef19..45afb168c 100644 --- a/actions/retest/vendor/modules.txt +++ b/actions/retest/vendor/modules.txt @@ -7,10 +7,10 @@ github.com/google/go-github/github # github.com/google/go-querystring v1.1.0 ## explicit; go 1.10 github.com/google/go-querystring/query -# golang.org/x/net v0.7.0 +# golang.org/x/net v0.8.0 ## explicit; go 1.17 golang.org/x/net/context -# golang.org/x/oauth2 v0.5.0 +# golang.org/x/oauth2 v0.6.0 ## explicit; go 1.17 golang.org/x/oauth2 golang.org/x/oauth2/internal From da57f929f90335354bd5cadb9cb8ce1fbab3a8e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:13:50 +0000 Subject: [PATCH 011/165] rebase: Bump github.com/gemalto/kmip-go from 0.0.8 to 0.0.9 Bumps [github.com/gemalto/kmip-go](https://github.com/gemalto/kmip-go) from 0.0.8 to 0.0.9. - [Release notes](https://github.com/gemalto/kmip-go/releases) - [Commits](https://github.com/gemalto/kmip-go/compare/v0.0.8...v0.0.9) --- updated-dependencies: - dependency-name: github.com/gemalto/kmip-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- vendor/github.com/gemalto/kmip-go/Makefile | 2 +- vendor/modules.txt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index c99f90f08..2c6adda01 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/container-storage-interface/spec v1.7.0 github.com/csi-addons/replication-lib-utils v0.2.0 github.com/csi-addons/spec v0.1.2-0.20221101132540-98eff76b0ff8 - github.com/gemalto/kmip-go v0.0.8 + github.com/gemalto/kmip-go v0.0.9 github.com/golang/protobuf v1.5.2 github.com/google/fscrypt v0.3.4 github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index 766db022e..db4f51668 100644 --- a/go.sum +++ b/go.sum @@ -305,8 +305,8 @@ github.com/gammazero/deque v0.0.0-20190130191400-2afb3858e9c7/go.mod h1:GeIq9qoE github.com/gammazero/workerpool v0.0.0-20190406235159-88d534f22b56/go.mod h1:w9RqFVO2BM3xwWEcAB8Fwp0OviTBBEiRmSBDfbXnd3w= github.com/gemalto/flume v0.13.0 h1:EEeQvAxyFys3BH8IxEU7ZpM6Kr1sYn20HuZq6dgyMR8= github.com/gemalto/flume v0.13.0/go.mod h1:3iOEZiK/HD8SnFTqHCQoOHQKaHlBY0b6z55P8SLaOzk= -github.com/gemalto/kmip-go v0.0.8 h1:RvKWTd2ACxOs7OF1f6SvPYebjmQbN0myfDHVQmX/k8g= -github.com/gemalto/kmip-go v0.0.8/go.mod h1:7bAnjuzri8yGoJMwngnAd0HdXMRDQU+l1Zaiz12Tr68= +github.com/gemalto/kmip-go v0.0.9 h1:PMm0j3k5l7H6BIp13+V6aq0mvp0O3YlKVHkDweLkzik= +github.com/gemalto/kmip-go v0.0.9/go.mod h1:YBUgKtkYpGCL+xA1oClQrMYTWDvHN/A2wSh2LmT5+JY= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= diff --git a/vendor/github.com/gemalto/kmip-go/Makefile b/vendor/github.com/gemalto/kmip-go/Makefile index a593187a2..e47188a49 100644 --- a/vendor/github.com/gemalto/kmip-go/Makefile +++ b/vendor/github.com/gemalto/kmip-go/Makefile @@ -3,7 +3,7 @@ BUILD_FLAGS = TEST_FLAGS = COMPOSE ?= docker-compose -all: fmt build up test lint +all: tidy fmt build up test lint build: go build $(BUILD_FLAGS) ./... diff --git a/vendor/modules.txt b/vendor/modules.txt index 7f791ea3b..d5bcd741f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -179,7 +179,7 @@ github.com/fsnotify/fsnotify # github.com/gemalto/flume v0.13.0 ## explicit; go 1.14 github.com/gemalto/flume -# github.com/gemalto/kmip-go v0.0.8 +# github.com/gemalto/kmip-go v0.0.9 ## explicit; go 1.17 github.com/gemalto/kmip-go github.com/gemalto/kmip-go/internal/kmiputil From e3ae53f11d5e3df6d578371ab066ef8a9bf34506 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Mar 2023 20:14:36 +0000 Subject: [PATCH 012/165] rebase: Bump golang.org/x/net from 0.7.0 to 0.8.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.7.0 to 0.8.0. - [Release notes](https://github.com/golang/net/releases) - [Commits](https://github.com/golang/net/compare/v0.7.0...v0.8.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 8 +- go.sum | 16 +- vendor/golang.org/x/net/html/doc.go | 15 ++ vendor/golang.org/x/net/html/escape.go | 81 ++++++++++ vendor/golang.org/x/net/html/render.go | 2 +- vendor/golang.org/x/net/html/token.go | 10 +- vendor/golang.org/x/sys/cpu/hwcap_linux.go | 15 ++ vendor/golang.org/x/sys/cpu/runtime_auxv.go | 16 ++ .../x/sys/cpu/runtime_auxv_go121.go | 19 +++ vendor/golang.org/x/sys/unix/ioctl.go | 17 +-- vendor/golang.org/x/sys/unix/ioctl_zos.go | 8 +- vendor/golang.org/x/sys/unix/ptrace_darwin.go | 6 + vendor/golang.org/x/sys/unix/ptrace_ios.go | 6 + vendor/golang.org/x/sys/unix/syscall_aix.go | 5 +- vendor/golang.org/x/sys/unix/syscall_bsd.go | 3 +- .../golang.org/x/sys/unix/syscall_darwin.go | 12 +- .../x/sys/unix/syscall_darwin_amd64.go | 1 + .../x/sys/unix/syscall_darwin_arm64.go | 1 + .../x/sys/unix/syscall_dragonfly.go | 1 + .../golang.org/x/sys/unix/syscall_freebsd.go | 43 +++++- .../x/sys/unix/syscall_freebsd_386.go | 17 +-- .../x/sys/unix/syscall_freebsd_amd64.go | 17 +-- .../x/sys/unix/syscall_freebsd_arm.go | 15 +- .../x/sys/unix/syscall_freebsd_arm64.go | 15 +- .../x/sys/unix/syscall_freebsd_riscv64.go | 15 +- vendor/golang.org/x/sys/unix/syscall_hurd.go | 8 + vendor/golang.org/x/sys/unix/syscall_linux.go | 36 +++-- .../golang.org/x/sys/unix/syscall_netbsd.go | 5 +- .../golang.org/x/sys/unix/syscall_openbsd.go | 1 + .../golang.org/x/sys/unix/syscall_solaris.go | 21 +-- .../x/sys/unix/syscall_zos_s390x.go | 4 +- vendor/golang.org/x/sys/unix/zerrors_linux.go | 10 +- .../x/sys/unix/zptrace_armnn_linux.go | 8 +- .../x/sys/unix/zptrace_linux_arm64.go | 4 +- .../x/sys/unix/zptrace_mipsnn_linux.go | 8 +- .../x/sys/unix/zptrace_mipsnnle_linux.go | 8 +- .../x/sys/unix/zptrace_x86_linux.go | 8 +- .../golang.org/x/sys/unix/zsyscall_aix_ppc.go | 10 ++ .../x/sys/unix/zsyscall_aix_ppc64.go | 10 ++ .../x/sys/unix/zsyscall_aix_ppc64_gc.go | 7 + .../x/sys/unix/zsyscall_aix_ppc64_gccgo.go | 8 + .../x/sys/unix/zsyscall_darwin_amd64.go | 16 ++ .../x/sys/unix/zsyscall_darwin_arm64.go | 16 ++ .../x/sys/unix/zsyscall_dragonfly_amd64.go | 10 ++ .../x/sys/unix/zsyscall_freebsd_386.go | 20 +++ .../x/sys/unix/zsyscall_freebsd_amd64.go | 20 +++ .../x/sys/unix/zsyscall_freebsd_arm.go | 20 +++ .../x/sys/unix/zsyscall_freebsd_arm64.go | 20 +++ .../x/sys/unix/zsyscall_freebsd_riscv64.go | 20 +++ .../golang.org/x/sys/unix/zsyscall_linux.go | 10 ++ .../x/sys/unix/zsyscall_netbsd_386.go | 10 ++ .../x/sys/unix/zsyscall_netbsd_amd64.go | 10 ++ .../x/sys/unix/zsyscall_netbsd_arm.go | 10 ++ .../x/sys/unix/zsyscall_netbsd_arm64.go | 10 ++ .../x/sys/unix/zsyscall_openbsd_386.go | 8 + .../x/sys/unix/zsyscall_openbsd_amd64.go | 8 + .../x/sys/unix/zsyscall_openbsd_arm.go | 8 + .../x/sys/unix/zsyscall_openbsd_arm64.go | 8 + .../x/sys/unix/zsyscall_openbsd_mips64.go | 8 + .../x/sys/unix/zsyscall_openbsd_ppc64.go | 8 + .../x/sys/unix/zsyscall_openbsd_riscv64.go | 8 + .../x/sys/unix/zsyscall_solaris_amd64.go | 11 ++ .../x/sys/unix/zsyscall_zos_s390x.go | 10 ++ .../x/sys/unix/ztypes_freebsd_386.go | 2 +- .../x/sys/unix/ztypes_freebsd_amd64.go | 2 +- .../x/sys/unix/ztypes_freebsd_arm.go | 2 +- .../x/sys/unix/ztypes_freebsd_arm64.go | 2 +- .../x/sys/unix/ztypes_freebsd_riscv64.go | 2 +- vendor/golang.org/x/sys/unix/ztypes_linux.go | 140 +++++++++++++----- .../golang.org/x/sys/unix/ztypes_linux_386.go | 2 +- .../x/sys/unix/ztypes_linux_amd64.go | 2 +- .../golang.org/x/sys/unix/ztypes_linux_arm.go | 2 +- .../x/sys/unix/ztypes_linux_arm64.go | 2 +- .../x/sys/unix/ztypes_linux_loong64.go | 2 +- .../x/sys/unix/ztypes_linux_mips.go | 2 +- .../x/sys/unix/ztypes_linux_mips64.go | 2 +- .../x/sys/unix/ztypes_linux_mips64le.go | 2 +- .../x/sys/unix/ztypes_linux_mipsle.go | 2 +- .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 2 +- .../x/sys/unix/ztypes_linux_ppc64.go | 2 +- .../x/sys/unix/ztypes_linux_ppc64le.go | 2 +- .../x/sys/unix/ztypes_linux_riscv64.go | 2 +- .../x/sys/unix/ztypes_linux_s390x.go | 2 +- .../x/sys/unix/ztypes_linux_sparc64.go | 2 +- .../x/sys/windows/syscall_windows.go | 6 +- .../golang.org/x/sys/windows/types_windows.go | 85 +++++++++++ .../x/sys/windows/zsyscall_windows.go | 27 ++++ .../x/text/encoding/internal/internal.go | 2 +- .../x/text/unicode/norm/forminfo.go | 2 +- vendor/modules.txt | 8 +- 90 files changed, 877 insertions(+), 222 deletions(-) create mode 100644 vendor/golang.org/x/sys/cpu/runtime_auxv.go create mode 100644 vendor/golang.org/x/sys/cpu/runtime_auxv_go121.go diff --git a/go.mod b/go.mod index 2c6adda01..a0124fa16 100644 --- a/go.mod +++ b/go.mod @@ -28,8 +28,8 @@ require ( github.com/prometheus/client_golang v1.14.0 github.com/stretchr/testify v1.8.1 golang.org/x/crypto v0.6.0 - golang.org/x/net v0.7.0 - golang.org/x/sys v0.5.0 + golang.org/x/net v0.8.0 + golang.org/x/sys v0.6.0 google.golang.org/grpc v1.53.0 google.golang.org/protobuf v1.28.1 k8s.io/api v0.26.1 @@ -138,8 +138,8 @@ require ( go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/oauth2 v0.4.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index db4f51668..2c11fc9d8 100644 --- a/go.sum +++ b/go.sum @@ -1220,8 +1220,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1344,15 +1344,15 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1365,8 +1365,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go index 822ed42a0..7a96eae33 100644 --- a/vendor/golang.org/x/net/html/doc.go +++ b/vendor/golang.org/x/net/html/doc.go @@ -92,6 +92,21 @@ example, to process each anchor node in depth-first order: The relevant specifications include: https://html.spec.whatwg.org/multipage/syntax.html and https://html.spec.whatwg.org/multipage/syntax.html#tokenization + +# Security Considerations + +Care should be taken when parsing and interpreting HTML, whether full documents +or fragments, within the framework of the HTML specification, especially with +regard to untrusted inputs. + +This package provides both a tokenizer and a parser. Only the parser constructs +a DOM according to the HTML specification, resolving malformed and misplaced +tags where appropriate. The tokenizer simply tokenizes the HTML presented to it, +and as such does not resolve issues that may exist in the processed HTML, +producing a literal interpretation of the input. + +If your use case requires semantically well-formed HTML, as defined by the +WHATWG specifiction, the parser should be used rather than the tokenizer. */ package html // import "golang.org/x/net/html" diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go index d85613962..04c6bec21 100644 --- a/vendor/golang.org/x/net/html/escape.go +++ b/vendor/golang.org/x/net/html/escape.go @@ -193,6 +193,87 @@ func lower(b []byte) []byte { return b } +// escapeComment is like func escape but escapes its input bytes less often. +// Per https://github.com/golang/go/issues/58246 some HTML comments are (1) +// meaningful and (2) contain angle brackets that we'd like to avoid escaping +// unless we have to. +// +// "We have to" includes the '&' byte, since that introduces other escapes. +// +// It also includes those bytes (not including EOF) that would otherwise end +// the comment. Per the summary table at the bottom of comment_test.go, this is +// the '>' byte that, per above, we'd like to avoid escaping unless we have to. +// +// Studying the summary table (and T actions in its '>' column) closely, we +// only need to escape in states 43, 44, 49, 51 and 52. State 43 is at the +// start of the comment data. State 52 is after a '!'. The other three states +// are after a '-'. +// +// Our algorithm is thus to escape every '&' and to escape '>' if and only if: +// - The '>' is after a '!' or '-' (in the unescaped data) or +// - The '>' is at the start of the comment data (after the opening ""); err != nil { diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index 50f7c6aac..5c2a1f4ef 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -110,7 +110,7 @@ func (t Token) String() string { case SelfClosingTagToken: return "<" + t.tagString() + "/>" case CommentToken: - return "" + return "" case DoctypeToken: return "" } @@ -598,10 +598,10 @@ scriptDataDoubleEscapeEnd: // readComment reads the next comment token starting with " + // t0 t1 t2 + // + // We have the guarantees: + // - in normal cases, the interval is 5 minutes. + // - in failover, the interval is >5m and <10m + // + // FAQ: + // - What if time is not accurate? We don't care as long as someone did the compaction. Atomicity is ensured using + // etcd API. + // - What happened under heavy load scenarios? Initially, each apiserver will do only one compaction + // every 5 minutes. This is very unlikely affecting or affected w.r.t. server load. + + var compactTime int64 + var rev int64 + var err error + for { + select { + case <-time.After(interval): + case <-ctx.Done(): + return + } + + compactTime, rev, err = compact(ctx, client, compactTime, rev) + if err != nil { + klog.Errorf("etcd: endpoint (%v) compact failed: %v", client.Endpoints(), err) + continue + } + } +} + +// compact compacts etcd store and returns current rev. +// It will return the current compact time and global revision if no error occurred. +// Note that CAS fail will not incur any error. +func compact(ctx context.Context, client *clientv3.Client, t, rev int64) (int64, int64, error) { + resp, err := client.KV.Txn(ctx).If( + clientv3.Compare(clientv3.Version(compactRevKey), "=", t), + ).Then( + clientv3.OpPut(compactRevKey, strconv.FormatInt(rev, 10)), // Expect side effect: increment Version + ).Else( + clientv3.OpGet(compactRevKey), + ).Commit() + if err != nil { + return t, rev, err + } + + curRev := resp.Header.Revision + + if !resp.Succeeded { + curTime := resp.Responses[0].GetResponseRange().Kvs[0].Version + return curTime, curRev, nil + } + curTime := t + 1 + + if rev == 0 { + // We don't compact on bootstrap. + return curTime, curRev, nil + } + if _, err = client.Compact(ctx, rev); err != nil { + return curTime, curRev, err + } + klog.V(4).Infof("etcd: compacted rev (%d), endpoints (%v)", rev, client.Endpoints()) + return curTime, curRev, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/errors.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/errors.go new file mode 100644 index 000000000..d71c9917d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/errors.go @@ -0,0 +1,72 @@ +/* +Copyright 2016 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 etcd3 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apiserver/pkg/storage" + + etcdrpc "go.etcd.io/etcd/api/v3/v3rpc/rpctypes" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +func interpretWatchError(err error) error { + switch { + case err == etcdrpc.ErrCompacted: + return errors.NewResourceExpired("The resourceVersion for the provided watch is too old.") + } + return err +} + +const ( + expired string = "The resourceVersion for the provided list is too old." + continueExpired string = "The provided continue parameter is too old " + + "to display a consistent list result. You can start a new list without " + + "the continue parameter." + inconsistentContinue string = "The provided continue parameter is too old " + + "to display a consistent list result. You can start a new list without " + + "the continue parameter, or use the continue token in this response to " + + "retrieve the remainder of the results. Continuing with the provided " + + "token results in an inconsistent list - objects that were created, " + + "modified, or deleted between the time the first chunk was returned " + + "and now may show up in the list." +) + +func interpretListError(err error, paging bool, continueKey, keyPrefix string) error { + switch { + case err == etcdrpc.ErrCompacted: + if paging { + return handleCompactedErrorForPaging(continueKey, keyPrefix) + } + return errors.NewResourceExpired(expired) + } + return err +} + +func handleCompactedErrorForPaging(continueKey, keyPrefix string) error { + // continueToken.ResoureVersion=-1 means that the apiserver can + // continue the list at the latest resource version. We don't use rv=0 + // for this purpose to distinguish from a bad token that has empty rv. + newToken, err := storage.EncodeContinue(continueKey, keyPrefix, -1) + if err != nil { + utilruntime.HandleError(err) + return errors.NewResourceExpired(continueExpired) + } + statusError := errors.NewResourceExpired(inconsistentContinue) + statusError.ErrStatus.ListMeta.Continue = newToken + return statusError +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/event.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/event.go new file mode 100644 index 000000000..3e5bfb1c6 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/event.go @@ -0,0 +1,71 @@ +/* +Copyright 2016 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 etcd3 + +import ( + "fmt" + "go.etcd.io/etcd/api/v3/mvccpb" + clientv3 "go.etcd.io/etcd/client/v3" +) + +type event struct { + key string + value []byte + prevValue []byte + rev int64 + isDeleted bool + isCreated bool + isProgressNotify bool +} + +// parseKV converts a KeyValue retrieved from an initial sync() listing to a synthetic isCreated event. +func parseKV(kv *mvccpb.KeyValue) *event { + return &event{ + key: string(kv.Key), + value: kv.Value, + prevValue: nil, + rev: kv.ModRevision, + isDeleted: false, + isCreated: true, + } +} + +func parseEvent(e *clientv3.Event) (*event, error) { + if !e.IsCreate() && e.PrevKv == nil { + // If the previous value is nil, error. One example of how this is possible is if the previous value has been compacted already. + return nil, fmt.Errorf("etcd event received with PrevKv=nil (key=%q, modRevision=%d, type=%s)", string(e.Kv.Key), e.Kv.ModRevision, e.Type.String()) + + } + ret := &event{ + key: string(e.Kv.Key), + value: e.Kv.Value, + rev: e.Kv.ModRevision, + isDeleted: e.Type == clientv3.EventTypeDelete, + isCreated: e.IsCreate(), + } + if e.PrevKv != nil { + ret.prevValue = e.PrevKv.Value + } + return ret, nil +} + +func progressNotifyEvent(rev int64) *event { + return &event{ + rev: rev, + isProgressNotify: true, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/healthcheck.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/healthcheck.go new file mode 100644 index 000000000..ad051d2d6 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/healthcheck.go @@ -0,0 +1,40 @@ +/* +Copyright 2015 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 etcd3 + +import ( + "encoding/json" + "fmt" +) + +// etcdHealth encodes data returned from etcd /healthz handler. +type etcdHealth struct { + // Note this has to be public so the json library can modify it. + Health string `json:"health"` +} + +// EtcdHealthCheck decodes data returned from etcd /healthz handler. +func EtcdHealthCheck(data []byte) error { + obj := etcdHealth{} + if err := json.Unmarshal(data, &obj); err != nil { + return err + } + if obj.Health != "true" { + return fmt.Errorf("Unhealthy status: %s", obj.Health) + } + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go new file mode 100644 index 000000000..96d592e79 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go @@ -0,0 +1,108 @@ +/* +Copyright 2022 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 etcd3 + +import ( + "context" + "time" + + clientv3 "go.etcd.io/etcd/client/v3" + endpointsrequest "k8s.io/apiserver/pkg/endpoints/request" +) + +// NewETCDLatencyTracker returns an implementation of +// clientv3.KV that times the calls from the specified +// 'delegate' KV instance in order to track latency incurred. +func NewETCDLatencyTracker(delegate clientv3.KV) clientv3.KV { + return &clientV3KVLatencyTracker{KV: delegate} +} + +// clientV3KVLatencyTracker decorates a clientv3.KV instance and times +// each call so we can track the latency an API request incurs in etcd +// round trips (the time it takes to send data to etcd and get the +// complete response back) +// +// If an API request involves N (N>=1) round trips to etcd, then we will sum +// up the latenciy incurred in each roundtrip. + +// It uses the context associated with the request in flight, so there +// are no states shared among the requests in flight, and so there is no +// concurrency overhead. +// If the goroutine executing the request handler makes concurrent calls +// to the underlying storage layer, that is protected since the latency +// tracking function TrackStorageLatency is thread safe. +// +// NOTE: Compact is an asynchronous process and is not associated with +// +// any request, so we will not be tracking its latency. +type clientV3KVLatencyTracker struct { + clientv3.KV +} + +func (c *clientV3KVLatencyTracker) Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(ctx, time.Since(startedAt)) + }() + + return c.KV.Put(ctx, key, val, opts...) +} + +func (c *clientV3KVLatencyTracker) Get(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.GetResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(ctx, time.Since(startedAt)) + }() + + return c.KV.Get(ctx, key, opts...) +} + +func (c *clientV3KVLatencyTracker) Delete(ctx context.Context, key string, opts ...clientv3.OpOption) (*clientv3.DeleteResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(ctx, time.Since(startedAt)) + }() + + return c.KV.Delete(ctx, key, opts...) +} + +func (c *clientV3KVLatencyTracker) Do(ctx context.Context, op clientv3.Op) (clientv3.OpResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(ctx, time.Since(startedAt)) + }() + + return c.KV.Do(ctx, op) +} + +func (c *clientV3KVLatencyTracker) Txn(ctx context.Context) clientv3.Txn { + return &clientV3TxnTracker{ctx: ctx, Txn: c.KV.Txn(ctx)} +} + +type clientV3TxnTracker struct { + ctx context.Context + clientv3.Txn +} + +func (t *clientV3TxnTracker) Commit() (*clientv3.TxnResponse, error) { + startedAt := time.Now() + defer func() { + endpointsrequest.TrackStorageLatency(t.ctx, time.Since(startedAt)) + }() + + return t.Txn.Commit() +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/lease_manager.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/lease_manager.go new file mode 100644 index 000000000..12c9d00c7 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/lease_manager.go @@ -0,0 +1,131 @@ +/* +Copyright 2018 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 etcd3 + +import ( + "context" + "sync" + "time" + + clientv3 "go.etcd.io/etcd/client/v3" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" +) + +const ( + defaultLeaseReuseDurationSeconds = 60 + defaultLeaseMaxObjectCount = 1000 +) + +// LeaseManagerConfig is configuration for creating a lease manager. +type LeaseManagerConfig struct { + // ReuseDurationSeconds specifies time in seconds that each lease is reused + ReuseDurationSeconds int64 + // MaxObjectCount specifies how many objects that a lease can attach + MaxObjectCount int64 +} + +// NewDefaultLeaseManagerConfig creates a LeaseManagerConfig with default values +func NewDefaultLeaseManagerConfig() LeaseManagerConfig { + return LeaseManagerConfig{ + ReuseDurationSeconds: defaultLeaseReuseDurationSeconds, + MaxObjectCount: defaultLeaseMaxObjectCount, + } +} + +// leaseManager is used to manage leases requested from etcd. If a new write +// needs a lease that has similar expiration time to the previous one, the old +// lease will be reused to reduce the overhead of etcd, since lease operations +// are expensive. In the implementation, we only store one previous lease, +// since all the events have the same ttl. +type leaseManager struct { + client *clientv3.Client // etcd client used to grant leases + leaseMu sync.Mutex + prevLeaseID clientv3.LeaseID + prevLeaseExpirationTime time.Time + // The period of time in seconds and percent of TTL that each lease is + // reused. The minimum of them is used to avoid unreasonably large + // numbers. + leaseReuseDurationSeconds int64 + leaseReuseDurationPercent float64 + leaseMaxAttachedObjectCount int64 + leaseAttachedObjectCount int64 +} + +// newDefaultLeaseManager creates a new lease manager using default setting. +func newDefaultLeaseManager(client *clientv3.Client, config LeaseManagerConfig) *leaseManager { + if config.MaxObjectCount <= 0 { + config.MaxObjectCount = defaultLeaseMaxObjectCount + } + return newLeaseManager(client, config.ReuseDurationSeconds, 0.05, config.MaxObjectCount) +} + +// newLeaseManager creates a new lease manager with the number of buffered +// leases, lease reuse duration in seconds and percentage. The percentage +// value x means x*100%. +func newLeaseManager(client *clientv3.Client, leaseReuseDurationSeconds int64, leaseReuseDurationPercent float64, maxObjectCount int64) *leaseManager { + return &leaseManager{ + client: client, + leaseReuseDurationSeconds: leaseReuseDurationSeconds, + leaseReuseDurationPercent: leaseReuseDurationPercent, + leaseMaxAttachedObjectCount: maxObjectCount, + } +} + +// GetLease returns a lease based on requested ttl: if the cached previous +// lease can be reused, reuse it; otherwise request a new one from etcd. +func (l *leaseManager) GetLease(ctx context.Context, ttl int64) (clientv3.LeaseID, error) { + now := time.Now() + l.leaseMu.Lock() + defer l.leaseMu.Unlock() + // check if previous lease can be reused + reuseDurationSeconds := l.getReuseDurationSecondsLocked(ttl) + valid := now.Add(time.Duration(ttl) * time.Second).Before(l.prevLeaseExpirationTime) + sufficient := now.Add(time.Duration(ttl+reuseDurationSeconds) * time.Second).After(l.prevLeaseExpirationTime) + + // We count all operations that happened in the same lease, regardless of success or failure. + // Currently each GetLease call only attach 1 object + l.leaseAttachedObjectCount++ + + if valid && sufficient && l.leaseAttachedObjectCount <= l.leaseMaxAttachedObjectCount { + return l.prevLeaseID, nil + } + + // request a lease with a little extra ttl from etcd + ttl += reuseDurationSeconds + lcr, err := l.client.Lease.Grant(ctx, ttl) + if err != nil { + return clientv3.LeaseID(0), err + } + // cache the new lease id + l.prevLeaseID = lcr.ID + l.prevLeaseExpirationTime = now.Add(time.Duration(ttl) * time.Second) + // refresh count + metrics.UpdateLeaseObjectCount(l.leaseAttachedObjectCount) + l.leaseAttachedObjectCount = 1 + return lcr.ID, nil +} + +// getReuseDurationSecondsLocked returns the reusable duration in seconds +// based on the configuration. Lock has to be acquired before calling this +// function. +func (l *leaseManager) getReuseDurationSecondsLocked(ttl int64) int64 { + reuseDurationSeconds := int64(l.leaseReuseDurationPercent * float64(ttl)) + if reuseDurationSeconds > l.leaseReuseDurationSeconds { + reuseDurationSeconds = l.leaseReuseDurationSeconds + } + return reuseDurationSeconds +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/logger.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/logger.go new file mode 100644 index 000000000..773d12f6f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/logger.go @@ -0,0 +1,90 @@ +/* +Copyright 2018 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 etcd3 + +import ( + "fmt" + + "google.golang.org/grpc/grpclog" + "k8s.io/klog/v2" +) + +func init() { + grpclog.SetLoggerV2(klogWrapper{}) +} + +type klogWrapper struct{} + +const klogWrapperDepth = 4 + +func (klogWrapper) Info(args ...interface{}) { + if klogV := klog.V(5); klogV.Enabled() { + klogV.InfoSDepth(klogWrapperDepth, fmt.Sprint(args...)) + } +} + +func (klogWrapper) Infoln(args ...interface{}) { + if klogV := klog.V(5); klogV.Enabled() { + klogV.InfoSDepth(klogWrapperDepth, fmt.Sprintln(args...)) + } +} + +func (klogWrapper) Infof(format string, args ...interface{}) { + if klogV := klog.V(5); klogV.Enabled() { + klog.V(5).InfoSDepth(klogWrapperDepth, fmt.Sprintf(format, args...)) + } +} + +func (klogWrapper) Warning(args ...interface{}) { + klog.WarningDepth(klogWrapperDepth, args...) +} + +func (klogWrapper) Warningln(args ...interface{}) { + klog.WarningDepth(klogWrapperDepth, fmt.Sprintln(args...)) +} + +func (klogWrapper) Warningf(format string, args ...interface{}) { + klog.WarningDepth(klogWrapperDepth, fmt.Sprintf(format, args...)) +} + +func (klogWrapper) Error(args ...interface{}) { + klog.ErrorDepth(klogWrapperDepth, args...) +} + +func (klogWrapper) Errorln(args ...interface{}) { + klog.ErrorDepth(klogWrapperDepth, fmt.Sprintln(args...)) +} + +func (klogWrapper) Errorf(format string, args ...interface{}) { + klog.ErrorDepth(klogWrapperDepth, fmt.Sprintf(format, args...)) +} + +func (klogWrapper) Fatal(args ...interface{}) { + klog.FatalDepth(klogWrapperDepth, args...) +} + +func (klogWrapper) Fatalln(args ...interface{}) { + klog.FatalDepth(klogWrapperDepth, fmt.Sprintln(args...)) +} + +func (klogWrapper) Fatalf(format string, args ...interface{}) { + klog.FatalDepth(klogWrapperDepth, fmt.Sprintf(format, args...)) +} + +func (klogWrapper) V(l int) bool { + return bool(klog.V(klog.Level(l)).Enabled()) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/OWNERS new file mode 100644 index 000000000..433e84aa3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - logicalhan diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go new file mode 100644 index 000000000..825582294 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go @@ -0,0 +1,179 @@ +/* +Copyright 2015 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 metrics + +import ( + "sync" + "time" + + compbasemetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +/* + * By default, all the following metrics are defined as falling under + * ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes) + * + * Promoting the stability level of the metric is a responsibility of the component owner, since it + * involves explicitly acknowledging support for the metric across multiple releases, in accordance with + * the metric stability policy. + */ +var ( + etcdRequestLatency = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Name: "etcd_request_duration_seconds", + Help: "Etcd request latency in seconds for each operation and object type.", + // Etcd request latency in seconds for each operation and object type. + // This metric is used for verifying etcd api call latencies SLO + // keep consistent with apiserver metric 'requestLatencies' in + // staging/src/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go + Buckets: []float64{0.005, 0.025, 0.05, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.25, 1.5, 2, 3, + 4, 5, 6, 8, 10, 15, 20, 30, 45, 60}, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"operation", "type"}, + ) + objectCounts = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Name: "apiserver_storage_objects", + Help: "Number of stored objects at the time of last check split by kind.", + StabilityLevel: compbasemetrics.STABLE, + }, + []string{"resource"}, + ) + dbTotalSize = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Subsystem: "apiserver", + Name: "storage_db_total_size_in_bytes", + Help: "Total size of the storage database file physically allocated in bytes.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"endpoint"}, + ) + etcdBookmarkCounts = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Name: "etcd_bookmark_counts", + Help: "Number of etcd bookmarks (progress notify events) split by kind.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + etcdLeaseObjectCounts = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Name: "etcd_lease_object_counts", + Help: "Number of objects attached to a single etcd lease.", + Buckets: []float64{10, 50, 100, 500, 1000, 2500, 5000}, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{}, + ) + listStorageCount = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_storage_list_total", + Help: "Number of LIST requests served from storage", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + listStorageNumFetched = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_storage_list_fetched_objects_total", + Help: "Number of objects read from storage in the course of serving a LIST request", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + listStorageNumSelectorEvals = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_storage_list_evaluated_objects_total", + Help: "Number of objects tested in the course of serving a LIST request from storage", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + listStorageNumReturned = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Name: "apiserver_storage_list_returned_objects_total", + Help: "Number of objects returned for a LIST request from storage", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) +) + +var registerMetrics sync.Once + +// Register all metrics. +func Register() { + // Register the metrics. + registerMetrics.Do(func() { + legacyregistry.MustRegister(etcdRequestLatency) + legacyregistry.MustRegister(objectCounts) + legacyregistry.MustRegister(dbTotalSize) + legacyregistry.MustRegister(etcdBookmarkCounts) + legacyregistry.MustRegister(etcdLeaseObjectCounts) + legacyregistry.MustRegister(listStorageCount) + legacyregistry.MustRegister(listStorageNumFetched) + legacyregistry.MustRegister(listStorageNumSelectorEvals) + legacyregistry.MustRegister(listStorageNumReturned) + }) +} + +// UpdateObjectCount sets the apiserver_storage_object_counts metric. +func UpdateObjectCount(resourcePrefix string, count int64) { + objectCounts.WithLabelValues(resourcePrefix).Set(float64(count)) +} + +// RecordEtcdRequestLatency sets the etcd_request_duration_seconds metrics. +func RecordEtcdRequestLatency(verb, resource string, startTime time.Time) { + etcdRequestLatency.WithLabelValues(verb, resource).Observe(sinceInSeconds(startTime)) +} + +// RecordEtcdBookmark updates the etcd_bookmark_counts metric. +func RecordEtcdBookmark(resource string) { + etcdBookmarkCounts.WithLabelValues(resource).Inc() +} + +// Reset resets the etcd_request_duration_seconds metric. +func Reset() { + etcdRequestLatency.Reset() +} + +// sinceInSeconds gets the time since the specified start in seconds. +func sinceInSeconds(start time.Time) float64 { + return time.Since(start).Seconds() +} + +// UpdateEtcdDbSize sets the etcd_db_total_size_in_bytes metric. +func UpdateEtcdDbSize(ep string, size int64) { + dbTotalSize.WithLabelValues(ep).Set(float64(size)) +} + +// UpdateLeaseObjectCount sets the etcd_lease_object_counts metric. +func UpdateLeaseObjectCount(count int64) { + // Currently we only store one previous lease, since all the events have the same ttl. + // See pkg/storage/etcd3/lease_manager.go + etcdLeaseObjectCounts.WithLabelValues().Observe(float64(count)) +} + +// RecordListEtcd3Metrics notes various metrics of the cost to serve a LIST request +func RecordStorageListMetrics(resource string, numFetched, numEvald, numReturned int) { + listStorageCount.WithLabelValues(resource).Inc() + listStorageNumFetched.WithLabelValues(resource).Add(float64(numFetched)) + listStorageNumSelectorEvals.WithLabelValues(resource).Add(float64(numEvald)) + listStorageNumReturned.WithLabelValues(resource).Add(float64(numReturned)) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go new file mode 100644 index 000000000..51e5b9012 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -0,0 +1,1028 @@ +/* +Copyright 2016 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 etcd3 + +import ( + "bytes" + "context" + "errors" + "fmt" + "path" + "reflect" + "strings" + "time" + + clientv3 "go.etcd.io/etcd/client/v3" + "go.opentelemetry.io/otel/attribute" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/audit" + "k8s.io/apiserver/pkg/features" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" + "k8s.io/apiserver/pkg/storage/value" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/component-base/tracing" + "k8s.io/klog/v2" +) + +const ( + // maxLimit is a maximum page limit increase used when fetching objects from etcd. + // This limit is used only for increasing page size by kube-apiserver. If request + // specifies larger limit initially, it won't be changed. + maxLimit = 10000 +) + +// authenticatedDataString satisfies the value.Context interface. It uses the key to +// authenticate the stored data. This does not defend against reuse of previously +// encrypted values under the same key, but will prevent an attacker from using an +// encrypted value from a different key. A stronger authenticated data segment would +// include the etcd3 Version field (which is incremented on each write to a key and +// reset when the key is deleted), but an attacker with write access to etcd can +// force deletion and recreation of keys to weaken that angle. +type authenticatedDataString string + +// AuthenticatedData implements the value.Context interface. +func (d authenticatedDataString) AuthenticatedData() []byte { + return []byte(string(d)) +} + +var _ value.Context = authenticatedDataString("") + +type store struct { + client *clientv3.Client + codec runtime.Codec + versioner storage.Versioner + transformer value.Transformer + pathPrefix string + groupResource schema.GroupResource + groupResourceString string + watcher *watcher + pagingEnabled bool + leaseManager *leaseManager +} + +type objState struct { + obj runtime.Object + meta *storage.ResponseMeta + rev int64 + data []byte + stale bool +} + +// New returns an etcd3 implementation of storage.Interface. +func New(c *clientv3.Client, codec runtime.Codec, newFunc func() runtime.Object, prefix string, groupResource schema.GroupResource, transformer value.Transformer, pagingEnabled bool, leaseManagerConfig LeaseManagerConfig) storage.Interface { + return newStore(c, codec, newFunc, prefix, groupResource, transformer, pagingEnabled, leaseManagerConfig) +} + +func newStore(c *clientv3.Client, codec runtime.Codec, newFunc func() runtime.Object, prefix string, groupResource schema.GroupResource, transformer value.Transformer, pagingEnabled bool, leaseManagerConfig LeaseManagerConfig) *store { + versioner := storage.APIObjectVersioner{} + // for compatibility with etcd2 impl. + // no-op for default prefix of '/registry'. + // keeps compatibility with etcd2 impl for custom prefixes that don't start with '/' + pathPrefix := path.Join("/", prefix) + if !strings.HasSuffix(pathPrefix, "/") { + // Ensure the pathPrefix ends in "/" here to simplify key concatenation later. + pathPrefix += "/" + } + result := &store{ + client: c, + codec: codec, + versioner: versioner, + transformer: transformer, + pagingEnabled: pagingEnabled, + pathPrefix: pathPrefix, + groupResource: groupResource, + groupResourceString: groupResource.String(), + watcher: newWatcher(c, codec, groupResource, newFunc, versioner), + leaseManager: newDefaultLeaseManager(c, leaseManagerConfig), + } + return result +} + +// Versioner implements storage.Interface.Versioner. +func (s *store) Versioner() storage.Versioner { + return s.versioner +} + +// Get implements storage.Interface.Get. +func (s *store) Get(ctx context.Context, key string, opts storage.GetOptions, out runtime.Object) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + startTime := time.Now() + getResp, err := s.client.KV.Get(ctx, preparedKey) + metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime) + if err != nil { + return err + } + if err = s.validateMinimumResourceVersion(opts.ResourceVersion, uint64(getResp.Header.Revision)); err != nil { + return err + } + + if len(getResp.Kvs) == 0 { + if opts.IgnoreNotFound { + return runtime.SetZeroValue(out) + } + return storage.NewKeyNotFoundError(preparedKey, 0) + } + kv := getResp.Kvs[0] + + data, _, err := s.transformer.TransformFromStorage(ctx, kv.Value, authenticatedDataString(preparedKey)) + if err != nil { + return storage.NewInternalError(err.Error()) + } + + return decode(s.codec, s.versioner, data, out, kv.ModRevision) +} + +// Create implements storage.Interface.Create. +func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + ctx, span := tracing.Start(ctx, "Create etcd3", + attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)), + attribute.String("key", key), + attribute.String("type", getTypeName(obj)), + attribute.String("resource", s.groupResourceString), + ) + defer span.End(500 * time.Millisecond) + if version, err := s.versioner.ObjectResourceVersion(obj); err == nil && version != 0 { + return errors.New("resourceVersion should not be set on objects to be created") + } + if err := s.versioner.PrepareObjectForStorage(obj); err != nil { + return fmt.Errorf("PrepareObjectForStorage failed: %v", err) + } + span.AddEvent("About to Encode") + data, err := runtime.Encode(s.codec, obj) + if err != nil { + span.AddEvent("Encode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + return err + } + span.AddEvent("Encode succeeded", attribute.Int("len", len(data))) + + opts, err := s.ttlOpts(ctx, int64(ttl)) + if err != nil { + return err + } + + newData, err := s.transformer.TransformToStorage(ctx, data, authenticatedDataString(preparedKey)) + if err != nil { + span.AddEvent("TransformToStorage failed", attribute.String("err", err.Error())) + return storage.NewInternalError(err.Error()) + } + span.AddEvent("TransformToStorage succeeded") + + startTime := time.Now() + txnResp, err := s.client.KV.Txn(ctx).If( + notFound(preparedKey), + ).Then( + clientv3.OpPut(preparedKey, string(newData), opts...), + ).Commit() + metrics.RecordEtcdRequestLatency("create", s.groupResourceString, startTime) + if err != nil { + span.AddEvent("Txn call failed", attribute.String("err", err.Error())) + return err + } + span.AddEvent("Txn call succeeded") + + if !txnResp.Succeeded { + return storage.NewKeyExistsError(preparedKey, 0) + } + + if out != nil { + putResp := txnResp.Responses[0].GetResponsePut() + err = decode(s.codec, s.versioner, data, out, putResp.Header.Revision) + if err != nil { + span.AddEvent("decode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + return err + } + span.AddEvent("decode succeeded", attribute.Int("len", len(data))) + } + return nil +} + +// Delete implements storage.Interface.Delete. +func (s *store) Delete( + ctx context.Context, key string, out runtime.Object, preconditions *storage.Preconditions, + validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + v, err := conversion.EnforcePtr(out) + if err != nil { + return fmt.Errorf("unable to convert output object to pointer: %v", err) + } + return s.conditionalDelete(ctx, preparedKey, out, v, preconditions, validateDeletion, cachedExistingObject) +} + +func (s *store) conditionalDelete( + ctx context.Context, key string, out runtime.Object, v reflect.Value, preconditions *storage.Preconditions, + validateDeletion storage.ValidateObjectFunc, cachedExistingObject runtime.Object) error { + getCurrentState := func() (*objState, error) { + startTime := time.Now() + getResp, err := s.client.KV.Get(ctx, key) + metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime) + if err != nil { + return nil, err + } + return s.getState(ctx, getResp, key, v, false) + } + + var origState *objState + var err error + var origStateIsCurrent bool + if cachedExistingObject != nil { + origState, err = s.getStateFromObject(cachedExistingObject) + } else { + origState, err = getCurrentState() + origStateIsCurrent = true + } + if err != nil { + return err + } + + for { + if preconditions != nil { + if err := preconditions.Check(key, origState.obj); err != nil { + if origStateIsCurrent { + return err + } + + // It's possible we're working with stale data. + // Remember the revision of the potentially stale data and the resulting update error + cachedRev := origState.rev + cachedUpdateErr := err + + // Actually fetch + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + + // it turns out our cached data was not stale, return the error + if cachedRev == origState.rev { + return cachedUpdateErr + } + + // Retry + continue + } + } + if err := validateDeletion(ctx, origState.obj); err != nil { + if origStateIsCurrent { + return err + } + + // It's possible we're working with stale data. + // Remember the revision of the potentially stale data and the resulting update error + cachedRev := origState.rev + cachedUpdateErr := err + + // Actually fetch + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + + // it turns out our cached data was not stale, return the error + if cachedRev == origState.rev { + return cachedUpdateErr + } + + // Retry + continue + } + + startTime := time.Now() + txnResp, err := s.client.KV.Txn(ctx).If( + clientv3.Compare(clientv3.ModRevision(key), "=", origState.rev), + ).Then( + clientv3.OpDelete(key), + ).Else( + clientv3.OpGet(key), + ).Commit() + metrics.RecordEtcdRequestLatency("delete", s.groupResourceString, startTime) + if err != nil { + return err + } + if !txnResp.Succeeded { + getResp := (*clientv3.GetResponse)(txnResp.Responses[0].GetResponseRange()) + klog.V(4).Infof("deletion of %s failed because of a conflict, going to retry", key) + origState, err = s.getState(ctx, getResp, key, v, false) + if err != nil { + return err + } + origStateIsCurrent = true + continue + } + + if len(txnResp.Responses) == 0 || txnResp.Responses[0].GetResponseDeleteRange() == nil { + return errors.New(fmt.Sprintf("invalid DeleteRange response: %v", txnResp.Responses)) + } + deleteResp := txnResp.Responses[0].GetResponseDeleteRange() + if deleteResp.Header == nil { + return errors.New("invalid DeleteRange response - nil header") + } + return decode(s.codec, s.versioner, origState.data, out, deleteResp.Header.Revision) + } +} + +// GuaranteedUpdate implements storage.Interface.GuaranteedUpdate. +func (s *store) GuaranteedUpdate( + ctx context.Context, key string, destination runtime.Object, ignoreNotFound bool, + preconditions *storage.Preconditions, tryUpdate storage.UpdateFunc, cachedExistingObject runtime.Object) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + ctx, span := tracing.Start(ctx, "GuaranteedUpdate etcd3", + attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)), + attribute.String("key", key), + attribute.String("type", getTypeName(destination)), + attribute.String("resource", s.groupResourceString)) + defer span.End(500 * time.Millisecond) + + v, err := conversion.EnforcePtr(destination) + if err != nil { + return fmt.Errorf("unable to convert output object to pointer: %v", err) + } + + getCurrentState := func() (*objState, error) { + startTime := time.Now() + getResp, err := s.client.KV.Get(ctx, preparedKey) + metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime) + if err != nil { + return nil, err + } + return s.getState(ctx, getResp, preparedKey, v, ignoreNotFound) + } + + var origState *objState + var origStateIsCurrent bool + if cachedExistingObject != nil { + origState, err = s.getStateFromObject(cachedExistingObject) + } else { + origState, err = getCurrentState() + origStateIsCurrent = true + } + if err != nil { + return err + } + span.AddEvent("initial value restored") + + transformContext := authenticatedDataString(preparedKey) + for { + if err := preconditions.Check(preparedKey, origState.obj); err != nil { + // If our data is already up to date, return the error + if origStateIsCurrent { + return err + } + + // It's possible we were working with stale data + // Actually fetch + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + // Retry + continue + } + + ret, ttl, err := s.updateState(origState, tryUpdate) + if err != nil { + // If our data is already up to date, return the error + if origStateIsCurrent { + return err + } + + // It's possible we were working with stale data + // Remember the revision of the potentially stale data and the resulting update error + cachedRev := origState.rev + cachedUpdateErr := err + + // Actually fetch + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + + // it turns out our cached data was not stale, return the error + if cachedRev == origState.rev { + return cachedUpdateErr + } + + // Retry + continue + } + + span.AddEvent("About to Encode") + data, err := runtime.Encode(s.codec, ret) + if err != nil { + span.AddEvent("Encode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + return err + } + span.AddEvent("Encode succeeded", attribute.Int("len", len(data))) + if !origState.stale && bytes.Equal(data, origState.data) { + // if we skipped the original Get in this loop, we must refresh from + // etcd in order to be sure the data in the store is equivalent to + // our desired serialization + if !origStateIsCurrent { + origState, err = getCurrentState() + if err != nil { + return err + } + origStateIsCurrent = true + if !bytes.Equal(data, origState.data) { + // original data changed, restart loop + continue + } + } + // recheck that the data from etcd is not stale before short-circuiting a write + if !origState.stale { + return decode(s.codec, s.versioner, origState.data, destination, origState.rev) + } + } + + newData, err := s.transformer.TransformToStorage(ctx, data, transformContext) + if err != nil { + span.AddEvent("TransformToStorage failed", attribute.String("err", err.Error())) + return storage.NewInternalError(err.Error()) + } + span.AddEvent("TransformToStorage succeeded") + + opts, err := s.ttlOpts(ctx, int64(ttl)) + if err != nil { + return err + } + span.AddEvent("Transaction prepared") + + startTime := time.Now() + txnResp, err := s.client.KV.Txn(ctx).If( + clientv3.Compare(clientv3.ModRevision(preparedKey), "=", origState.rev), + ).Then( + clientv3.OpPut(preparedKey, string(newData), opts...), + ).Else( + clientv3.OpGet(preparedKey), + ).Commit() + metrics.RecordEtcdRequestLatency("update", s.groupResourceString, startTime) + if err != nil { + span.AddEvent("Txn call failed", attribute.String("err", err.Error())) + return err + } + span.AddEvent("Txn call completed") + span.AddEvent("Transaction committed") + if !txnResp.Succeeded { + getResp := (*clientv3.GetResponse)(txnResp.Responses[0].GetResponseRange()) + klog.V(4).Infof("GuaranteedUpdate of %s failed because of a conflict, going to retry", preparedKey) + origState, err = s.getState(ctx, getResp, preparedKey, v, ignoreNotFound) + if err != nil { + return err + } + span.AddEvent("Retry value restored") + origStateIsCurrent = true + continue + } + putResp := txnResp.Responses[0].GetResponsePut() + + err = decode(s.codec, s.versioner, data, destination, putResp.Header.Revision) + if err != nil { + span.AddEvent("decode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + return err + } + span.AddEvent("decode succeeded", attribute.Int("len", len(data))) + return nil + } +} + +func getNewItemFunc(listObj runtime.Object, v reflect.Value) func() runtime.Object { + // For unstructured lists with a target group/version, preserve the group/version in the instantiated list items + if unstructuredList, isUnstructured := listObj.(*unstructured.UnstructuredList); isUnstructured { + if apiVersion := unstructuredList.GetAPIVersion(); len(apiVersion) > 0 { + return func() runtime.Object { + return &unstructured.Unstructured{Object: map[string]interface{}{"apiVersion": apiVersion}} + } + } + } + + // Otherwise just instantiate an empty item + elem := v.Type().Elem() + return func() runtime.Object { + return reflect.New(elem).Interface().(runtime.Object) + } +} + +func (s *store) Count(key string) (int64, error) { + preparedKey, err := s.prepareKey(key) + if err != nil { + return 0, err + } + + // We need to make sure the key ended with "/" so that we only get children "directories". + // e.g. if we have key "/a", "/a/b", "/ab", getting keys with prefix "/a" will return all three, + // while with prefix "/a/" will return only "/a/b" which is the correct answer. + if !strings.HasSuffix(preparedKey, "/") { + preparedKey += "/" + } + + startTime := time.Now() + getResp, err := s.client.KV.Get(context.Background(), preparedKey, clientv3.WithRange(clientv3.GetPrefixRangeEnd(preparedKey)), clientv3.WithCountOnly()) + metrics.RecordEtcdRequestLatency("listWithCount", preparedKey, startTime) + if err != nil { + return 0, err + } + return getResp.Count, nil +} + +// GetList implements storage.Interface. +func (s *store) GetList(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error { + preparedKey, err := s.prepareKey(key) + if err != nil { + return err + } + recursive := opts.Recursive + resourceVersion := opts.ResourceVersion + match := opts.ResourceVersionMatch + pred := opts.Predicate + ctx, span := tracing.Start(ctx, fmt.Sprintf("List(recursive=%v) etcd3", recursive), + attribute.String("audit-id", audit.GetAuditIDTruncated(ctx)), + attribute.String("key", key), + attribute.String("resourceVersion", resourceVersion), + attribute.String("resourceVersionMatch", string(match)), + attribute.Int("limit", int(pred.Limit)), + attribute.String("continue", pred.Continue)) + defer span.End(500 * time.Millisecond) + listPtr, err := meta.GetItemsPtr(listObj) + if err != nil { + return err + } + v, err := conversion.EnforcePtr(listPtr) + if err != nil || v.Kind() != reflect.Slice { + return fmt.Errorf("need ptr to slice: %v", err) + } + + // For recursive lists, we need to make sure the key ended with "/" so that we only + // get children "directories". e.g. if we have key "/a", "/a/b", "/ab", getting keys + // with prefix "/a" will return all three, while with prefix "/a/" will return only + // "/a/b" which is the correct answer. + if recursive && !strings.HasSuffix(preparedKey, "/") { + preparedKey += "/" + } + keyPrefix := preparedKey + + // set the appropriate clientv3 options to filter the returned data set + var limitOption *clientv3.OpOption + limit := pred.Limit + var paging bool + options := make([]clientv3.OpOption, 0, 4) + if s.pagingEnabled && pred.Limit > 0 { + paging = true + options = append(options, clientv3.WithLimit(limit)) + limitOption = &options[len(options)-1] + } + + newItemFunc := getNewItemFunc(listObj, v) + + var fromRV *uint64 + if len(resourceVersion) > 0 { + parsedRV, err := s.versioner.ParseResourceVersion(resourceVersion) + if err != nil { + return apierrors.NewBadRequest(fmt.Sprintf("invalid resource version: %v", err)) + } + fromRV = &parsedRV + } + + var returnedRV, continueRV, withRev int64 + var continueKey string + switch { + case recursive && s.pagingEnabled && len(pred.Continue) > 0: + continueKey, continueRV, err = storage.DecodeContinue(pred.Continue, keyPrefix) + if err != nil { + return apierrors.NewBadRequest(fmt.Sprintf("invalid continue token: %v", err)) + } + + if len(resourceVersion) > 0 && resourceVersion != "0" { + return apierrors.NewBadRequest("specifying resource version is not allowed when using continue") + } + + rangeEnd := clientv3.GetPrefixRangeEnd(keyPrefix) + options = append(options, clientv3.WithRange(rangeEnd)) + preparedKey = continueKey + + // If continueRV > 0, the LIST request needs a specific resource version. + // continueRV==0 is invalid. + // If continueRV < 0, the request is for the latest resource version. + if continueRV > 0 { + withRev = continueRV + returnedRV = continueRV + } + case recursive && s.pagingEnabled && pred.Limit > 0: + if fromRV != nil { + switch match { + case metav1.ResourceVersionMatchNotOlderThan: + // The not older than constraint is checked after we get a response from etcd, + // and returnedRV is then set to the revision we get from the etcd response. + case metav1.ResourceVersionMatchExact: + returnedRV = int64(*fromRV) + withRev = returnedRV + case "": // legacy case + if *fromRV > 0 { + returnedRV = int64(*fromRV) + withRev = returnedRV + } + default: + return fmt.Errorf("unknown ResourceVersionMatch value: %v", match) + } + } + + rangeEnd := clientv3.GetPrefixRangeEnd(keyPrefix) + options = append(options, clientv3.WithRange(rangeEnd)) + default: + if fromRV != nil { + switch match { + case metav1.ResourceVersionMatchNotOlderThan: + // The not older than constraint is checked after we get a response from etcd, + // and returnedRV is then set to the revision we get from the etcd response. + case metav1.ResourceVersionMatchExact: + returnedRV = int64(*fromRV) + withRev = returnedRV + case "": // legacy case + default: + return fmt.Errorf("unknown ResourceVersionMatch value: %v", match) + } + } + + if recursive { + options = append(options, clientv3.WithPrefix()) + } + } + if withRev != 0 { + options = append(options, clientv3.WithRev(withRev)) + } + + // loop until we have filled the requested limit from etcd or there are no more results + var lastKey []byte + var hasMore bool + var getResp *clientv3.GetResponse + var numFetched int + var numEvald int + // Because these metrics are for understanding the costs of handling LIST requests, + // get them recorded even in error cases. + defer func() { + numReturn := v.Len() + metrics.RecordStorageListMetrics(s.groupResourceString, numFetched, numEvald, numReturn) + }() + for { + startTime := time.Now() + getResp, err = s.client.KV.Get(ctx, preparedKey, options...) + if recursive { + metrics.RecordEtcdRequestLatency("list", s.groupResourceString, startTime) + } else { + metrics.RecordEtcdRequestLatency("get", s.groupResourceString, startTime) + } + if err != nil { + return interpretListError(err, len(pred.Continue) > 0, continueKey, keyPrefix) + } + numFetched += len(getResp.Kvs) + if err = s.validateMinimumResourceVersion(resourceVersion, uint64(getResp.Header.Revision)); err != nil { + return err + } + hasMore = getResp.More + + if len(getResp.Kvs) == 0 && getResp.More { + return fmt.Errorf("no results were found, but etcd indicated there were more values remaining") + } + + // avoid small allocations for the result slice, since this can be called in many + // different contexts and we don't know how significantly the result will be filtered + if pred.Empty() { + growSlice(v, len(getResp.Kvs)) + } else { + growSlice(v, 2048, len(getResp.Kvs)) + } + + // take items from the response until the bucket is full, filtering as we go + for i, kv := range getResp.Kvs { + if paging && int64(v.Len()) >= pred.Limit { + hasMore = true + break + } + lastKey = kv.Key + + data, _, err := s.transformer.TransformFromStorage(ctx, kv.Value, authenticatedDataString(kv.Key)) + if err != nil { + return storage.NewInternalErrorf("unable to transform key %q: %v", kv.Key, err) + } + + if err := appendListItem(v, data, uint64(kv.ModRevision), pred, s.codec, s.versioner, newItemFunc); err != nil { + return err + } + numEvald++ + + // free kv early. Long lists can take O(seconds) to decode. + getResp.Kvs[i] = nil + } + + // indicate to the client which resource version was returned + if returnedRV == 0 { + returnedRV = getResp.Header.Revision + } + + // no more results remain or we didn't request paging + if !hasMore || !paging { + break + } + // we're paging but we have filled our bucket + if int64(v.Len()) >= pred.Limit { + break + } + + if limit < maxLimit { + // We got incomplete result due to field/label selector dropping the object. + // Double page size to reduce total number of calls to etcd. + limit *= 2 + if limit > maxLimit { + limit = maxLimit + } + *limitOption = clientv3.WithLimit(limit) + } + preparedKey = string(lastKey) + "\x00" + if withRev == 0 { + withRev = returnedRV + options = append(options, clientv3.WithRev(withRev)) + } + } + + // instruct the client to begin querying from immediately after the last key we returned + // we never return a key that the client wouldn't be allowed to see + if hasMore { + // we want to start immediately after the last key + next, err := storage.EncodeContinue(string(lastKey)+"\x00", keyPrefix, returnedRV) + if err != nil { + return err + } + var remainingItemCount *int64 + // getResp.Count counts in objects that do not match the pred. + // Instead of returning inaccurate count for non-empty selectors, we return nil. + // Only set remainingItemCount if the predicate is empty. + if utilfeature.DefaultFeatureGate.Enabled(features.RemainingItemCount) { + if pred.Empty() { + c := int64(getResp.Count - pred.Limit) + remainingItemCount = &c + } + } + return s.versioner.UpdateList(listObj, uint64(returnedRV), next, remainingItemCount) + } + + // no continuation + return s.versioner.UpdateList(listObj, uint64(returnedRV), "", nil) +} + +// growSlice takes a slice value and grows its capacity up +// to the maximum of the passed sizes or maxCapacity, whichever +// is smaller. Above maxCapacity decisions about allocation are left +// to the Go runtime on append. This allows a caller to make an +// educated guess about the potential size of the total list while +// still avoiding overly aggressive initial allocation. If sizes +// is empty maxCapacity will be used as the size to grow. +func growSlice(v reflect.Value, maxCapacity int, sizes ...int) { + cap := v.Cap() + max := cap + for _, size := range sizes { + if size > max { + max = size + } + } + if len(sizes) == 0 || max > maxCapacity { + max = maxCapacity + } + if max <= cap { + return + } + if v.Len() > 0 { + extra := reflect.MakeSlice(v.Type(), v.Len(), max) + reflect.Copy(extra, v) + v.Set(extra) + } else { + extra := reflect.MakeSlice(v.Type(), 0, max) + v.Set(extra) + } +} + +// Watch implements storage.Interface.Watch. +func (s *store) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { + preparedKey, err := s.prepareKey(key) + if err != nil { + return nil, err + } + rev, err := s.versioner.ParseResourceVersion(opts.ResourceVersion) + if err != nil { + return nil, err + } + return s.watcher.Watch(ctx, preparedKey, int64(rev), opts.Recursive, opts.ProgressNotify, s.transformer, opts.Predicate) +} + +func (s *store) getState(ctx context.Context, getResp *clientv3.GetResponse, key string, v reflect.Value, ignoreNotFound bool) (*objState, error) { + state := &objState{ + meta: &storage.ResponseMeta{}, + } + + if u, ok := v.Addr().Interface().(runtime.Unstructured); ok { + state.obj = u.NewEmptyInstance() + } else { + state.obj = reflect.New(v.Type()).Interface().(runtime.Object) + } + + if len(getResp.Kvs) == 0 { + if !ignoreNotFound { + return nil, storage.NewKeyNotFoundError(key, 0) + } + if err := runtime.SetZeroValue(state.obj); err != nil { + return nil, err + } + } else { + data, stale, err := s.transformer.TransformFromStorage(ctx, getResp.Kvs[0].Value, authenticatedDataString(key)) + if err != nil { + return nil, storage.NewInternalError(err.Error()) + } + state.rev = getResp.Kvs[0].ModRevision + state.meta.ResourceVersion = uint64(state.rev) + state.data = data + state.stale = stale + if err := decode(s.codec, s.versioner, state.data, state.obj, state.rev); err != nil { + return nil, err + } + } + return state, nil +} + +func (s *store) getStateFromObject(obj runtime.Object) (*objState, error) { + state := &objState{ + obj: obj, + meta: &storage.ResponseMeta{}, + } + + rv, err := s.versioner.ObjectResourceVersion(obj) + if err != nil { + return nil, fmt.Errorf("couldn't get resource version: %v", err) + } + state.rev = int64(rv) + state.meta.ResourceVersion = uint64(state.rev) + + // Compute the serialized form - for that we need to temporarily clean + // its resource version field (those are not stored in etcd). + if err := s.versioner.PrepareObjectForStorage(obj); err != nil { + return nil, fmt.Errorf("PrepareObjectForStorage failed: %v", err) + } + state.data, err = runtime.Encode(s.codec, obj) + if err != nil { + return nil, err + } + if err := s.versioner.UpdateObject(state.obj, uint64(rv)); err != nil { + klog.Errorf("failed to update object version: %v", err) + } + return state, nil +} + +func (s *store) updateState(st *objState, userUpdate storage.UpdateFunc) (runtime.Object, uint64, error) { + ret, ttlPtr, err := userUpdate(st.obj, *st.meta) + if err != nil { + return nil, 0, err + } + + if err := s.versioner.PrepareObjectForStorage(ret); err != nil { + return nil, 0, fmt.Errorf("PrepareObjectForStorage failed: %v", err) + } + var ttl uint64 + if ttlPtr != nil { + ttl = *ttlPtr + } + return ret, ttl, nil +} + +// ttlOpts returns client options based on given ttl. +// ttl: if ttl is non-zero, it will attach the key to a lease with ttl of roughly the same length +func (s *store) ttlOpts(ctx context.Context, ttl int64) ([]clientv3.OpOption, error) { + if ttl == 0 { + return nil, nil + } + id, err := s.leaseManager.GetLease(ctx, ttl) + if err != nil { + return nil, err + } + return []clientv3.OpOption{clientv3.WithLease(id)}, nil +} + +// validateMinimumResourceVersion returns a 'too large resource' version error when the provided minimumResourceVersion is +// greater than the most recent actualRevision available from storage. +func (s *store) validateMinimumResourceVersion(minimumResourceVersion string, actualRevision uint64) error { + if minimumResourceVersion == "" { + return nil + } + minimumRV, err := s.versioner.ParseResourceVersion(minimumResourceVersion) + if err != nil { + return apierrors.NewBadRequest(fmt.Sprintf("invalid resource version: %v", err)) + } + // Enforce the storage.Interface guarantee that the resource version of the returned data + // "will be at least 'resourceVersion'". + if minimumRV > actualRevision { + return storage.NewTooLargeResourceVersionError(minimumRV, actualRevision, 0) + } + return nil +} + +func (s *store) prepareKey(key string) (string, error) { + if key == ".." || + strings.HasPrefix(key, "../") || + strings.HasSuffix(key, "/..") || + strings.Contains(key, "/../") { + return "", fmt.Errorf("invalid key: %q", key) + } + if key == "." || + strings.HasPrefix(key, "./") || + strings.HasSuffix(key, "/.") || + strings.Contains(key, "/./") { + return "", fmt.Errorf("invalid key: %q", key) + } + if key == "" || key == "/" { + return "", fmt.Errorf("empty key: %q", key) + } + // We ensured that pathPrefix ends in '/' in construction, so skip any leading '/' in the key now. + startIndex := 0 + if key[0] == '/' { + startIndex = 1 + } + return s.pathPrefix + key[startIndex:], nil +} + +// decode decodes value of bytes into object. It will also set the object resource version to rev. +// On success, objPtr would be set to the object. +func decode(codec runtime.Codec, versioner storage.Versioner, value []byte, objPtr runtime.Object, rev int64) error { + if _, err := conversion.EnforcePtr(objPtr); err != nil { + return fmt.Errorf("unable to convert output object to pointer: %v", err) + } + _, _, err := codec.Decode(value, nil, objPtr) + if err != nil { + return err + } + // being unable to set the version does not prevent the object from being extracted + if err := versioner.UpdateObject(objPtr, uint64(rev)); err != nil { + klog.Errorf("failed to update object version: %v", err) + } + return nil +} + +// appendListItem decodes and appends the object (if it passes filter) to v, which must be a slice. +func appendListItem(v reflect.Value, data []byte, rev uint64, pred storage.SelectionPredicate, codec runtime.Codec, versioner storage.Versioner, newItemFunc func() runtime.Object) error { + obj, _, err := codec.Decode(data, nil, newItemFunc()) + if err != nil { + return err + } + // being unable to set the version does not prevent the object from being extracted + if err := versioner.UpdateObject(obj, rev); err != nil { + klog.Errorf("failed to update object version: %v", err) + } + if matched, err := pred.Matches(obj); err == nil && matched { + v.Set(reflect.Append(v, reflect.ValueOf(obj).Elem())) + } + return nil +} + +func notFound(key string) clientv3.Cmp { + return clientv3.Compare(clientv3.ModRevision(key), "=", 0) +} + +// getTypeName returns type name of an object for reporting purposes. +func getTypeName(obj interface{}) string { + return reflect.TypeOf(obj).String() +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go new file mode 100644 index 000000000..c0b7be35c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go @@ -0,0 +1,466 @@ +/* +Copyright 2016 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 etcd3 + +import ( + "context" + "fmt" + "os" + "reflect" + "strconv" + "strings" + "sync" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" + "k8s.io/apiserver/pkg/storage/value" + utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol" + + clientv3 "go.etcd.io/etcd/client/v3" + "k8s.io/klog/v2" +) + +const ( + // We have set a buffer in order to reduce times of context switches. + incomingBufSize = 100 + outgoingBufSize = 100 +) + +// fatalOnDecodeError is used during testing to panic the server if watcher encounters a decoding error +var fatalOnDecodeError = false + +func init() { + // check to see if we are running in a test environment + TestOnlySetFatalOnDecodeError(true) + fatalOnDecodeError, _ = strconv.ParseBool(os.Getenv("KUBE_PANIC_WATCH_DECODE_ERROR")) +} + +// TestOnlySetFatalOnDecodeError should only be used for cases where decode errors are expected and need to be tested. e.g. conversion webhooks. +func TestOnlySetFatalOnDecodeError(b bool) { + fatalOnDecodeError = b +} + +type watcher struct { + client *clientv3.Client + codec runtime.Codec + newFunc func() runtime.Object + objectType string + groupResource schema.GroupResource + versioner storage.Versioner +} + +// watchChan implements watch.Interface. +type watchChan struct { + watcher *watcher + transformer value.Transformer + key string + initialRev int64 + recursive bool + progressNotify bool + internalPred storage.SelectionPredicate + ctx context.Context + cancel context.CancelFunc + incomingEventChan chan *event + resultChan chan watch.Event + errChan chan error +} + +func newWatcher(client *clientv3.Client, codec runtime.Codec, groupResource schema.GroupResource, newFunc func() runtime.Object, versioner storage.Versioner) *watcher { + res := &watcher{ + client: client, + codec: codec, + groupResource: groupResource, + newFunc: newFunc, + versioner: versioner, + } + if newFunc == nil { + res.objectType = "" + } else { + res.objectType = reflect.TypeOf(newFunc()).String() + } + return res +} + +// Watch watches on a key and returns a watch.Interface that transfers relevant notifications. +// If rev is zero, it will return the existing object(s) and then start watching from +// the maximum revision+1 from returned objects. +// If rev is non-zero, it will watch events happened after given revision. +// If recursive is false, it watches on given key. +// If recursive is true, it watches any children and directories under the key, excluding the root key itself. +// pred must be non-nil. Only if pred matches the change, it will be returned. +func (w *watcher) Watch(ctx context.Context, key string, rev int64, recursive, progressNotify bool, transformer value.Transformer, pred storage.SelectionPredicate) (watch.Interface, error) { + if recursive && !strings.HasSuffix(key, "/") { + key += "/" + } + wc := w.createWatchChan(ctx, key, rev, recursive, progressNotify, transformer, pred) + go wc.run() + + // For etcd watch we don't have an easy way to answer whether the watch + // has already caught up. So in the initial version (given that watchcache + // is by default enabled for all resources but Events), we just deliver + // the initialization signal immediately. Improving this will be explored + // in the future. + utilflowcontrol.WatchInitialized(ctx) + + return wc, nil +} + +func (w *watcher) createWatchChan(ctx context.Context, key string, rev int64, recursive, progressNotify bool, transformer value.Transformer, pred storage.SelectionPredicate) *watchChan { + wc := &watchChan{ + watcher: w, + transformer: transformer, + key: key, + initialRev: rev, + recursive: recursive, + progressNotify: progressNotify, + internalPred: pred, + incomingEventChan: make(chan *event, incomingBufSize), + resultChan: make(chan watch.Event, outgoingBufSize), + errChan: make(chan error, 1), + } + if pred.Empty() { + // The filter doesn't filter out any object. + wc.internalPred = storage.Everything + } + + // The etcd server waits until it cannot find a leader for 3 election + // timeouts to cancel existing streams. 3 is currently a hard coded + // constant. The election timeout defaults to 1000ms. If the cluster is + // healthy, when the leader is stopped, the leadership transfer should be + // smooth. (leader transfers its leadership before stopping). If leader is + // hard killed, other servers will take an election timeout to realize + // leader lost and start campaign. + wc.ctx, wc.cancel = context.WithCancel(clientv3.WithRequireLeader(ctx)) + return wc +} + +func (wc *watchChan) run() { + watchClosedCh := make(chan struct{}) + go wc.startWatching(watchClosedCh) + + var resultChanWG sync.WaitGroup + resultChanWG.Add(1) + go wc.processEvent(&resultChanWG) + + select { + case err := <-wc.errChan: + if err == context.Canceled { + break + } + errResult := transformErrorToEvent(err) + if errResult != nil { + // error result is guaranteed to be received by user before closing ResultChan. + select { + case wc.resultChan <- *errResult: + case <-wc.ctx.Done(): // user has given up all results + } + } + case <-watchClosedCh: + case <-wc.ctx.Done(): // user cancel + } + + // We use wc.ctx to reap all goroutines. Under whatever condition, we should stop them all. + // It's fine to double cancel. + wc.cancel() + + // we need to wait until resultChan wouldn't be used anymore + resultChanWG.Wait() + close(wc.resultChan) +} + +func (wc *watchChan) Stop() { + wc.cancel() +} + +func (wc *watchChan) ResultChan() <-chan watch.Event { + return wc.resultChan +} + +// sync tries to retrieve existing data and send them to process. +// The revision to watch will be set to the revision in response. +// All events sent will have isCreated=true +func (wc *watchChan) sync() error { + opts := []clientv3.OpOption{} + if wc.recursive { + opts = append(opts, clientv3.WithPrefix()) + } + getResp, err := wc.watcher.client.Get(wc.ctx, wc.key, opts...) + if err != nil { + return err + } + wc.initialRev = getResp.Header.Revision + for _, kv := range getResp.Kvs { + wc.sendEvent(parseKV(kv)) + } + return nil +} + +// logWatchChannelErr checks whether the error is about mvcc revision compaction which is regarded as warning +func logWatchChannelErr(err error) { + if !strings.Contains(err.Error(), "mvcc: required revision has been compacted") { + klog.Errorf("watch chan error: %v", err) + } else { + klog.Warningf("watch chan error: %v", err) + } +} + +// startWatching does: +// - get current objects if initialRev=0; set initialRev to current rev +// - watch on given key and send events to process. +func (wc *watchChan) startWatching(watchClosedCh chan struct{}) { + if wc.initialRev == 0 { + if err := wc.sync(); err != nil { + klog.Errorf("failed to sync with latest state: %v", err) + wc.sendError(err) + return + } + } + opts := []clientv3.OpOption{clientv3.WithRev(wc.initialRev + 1), clientv3.WithPrevKV()} + if wc.recursive { + opts = append(opts, clientv3.WithPrefix()) + } + if wc.progressNotify { + opts = append(opts, clientv3.WithProgressNotify()) + } + wch := wc.watcher.client.Watch(wc.ctx, wc.key, opts...) + for wres := range wch { + if wres.Err() != nil { + err := wres.Err() + // If there is an error on server (e.g. compaction), the channel will return it before closed. + logWatchChannelErr(err) + wc.sendError(err) + return + } + if wres.IsProgressNotify() { + wc.sendEvent(progressNotifyEvent(wres.Header.GetRevision())) + metrics.RecordEtcdBookmark(wc.watcher.groupResource.String()) + continue + } + + for _, e := range wres.Events { + parsedEvent, err := parseEvent(e) + if err != nil { + logWatchChannelErr(err) + wc.sendError(err) + return + } + wc.sendEvent(parsedEvent) + } + } + // When we come to this point, it's only possible that client side ends the watch. + // e.g. cancel the context, close the client. + // If this watch chan is broken and context isn't cancelled, other goroutines will still hang. + // We should notify the main thread that this goroutine has exited. + close(watchClosedCh) +} + +// processEvent processes events from etcd watcher and sends results to resultChan. +func (wc *watchChan) processEvent(wg *sync.WaitGroup) { + defer wg.Done() + + for { + select { + case e := <-wc.incomingEventChan: + res := wc.transform(e) + if res == nil { + continue + } + if len(wc.resultChan) == outgoingBufSize { + klog.V(3).InfoS("Fast watcher, slow processing. Probably caused by slow dispatching events to watchers", "outgoingEvents", outgoingBufSize, "objectType", wc.watcher.objectType, "groupResource", wc.watcher.groupResource) + } + // If user couldn't receive results fast enough, we also block incoming events from watcher. + // Because storing events in local will cause more memory usage. + // The worst case would be closing the fast watcher. + select { + case wc.resultChan <- *res: + case <-wc.ctx.Done(): + return + } + case <-wc.ctx.Done(): + return + } + } +} + +func (wc *watchChan) filter(obj runtime.Object) bool { + if wc.internalPred.Empty() { + return true + } + matched, err := wc.internalPred.Matches(obj) + return err == nil && matched +} + +func (wc *watchChan) acceptAll() bool { + return wc.internalPred.Empty() +} + +// transform transforms an event into a result for user if not filtered. +func (wc *watchChan) transform(e *event) (res *watch.Event) { + curObj, oldObj, err := wc.prepareObjs(e) + if err != nil { + klog.Errorf("failed to prepare current and previous objects: %v", err) + wc.sendError(err) + return nil + } + + switch { + case e.isProgressNotify: + if wc.watcher.newFunc == nil { + return nil + } + object := wc.watcher.newFunc() + if err := wc.watcher.versioner.UpdateObject(object, uint64(e.rev)); err != nil { + klog.Errorf("failed to propagate object version: %v", err) + return nil + } + res = &watch.Event{ + Type: watch.Bookmark, + Object: object, + } + case e.isDeleted: + if !wc.filter(oldObj) { + return nil + } + res = &watch.Event{ + Type: watch.Deleted, + Object: oldObj, + } + case e.isCreated: + if !wc.filter(curObj) { + return nil + } + res = &watch.Event{ + Type: watch.Added, + Object: curObj, + } + default: + if wc.acceptAll() { + res = &watch.Event{ + Type: watch.Modified, + Object: curObj, + } + return res + } + curObjPasses := wc.filter(curObj) + oldObjPasses := wc.filter(oldObj) + switch { + case curObjPasses && oldObjPasses: + res = &watch.Event{ + Type: watch.Modified, + Object: curObj, + } + case curObjPasses && !oldObjPasses: + res = &watch.Event{ + Type: watch.Added, + Object: curObj, + } + case !curObjPasses && oldObjPasses: + res = &watch.Event{ + Type: watch.Deleted, + Object: oldObj, + } + } + } + return res +} + +func transformErrorToEvent(err error) *watch.Event { + err = interpretWatchError(err) + if _, ok := err.(apierrors.APIStatus); !ok { + err = apierrors.NewInternalError(err) + } + status := err.(apierrors.APIStatus).Status() + return &watch.Event{ + Type: watch.Error, + Object: &status, + } +} + +func (wc *watchChan) sendError(err error) { + select { + case wc.errChan <- err: + case <-wc.ctx.Done(): + } +} + +func (wc *watchChan) sendEvent(e *event) { + if len(wc.incomingEventChan) == incomingBufSize { + klog.V(3).InfoS("Fast watcher, slow processing. Probably caused by slow decoding, user not receiving fast, or other processing logic", "incomingEvents", incomingBufSize, "objectType", wc.watcher.objectType, "groupResource", wc.watcher.groupResource) + } + select { + case wc.incomingEventChan <- e: + case <-wc.ctx.Done(): + } +} + +func (wc *watchChan) prepareObjs(e *event) (curObj runtime.Object, oldObj runtime.Object, err error) { + if e.isProgressNotify { + // progressNotify events doesn't contain neither current nor previous object version, + return nil, nil, nil + } + + if !e.isDeleted { + data, _, err := wc.transformer.TransformFromStorage(wc.ctx, e.value, authenticatedDataString(e.key)) + if err != nil { + return nil, nil, err + } + curObj, err = decodeObj(wc.watcher.codec, wc.watcher.versioner, data, e.rev) + if err != nil { + return nil, nil, err + } + } + // We need to decode prevValue, only if this is deletion event or + // the underlying filter doesn't accept all objects (otherwise we + // know that the filter for previous object will return true and + // we need the object only to compute whether it was filtered out + // before). + if len(e.prevValue) > 0 && (e.isDeleted || !wc.acceptAll()) { + data, _, err := wc.transformer.TransformFromStorage(wc.ctx, e.prevValue, authenticatedDataString(e.key)) + if err != nil { + return nil, nil, err + } + // Note that this sends the *old* object with the etcd revision for the time at + // which it gets deleted. + oldObj, err = decodeObj(wc.watcher.codec, wc.watcher.versioner, data, e.rev) + if err != nil { + return nil, nil, err + } + } + return curObj, oldObj, nil +} + +func decodeObj(codec runtime.Codec, versioner storage.Versioner, data []byte, rev int64) (_ runtime.Object, err error) { + obj, err := runtime.Decode(codec, []byte(data)) + if err != nil { + if fatalOnDecodeError { + // we are running in a test environment and thus an + // error here is due to a coder mistake if the defer + // does not catch it + panic(err) + } + return nil, err + } + // ensure resource version is set on the object we load from etcd + if err := versioner.UpdateObject(obj, uint64(rev)); err != nil { + return nil, fmt.Errorf("failure to version api object (%d) %#v: %v", rev, obj, err) + } + return obj, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/interfaces.go b/vendor/k8s.io/apiserver/pkg/storage/interfaces.go new file mode 100644 index 000000000..812aa412b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/interfaces.go @@ -0,0 +1,271 @@ +/* +Copyright 2015 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 storage + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" +) + +// Versioner abstracts setting and retrieving metadata fields from database response +// onto the object ot list. It is required to maintain storage invariants - updating an +// object twice with the same data except for the ResourceVersion and SelfLink must be +// a no-op. A resourceVersion of type uint64 is a 'raw' resourceVersion, +// intended to be sent directly to or from the backend. A resourceVersion of +// type string is a 'safe' resourceVersion, intended for consumption by users. +type Versioner interface { + // UpdateObject sets storage metadata into an API object. Returns an error if the object + // cannot be updated correctly. May return nil if the requested object does not need metadata + // from database. + UpdateObject(obj runtime.Object, resourceVersion uint64) error + // UpdateList sets the resource version into an API list object. Returns an error if the object + // cannot be updated correctly. May return nil if the requested object does not need metadata from + // database. continueValue is optional and indicates that more results are available if the client + // passes that value to the server in a subsequent call. remainingItemCount indicates the number + // of remaining objects if the list is partial. The remainingItemCount field is omitted during + // serialization if it is set to nil. + UpdateList(obj runtime.Object, resourceVersion uint64, continueValue string, remainingItemCount *int64) error + // PrepareObjectForStorage should set SelfLink and ResourceVersion to the empty value. Should + // return an error if the specified object cannot be updated. + PrepareObjectForStorage(obj runtime.Object) error + // ObjectResourceVersion returns the resource version (for persistence) of the specified object. + // Should return an error if the specified object does not have a persistable version. + ObjectResourceVersion(obj runtime.Object) (uint64, error) + + // ParseResourceVersion takes a resource version argument and + // converts it to the storage backend. For watch we should pass to helper.Watch(). + // Because resourceVersion is an opaque value, the default watch + // behavior for non-zero watch is to watch the next value (if you pass + // "1", you will see updates from "2" onwards). + ParseResourceVersion(resourceVersion string) (uint64, error) +} + +// ResponseMeta contains information about the database metadata that is associated with +// an object. It abstracts the actual underlying objects to prevent coupling with concrete +// database and to improve testability. +type ResponseMeta struct { + // TTL is the time to live of the node that contained the returned object. It may be + // zero or negative in some cases (objects may be expired after the requested + // expiration time due to server lag). + TTL int64 + // The resource version of the node that contained the returned object. + ResourceVersion uint64 +} + +// IndexerFunc is a function that for a given object computes +// `` for a particular ``. +type IndexerFunc func(obj runtime.Object) string + +// IndexerFuncs is a mapping from `` to function that +// for a given object computes ``. +type IndexerFuncs map[string]IndexerFunc + +// Everything accepts all objects. +var Everything = SelectionPredicate{ + Label: labels.Everything(), + Field: fields.Everything(), +} + +// MatchValue defines a pair (``, ``). +type MatchValue struct { + IndexName string + Value string +} + +// Pass an UpdateFunc to Interface.GuaranteedUpdate to make an update +// that is guaranteed to succeed. +// See the comment for GuaranteedUpdate for more details. +type UpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error) + +// ValidateObjectFunc is a function to act on a given object. An error may be returned +// if the hook cannot be completed. The function may NOT transform the provided +// object. +type ValidateObjectFunc func(ctx context.Context, obj runtime.Object) error + +// ValidateAllObjectFunc is a "admit everything" instance of ValidateObjectFunc. +func ValidateAllObjectFunc(ctx context.Context, obj runtime.Object) error { + return nil +} + +// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out. +type Preconditions struct { + // Specifies the target UID. + // +optional + UID *types.UID `json:"uid,omitempty"` + // Specifies the target ResourceVersion + // +optional + ResourceVersion *string `json:"resourceVersion,omitempty"` +} + +// NewUIDPreconditions returns a Preconditions with UID set. +func NewUIDPreconditions(uid string) *Preconditions { + u := types.UID(uid) + return &Preconditions{UID: &u} +} + +func (p *Preconditions) Check(key string, obj runtime.Object) error { + if p == nil { + return nil + } + objMeta, err := meta.Accessor(obj) + if err != nil { + return NewInternalErrorf( + "can't enforce preconditions %v on un-introspectable object %v, got error: %v", + *p, + obj, + err) + } + if p.UID != nil && *p.UID != objMeta.GetUID() { + err := fmt.Sprintf( + "Precondition failed: UID in precondition: %v, UID in object meta: %v", + *p.UID, + objMeta.GetUID()) + return NewInvalidObjError(key, err) + } + if p.ResourceVersion != nil && *p.ResourceVersion != objMeta.GetResourceVersion() { + err := fmt.Sprintf( + "Precondition failed: ResourceVersion in precondition: %v, ResourceVersion in object meta: %v", + *p.ResourceVersion, + objMeta.GetResourceVersion()) + return NewInvalidObjError(key, err) + } + return nil +} + +// Interface offers a common interface for object marshaling/unmarshaling operations and +// hides all the storage-related operations behind it. +type Interface interface { + // Returns Versioner associated with this interface. + Versioner() Versioner + + // Create adds a new object at a key unless it already exists. 'ttl' is time-to-live + // in seconds (0 means forever). If no error is returned and out is not nil, out will be + // set to the read value from database. + Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error + + // Delete removes the specified key and returns the value that existed at that spot. + // If key didn't exist, it will return NotFound storage error. + // If 'cachedExistingObject' is non-nil, it can be used as a suggestion about the + // current version of the object to avoid read operation from storage to get it. + // However, the implementations have to retry in case suggestion is stale. + Delete( + ctx context.Context, key string, out runtime.Object, preconditions *Preconditions, + validateDeletion ValidateObjectFunc, cachedExistingObject runtime.Object) error + + // Watch begins watching the specified key. Events are decoded into API objects, + // and any items selected by 'p' are sent down to returned watch.Interface. + // resourceVersion may be used to specify what version to begin watching, + // which should be the current resourceVersion, and no longer rv+1 + // (e.g. reconnecting without missing any updates). + // If resource version is "0", this interface will get current object at given key + // and send it in an "ADDED" event, before watch starts. + Watch(ctx context.Context, key string, opts ListOptions) (watch.Interface, error) + + // Get unmarshals object found at key into objPtr. On a not found error, will either + // return a zero object of the requested type, or an error, depending on 'opts.ignoreNotFound'. + // Treats empty responses and nil response nodes exactly like a not found error. + // The returned contents may be delayed, but it is guaranteed that they will + // match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'. + Get(ctx context.Context, key string, opts GetOptions, objPtr runtime.Object) error + + // GetList unmarshalls objects found at key into a *List api object (an object + // that satisfies runtime.IsList definition). + // If 'opts.Recursive' is false, 'key' is used as an exact match. If `opts.Recursive' + // is true, 'key' is used as a prefix. + // The returned contents may be delayed, but it is guaranteed that they will + // match 'opts.ResourceVersion' according 'opts.ResourceVersionMatch'. + GetList(ctx context.Context, key string, opts ListOptions, listObj runtime.Object) error + + // GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'destination') + // retrying the update until success if there is index conflict. + // Note that object passed to tryUpdate may change across invocations of tryUpdate() if + // other writers are simultaneously updating it, so tryUpdate() needs to take into account + // the current contents of the object when deciding how the update object should look. + // If the key doesn't exist, it will return NotFound storage error if ignoreNotFound=false + // else `destination` will be set to the zero value of it's type. + // If the eventual successful invocation of `tryUpdate` returns an output with the same serialized + // contents as the input, it won't perform any update, but instead set `destination` to an object with those + // contents. + // If 'cachedExistingObject' is non-nil, it can be used as a suggestion about the + // current version of the object to avoid read operation from storage to get it. + // However, the implementations have to retry in case suggestion is stale. + // + // Example: + // + // s := /* implementation of Interface */ + // err := s.GuaranteedUpdate( + // "myKey", &MyType{}, true, preconditions, + // func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) { + // // Before each invocation of the user defined function, "input" is reset to + // // current contents for "myKey" in database. + // curr := input.(*MyType) // Guaranteed to succeed. + // + // // Make the modification + // curr.Counter++ + // + // // Return the modified object - return an error to stop iterating. Return + // // a uint64 to alter the TTL on the object, or nil to keep it the same value. + // return cur, nil, nil + // }, cachedExistingObject + // ) + GuaranteedUpdate( + ctx context.Context, key string, destination runtime.Object, ignoreNotFound bool, + preconditions *Preconditions, tryUpdate UpdateFunc, cachedExistingObject runtime.Object) error + + // Count returns number of different entries under the key (generally being path prefix). + Count(key string) (int64, error) +} + +// GetOptions provides the options that may be provided for storage get operations. +type GetOptions struct { + // IgnoreNotFound determines what is returned if the requested object is not found. If + // true, a zero object is returned. If false, an error is returned. + IgnoreNotFound bool + // ResourceVersion provides a resource version constraint to apply to the get operation + // as a "not older than" constraint: the result contains data at least as new as the provided + // ResourceVersion. The newest available data is preferred, but any data not older than this + // ResourceVersion may be served. + ResourceVersion string +} + +// ListOptions provides the options that may be provided for storage list operations. +type ListOptions struct { + // ResourceVersion provides a resource version constraint to apply to the list operation + // as a "not older than" constraint: the result contains data at least as new as the provided + // ResourceVersion. The newest available data is preferred, but any data not older than this + // ResourceVersion may be served. + ResourceVersion string + // ResourceVersionMatch provides the rule for how the resource version constraint applies. If set + // to the default value "" the legacy resource version semantic apply. + ResourceVersionMatch metav1.ResourceVersionMatch + // Predicate provides the selection rules for the list operation. + Predicate SelectionPredicate + // Recursive determines whether the list or watch is defined for a single object located at the + // given key, or for the whole set of objects with the given key as a prefix. + Recursive bool + // ProgressNotify determines whether storage-originated bookmark (progress notify) events should + // be delivered to the users. The option is ignored for non-watch requests. + ProgressNotify bool +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go b/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go new file mode 100644 index 000000000..7370518e3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go @@ -0,0 +1,159 @@ +/* +Copyright 2016 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 storage + +import ( + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +// AttrFunc returns label and field sets and the uninitialized flag for List or Watch to match. +// In any failure to parse given object, it returns error. +type AttrFunc func(obj runtime.Object) (labels.Set, fields.Set, error) + +// FieldMutationFunc allows the mutation of the field selection fields. It is mutating to +// avoid the extra allocation on this common path +type FieldMutationFunc func(obj runtime.Object, fieldSet fields.Set) error + +func DefaultClusterScopedAttr(obj runtime.Object) (labels.Set, fields.Set, error) { + metadata, err := meta.Accessor(obj) + if err != nil { + return nil, nil, err + } + fieldSet := fields.Set{ + "metadata.name": metadata.GetName(), + } + + return labels.Set(metadata.GetLabels()), fieldSet, nil +} + +func DefaultNamespaceScopedAttr(obj runtime.Object) (labels.Set, fields.Set, error) { + metadata, err := meta.Accessor(obj) + if err != nil { + return nil, nil, err + } + fieldSet := fields.Set{ + "metadata.name": metadata.GetName(), + "metadata.namespace": metadata.GetNamespace(), + } + + return labels.Set(metadata.GetLabels()), fieldSet, nil +} + +func (f AttrFunc) WithFieldMutation(fieldMutator FieldMutationFunc) AttrFunc { + return func(obj runtime.Object) (labels.Set, fields.Set, error) { + labelSet, fieldSet, err := f(obj) + if err != nil { + return nil, nil, err + } + if err := fieldMutator(obj, fieldSet); err != nil { + return nil, nil, err + } + return labelSet, fieldSet, nil + } +} + +// SelectionPredicate is used to represent the way to select objects from api storage. +type SelectionPredicate struct { + Label labels.Selector + Field fields.Selector + GetAttrs AttrFunc + IndexLabels []string + IndexFields []string + Limit int64 + Continue string + AllowWatchBookmarks bool +} + +// Matches returns true if the given object's labels and fields (as +// returned by s.GetAttrs) match s.Label and s.Field. An error is +// returned if s.GetAttrs fails. +func (s *SelectionPredicate) Matches(obj runtime.Object) (bool, error) { + if s.Empty() { + return true, nil + } + labels, fields, err := s.GetAttrs(obj) + if err != nil { + return false, err + } + matched := s.Label.Matches(labels) + if matched && s.Field != nil { + matched = matched && s.Field.Matches(fields) + } + return matched, nil +} + +// MatchesObjectAttributes returns true if the given labels and fields +// match s.Label and s.Field. +func (s *SelectionPredicate) MatchesObjectAttributes(l labels.Set, f fields.Set) bool { + if s.Label.Empty() && s.Field.Empty() { + return true + } + matched := s.Label.Matches(l) + if matched && s.Field != nil { + matched = (matched && s.Field.Matches(f)) + } + return matched +} + +// MatchesSingle will return (name, true) if and only if s.Field matches on the object's +// name. +func (s *SelectionPredicate) MatchesSingle() (string, bool) { + if len(s.Continue) > 0 { + return "", false + } + // TODO: should be namespace.name + if name, ok := s.Field.RequiresExactMatch("metadata.name"); ok { + return name, true + } + return "", false +} + +// Empty returns true if the predicate performs no filtering. +func (s *SelectionPredicate) Empty() bool { + return s.Label.Empty() && s.Field.Empty() +} + +// For any index defined by IndexFields, if a matcher can match only (a subset) +// of objects that return for a given index, a pair (, ) +// wil be returned. +func (s *SelectionPredicate) MatcherIndex() []MatchValue { + var result []MatchValue + for _, field := range s.IndexFields { + if value, ok := s.Field.RequiresExactMatch(field); ok { + result = append(result, MatchValue{IndexName: FieldIndex(field), Value: value}) + } + } + for _, label := range s.IndexLabels { + if value, ok := s.Label.RequiresExactMatch(label); ok { + result = append(result, MatchValue{IndexName: LabelIndex(label), Value: value}) + } + } + return result +} + +// LabelIndex add prefix for label index. +func LabelIndex(label string) string { + return "l:" + label +} + +// FiledIndex add prefix for field index. +func FieldIndex(field string) string { + return "f:" + field +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/OWNERS new file mode 100644 index 000000000..c29de755d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/OWNERS @@ -0,0 +1,6 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +reviewers: + - lavalamp + - smarterclayton + - wojtek-t diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/config.go b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/config.go new file mode 100644 index 000000000..47534c978 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/config.go @@ -0,0 +1,128 @@ +/* +Copyright 2016 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 storagebackend + +import ( + "time" + + oteltrace "go.opentelemetry.io/otel/trace" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/server/egressselector" + "k8s.io/apiserver/pkg/storage/etcd3" + "k8s.io/apiserver/pkg/storage/value" + flowcontrolrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" +) + +const ( + StorageTypeUnset = "" + StorageTypeETCD2 = "etcd2" + StorageTypeETCD3 = "etcd3" + + DefaultCompactInterval = 5 * time.Minute + DefaultDBMetricPollInterval = 30 * time.Second + DefaultHealthcheckTimeout = 2 * time.Second + DefaultReadinessTimeout = 2 * time.Second +) + +// TransportConfig holds all connection related info, i.e. equal TransportConfig means equal servers we talk to. +type TransportConfig struct { + // ServerList is the list of storage servers to connect with. + ServerList []string + // TLS credentials + KeyFile string + CertFile string + TrustedCAFile string + // function to determine the egress dialer. (i.e. konnectivity server dialer) + EgressLookup egressselector.Lookup + // The TracerProvider can add tracing the connection + TracerProvider oteltrace.TracerProvider +} + +// Config is configuration for creating a storage backend. +type Config struct { + // Type defines the type of storage backend. Default ("") is "etcd3". + Type string + // Prefix is the prefix to all keys passed to storage.Interface methods. + Prefix string + // Transport holds all connection related info, i.e. equal TransportConfig means equal servers we talk to. + Transport TransportConfig + // Paging indicates whether the server implementation should allow paging (if it is + // supported). This is generally configured by feature gating, or by a specific + // resource type not wishing to allow paging, and is not intended for end users to + // set. + Paging bool + + Codec runtime.Codec + // EncodeVersioner is the same groupVersioner used to build the + // storage encoder. Given a list of kinds the input object might belong + // to, the EncodeVersioner outputs the gvk the object will be + // converted to before persisted in etcd. + EncodeVersioner runtime.GroupVersioner + // Transformer allows the value to be transformed prior to persisting into etcd. + Transformer value.Transformer + + // CompactionInterval is an interval of requesting compaction from apiserver. + // If the value is 0, no compaction will be issued. + CompactionInterval time.Duration + // CountMetricPollPeriod specifies how often should count metric be updated + CountMetricPollPeriod time.Duration + // DBMetricPollInterval specifies how often should storage backend metric be updated. + DBMetricPollInterval time.Duration + // HealthcheckTimeout specifies the timeout used when checking health + HealthcheckTimeout time.Duration + // ReadycheckTimeout specifies the timeout used when checking readiness + ReadycheckTimeout time.Duration + + LeaseManagerConfig etcd3.LeaseManagerConfig + + // StorageObjectCountTracker is used to keep track of the total + // number of objects in the storage per resource. + StorageObjectCountTracker flowcontrolrequest.StorageObjectCountTracker +} + +// ConfigForResource is a Config specialized to a particular `schema.GroupResource` +type ConfigForResource struct { + // Config is the resource-independent configuration + Config + + // GroupResource is the relevant one + GroupResource schema.GroupResource +} + +// ForResource specializes to the given resource +func (config *Config) ForResource(resource schema.GroupResource) *ConfigForResource { + return &ConfigForResource{ + Config: *config, + GroupResource: resource, + } +} + +func NewDefaultConfig(prefix string, codec runtime.Codec) *Config { + return &Config{ + Paging: true, + Prefix: prefix, + Codec: codec, + CompactionInterval: DefaultCompactInterval, + DBMetricPollInterval: DefaultDBMetricPollInterval, + HealthcheckTimeout: DefaultHealthcheckTimeout, + ReadycheckTimeout: DefaultReadinessTimeout, + LeaseManagerConfig: etcd3.NewDefaultLeaseManagerConfig(), + Transport: TransportConfig{TracerProvider: oteltrace.NewNoopTracerProvider()}, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go new file mode 100644 index 000000000..c17859649 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go @@ -0,0 +1,434 @@ +/* +Copyright 2016 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 factory + +import ( + "context" + "fmt" + "log" + "net" + "net/url" + "os" + "path" + "strings" + "sync" + "time" + + grpcprom "github.com/grpc-ecosystem/go-grpc-prometheus" + "go.etcd.io/etcd/client/pkg/v3/logutil" + "go.etcd.io/etcd/client/pkg/v3/transport" + clientv3 "go.etcd.io/etcd/client/v3" + "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "golang.org/x/time/rate" + "google.golang.org/grpc" + + "k8s.io/apimachinery/pkg/runtime" + utilnet "k8s.io/apimachinery/pkg/util/net" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + genericfeatures "k8s.io/apiserver/pkg/features" + "k8s.io/apiserver/pkg/server/egressselector" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/etcd3" + "k8s.io/apiserver/pkg/storage/etcd3/metrics" + "k8s.io/apiserver/pkg/storage/storagebackend" + "k8s.io/apiserver/pkg/storage/value/encrypt/identity" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/component-base/metrics/legacyregistry" + tracing "k8s.io/component-base/tracing" + "k8s.io/klog/v2" +) + +const ( + // The short keepalive timeout and interval have been chosen to aggressively + // detect a failed etcd server without introducing much overhead. + keepaliveTime = 30 * time.Second + keepaliveTimeout = 10 * time.Second + + // dialTimeout is the timeout for failing to establish a connection. + // It is set to 20 seconds as times shorter than that will cause TLS connections to fail + // on heavily loaded arm64 CPUs (issue #64649) + dialTimeout = 20 * time.Second + + dbMetricsMonitorJitter = 0.5 +) + +// TODO(negz): Stop using a package scoped logger. At the time of writing we're +// creating an etcd client for each CRD. We need to pass each etcd client a +// logger or each client will create its own, which comes with a significant +// memory cost (around 20% of the API server's memory when hundreds of CRDs are +// present). The correct fix here is to not create a client per CRD. See +// https://github.com/kubernetes/kubernetes/issues/111476 for more. +var etcd3ClientLogger *zap.Logger + +func init() { + // grpcprom auto-registers (via an init function) their client metrics, since we are opting out of + // using the global prometheus registry and using our own wrapped global registry, + // we need to explicitly register these metrics to our global registry here. + // For reference: https://github.com/kubernetes/kubernetes/pull/81387 + legacyregistry.RawMustRegister(grpcprom.DefaultClientMetrics) + dbMetricsMonitors = make(map[string]struct{}) + + l, err := logutil.CreateDefaultZapLogger(etcdClientDebugLevel()) + if err != nil { + l = zap.NewNop() + } + etcd3ClientLogger = l.Named("etcd-client") +} + +// etcdClientDebugLevel translates ETCD_CLIENT_DEBUG into zap log level. +// NOTE(negz): This is a copy of a private etcd client function: +// https://github.com/etcd-io/etcd/blob/v3.5.4/client/v3/logger.go#L47 +func etcdClientDebugLevel() zapcore.Level { + envLevel := os.Getenv("ETCD_CLIENT_DEBUG") + if envLevel == "" || envLevel == "true" { + return zapcore.InfoLevel + } + var l zapcore.Level + if err := l.Set(envLevel); err == nil { + log.Printf("Deprecated env ETCD_CLIENT_DEBUG value. Using default level: 'info'") + return zapcore.InfoLevel + } + return l +} + +func newETCD3HealthCheck(c storagebackend.Config, stopCh <-chan struct{}) (func() error, error) { + timeout := storagebackend.DefaultHealthcheckTimeout + if c.HealthcheckTimeout != time.Duration(0) { + timeout = c.HealthcheckTimeout + } + return newETCD3Check(c, timeout, stopCh) +} + +func newETCD3ReadyCheck(c storagebackend.Config, stopCh <-chan struct{}) (func() error, error) { + timeout := storagebackend.DefaultReadinessTimeout + if c.ReadycheckTimeout != time.Duration(0) { + timeout = c.ReadycheckTimeout + } + return newETCD3Check(c, timeout, stopCh) +} + +// atomic error acts as a cache for atomically store an error +// the error is only updated if the timestamp is more recent than +// current stored error. +type atomicLastError struct { + mu sync.RWMutex + err error + timestamp time.Time +} + +func (a *atomicLastError) Store(err error, t time.Time) { + a.mu.Lock() + defer a.mu.Unlock() + if a.timestamp.IsZero() || a.timestamp.Before(t) { + a.err = err + a.timestamp = t + } +} + +func (a *atomicLastError) Load() error { + a.mu.RLock() + defer a.mu.RUnlock() + return a.err +} + +func newETCD3Check(c storagebackend.Config, timeout time.Duration, stopCh <-chan struct{}) (func() error, error) { + // constructing the etcd v3 client blocks and times out if etcd is not available. + // retry in a loop in the background until we successfully create the client, storing the client or error encountered + + lock := sync.RWMutex{} + var client *clientv3.Client + clientErr := fmt.Errorf("etcd client connection not yet established") + + go wait.PollUntil(time.Second, func() (bool, error) { + newClient, err := newETCD3Client(c.Transport) + lock.Lock() + defer lock.Unlock() + // Ensure that server is already not shutting down. + select { + case <-stopCh: + if err == nil { + newClient.Close() + } + return true, nil + default: + } + if err != nil { + clientErr = err + return false, nil + } + client = newClient + clientErr = nil + return true, nil + }, stopCh) + + // Close the client on shutdown. + go func() { + defer utilruntime.HandleCrash() + <-stopCh + + lock.Lock() + defer lock.Unlock() + if client != nil { + client.Close() + clientErr = fmt.Errorf("server is shutting down") + } + }() + + // limit to a request every half of the configured timeout with a maximum burst of one + // rate limited requests will receive the last request sent error (note: not the last received response) + limiter := rate.NewLimiter(rate.Every(timeout/2), 1) + // initial state is the clientErr + lastError := &atomicLastError{err: fmt.Errorf("etcd client connection not yet established")} + + return func() error { + // Given that client is closed on shutdown we hold the lock for + // the entire period of healthcheck call to ensure that client will + // not be closed during healthcheck. + // Given that healthchecks has a 2s timeout, worst case of blocking + // shutdown for additional 2s seems acceptable. + lock.RLock() + defer lock.RUnlock() + + if clientErr != nil { + return clientErr + } + if limiter.Allow() == false { + return lastError.Load() + } + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + // See https://github.com/etcd-io/etcd/blob/c57f8b3af865d1b531b979889c602ba14377420e/etcdctl/ctlv3/command/ep_command.go#L118 + now := time.Now() + _, err := client.Get(ctx, path.Join("/", c.Prefix, "health")) + if err != nil { + err = fmt.Errorf("error getting data from etcd: %w", err) + } + lastError.Store(err, now) + return err + }, nil +} + +var newETCD3Client = func(c storagebackend.TransportConfig) (*clientv3.Client, error) { + tlsInfo := transport.TLSInfo{ + CertFile: c.CertFile, + KeyFile: c.KeyFile, + TrustedCAFile: c.TrustedCAFile, + } + tlsConfig, err := tlsInfo.ClientConfig() + if err != nil { + return nil, err + } + // NOTE: Client relies on nil tlsConfig + // for non-secure connections, update the implicit variable + if len(c.CertFile) == 0 && len(c.KeyFile) == 0 && len(c.TrustedCAFile) == 0 { + tlsConfig = nil + } + networkContext := egressselector.Etcd.AsNetworkContext() + var egressDialer utilnet.DialFunc + if c.EgressLookup != nil { + egressDialer, err = c.EgressLookup(networkContext) + if err != nil { + return nil, err + } + } + dialOptions := []grpc.DialOption{ + grpc.WithBlock(), // block until the underlying connection is up + // use chained interceptors so that the default (retry and backoff) interceptors are added. + // otherwise they will be overwritten by the metric interceptor. + // + // these optional interceptors will be placed after the default ones. + // which seems to be what we want as the metrics will be collected on each attempt (retry) + grpc.WithChainUnaryInterceptor(grpcprom.UnaryClientInterceptor), + grpc.WithChainStreamInterceptor(grpcprom.StreamClientInterceptor), + } + if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerTracing) { + tracingOpts := []otelgrpc.Option{ + otelgrpc.WithPropagators(tracing.Propagators()), + otelgrpc.WithTracerProvider(c.TracerProvider), + } + // Even with Noop TracerProvider, the otelgrpc still handles context propagation. + // See https://github.com/open-telemetry/opentelemetry-go/tree/main/example/passthrough + dialOptions = append(dialOptions, + grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor(tracingOpts...)), + grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor(tracingOpts...))) + } + if egressDialer != nil { + dialer := func(ctx context.Context, addr string) (net.Conn, error) { + if strings.Contains(addr, "//") { + // etcd client prior to 3.5 passed URLs to dialer, normalize to address + u, err := url.Parse(addr) + if err != nil { + return nil, err + } + addr = u.Host + } + return egressDialer(ctx, "tcp", addr) + } + dialOptions = append(dialOptions, grpc.WithContextDialer(dialer)) + } + + cfg := clientv3.Config{ + DialTimeout: dialTimeout, + DialKeepAliveTime: keepaliveTime, + DialKeepAliveTimeout: keepaliveTimeout, + DialOptions: dialOptions, + Endpoints: c.ServerList, + TLS: tlsConfig, + Logger: etcd3ClientLogger, + } + + return clientv3.New(cfg) +} + +type runningCompactor struct { + interval time.Duration + cancel context.CancelFunc + client *clientv3.Client + refs int +} + +var ( + // compactorsMu guards access to compactors map + compactorsMu sync.Mutex + compactors = map[string]*runningCompactor{} + // dbMetricsMonitorsMu guards access to dbMetricsMonitors map + dbMetricsMonitorsMu sync.Mutex + dbMetricsMonitors map[string]struct{} +) + +// startCompactorOnce start one compactor per transport. If the interval get smaller on repeated calls, the +// compactor is replaced. A destroy func is returned. If all destroy funcs with the same transport are called, +// the compactor is stopped. +func startCompactorOnce(c storagebackend.TransportConfig, interval time.Duration) (func(), error) { + compactorsMu.Lock() + defer compactorsMu.Unlock() + + key := fmt.Sprintf("%v", c) // gives: {[server1 server2] keyFile certFile caFile} + if compactor, foundBefore := compactors[key]; !foundBefore || compactor.interval > interval { + compactorClient, err := newETCD3Client(c) + if err != nil { + return nil, err + } + + if foundBefore { + // replace compactor + compactor.cancel() + compactor.client.Close() + } else { + // start new compactor + compactor = &runningCompactor{} + compactors[key] = compactor + } + + ctx, cancel := context.WithCancel(context.Background()) + + compactor.interval = interval + compactor.cancel = cancel + compactor.client = compactorClient + + etcd3.StartCompactor(ctx, compactorClient, interval) + } + + compactors[key].refs++ + + return func() { + compactorsMu.Lock() + defer compactorsMu.Unlock() + + compactor := compactors[key] + compactor.refs-- + if compactor.refs == 0 { + compactor.cancel() + compactor.client.Close() + delete(compactors, key) + } + }, nil +} + +func newETCD3Storage(c storagebackend.ConfigForResource, newFunc func() runtime.Object) (storage.Interface, DestroyFunc, error) { + stopCompactor, err := startCompactorOnce(c.Transport, c.CompactionInterval) + if err != nil { + return nil, nil, err + } + + client, err := newETCD3Client(c.Transport) + if err != nil { + stopCompactor() + return nil, nil, err + } + + // decorate the KV instance so we can track etcd latency per request. + client.KV = etcd3.NewETCDLatencyTracker(client.KV) + + stopDBSizeMonitor, err := startDBSizeMonitorPerEndpoint(client, c.DBMetricPollInterval) + if err != nil { + return nil, nil, err + } + + var once sync.Once + destroyFunc := func() { + // we know that storage destroy funcs are called multiple times (due to reuse in subresources). + // Hence, we only destroy once. + // TODO: fix duplicated storage destroy calls higher level + once.Do(func() { + stopCompactor() + stopDBSizeMonitor() + client.Close() + }) + } + transformer := c.Transformer + if transformer == nil { + transformer = identity.NewEncryptCheckTransformer() + } + return etcd3.New(client, c.Codec, newFunc, c.Prefix, c.GroupResource, transformer, c.Paging, c.LeaseManagerConfig), destroyFunc, nil +} + +// startDBSizeMonitorPerEndpoint starts a loop to monitor etcd database size and update the +// corresponding metric etcd_db_total_size_in_bytes for each etcd server endpoint. +func startDBSizeMonitorPerEndpoint(client *clientv3.Client, interval time.Duration) (func(), error) { + if interval == 0 { + return func() {}, nil + } + dbMetricsMonitorsMu.Lock() + defer dbMetricsMonitorsMu.Unlock() + + ctx, cancel := context.WithCancel(context.Background()) + for _, ep := range client.Endpoints() { + if _, found := dbMetricsMonitors[ep]; found { + continue + } + dbMetricsMonitors[ep] = struct{}{} + endpoint := ep + klog.V(4).Infof("Start monitoring storage db size metric for endpoint %s with polling interval %v", endpoint, interval) + go wait.JitterUntilWithContext(ctx, func(context.Context) { + epStatus, err := client.Maintenance.Status(ctx, endpoint) + if err != nil { + klog.V(4).Infof("Failed to get storage db size for ep %s: %v", endpoint, err) + metrics.UpdateEtcdDbSize(endpoint, -1) + } else { + metrics.UpdateEtcdDbSize(endpoint, epStatus.DbSize) + } + }, interval, dbMetricsMonitorJitter, true) + } + + return func() { + cancel() + }, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/factory.go b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/factory.go new file mode 100644 index 000000000..4c8a409d6 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/storagebackend/factory/factory.go @@ -0,0 +1,63 @@ +/* +Copyright 2016 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 factory + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/storagebackend" +) + +// DestroyFunc is to destroy any resources used by the storage returned in Create() together. +type DestroyFunc func() + +// Create creates a storage backend based on given config. +func Create(c storagebackend.ConfigForResource, newFunc func() runtime.Object) (storage.Interface, DestroyFunc, error) { + switch c.Type { + case storagebackend.StorageTypeETCD2: + return nil, nil, fmt.Errorf("%s is no longer a supported storage backend", c.Type) + case storagebackend.StorageTypeUnset, storagebackend.StorageTypeETCD3: + return newETCD3Storage(c, newFunc) + default: + return nil, nil, fmt.Errorf("unknown storage type: %s", c.Type) + } +} + +// CreateHealthCheck creates a healthcheck function based on given config. +func CreateHealthCheck(c storagebackend.Config, stopCh <-chan struct{}) (func() error, error) { + switch c.Type { + case storagebackend.StorageTypeETCD2: + return nil, fmt.Errorf("%s is no longer a supported storage backend", c.Type) + case storagebackend.StorageTypeUnset, storagebackend.StorageTypeETCD3: + return newETCD3HealthCheck(c, stopCh) + default: + return nil, fmt.Errorf("unknown storage type: %s", c.Type) + } +} + +func CreateReadyCheck(c storagebackend.Config, stopCh <-chan struct{}) (func() error, error) { + switch c.Type { + case storagebackend.StorageTypeETCD2: + return nil, fmt.Errorf("%s is no longer a supported storage backend", c.Type) + case storagebackend.StorageTypeUnset, storagebackend.StorageTypeETCD3: + return newETCD3ReadyCheck(c, stopCh) + default: + return nil, fmt.Errorf("unknown storage type: %s", c.Type) + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/util.go b/vendor/k8s.io/apiserver/pkg/storage/util.go new file mode 100644 index 000000000..9da8d9713 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/util.go @@ -0,0 +1,81 @@ +/* +Copyright 2015 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 storage + +import ( + "fmt" + "sync/atomic" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/validation/path" + "k8s.io/apimachinery/pkg/runtime" +) + +type SimpleUpdateFunc func(runtime.Object) (runtime.Object, error) + +// SimpleUpdateFunc converts SimpleUpdateFunc into UpdateFunc +func SimpleUpdate(fn SimpleUpdateFunc) UpdateFunc { + return func(input runtime.Object, _ ResponseMeta) (runtime.Object, *uint64, error) { + out, err := fn(input) + return out, nil, err + } +} + +func EverythingFunc(runtime.Object) bool { + return true +} + +func NamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return "", err + } + name := meta.GetName() + if msgs := path.IsValidPathSegmentName(name); len(msgs) != 0 { + return "", fmt.Errorf("invalid name: %v", msgs) + } + return prefix + "/" + meta.GetNamespace() + "/" + name, nil +} + +func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return "", err + } + name := meta.GetName() + if msgs := path.IsValidPathSegmentName(name); len(msgs) != 0 { + return "", fmt.Errorf("invalid name: %v", msgs) + } + return prefix + "/" + name, nil +} + +// HighWaterMark is a thread-safe object for tracking the maximum value seen +// for some quantity. +type HighWaterMark int64 + +// Update returns true if and only if 'current' is the highest value ever seen. +func (hwm *HighWaterMark) Update(current int64) bool { + for { + old := atomic.LoadInt64((*int64)(hwm)) + if current <= old { + return false + } + if atomic.CompareAndSwapInt64((*int64)(hwm), old, current) { + return true + } + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/value/OWNERS new file mode 100644 index 000000000..d2ea8ec60 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/OWNERS @@ -0,0 +1,8 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - sig-auth-encryption-at-rest-approvers +reviewers: + - sig-auth-encryption-at-rest-reviewers +labels: + - sig/auth diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go new file mode 100644 index 000000000..69930c039 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go @@ -0,0 +1,153 @@ +/* +Copyright 2017 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 aes transforms values for storage at rest using AES-GCM. +package aes + +import ( + "bytes" + "context" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "errors" + "fmt" + "io" + + "k8s.io/apiserver/pkg/storage/value" +) + +// gcm implements AEAD encryption of the provided values given a cipher.Block algorithm. +// The authenticated data provided as part of the value.Context method must match when the same +// value is set to and loaded from storage. In order to ensure that values cannot be copied by +// an attacker from a location under their control, use characteristics of the storage location +// (such as the etcd key) as part of the authenticated data. +// +// Because this mode requires a generated IV and IV reuse is a known weakness of AES-GCM, keys +// must be rotated before a birthday attack becomes feasible. NIST SP 800-38D +// (http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf) recommends using the same +// key with random 96-bit nonces (the default nonce length) no more than 2^32 times, and +// therefore transformers using this implementation *must* ensure they allow for frequent key +// rotation. Future work should include investigation of AES-GCM-SIV as an alternative to +// random nonces. +type gcm struct { + block cipher.Block +} + +// NewGCMTransformer takes the given block cipher and performs encryption and decryption on the given +// data. +func NewGCMTransformer(block cipher.Block) value.Transformer { + return &gcm{block: block} +} + +func (t *gcm) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + aead, err := cipher.NewGCM(t.block) + if err != nil { + return nil, false, err + } + nonceSize := aead.NonceSize() + if len(data) < nonceSize { + return nil, false, fmt.Errorf("the stored data was shorter than the required size") + } + result, err := aead.Open(nil, data[:nonceSize], data[nonceSize:], dataCtx.AuthenticatedData()) + return result, false, err +} + +func (t *gcm) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + aead, err := cipher.NewGCM(t.block) + if err != nil { + return nil, err + } + nonceSize := aead.NonceSize() + result := make([]byte, nonceSize+aead.Overhead()+len(data)) + n, err := rand.Read(result[:nonceSize]) + if err != nil { + return nil, err + } + if n != nonceSize { + return nil, fmt.Errorf("unable to read sufficient random bytes") + } + cipherText := aead.Seal(result[nonceSize:nonceSize], result[:nonceSize], data, dataCtx.AuthenticatedData()) + return result[:nonceSize+len(cipherText)], nil +} + +// cbc implements encryption at rest of the provided values given a cipher.Block algorithm. +type cbc struct { + block cipher.Block +} + +// NewCBCTransformer takes the given block cipher and performs encryption and decryption on the given +// data. +func NewCBCTransformer(block cipher.Block) value.Transformer { + return &cbc{block: block} +} + +var ( + ErrInvalidBlockSize = fmt.Errorf("the stored data is not a multiple of the block size") + errInvalidPKCS7Data = errors.New("invalid PKCS7 data (empty or not padded)") + errInvalidPKCS7Padding = errors.New("invalid padding on input") +) + +func (t *cbc) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + blockSize := aes.BlockSize + if len(data) < blockSize { + return nil, false, fmt.Errorf("the stored data was shorter than the required size") + } + iv := data[:blockSize] + data = data[blockSize:] + + if len(data)%blockSize != 0 { + return nil, false, ErrInvalidBlockSize + } + + result := make([]byte, len(data)) + copy(result, data) + mode := cipher.NewCBCDecrypter(t.block, iv) + mode.CryptBlocks(result, result) + + // remove and verify PKCS#7 padding for CBC + c := result[len(result)-1] + paddingSize := int(c) + size := len(result) - paddingSize + if paddingSize == 0 || paddingSize > len(result) { + return nil, false, errInvalidPKCS7Data + } + for i := 0; i < paddingSize; i++ { + if result[size+i] != c { + return nil, false, errInvalidPKCS7Padding + } + } + + return result[:size], false, nil +} + +func (t *cbc) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + blockSize := aes.BlockSize + paddingSize := blockSize - (len(data) % blockSize) + result := make([]byte, blockSize+len(data)+paddingSize) + iv := result[:blockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, fmt.Errorf("unable to read sufficient random bytes") + } + copy(result[blockSize:], data) + + // add PKCS#7 padding for CBC + copy(result[blockSize+len(data):], bytes.Repeat([]byte{byte(paddingSize)}, paddingSize)) + + mode := cipher.NewCBCEncrypter(t.block, iv) + mode.CryptBlocks(result[blockSize:], result[blockSize:]) + return result, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go new file mode 100644 index 000000000..43d2e00a2 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go @@ -0,0 +1,198 @@ +/* +Copyright 2017 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 envelope transforms values for storage at rest using a Envelope provider +package envelope + +import ( + "context" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "fmt" + "time" + + "k8s.io/apiserver/pkg/storage/value" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" + "k8s.io/utils/lru" + + "golang.org/x/crypto/cryptobyte" +) + +func init() { + value.RegisterMetrics() + metrics.RegisterMetrics() +} + +// Service allows encrypting and decrypting data using an external Key Management Service. +type Service interface { + // Decrypt a given bytearray to obtain the original data as bytes. + Decrypt(data []byte) ([]byte, error) + // Encrypt bytes to a ciphertext. + Encrypt(data []byte) ([]byte, error) +} + +type envelopeTransformer struct { + envelopeService Service + + // transformers is a thread-safe LRU cache which caches decrypted DEKs indexed by their encrypted form. + transformers *lru.Cache + + // baseTransformerFunc creates a new transformer for encrypting the data with the DEK. + baseTransformerFunc func(cipher.Block) value.Transformer + + cacheSize int + cacheEnabled bool +} + +// NewEnvelopeTransformer returns a transformer which implements a KEK-DEK based envelope encryption scheme. +// It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to +// the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently +// used decrypted DEKs in memory. +func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) value.Transformer { + var ( + cache *lru.Cache + ) + + if cacheSize > 0 { + cache = lru.New(cacheSize) + } + return &envelopeTransformer{ + envelopeService: envelopeService, + transformers: cache, + baseTransformerFunc: baseTransformerFunc, + cacheEnabled: cacheSize > 0, + cacheSize: cacheSize, + } +} + +// TransformFromStorage decrypts data encrypted by this transformer using envelope encryption. +func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + metrics.RecordArrival(metrics.FromStorageLabel, time.Now()) + + // Read the 16 bit length-of-DEK encoded at the start of the encrypted DEK. 16 bits can + // represent a maximum key length of 65536 bytes. We are using a 256 bit key, whose + // length cannot fit in 8 bits (1 byte). Thus, we use 16 bits (2 bytes) to store the length. + var encKey cryptobyte.String + s := cryptobyte.String(data) + if ok := s.ReadUint16LengthPrefixed(&encKey); !ok { + return nil, false, fmt.Errorf("invalid data encountered by envelope transformer: failed to read uint16 length prefixed data") + } + + encData := []byte(s) + + // Look up the decrypted DEK from cache or Envelope. + transformer := t.getTransformer(encKey) + if transformer == nil { + if t.cacheEnabled { + value.RecordCacheMiss() + } + key, err := t.envelopeService.Decrypt(encKey) + if err != nil { + // Do NOT wrap this err using fmt.Errorf() or similar functions + // because this gRPC status error has useful error code when + // record the metric. + return nil, false, err + } + + transformer, err = t.addTransformer(encKey, key) + if err != nil { + return nil, false, err + } + } + + return transformer.TransformFromStorage(ctx, encData, dataCtx) +} + +// TransformToStorage encrypts data to be written to disk using envelope encryption. +func (t *envelopeTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + metrics.RecordArrival(metrics.ToStorageLabel, time.Now()) + newKey, err := generateKey(32) + if err != nil { + return nil, err + } + + encKey, err := t.envelopeService.Encrypt(newKey) + if err != nil { + // Do NOT wrap this err using fmt.Errorf() or similar functions + // because this gRPC status error has useful error code when + // record the metric. + return nil, err + } + + transformer, err := t.addTransformer(encKey, newKey) + if err != nil { + return nil, err + } + + result, err := transformer.TransformToStorage(ctx, data, dataCtx) + if err != nil { + return nil, err + } + // Append the length of the encrypted DEK as the first 2 bytes. + b := cryptobyte.NewBuilder(nil) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(encKey)) + }) + b.AddBytes(result) + + return b.Bytes() +} + +var _ value.Transformer = &envelopeTransformer{} + +// addTransformer inserts a new transformer to the Envelope cache of DEKs for future reads. +func (t *envelopeTransformer) addTransformer(encKey []byte, key []byte) (value.Transformer, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + transformer := t.baseTransformerFunc(block) + // Use base64 of encKey as the key into the cache because hashicorp/golang-lru + // cannot hash []uint8. + if t.cacheEnabled { + t.transformers.Add(base64.StdEncoding.EncodeToString(encKey), transformer) + metrics.RecordDekCacheFillPercent(float64(t.transformers.Len()) / float64(t.cacheSize)) + } + return transformer, nil +} + +// getTransformer fetches the transformer corresponding to encKey from cache, if it exists. +func (t *envelopeTransformer) getTransformer(encKey []byte) value.Transformer { + if !t.cacheEnabled { + return nil + } + + _transformer, found := t.transformers.Get(base64.StdEncoding.EncodeToString(encKey)) + if found { + return _transformer.(value.Transformer) + } + return nil +} + +// generateKey generates a random key using system randomness. +func generateKey(length int) (key []byte, err error) { + defer func(start time.Time) { + value.RecordDataKeyGeneration(start, err) + }(time.Now()) + key = make([]byte, length) + if _, err = rand.Read(key); err != nil { + return nil, err + } + + return key, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go new file mode 100644 index 000000000..2b7014460 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go @@ -0,0 +1,162 @@ +/* +Copyright 2017 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 envelope transforms values for storage at rest using a Envelope provider +package envelope + +import ( + "context" + "fmt" + "net" + "sync" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util" + "k8s.io/klog/v2" + kmsapi "k8s.io/kms/apis/v1beta1" +) + +const ( + // unixProtocol is the only supported protocol for remote KMS provider. + unixProtocol = "unix" + // Current version for the protocol interface definition. + kmsapiVersion = "v1beta1" + + versionErrorf = "KMS provider api version %s is not supported, only %s is supported now" +) + +// The gRPC implementation for envelope.Service. +type gRPCService struct { + kmsClient kmsapi.KeyManagementServiceClient + connection *grpc.ClientConn + callTimeout time.Duration + mux sync.RWMutex + versionChecked bool +} + +// NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider. +func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (Service, error) { + klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint) + + addr, err := util.ParseEndpoint(endpoint) + if err != nil { + return nil, err + } + + s := &gRPCService{callTimeout: callTimeout} + s.connection, err = grpc.Dial( + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUnaryInterceptor(s.interceptor), + grpc.WithDefaultCallOptions(grpc.WaitForReady(true)), + grpc.WithContextDialer( + func(context.Context, string) (net.Conn, error) { + // Ignoring addr and timeout arguments: + // addr - comes from the closure + c, err := net.DialUnix(unixProtocol, nil, &net.UnixAddr{Name: addr}) + if err != nil { + klog.Errorf("failed to create connection to unix socket: %s, error: %v", addr, err) + } else { + klog.V(4).Infof("Successfully dialed Unix socket %v", addr) + } + return c, err + })) + + if err != nil { + return nil, fmt.Errorf("failed to create connection to %s, error: %v", endpoint, err) + } + + s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection) + + go func() { + defer utilruntime.HandleCrash() + + <-ctx.Done() + _ = s.connection.Close() + }() + + return s, nil +} + +func (g *gRPCService) checkAPIVersion(ctx context.Context) error { + g.mux.Lock() + defer g.mux.Unlock() + + if g.versionChecked { + return nil + } + + request := &kmsapi.VersionRequest{Version: kmsapiVersion} + response, err := g.kmsClient.Version(ctx, request) + if err != nil { + return fmt.Errorf("failed get version from remote KMS provider: %v", err) + } + if response.Version != kmsapiVersion { + return fmt.Errorf(versionErrorf, response.Version, kmsapiVersion) + } + g.versionChecked = true + + klog.V(4).Infof("Version of KMS provider is %s", response.Version) + return nil +} + +// Decrypt a given data string to obtain the original byte data. +func (g *gRPCService) Decrypt(cipher []byte) ([]byte, error) { + ctx, cancel := context.WithTimeout(context.Background(), g.callTimeout) + defer cancel() + + request := &kmsapi.DecryptRequest{Cipher: cipher, Version: kmsapiVersion} + response, err := g.kmsClient.Decrypt(ctx, request) + if err != nil { + return nil, err + } + return response.Plain, nil +} + +// Encrypt bytes to a string ciphertext. +func (g *gRPCService) Encrypt(plain []byte) ([]byte, error) { + ctx, cancel := context.WithTimeout(context.Background(), g.callTimeout) + defer cancel() + + request := &kmsapi.EncryptRequest{Plain: plain, Version: kmsapiVersion} + response, err := g.kmsClient.Encrypt(ctx, request) + if err != nil { + return nil, err + } + return response.Cipher, nil +} + +func (g *gRPCService) interceptor( + ctx context.Context, + method string, + req interface{}, + reply interface{}, + cc *grpc.ClientConn, + invoker grpc.UnaryInvoker, + opts ...grpc.CallOption, +) error { + if !kmsapi.IsVersionCheckMethod(method) { + if err := g.checkAPIVersion(ctx); err != nil { + return err + } + } + + return invoker(ctx, method, req, reply, cc, opts...) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go new file mode 100644 index 000000000..726e3053e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go @@ -0,0 +1,315 @@ +/* +Copyright 2022 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 kmsv2 transforms values for storage at rest using a Envelope v2 provider +package kmsv2 + +import ( + "context" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "fmt" + "time" + + "github.com/gogo/protobuf/proto" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/apimachinery/pkg/util/validation" + "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/apiserver/pkg/storage/value" + kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" + "k8s.io/klog/v2" + "k8s.io/utils/lru" +) + +const ( + // KMSAPIVersion is the version of the KMS API. + KMSAPIVersion = "v2alpha1" + // annotationsMaxSize is the maximum size of the annotations. + annotationsMaxSize = 32 * 1024 // 32 kB + // keyIDMaxSize is the maximum size of the keyID. + keyIDMaxSize = 1 * 1024 // 1 kB + // encryptedDEKMaxSize is the maximum size of the encrypted DEK. + encryptedDEKMaxSize = 1 * 1024 // 1 kB +) + +// Service allows encrypting and decrypting data using an external Key Management Service. +type Service interface { + // Decrypt a given bytearray to obtain the original data as bytes. + Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) + // Encrypt bytes to a ciphertext. + Encrypt(ctx context.Context, uid string, data []byte) (*EncryptResponse, error) + // Status returns the status of the KMS. + Status(ctx context.Context) (*StatusResponse, error) +} + +type envelopeTransformer struct { + envelopeService Service + + // transformers is a thread-safe LRU cache which caches decrypted DEKs indexed by their encrypted form. + transformers *lru.Cache + + // baseTransformerFunc creates a new transformer for encrypting the data with the DEK. + baseTransformerFunc func(cipher.Block) value.Transformer + + cacheSize int + cacheEnabled bool +} + +// EncryptResponse is the response from the Envelope service when encrypting data. +type EncryptResponse struct { + Ciphertext []byte + KeyID string + Annotations map[string][]byte +} + +// DecryptRequest is the request to the Envelope service when decrypting data. +type DecryptRequest struct { + Ciphertext []byte + KeyID string + Annotations map[string][]byte +} + +// StatusResponse is the response from the Envelope service when getting the status of the service. +type StatusResponse struct { + Version string + Healthz string + KeyID string +} + +// NewEnvelopeTransformer returns a transformer which implements a KEK-DEK based envelope encryption scheme. +// It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to +// the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently +// used decrypted DEKs in memory. +func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) value.Transformer { + var cache *lru.Cache + + if cacheSize > 0 { + // TODO(aramase): Switch to using expiring cache: kubernetes/kubernetes/staging/src/k8s.io/apimachinery/pkg/util/cache/expiring.go. + // It handles scans a lot better, doesn't have to be right sized, and don't have a global lock on reads. + cache = lru.New(cacheSize) + } + + return &envelopeTransformer{ + envelopeService: envelopeService, + transformers: cache, + baseTransformerFunc: baseTransformerFunc, + cacheEnabled: cacheSize > 0, + cacheSize: cacheSize, + } +} + +// TransformFromStorage decrypts data encrypted by this transformer using envelope encryption. +func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + metrics.RecordArrival(metrics.FromStorageLabel, time.Now()) + + // Deserialize the EncryptedObject from the data. + encryptedObject, err := t.doDecode(data) + if err != nil { + return nil, false, err + } + + // Look up the decrypted DEK from cache or Envelope. + transformer := t.getTransformer(encryptedObject.EncryptedDEK) + if transformer == nil { + if t.cacheEnabled { + value.RecordCacheMiss() + } + uid := string(uuid.NewUUID()) + klog.V(6).InfoS("Decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) + key, err := t.envelopeService.Decrypt(ctx, uid, &DecryptRequest{ + Ciphertext: encryptedObject.EncryptedDEK, + KeyID: encryptedObject.KeyID, + Annotations: encryptedObject.Annotations, + }) + if err != nil { + return nil, false, fmt.Errorf("failed to decrypt DEK, error: %w", err) + } + + transformer, err = t.addTransformer(encryptedObject.EncryptedDEK, key) + if err != nil { + return nil, false, err + } + } + + return transformer.TransformFromStorage(ctx, encryptedObject.EncryptedData, dataCtx) +} + +// TransformToStorage encrypts data to be written to disk using envelope encryption. +func (t *envelopeTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + metrics.RecordArrival(metrics.ToStorageLabel, time.Now()) + newKey, err := generateKey(32) + if err != nil { + return nil, err + } + + uid := string(uuid.NewUUID()) + klog.V(6).InfoS("Encrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) + resp, err := t.envelopeService.Encrypt(ctx, uid, newKey) + if err != nil { + return nil, fmt.Errorf("failed to encrypt DEK, error: %w", err) + } + + transformer, err := t.addTransformer(resp.Ciphertext, newKey) + if err != nil { + return nil, err + } + + result, err := transformer.TransformToStorage(ctx, data, dataCtx) + if err != nil { + return nil, err + } + + encObject := &kmstypes.EncryptedObject{ + KeyID: resp.KeyID, + EncryptedDEK: resp.Ciphertext, + EncryptedData: result, + Annotations: resp.Annotations, + } + + // Serialize the EncryptedObject to a byte array. + return t.doEncode(encObject) +} + +// addTransformer inserts a new transformer to the Envelope cache of DEKs for future reads. +func (t *envelopeTransformer) addTransformer(encKey []byte, key []byte) (value.Transformer, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + transformer := t.baseTransformerFunc(block) + // Use base64 of encKey as the key into the cache because hashicorp/golang-lru + // cannot hash []uint8. + if t.cacheEnabled { + t.transformers.Add(base64.StdEncoding.EncodeToString(encKey), transformer) + metrics.RecordDekCacheFillPercent(float64(t.transformers.Len()) / float64(t.cacheSize)) + } + return transformer, nil +} + +// getTransformer fetches the transformer corresponding to encKey from cache, if it exists. +func (t *envelopeTransformer) getTransformer(encKey []byte) value.Transformer { + if !t.cacheEnabled { + return nil + } + + _transformer, found := t.transformers.Get(base64.StdEncoding.EncodeToString(encKey)) + if found { + return _transformer.(value.Transformer) + } + return nil +} + +// doEncode encodes the EncryptedObject to a byte array. +func (t *envelopeTransformer) doEncode(request *kmstypes.EncryptedObject) ([]byte, error) { + if err := validateEncryptedObject(request); err != nil { + return nil, err + } + return proto.Marshal(request) +} + +// doDecode decodes the byte array to an EncryptedObject. +func (t *envelopeTransformer) doDecode(originalData []byte) (*kmstypes.EncryptedObject, error) { + o := &kmstypes.EncryptedObject{} + if err := proto.Unmarshal(originalData, o); err != nil { + return nil, err + } + // validate the EncryptedObject + if err := validateEncryptedObject(o); err != nil { + return nil, err + } + + return o, nil +} + +// generateKey generates a random key using system randomness. +func generateKey(length int) (key []byte, err error) { + defer func(start time.Time) { + value.RecordDataKeyGeneration(start, err) + }(time.Now()) + key = make([]byte, length) + if _, err = rand.Read(key); err != nil { + return nil, err + } + + return key, nil +} + +func validateEncryptedObject(o *kmstypes.EncryptedObject) error { + if o == nil { + return fmt.Errorf("encrypted object is nil") + } + if len(o.EncryptedData) == 0 { + return fmt.Errorf("encrypted data is empty") + } + if err := validateEncryptedDEK(o.EncryptedDEK); err != nil { + return fmt.Errorf("failed to validate encrypted DEK: %w", err) + } + if err := validateKeyID(o.KeyID); err != nil { + return fmt.Errorf("failed to validate key id: %w", err) + } + if err := validateAnnotations(o.Annotations); err != nil { + return fmt.Errorf("failed to validate annotations: %w", err) + } + return nil +} + +// validateEncryptedDEK tests the following: +// 1. The encrypted DEK is not empty. +// 2. The size of encrypted DEK is less than 1 kB. +func validateEncryptedDEK(encryptedDEK []byte) error { + if len(encryptedDEK) == 0 { + return fmt.Errorf("encrypted DEK is empty") + } + if len(encryptedDEK) > encryptedDEKMaxSize { + return fmt.Errorf("encrypted DEK is %d bytes, which exceeds the max size of %d", len(encryptedDEK), encryptedDEKMaxSize) + } + return nil +} + +// validateAnnotations tests the following: +// 1. checks if the annotation key is fully qualified +// 2. The size of annotations keys + values is less than 32 kB. +func validateAnnotations(annotations map[string][]byte) error { + var errs []error + var totalSize uint64 + for k, v := range annotations { + if fieldErr := validation.IsFullyQualifiedDomainName(field.NewPath("annotations"), k); fieldErr != nil { + errs = append(errs, fieldErr.ToAggregate()) + } + totalSize += uint64(len(k)) + uint64(len(v)) + } + if totalSize > annotationsMaxSize { + errs = append(errs, fmt.Errorf("total size of annotations is %d, which exceeds the max size of %d", totalSize, annotationsMaxSize)) + } + return utilerrors.NewAggregate(errs) +} + +// validateKeyID tests the following: +// 1. The keyID is not empty. +// 2. The size of keyID is less than 1 kB. +func validateKeyID(keyID string) error { + if len(keyID) == 0 { + return fmt.Errorf("keyID is empty") + } + if len(keyID) > keyIDMaxSize { + return fmt.Errorf("keyID is %d bytes, which exceeds the max size of %d", len(keyID), keyIDMaxSize) + } + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go new file mode 100644 index 000000000..692aeef53 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go @@ -0,0 +1,139 @@ +/* +Copyright 2022 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 kmsv2 transforms values for storage at rest using a Envelope provider +package kmsv2 + +import ( + "context" + "fmt" + "net" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util" + "k8s.io/klog/v2" + kmsapi "k8s.io/kms/apis/v2alpha1" +) + +const ( + // unixProtocol is the only supported protocol for remote KMS provider. + unixProtocol = "unix" +) + +// The gRPC implementation for envelope.Service. +type gRPCService struct { + kmsClient kmsapi.KeyManagementServiceClient + connection *grpc.ClientConn + callTimeout time.Duration +} + +// NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider. +func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (Service, error) { + klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint) + + addr, err := util.ParseEndpoint(endpoint) + if err != nil { + return nil, err + } + + s := &gRPCService{callTimeout: callTimeout} + s.connection, err = grpc.Dial( + addr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithDefaultCallOptions(grpc.WaitForReady(true)), + grpc.WithContextDialer( + func(context.Context, string) (net.Conn, error) { + // Ignoring addr and timeout arguments: + // addr - comes from the closure + c, err := net.DialUnix(unixProtocol, nil, &net.UnixAddr{Name: addr}) + if err != nil { + klog.Errorf("failed to create connection to unix socket: %s, error: %v", addr, err) + } else { + klog.V(4).Infof("Successfully dialed Unix socket %v", addr) + } + return c, err + })) + + if err != nil { + return nil, fmt.Errorf("failed to create connection to %s, error: %v", endpoint, err) + } + + s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection) + + go func() { + defer utilruntime.HandleCrash() + + <-ctx.Done() + _ = s.connection.Close() + }() + + return s, nil +} + +// Decrypt a given data string to obtain the original byte data. +func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) { + ctx, cancel := context.WithTimeout(ctx, g.callTimeout) + defer cancel() + + request := &kmsapi.DecryptRequest{ + Ciphertext: req.Ciphertext, + Uid: uid, + KeyId: req.KeyID, + Annotations: req.Annotations, + } + response, err := g.kmsClient.Decrypt(ctx, request) + if err != nil { + return nil, err + } + return response.Plaintext, nil +} + +// Encrypt bytes to a string ciphertext. +func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) (*EncryptResponse, error) { + ctx, cancel := context.WithTimeout(ctx, g.callTimeout) + defer cancel() + + request := &kmsapi.EncryptRequest{ + Plaintext: plaintext, + Uid: uid, + } + response, err := g.kmsClient.Encrypt(ctx, request) + if err != nil { + return nil, err + } + return &EncryptResponse{ + Ciphertext: response.Ciphertext, + KeyID: response.KeyId, + Annotations: response.Annotations, + }, nil +} + +// Status returns the status of the KMSv2 provider. +func (g *gRPCService) Status(ctx context.Context) (*StatusResponse, error) { + ctx, cancel := context.WithTimeout(ctx, g.callTimeout) + defer cancel() + + request := &kmsapi.StatusRequest{} + response, err := g.kmsClient.Status(ctx, request) + if err != nil { + return nil, err + } + return &StatusResponse{Version: response.Version, Healthz: response.Healthz, KeyID: response.KeyId}, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/OWNERS new file mode 100644 index 000000000..fa20d4cbe --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/OWNERS @@ -0,0 +1,9 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +# Disable inheritance as this is an api owners file +options: + no_parent_owners: true +approvers: + - api-approvers +reviewers: + - sig-auth-api-reviewers diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.pb.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.pb.go new file mode 100644 index 000000000..307b0b248 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.pb.go @@ -0,0 +1,128 @@ +/* +Copyright 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. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: api.proto + +package v2alpha1 + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// EncryptedObject is the representation of data stored in etcd after envelope encryption. +type EncryptedObject struct { + // EncryptedData is the encrypted data. + EncryptedData []byte `protobuf:"bytes,1,opt,name=encryptedData,proto3" json:"encryptedData,omitempty"` + // KeyID is the KMS key ID used for encryption operations. + KeyID string `protobuf:"bytes,2,opt,name=keyID,proto3" json:"keyID,omitempty"` + // EncryptedDEK is the encrypted DEK. + EncryptedDEK []byte `protobuf:"bytes,3,opt,name=encryptedDEK,proto3" json:"encryptedDEK,omitempty"` + // Annotations is additional metadata that was provided by the KMS plugin. + Annotations map[string][]byte `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptedObject) Reset() { *m = EncryptedObject{} } +func (m *EncryptedObject) String() string { return proto.CompactTextString(m) } +func (*EncryptedObject) ProtoMessage() {} +func (*EncryptedObject) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{0} +} +func (m *EncryptedObject) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptedObject.Unmarshal(m, b) +} +func (m *EncryptedObject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptedObject.Marshal(b, m, deterministic) +} +func (m *EncryptedObject) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptedObject.Merge(m, src) +} +func (m *EncryptedObject) XXX_Size() int { + return xxx_messageInfo_EncryptedObject.Size(m) +} +func (m *EncryptedObject) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptedObject.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptedObject proto.InternalMessageInfo + +func (m *EncryptedObject) GetEncryptedData() []byte { + if m != nil { + return m.EncryptedData + } + return nil +} + +func (m *EncryptedObject) GetKeyID() string { + if m != nil { + return m.KeyID + } + return "" +} + +func (m *EncryptedObject) GetEncryptedDEK() []byte { + if m != nil { + return m.EncryptedDEK + } + return nil +} + +func (m *EncryptedObject) GetAnnotations() map[string][]byte { + if m != nil { + return m.Annotations + } + return nil +} + +func init() { + proto.RegisterType((*EncryptedObject)(nil), "v2alpha1.EncryptedObject") + proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.EncryptedObject.AnnotationsEntry") +} + +func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } + +var fileDescriptor_00212fb1f9d3bf1c = []byte{ + // 200 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x2c, 0xc8, 0xd4, + 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x28, 0x33, 0x4a, 0xcc, 0x29, 0xc8, 0x48, 0x34, 0x54, + 0xfa, 0xcf, 0xc8, 0xc5, 0xef, 0x9a, 0x97, 0x5c, 0x54, 0x59, 0x50, 0x92, 0x9a, 0xe2, 0x9f, 0x94, + 0x95, 0x9a, 0x5c, 0x22, 0xa4, 0xc2, 0xc5, 0x9b, 0x0a, 0x13, 0x72, 0x49, 0x2c, 0x49, 0x94, 0x60, + 0x54, 0x60, 0xd4, 0xe0, 0x09, 0x42, 0x15, 0x14, 0x12, 0xe1, 0x62, 0xcd, 0x4e, 0xad, 0xf4, 0x74, + 0x91, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x70, 0x84, 0x94, 0xb8, 0x78, 0x10, 0xca, 0x5c, + 0xbd, 0x25, 0x98, 0xc1, 0x5a, 0x51, 0xc4, 0x84, 0x7c, 0xb8, 0xb8, 0x13, 0xf3, 0xf2, 0xf2, 0x4b, + 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0x25, 0x58, 0x14, 0x98, 0x35, 0xb8, 0x8d, 0xb4, 0xf4, 0x60, + 0x6e, 0xd2, 0x43, 0x73, 0x8f, 0x9e, 0x23, 0x42, 0xb1, 0x6b, 0x5e, 0x49, 0x51, 0x65, 0x10, 0xb2, + 0x76, 0x29, 0x3b, 0x2e, 0x01, 0x74, 0x05, 0x42, 0x02, 0x5c, 0xcc, 0xd9, 0xa9, 0x95, 0x60, 0x77, + 0x73, 0x06, 0x81, 0x98, 0x20, 0xd7, 0x96, 0x25, 0xe6, 0x94, 0xa6, 0x82, 0x5d, 0xcb, 0x13, 0x04, + 0xe1, 0x58, 0x31, 0x59, 0x30, 0x26, 0xb1, 0x81, 0x83, 0xc4, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, + 0x88, 0x8c, 0xbb, 0x4e, 0x1f, 0x01, 0x00, 0x00, +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.proto b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.proto new file mode 100644 index 000000000..e3b978b05 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.proto @@ -0,0 +1,35 @@ +/* +Copyright 2022 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. +*/ + +// To regenerate api.pb.go run hack/update-generated-kms.sh +syntax = "proto3"; + +package v2alpha1; + +// EncryptedObject is the representation of data stored in etcd after envelope encryption. +message EncryptedObject { + // EncryptedData is the encrypted data. + bytes encryptedData = 1; + + // KeyID is the KMS key ID used for encryption operations. + string keyID = 2; + + // EncryptedDEK is the encrypted DEK. + bytes encryptedDEK = 3; + + // Annotations is additional metadata that was provided by the KMS plugin. + map annotations = 4; +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/v2alpha1.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/v2alpha1.go new file mode 100644 index 000000000..b8bed64e8 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/v2alpha1.go @@ -0,0 +1,18 @@ +/* +Copyright 2022 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 v2alpha1 contains definition of kms-plugin's serialized types. +package v2alpha1 diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go new file mode 100644 index 000000000..ca0e0ad0f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go @@ -0,0 +1,106 @@ +/* +Copyright 2020 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 metrics + +import ( + "sync" + "time" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +const ( + namespace = "apiserver" + subsystem = "envelope_encryption" + FromStorageLabel = "from_storage" + ToStorageLabel = "to_storage" +) + +/* + * By default, all the following metrics are defined as falling under + * ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes) + * + * Promoting the stability level of the metric is a responsibility of the component owner, since it + * involves explicitly acknowledging support for the metric across multiple releases, in accordance with + * the metric stability policy. + */ +var ( + lockLastFromStorage sync.Mutex + lockLastToStorage sync.Mutex + + lastFromStorage time.Time + lastToStorage time.Time + + dekCacheFillPercent = metrics.NewGauge( + &metrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dek_cache_fill_percent", + Help: "Percent of the cache slots currently occupied by cached DEKs.", + StabilityLevel: metrics.ALPHA, + }, + ) + + dekCacheInterArrivals = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dek_cache_inter_arrival_time_seconds", + Help: "Time (in seconds) of inter arrival of transformation requests.", + StabilityLevel: metrics.ALPHA, + Buckets: metrics.ExponentialBuckets(60, 2, 10), + }, + []string{"transformation_type"}, + ) +) + +var registerMetricsFunc sync.Once + +func RegisterMetrics() { + registerMetricsFunc.Do(func() { + legacyregistry.MustRegister(dekCacheFillPercent) + legacyregistry.MustRegister(dekCacheInterArrivals) + }) +} + +func RecordArrival(transformationType string, start time.Time) { + switch transformationType { + case FromStorageLabel: + lockLastFromStorage.Lock() + defer lockLastFromStorage.Unlock() + + if lastFromStorage.IsZero() { + lastFromStorage = start + } + dekCacheInterArrivals.WithLabelValues(transformationType).Observe(start.Sub(lastFromStorage).Seconds()) + lastFromStorage = start + case ToStorageLabel: + lockLastToStorage.Lock() + defer lockLastToStorage.Unlock() + + if lastToStorage.IsZero() { + lastToStorage = start + } + dekCacheInterArrivals.WithLabelValues(transformationType).Observe(start.Sub(lastToStorage).Seconds()) + lastToStorage = start + } +} + +func RecordDekCacheFillPercent(percent float64) { + dekCacheFillPercent.Set(percent) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util/util.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util/util.go new file mode 100644 index 000000000..f062370ab --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util/util.go @@ -0,0 +1,54 @@ +/* +Copyright 2022 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 util + +import ( + "fmt" + "net/url" + "strings" +) + +const ( + // unixProtocol is the only supported protocol for remote KMS provider. + unixProtocol = "unix" +) + +// Parse the endpoint to extract schema, host or path. +func ParseEndpoint(endpoint string) (string, error) { + if len(endpoint) == 0 { + return "", fmt.Errorf("remote KMS provider can't use empty string as endpoint") + } + + u, err := url.Parse(endpoint) + if err != nil { + return "", fmt.Errorf("invalid endpoint %q for remote KMS provider, error: %v", endpoint, err) + } + + if u.Scheme != unixProtocol { + return "", fmt.Errorf("unsupported scheme %q for remote KMS provider", u.Scheme) + } + + // Linux abstract namespace socket - no physical file required + // Warning: Linux Abstract sockets have not concept of ACL (unlike traditional file based sockets). + // However, Linux Abstract sockets are subject to Linux networking namespace, so will only be accessible to + // containers within the same pod (unless host networking is used). + if strings.HasPrefix(u.Path, "/@") { + return strings.TrimPrefix(u.Path, "/"), nil + } + + return u.Path, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity/identity.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity/identity.go new file mode 100644 index 000000000..8d967d706 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity/identity.go @@ -0,0 +1,57 @@ +/* +Copyright 2017 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 identity + +import ( + "bytes" + "context" + "fmt" + + "k8s.io/apiserver/pkg/storage/value" +) + +var ( + transformer = identityTransformer{} + encryptedPrefix = []byte("k8s:enc:") + errEncryptedData = fmt.Errorf("identity transformer tried to read encrypted data") +) + +// identityTransformer performs no transformation on provided data, but validates +// that the data is not encrypted data during TransformFromStorage +type identityTransformer struct{} + +// NewEncryptCheckTransformer returns an identityTransformer which returns an error +// on attempts to read encrypted data +func NewEncryptCheckTransformer() value.Transformer { + return transformer +} + +// TransformFromStorage returns the input bytes if the data is not encrypted +func (identityTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + // identityTransformer has to return an error if the data is encoded using another transformer. + // JSON data starts with '{'. Protobuf data has a prefix 'k8s[\x00-\xFF]'. + // Prefix 'k8s:enc:' is reserved for encrypted data on disk. + if bytes.HasPrefix(data, encryptedPrefix) { + return nil, false, errEncryptedData + } + return data, false, nil +} + +// TransformToStorage implements the Transformer interface for identityTransformer +func (identityTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + return data, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/secretbox/secretbox.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/secretbox/secretbox.go new file mode 100644 index 000000000..9aec8acd3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/secretbox/secretbox.go @@ -0,0 +1,70 @@ +/* +Copyright 2017 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 secretbox transforms values for storage at rest using XSalsa20 and Poly1305. +package secretbox + +import ( + "context" + "crypto/rand" + "fmt" + + "golang.org/x/crypto/nacl/secretbox" + + "k8s.io/apiserver/pkg/storage/value" +) + +// secretbox implements at rest encryption of the provided values given a 32 byte secret key. +// Uses a standard 24 byte nonce (placed at the beginning of the cipher text) generated +// from crypto/rand. Does not perform authentication of the data at rest. +type secretboxTransformer struct { + key [32]byte +} + +const nonceSize = 24 + +// NewSecretboxTransformer takes the given key and performs encryption and decryption on the given +// data. +func NewSecretboxTransformer(key [32]byte) value.Transformer { + return &secretboxTransformer{key: key} +} + +func (t *secretboxTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { + if len(data) < (secretbox.Overhead + nonceSize) { + return nil, false, fmt.Errorf("the stored data was shorter than the required size") + } + var nonce [nonceSize]byte + copy(nonce[:], data[:nonceSize]) + data = data[nonceSize:] + out := make([]byte, 0, len(data)-secretbox.Overhead) + result, ok := secretbox.Open(out, data, &nonce, &t.key) + if !ok { + return nil, false, fmt.Errorf("output array was not large enough for encryption") + } + return result, false, nil +} + +func (t *secretboxTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { + var nonce [nonceSize]byte + n, err := rand.Read(nonce[:]) + if err != nil { + return nil, err + } + if n != nonceSize { + return nil, fmt.Errorf("unable to read sufficient random bytes") + } + return secretbox.Seal(nonce[:], data, &nonce, &t.key), nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go new file mode 100644 index 000000000..63ab526af --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go @@ -0,0 +1,141 @@ +/* +Copyright 2019 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 value + +import ( + "sync" + "time" + + "google.golang.org/grpc/status" + + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +const ( + namespace = "apiserver" + subsystem = "storage" +) + +/* + * By default, all the following metrics are defined as falling under + * ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes) + * + * Promoting the stability level of the metric is a responsibility of the component owner, since it + * involves explicitly acknowledging support for the metric across multiple releases, in accordance with + * the metric stability policy. + */ +var ( + transformerLatencies = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "transformation_duration_seconds", + Help: "Latencies in seconds of value transformation operations.", + // In-process transformations (ex. AES CBC) complete on the order of 20 microseconds. However, when + // external KMS is involved latencies may climb into hundreds of milliseconds. + Buckets: metrics.ExponentialBuckets(5e-6, 2, 25), + StabilityLevel: metrics.ALPHA, + }, + []string{"transformation_type"}, + ) + + transformerOperationsTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "transformation_operations_total", + Help: "Total number of transformations.", + StabilityLevel: metrics.ALPHA, + }, + []string{"transformation_type", "transformer_prefix", "status"}, + ) + + envelopeTransformationCacheMissTotal = metrics.NewCounter( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "envelope_transformation_cache_misses_total", + Help: "Total number of cache misses while accessing key decryption key(KEK).", + StabilityLevel: metrics.ALPHA, + }, + ) + + dataKeyGenerationLatencies = metrics.NewHistogram( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "data_key_generation_duration_seconds", + Help: "Latencies in seconds of data encryption key(DEK) generation operations.", + Buckets: metrics.ExponentialBuckets(5e-6, 2, 14), + StabilityLevel: metrics.ALPHA, + }, + ) + + dataKeyGenerationFailuresTotal = metrics.NewCounter( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "data_key_generation_failures_total", + Help: "Total number of failed data encryption key(DEK) generation operations.", + StabilityLevel: metrics.ALPHA, + }, + ) +) + +var registerMetrics sync.Once + +func RegisterMetrics() { + registerMetrics.Do(func() { + legacyregistry.MustRegister(transformerLatencies) + legacyregistry.MustRegister(transformerOperationsTotal) + legacyregistry.MustRegister(envelopeTransformationCacheMissTotal) + legacyregistry.MustRegister(dataKeyGenerationLatencies) + legacyregistry.MustRegister(dataKeyGenerationFailuresTotal) + }) +} + +// RecordTransformation records latencies and count of TransformFromStorage and TransformToStorage operations. +// Note that transformation_failures_total metric is deprecated, use transformation_operations_total instead. +func RecordTransformation(transformationType, transformerPrefix string, start time.Time, err error) { + transformerOperationsTotal.WithLabelValues(transformationType, transformerPrefix, status.Code(err).String()).Inc() + + switch { + case err == nil: + transformerLatencies.WithLabelValues(transformationType).Observe(sinceInSeconds(start)) + } +} + +// RecordCacheMiss records a miss on Key Encryption Key(KEK) - call to KMS was required to decrypt KEK. +func RecordCacheMiss() { + envelopeTransformationCacheMissTotal.Inc() +} + +// RecordDataKeyGeneration records latencies and count of Data Encryption Key generation operations. +func RecordDataKeyGeneration(start time.Time, err error) { + if err != nil { + dataKeyGenerationFailuresTotal.Inc() + return + } + + dataKeyGenerationLatencies.Observe(sinceInSeconds(start)) +} + +// sinceInSeconds gets the time since the specified start in seconds. +func sinceInSeconds(start time.Time) float64 { + return time.Since(start).Seconds() +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go b/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go new file mode 100644 index 000000000..8e5bf94c9 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go @@ -0,0 +1,166 @@ +/* +Copyright 2017 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 value contains methods for assisting with transformation of values in storage. +package value + +import ( + "bytes" + "context" + "fmt" + "time" + + "k8s.io/apimachinery/pkg/util/errors" +) + +func init() { + RegisterMetrics() +} + +// Context is additional information that a storage transformation may need to verify the data at rest. +type Context interface { + // AuthenticatedData should return an array of bytes that describes the current value. If the value changes, + // the transformer may report the value as unreadable or tampered. This may be nil if no such description exists + // or is needed. For additional verification, set this to data that strongly identifies the value, such as + // the key and creation version of the stored data. + AuthenticatedData() []byte +} + +// Transformer allows a value to be transformed before being read from or written to the underlying store. The methods +// must be able to undo the transformation caused by the other. +type Transformer interface { + // TransformFromStorage may transform the provided data from its underlying storage representation or return an error. + // Stale is true if the object on disk is stale and a write to etcd should be issued, even if the contents of the object + // have not changed. + TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, stale bool, err error) + // TransformToStorage may transform the provided data into the appropriate form in storage or return an error. + TransformToStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, err error) +} + +// DefaultContext is a simple implementation of Context for a slice of bytes. +type DefaultContext []byte + +// AuthenticatedData returns itself. +func (c DefaultContext) AuthenticatedData() []byte { return c } + +// PrefixTransformer holds a transformer interface and the prefix that the transformation is located under. +type PrefixTransformer struct { + Prefix []byte + Transformer Transformer +} + +type prefixTransformers struct { + transformers []PrefixTransformer + err error +} + +var _ Transformer = &prefixTransformers{} + +// NewPrefixTransformers supports the Transformer interface by checking the incoming data against the provided +// prefixes in order. The first matching prefix will be used to transform the value (the prefix is stripped +// before the Transformer interface is invoked). The first provided transformer will be used when writing to +// the store. +func NewPrefixTransformers(err error, transformers ...PrefixTransformer) Transformer { + if err == nil { + err = fmt.Errorf("the provided value does not match any of the supported transformers") + } + return &prefixTransformers{ + transformers: transformers, + err: err, + } +} + +// TransformFromStorage finds the first transformer with a prefix matching the provided data and returns +// the result of transforming the value. It will always mark any transformation as stale that is not using +// the first transformer. +func (t *prefixTransformers) TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, bool, error) { + start := time.Now() + var errs []error + for i, transformer := range t.transformers { + if bytes.HasPrefix(data, transformer.Prefix) { + result, stale, err := transformer.Transformer.TransformFromStorage(ctx, data[len(transformer.Prefix):], dataCtx) + // To migrate away from encryption, user can specify an identity transformer higher up + // (in the config file) than the encryption transformer. In that scenario, the identity transformer needs to + // identify (during reads from disk) whether the data being read is encrypted or not. If the data is encrypted, + // it shall throw an error, but that error should not prevent the next subsequent transformer from being tried. + if len(transformer.Prefix) == 0 && err != nil { + continue + } + if len(transformer.Prefix) == 0 { + RecordTransformation("from_storage", "identity", start, err) + } else { + RecordTransformation("from_storage", string(transformer.Prefix), start, err) + } + + // It is valid to have overlapping prefixes when the same encryption provider + // is specified multiple times but with different keys (the first provider is + // being rotated to and some later provider is being rotated away from). + // + // Example: + // + // { + // "aescbc": { + // "keys": [ + // { + // "name": "2", + // "secret": "some key 2" + // } + // ] + // } + // }, + // { + // "aescbc": { + // "keys": [ + // { + // "name": "1", + // "secret": "some key 1" + // } + // ] + // } + // }, + // + // The transformers for both aescbc configs share the prefix k8s:enc:aescbc:v1: + // but a failure in the first one should not prevent a later match from being attempted. + // Thus we never short-circuit on a prefix match that results in an error. + if err != nil { + errs = append(errs, err) + continue + } + + return result, stale || i != 0, err + } + } + if err := errors.Reduce(errors.NewAggregate(errs)); err != nil { + return nil, false, err + } + RecordTransformation("from_storage", "unknown", start, t.err) + return nil, false, t.err +} + +// TransformToStorage uses the first transformer and adds its prefix to the data. +func (t *prefixTransformers) TransformToStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, error) { + start := time.Now() + transformer := t.transformers[0] + result, err := transformer.Transformer.TransformToStorage(ctx, data, dataCtx) + RecordTransformation("to_storage", string(transformer.Prefix), start, err) + if err != nil { + return nil, err + } + prefixedData := make([]byte, len(transformer.Prefix), len(result)+len(transformer.Prefix)) + copy(prefixedData, transformer.Prefix) + prefixedData = append(prefixedData, result...) + return prefixedData, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storageversion/OWNERS b/vendor/k8s.io/apiserver/pkg/storageversion/OWNERS new file mode 100644 index 000000000..869b3da0d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storageversion/OWNERS @@ -0,0 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - caesarxuchao + - roycaihw diff --git a/vendor/k8s.io/apiserver/pkg/storageversion/manager.go b/vendor/k8s.io/apiserver/pkg/storageversion/manager.go new file mode 100644 index 000000000..0e0d9542b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storageversion/manager.go @@ -0,0 +1,294 @@ +/* +Copyright 2020 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 storageversion + +import ( + "fmt" + "sort" + "sync" + "sync/atomic" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + _ "k8s.io/component-base/metrics/prometheus/workqueue" // for workqueue metric registration + "k8s.io/klog/v2" +) + +// ResourceInfo contains the information to register the resource to the +// storage version API. +type ResourceInfo struct { + GroupResource schema.GroupResource + + EncodingVersion string + // Used to calculate decodable versions. Can only be used after all + // equivalent versions are registered by InstallREST. + EquivalentResourceMapper runtime.EquivalentResourceRegistry + + // DirectlyDecodableVersions is a list of versions that the converter for REST storage knows how to convert. This + // contains items like apiextensions.k8s.io/v1beta1 even if we don't serve that version. + DirectlyDecodableVersions []schema.GroupVersion +} + +// Manager records the resources whose StorageVersions need updates, and provides a method to update those StorageVersions. +type Manager interface { + // AddResourceInfo records resources whose StorageVersions need updates + AddResourceInfo(resources ...*ResourceInfo) + // UpdateStorageVersions tries to update the StorageVersions of the recorded resources + UpdateStorageVersions(kubeAPIServerClientConfig *rest.Config, apiserverID string) + // PendingUpdate returns true if the StorageVersion of the given resource is still pending update. + PendingUpdate(gr schema.GroupResource) bool + // LastUpdateError returns the last error hit when updating the storage version of the given resource. + LastUpdateError(gr schema.GroupResource) error + // Completed returns true if updating StorageVersions of all recorded resources has completed. + Completed() bool +} + +var _ Manager = &defaultManager{} + +// defaultManager indicates if an apiserver has completed reporting its storage versions. +type defaultManager struct { + completed atomic.Bool + + mu sync.RWMutex + // managedResourceInfos records the ResourceInfos whose StorageVersions will get updated in the next + // UpdateStorageVersions call + managedResourceInfos map[*ResourceInfo]struct{} + // managedStatus records the update status of StorageVersion for each GroupResource. Since one + // ResourceInfo may expand into multiple GroupResource (e.g. ingresses.networking.k8s.io and ingresses.extensions), + // this map allows quick status lookup for a GroupResource, during API request handling. + managedStatus map[schema.GroupResource]*updateStatus +} + +type updateStatus struct { + done bool + lastErr error +} + +// NewDefaultManager creates a new defaultManager. +func NewDefaultManager() Manager { + s := &defaultManager{} + s.completed.Store(false) + s.managedResourceInfos = make(map[*ResourceInfo]struct{}) + s.managedStatus = make(map[schema.GroupResource]*updateStatus) + return s +} + +// AddResourceInfo adds ResourceInfo to the manager. +func (s *defaultManager) AddResourceInfo(resources ...*ResourceInfo) { + s.mu.Lock() + defer s.mu.Unlock() + for _, r := range resources { + s.managedResourceInfos[r] = struct{}{} + s.addPendingManagedStatusLocked(r) + } +} + +func (s *defaultManager) addPendingManagedStatusLocked(r *ResourceInfo) { + gvrs := r.EquivalentResourceMapper.EquivalentResourcesFor(r.GroupResource.WithVersion(""), "") + for _, gvr := range gvrs { + gr := gvr.GroupResource() + if _, ok := s.managedStatus[gr]; !ok { + s.managedStatus[gr] = &updateStatus{} + } + } +} + +// UpdateStorageVersions tries to update the StorageVersions of the recorded resources +func (s *defaultManager) UpdateStorageVersions(kubeAPIServerClientConfig *rest.Config, serverID string) { + clientset, err := kubernetes.NewForConfig(kubeAPIServerClientConfig) + if err != nil { + utilruntime.HandleError(fmt.Errorf("failed to get clientset: %v", err)) + return + } + sc := clientset.InternalV1alpha1().StorageVersions() + + s.mu.RLock() + resources := []ResourceInfo{} + for resource := range s.managedResourceInfos { + resources = append(resources, *resource) + } + s.mu.RUnlock() + hasFailure := false + // Sorting the list to make sure we have a consistent dedup result, and + // therefore avoid creating unnecessarily duplicated StorageVersion objects. + // For example, extensions.ingresses and networking.k8s.io.ingresses share + // the same underlying storage. Without sorting, in an HA cluster, one + // apiserver may dedup and update StorageVersion for extensions.ingresses, + // while another apiserver may dedup and update StorageVersion for + // networking.k8s.io.ingresses. The storage migrator (which migrates objects + // per GroupResource) will migrate these resources twice, since both + // StorageVersion objects have CommonEncodingVersion (each with one server registered). + sortResourceInfosByGroupResource(resources) + for _, r := range dedupResourceInfos(resources) { + decodableVersions := decodableVersions(r.DirectlyDecodableVersions, r.EquivalentResourceMapper, r.GroupResource) + gr := r.GroupResource + // Group must be a valid subdomain in DNS (RFC 1123) + if len(gr.Group) == 0 { + gr.Group = "core" + } + if err := updateStorageVersionFor(sc, serverID, gr, r.EncodingVersion, decodableVersions); err != nil { + utilruntime.HandleError(fmt.Errorf("failed to update storage version for %v: %v", r.GroupResource, err)) + s.recordStatusFailure(&r, err) + hasFailure = true + continue + } + klog.V(2).Infof("successfully updated storage version for %v", r.GroupResource) + s.recordStatusSuccess(&r) + } + if hasFailure { + return + } + klog.V(2).Infof("storage version updates complete") + s.setComplete() +} + +// dedupResourceInfos dedups ResourceInfos with the same underlying storage. +// ResourceInfos from the same Group with different Versions share the same underlying storage. +// ResourceInfos from different Groups may share the same underlying storage, e.g. +// networking.k8s.io ingresses and extensions ingresses. The StorageVersion manager +// only needs to update one StorageVersion for the equivalent Groups. +func dedupResourceInfos(infos []ResourceInfo) []ResourceInfo { + var ret []ResourceInfo + seen := make(map[schema.GroupResource]struct{}) + for _, info := range infos { + gr := info.GroupResource + if _, ok := seen[gr]; ok { + continue + } + gvrs := info.EquivalentResourceMapper.EquivalentResourcesFor(gr.WithVersion(""), "") + for _, gvr := range gvrs { + seen[gvr.GroupResource()] = struct{}{} + } + ret = append(ret, info) + } + return ret +} + +func sortResourceInfosByGroupResource(infos []ResourceInfo) { + sort.Sort(byGroupResource(infos)) +} + +type byGroupResource []ResourceInfo + +func (s byGroupResource) Len() int { return len(s) } + +func (s byGroupResource) Less(i, j int) bool { + if s[i].GroupResource.Group == s[j].GroupResource.Group { + return s[i].GroupResource.Resource < s[j].GroupResource.Resource + } + return s[i].GroupResource.Group < s[j].GroupResource.Group +} + +func (s byGroupResource) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// recordStatusSuccess marks updated ResourceInfo as completed. +func (s *defaultManager) recordStatusSuccess(r *ResourceInfo) { + s.mu.Lock() + defer s.mu.Unlock() + s.recordStatusSuccessLocked(r) +} + +func (s *defaultManager) recordStatusSuccessLocked(r *ResourceInfo) { + gvrs := r.EquivalentResourceMapper.EquivalentResourcesFor(r.GroupResource.WithVersion(""), "") + for _, gvr := range gvrs { + s.recordSuccessGroupResourceLocked(gvr.GroupResource()) + } +} + +func (s *defaultManager) recordSuccessGroupResourceLocked(gr schema.GroupResource) { + if _, ok := s.managedStatus[gr]; !ok { + return + } + s.managedStatus[gr].done = true + s.managedStatus[gr].lastErr = nil +} + +// recordStatusFailure records latest error updating ResourceInfo. +func (s *defaultManager) recordStatusFailure(r *ResourceInfo, err error) { + s.mu.Lock() + defer s.mu.Unlock() + s.recordStatusFailureLocked(r, err) +} + +func (s *defaultManager) recordStatusFailureLocked(r *ResourceInfo, err error) { + gvrs := r.EquivalentResourceMapper.EquivalentResourcesFor(r.GroupResource.WithVersion(""), "") + for _, gvr := range gvrs { + s.recordErrorGroupResourceLocked(gvr.GroupResource(), err) + } +} + +func (s *defaultManager) recordErrorGroupResourceLocked(gr schema.GroupResource, err error) { + if _, ok := s.managedStatus[gr]; !ok { + return + } + s.managedStatus[gr].lastErr = err +} + +// PendingUpdate returns if the StorageVersion of a resource is still wait to be updated. +func (s *defaultManager) PendingUpdate(gr schema.GroupResource) bool { + s.mu.RLock() + defer s.mu.RUnlock() + if _, ok := s.managedStatus[gr]; !ok { + return false + } + return !s.managedStatus[gr].done +} + +// LastUpdateError returns the last error hit when updating the storage version of the given resource. +func (s *defaultManager) LastUpdateError(gr schema.GroupResource) error { + s.mu.RLock() + defer s.mu.RUnlock() + if _, ok := s.managedStatus[gr]; !ok { + return fmt.Errorf("couldn't find managed status for %v", gr) + } + return s.managedStatus[gr].lastErr +} + +// setComplete marks the completion of updating StorageVersions. No write requests need to be blocked anymore. +func (s *defaultManager) setComplete() { + s.completed.Store(true) +} + +// Completed returns if updating StorageVersions has completed. +func (s *defaultManager) Completed() bool { + return s.completed.Load() +} + +func decodableVersions(directlyDecodableVersions []schema.GroupVersion, e runtime.EquivalentResourceRegistry, gr schema.GroupResource) []string { + var versions []string + for _, decodableVersions := range directlyDecodableVersions { + versions = append(versions, decodableVersions.String()) + } + + decodingGVRs := e.EquivalentResourcesFor(gr.WithVersion(""), "") + for _, v := range decodingGVRs { + found := false + for _, existingVersion := range versions { + if existingVersion == v.GroupVersion().String() { + found = true + } + } + if found { + continue + } + versions = append(versions, v.GroupVersion().String()) + } + return versions +} diff --git a/vendor/k8s.io/apiserver/pkg/storageversion/updater.go b/vendor/k8s.io/apiserver/pkg/storageversion/updater.go new file mode 100644 index 000000000..ce4d87e91 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storageversion/updater.go @@ -0,0 +1,196 @@ +/* +Copyright 2020 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 storageversion + +import ( + "context" + "fmt" + "time" + + "k8s.io/api/apiserverinternal/v1alpha1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/klog/v2" +) + +// Client has the methods required to update the storage version. +type Client interface { + Create(context.Context, *v1alpha1.StorageVersion, metav1.CreateOptions) (*v1alpha1.StorageVersion, error) + UpdateStatus(context.Context, *v1alpha1.StorageVersion, metav1.UpdateOptions) (*v1alpha1.StorageVersion, error) + Get(context.Context, string, metav1.GetOptions) (*v1alpha1.StorageVersion, error) +} + +// SetCommonEncodingVersion updates the CommonEncodingVersion and the AllEncodingVersionsEqual +// condition based on the StorageVersions. +func SetCommonEncodingVersion(sv *v1alpha1.StorageVersion) { + var oldCommonEncodingVersion *string + if sv.Status.CommonEncodingVersion != nil { + version := *sv.Status.CommonEncodingVersion + oldCommonEncodingVersion = &version + } + sv.Status.CommonEncodingVersion = nil + if len(sv.Status.StorageVersions) != 0 { + firstVersion := sv.Status.StorageVersions[0].EncodingVersion + agreed := true + for _, ssv := range sv.Status.StorageVersions { + if ssv.EncodingVersion != firstVersion { + agreed = false + break + } + } + if agreed { + sv.Status.CommonEncodingVersion = &firstVersion + } + } + + condition := v1alpha1.StorageVersionCondition{ + Type: v1alpha1.AllEncodingVersionsEqual, + Status: v1alpha1.ConditionFalse, + ObservedGeneration: sv.Generation, + LastTransitionTime: metav1.NewTime(time.Now()), + Reason: "CommonEncodingVersionUnset", + Message: "Common encoding version unset", + } + if sv.Status.CommonEncodingVersion != nil { + condition.Status = v1alpha1.ConditionTrue + condition.Reason = "CommonEncodingVersionSet" + condition.Message = "Common encoding version set" + } + forceTransition := false + if oldCommonEncodingVersion != nil && sv.Status.CommonEncodingVersion != nil && + *oldCommonEncodingVersion != *sv.Status.CommonEncodingVersion { + forceTransition = true + } + setStatusCondition(&sv.Status.Conditions, condition, forceTransition) +} + +func findStatusCondition(conditions []v1alpha1.StorageVersionCondition, + conditionType v1alpha1.StorageVersionConditionType) *v1alpha1.StorageVersionCondition { + for i := range conditions { + if conditions[i].Type == conditionType { + return &conditions[i] + } + } + return nil +} + +// setStatusCondition sets the corresponding condition in conditions to newCondition. +// conditions must be non-nil. +// 1. if the condition of the specified type already exists: all fields of the existing condition are updated to +// newCondition, LastTransitionTime is set to now if the new status differs from the old status +// 2. if a condition of the specified type does not exist: LastTransitionTime is set to now() if unset, +// and newCondition is appended +// +// NOTE: forceTransition allows overwriting LastTransitionTime even when the status doesn't change. +func setStatusCondition(conditions *[]v1alpha1.StorageVersionCondition, newCondition v1alpha1.StorageVersionCondition, + forceTransition bool) { + if conditions == nil { + return + } + + if newCondition.LastTransitionTime.IsZero() { + newCondition.LastTransitionTime = metav1.NewTime(time.Now()) + } + existingCondition := findStatusCondition(*conditions, newCondition.Type) + if existingCondition == nil { + *conditions = append(*conditions, newCondition) + return + } + + statusChanged := existingCondition.Status != newCondition.Status + if statusChanged || forceTransition { + existingCondition.LastTransitionTime = newCondition.LastTransitionTime + } + existingCondition.Status = newCondition.Status + existingCondition.Reason = newCondition.Reason + existingCondition.Message = newCondition.Message + existingCondition.ObservedGeneration = newCondition.ObservedGeneration +} + +// updateStorageVersionFor updates the storage version object for the resource. +func updateStorageVersionFor(c Client, apiserverID string, gr schema.GroupResource, encodingVersion string, decodableVersions []string) error { + retries := 3 + var retry int + var err error + for retry < retries { + err = singleUpdate(c, apiserverID, gr, encodingVersion, decodableVersions) + if err == nil { + return nil + } + if apierrors.IsAlreadyExists(err) || apierrors.IsConflict(err) { + time.Sleep(1 * time.Second) + continue + } + if err != nil { + klog.Errorf("retry %d, failed to update storage version for %v: %v", retry, gr, err) + retry++ + time.Sleep(1 * time.Second) + } + } + return err +} + +func singleUpdate(c Client, apiserverID string, gr schema.GroupResource, encodingVersion string, decodableVersions []string) error { + shouldCreate := false + name := fmt.Sprintf("%s.%s", gr.Group, gr.Resource) + sv, err := c.Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + if apierrors.IsNotFound(err) { + shouldCreate = true + sv = &v1alpha1.StorageVersion{} + sv.ObjectMeta.Name = name + } + updatedSV := localUpdateStorageVersion(sv, apiserverID, encodingVersion, decodableVersions) + if shouldCreate { + createdSV, err := c.Create(context.TODO(), updatedSV, metav1.CreateOptions{}) + if err != nil { + return err + } + // assign the calculated status to the object just created, then update status + createdSV.Status = updatedSV.Status + _, err = c.UpdateStatus(context.TODO(), createdSV, metav1.UpdateOptions{}) + return err + } + _, err = c.UpdateStatus(context.TODO(), updatedSV, metav1.UpdateOptions{}) + return err +} + +// localUpdateStorageVersion updates the input storageversion with given server storageversion info. +// The function updates the input storageversion in place. +func localUpdateStorageVersion(sv *v1alpha1.StorageVersion, apiserverID, encodingVersion string, decodableVersions []string) *v1alpha1.StorageVersion { + newSSV := v1alpha1.ServerStorageVersion{ + APIServerID: apiserverID, + EncodingVersion: encodingVersion, + DecodableVersions: decodableVersions, + } + foundSSV := false + for i, ssv := range sv.Status.StorageVersions { + if ssv.APIServerID == apiserverID { + sv.Status.StorageVersions[i] = newSSV + foundSSV = true + break + } + } + if !foundSSV { + sv.Status.StorageVersions = append(sv.Status.StorageVersions, newSSV) + } + SetCommonEncodingVersion(sv) + return sv +} diff --git a/vendor/k8s.io/apiserver/pkg/util/apihelpers/helpers.go b/vendor/k8s.io/apiserver/pkg/util/apihelpers/helpers.go new file mode 100644 index 000000000..ffc1a0e40 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/apihelpers/helpers.go @@ -0,0 +1,100 @@ +/* +Copyright 2019 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 apihelpers + +import ( + "sort" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" +) + +// SetFlowSchemaCondition sets conditions. +func SetFlowSchemaCondition(flowSchema *flowcontrol.FlowSchema, newCondition flowcontrol.FlowSchemaCondition) { + existingCondition := GetFlowSchemaConditionByType(flowSchema, newCondition.Type) + if existingCondition == nil { + flowSchema.Status.Conditions = append(flowSchema.Status.Conditions, newCondition) + return + } + + if existingCondition.Status != newCondition.Status { + existingCondition.Status = newCondition.Status + existingCondition.LastTransitionTime = newCondition.LastTransitionTime + } + + existingCondition.Reason = newCondition.Reason + existingCondition.Message = newCondition.Message +} + +// GetFlowSchemaConditionByType gets conditions. +func GetFlowSchemaConditionByType(flowSchema *flowcontrol.FlowSchema, conditionType flowcontrol.FlowSchemaConditionType) *flowcontrol.FlowSchemaCondition { + for i := range flowSchema.Status.Conditions { + if flowSchema.Status.Conditions[i].Type == conditionType { + return &flowSchema.Status.Conditions[i] + } + } + return nil +} + +// SetPriorityLevelConfigurationCondition sets conditions. +func SetPriorityLevelConfigurationCondition(priorityLevel *flowcontrol.PriorityLevelConfiguration, newCondition flowcontrol.PriorityLevelConfigurationCondition) { + existingCondition := GetPriorityLevelConfigurationConditionByType(priorityLevel, newCondition.Type) + if existingCondition == nil { + priorityLevel.Status.Conditions = append(priorityLevel.Status.Conditions, newCondition) + return + } + + if existingCondition.Status != newCondition.Status { + existingCondition.Status = newCondition.Status + existingCondition.LastTransitionTime = newCondition.LastTransitionTime + } + + existingCondition.Reason = newCondition.Reason + existingCondition.Message = newCondition.Message +} + +// GetPriorityLevelConfigurationConditionByType gets conditions. +func GetPriorityLevelConfigurationConditionByType(priorityLevel *flowcontrol.PriorityLevelConfiguration, conditionType flowcontrol.PriorityLevelConfigurationConditionType) *flowcontrol.PriorityLevelConfigurationCondition { + for i := range priorityLevel.Status.Conditions { + if priorityLevel.Status.Conditions[i].Type == conditionType { + return &priorityLevel.Status.Conditions[i] + } + } + return nil +} + +var _ sort.Interface = FlowSchemaSequence{} + +// FlowSchemaSequence holds sorted set of pointers to FlowSchema objects. +// FlowSchemaSequence implements `sort.Interface` +type FlowSchemaSequence []*flowcontrol.FlowSchema + +func (s FlowSchemaSequence) Len() int { + return len(s) +} + +func (s FlowSchemaSequence) Less(i, j int) bool { + // the flow-schema w/ lower matching-precedence is prior + if ip, jp := s[i].Spec.MatchingPrecedence, s[j].Spec.MatchingPrecedence; ip != jp { + return ip < jp + } + // sort alphabetically + return s[i].Name < s[j].Name +} + +func (s FlowSchemaSequence) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} diff --git a/vendor/k8s.io/apiserver/pkg/util/dryrun/dryrun.go b/vendor/k8s.io/apiserver/pkg/util/dryrun/dryrun.go new file mode 100644 index 000000000..3e28c2934 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/dryrun/dryrun.go @@ -0,0 +1,22 @@ +/* +Copyright 2018 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 dryrun + +// IsDryRun returns true if the DryRun flag is an actual dry-run. +func IsDryRun(flag []string) bool { + return len(flag) > 0 +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/OWNERS b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/OWNERS new file mode 100644 index 000000000..2556c589f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/OWNERS @@ -0,0 +1,15 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - lavalamp + - deads2k + - yue9944882 + - MikeSpreitzer +reviewers: + - lavalamp + - deads2k + - yue9944882 + - MikeSpreitzer +labels: + - sig/api-machinery + - area/apiserver diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_context.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_context.go new file mode 100644 index 000000000..1cd59049d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_context.go @@ -0,0 +1,93 @@ +/* +Copyright 2021 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 flowcontrol + +import ( + "context" + "sync" +) + +type priorityAndFairnessKeyType int + +const ( + // priorityAndFairnessInitializationSignalKey is a key under which + // initialization signal function for watch requests is stored + // in the context. + priorityAndFairnessInitializationSignalKey priorityAndFairnessKeyType = iota +) + +// WithInitializationSignal creates a copy of parent context with +// priority and fairness initialization signal value. +func WithInitializationSignal(ctx context.Context, signal InitializationSignal) context.Context { + return context.WithValue(ctx, priorityAndFairnessInitializationSignalKey, signal) +} + +// initializationSignalFrom returns an initialization signal function +// which when called signals that watch initialization has already finished +// to priority and fairness dispatcher. +func initializationSignalFrom(ctx context.Context) (InitializationSignal, bool) { + signal, ok := ctx.Value(priorityAndFairnessInitializationSignalKey).(InitializationSignal) + return signal, ok && signal != nil +} + +// WatchInitialized sends a signal to priority and fairness dispatcher +// that a given watch request has already been initialized. +func WatchInitialized(ctx context.Context) { + if signal, ok := initializationSignalFrom(ctx); ok { + signal.Signal() + } +} + +// RequestDelegated informs the priority and fairness dispatcher that +// a given request has been delegated to an aggregated API +// server. No-op when priority and fairness is disabled. +func RequestDelegated(ctx context.Context) { + // The watch initialization signal doesn't traverse request + // boundaries, so we generously fire it as soon as we know + // that the request won't be serviced locally. Safe to call + // for non-watch requests. + WatchInitialized(ctx) +} + +// InitializationSignal is an interface that allows sending and handling +// initialization signals. +type InitializationSignal interface { + // Signal notifies the dispatcher about finished initialization. + Signal() + // Wait waits for the initialization signal. + Wait() +} + +type initializationSignal struct { + once sync.Once + done chan struct{} +} + +func NewInitializationSignal() InitializationSignal { + return &initializationSignal{ + once: sync.Once{}, + done: make(chan struct{}), + } +} + +func (i *initializationSignal) Signal() { + i.once.Do(func() { close(i.done) }) +} + +func (i *initializationSignal) Wait() { + <-i.done +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go new file mode 100644 index 000000000..5718dd9e8 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go @@ -0,0 +1,1109 @@ +/* +Copyright 2019 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 flowcontrol + +import ( + "context" + "crypto/sha256" + "encoding/binary" + "errors" + "fmt" + "math" + "math/rand" + "sort" + "sync" + "time" + + "github.com/google/go-cmp/cmp" + apiequality "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + fcboot "k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/util/apihelpers" + fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" + fcfmt "k8s.io/apiserver/pkg/util/flowcontrol/format" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog/v2" + "k8s.io/utils/clock" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" + flowcontrolapplyconfiguration "k8s.io/client-go/applyconfigurations/flowcontrol/v1beta3" + flowcontrolclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3" + flowcontrollister "k8s.io/client-go/listers/flowcontrol/v1beta3" +) + +const timeFmt = "2006-01-02T15:04:05.999" + +// This file contains a simple local (to the apiserver) controller +// that digests API Priority and Fairness config objects (FlowSchema +// and PriorityLevelConfiguration) into the data structure that the +// filter uses. At this first level of development this controller +// takes the simplest possible approach: whenever notified of any +// change to any config object, or when any priority level that is +// undesired becomes completely unused, all the config objects are +// read and processed as a whole. + +const ( + // Borrowing among priority levels will be accomplished by periodically + // adjusting the current concurrency limits (CurrentCLs); + // borrowingAdjustmentPeriod is that period. + borrowingAdjustmentPeriod = 10 * time.Second + + // The input to the seat borrowing is smoothed seat demand figures. + // This constant controls the decay rate of that smoothing, + // as described in the comment on the `seatDemandStats` field of `priorityLevelState`. + // The particular number appearing here has the property that half-life + // of that decay is 5 minutes. + // This is a very preliminary guess at a good value and is likely to be tweaked + // once we get some experience with borrowing. + seatDemandSmoothingCoefficient = 0.977 +) + +// The funcs in this package follow the naming convention that the suffix +// "Locked" means the relevant mutex must be locked at the start of each +// call and will be locked upon return. For a configController, the +// suffix "ReadLocked" stipulates a read lock while just "Locked" +// stipulates a full lock. Absence of either suffix means that either +// (a) the lock must NOT be held at call time and will not be held +// upon return or (b) locking is irrelevant. + +// StartFunction begins the process of handling a request. If the +// request gets queued then this function uses the given hashValue as +// the source of entropy as it shuffle-shards the request into a +// queue. The descr1 and descr2 values play no role in the logic but +// appear in log messages. This method does not return until the +// queuing, if any, for this request is done. If `execute` is false +// then `afterExecution` is irrelevant and the request should be +// rejected. Otherwise the request should be executed and +// `afterExecution` must be called exactly once. +type StartFunction func(ctx context.Context, hashValue uint64) (execute bool, afterExecution func()) + +// RequestDigest holds necessary info from request for flow-control +type RequestDigest struct { + RequestInfo *request.RequestInfo + User user.Info +} + +// `*configController` maintains eventual consistency with the API +// objects that configure API Priority and Fairness, and provides a +// procedural interface to the configured behavior. The methods of +// this type and cfgMeal follow the convention that the suffix +// "Locked" means that the caller must hold the configController lock. +type configController struct { + name string // varies in tests of fighting controllers + clock clock.PassiveClock + queueSetFactory fq.QueueSetFactory + reqsGaugeVec metrics.RatioedGaugeVec + execSeatsGaugeVec metrics.RatioedGaugeVec + + // How this controller appears in an ObjectMeta ManagedFieldsEntry.Manager + asFieldManager string + + // Given a boolean indicating whether a FlowSchema's referenced + // PriorityLevelConfig exists, return a boolean indicating whether + // the reference is dangling + foundToDangling func(bool) bool + + // configQueue holds `(interface{})(0)` when the configuration + // objects need to be reprocessed. + configQueue workqueue.RateLimitingInterface + + plLister flowcontrollister.PriorityLevelConfigurationLister + plInformerSynced cache.InformerSynced + + fsLister flowcontrollister.FlowSchemaLister + fsInformerSynced cache.InformerSynced + + flowcontrolClient flowcontrolclient.FlowcontrolV1beta3Interface + + // serverConcurrencyLimit is the limit on the server's total + // number of non-exempt requests being served at once. This comes + // from server configuration. + serverConcurrencyLimit int + + // requestWaitLimit comes from server configuration. + requestWaitLimit time.Duration + + // watchTracker implements the necessary WatchTracker interface. + WatchTracker + + // the most recent update attempts, ordered by increasing age. + // Consumer trims to keep only the last minute's worth of entries. + // The controller uses this to limit itself to at most six updates + // to a given FlowSchema in any minute. + // This may only be accessed from the one and only worker goroutine. + mostRecentUpdates []updateAttempt + + // This must be locked while accessing the later fields. + // A lock for writing is needed + // for writing to any of the following: + // - the flowSchemas field + // - the slice held in the flowSchemas field + // - the priorityLevelStates field + // - the map held in the priorityLevelStates field + // - any field of a priorityLevelState held in that map + lock sync.RWMutex + + // flowSchemas holds the flow schema objects, sorted by increasing + // numerical (decreasing logical) matching precedence. Every + // FlowSchema in this slice is immutable. + flowSchemas apihelpers.FlowSchemaSequence + + // priorityLevelStates maps the PriorityLevelConfiguration object + // name to the state for that level. Every name referenced from a + // member of `flowSchemas` has an entry here. + priorityLevelStates map[string]*priorityLevelState + + // nominalCLSum is the sum of the nominalCL fields in the priorityLevelState records. + // This can exceed serverConcurrencyLimit because of the deliberate rounding up + // in the computation of the nominalCL values. + // This is tracked because it is an input to the allocation adjustment algorithm. + nominalCLSum int +} + +type updateAttempt struct { + timeUpdated time.Time + updatedItems sets.String // FlowSchema names +} + +// priorityLevelState holds the state specific to a priority level. +type priorityLevelState struct { + // the API object or prototype prescribing this level. Nothing + // reached through this pointer is mutable. + pl *flowcontrol.PriorityLevelConfiguration + + // qsCompleter holds the QueueSetCompleter derived from `config` + // and `queues` if config is not exempt, nil otherwise. + qsCompleter fq.QueueSetCompleter + + // The QueueSet for this priority level. This is nil if and only + // if the priority level is exempt. + queues fq.QueueSet + + // quiescing==true indicates that this priority level should be + // removed when its queues have all drained. May be true only if + // queues is non-nil. + quiescing bool + + // number of goroutines between Controller::Match and calling the + // returned StartFunction + numPending int + + // Observers tracking number of requests waiting, executing + reqsGaugePair metrics.RatioedGaugePair + + // Observer of number of seats occupied throughout execution + execSeatsObs metrics.RatioedGauge + + // Integrator of seat demand, reset every CurrentCL adjustment period + seatDemandIntegrator fq.Integrator + + // Gauge of seat demand / nominalCL + seatDemandRatioedGauge metrics.RatioedGauge + + // seatDemandStats is derived from periodically examining the seatDemandIntegrator. + // The average, standard deviation, and high watermark come directly from the integrator. + // envelope = avg + stdDev. + // Periodically smoothed gets replaced with `max(envelope, A*smoothed + (1-A)*envelope)`, + // where A is seatDemandSmoothingCoefficient. + seatDemandStats seatDemandStats + + // nominalCL is the nominal concurrency limit configured in the PriorityLevelConfiguration + nominalCL int + + // minCL is the nominal limit less the lendable amount + minCL int + + //maxCL is the nominal limit plus the amount that may be borrowed + maxCL int + + // currentCL is the dynamically derived concurrency limit to impose for now + currentCL int +} + +type seatDemandStats struct { + avg float64 + stdDev float64 + highWatermark float64 + smoothed float64 +} + +func (stats *seatDemandStats) update(obs fq.IntegratorResults) { + stats.avg = obs.Average + stats.stdDev = obs.Deviation + stats.highWatermark = obs.Max + envelope := obs.Average + obs.Deviation + stats.smoothed = math.Max(envelope, seatDemandSmoothingCoefficient*stats.smoothed+(1-seatDemandSmoothingCoefficient)*envelope) +} + +// NewTestableController is extra flexible to facilitate testing +func newTestableController(config TestableConfig) *configController { + cfgCtlr := &configController{ + name: config.Name, + clock: config.Clock, + queueSetFactory: config.QueueSetFactory, + reqsGaugeVec: config.ReqsGaugeVec, + execSeatsGaugeVec: config.ExecSeatsGaugeVec, + asFieldManager: config.AsFieldManager, + foundToDangling: config.FoundToDangling, + serverConcurrencyLimit: config.ServerConcurrencyLimit, + requestWaitLimit: config.RequestWaitLimit, + flowcontrolClient: config.FlowcontrolClient, + priorityLevelStates: make(map[string]*priorityLevelState), + WatchTracker: NewWatchTracker(), + } + klog.V(2).Infof("NewTestableController %q with serverConcurrencyLimit=%d, requestWaitLimit=%s, name=%s, asFieldManager=%q", cfgCtlr.name, cfgCtlr.serverConcurrencyLimit, cfgCtlr.requestWaitLimit, cfgCtlr.name, cfgCtlr.asFieldManager) + // Start with longish delay because conflicts will be between + // different processes, so take some time to go away. + cfgCtlr.configQueue = workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(200*time.Millisecond, 8*time.Hour), "priority_and_fairness_config_queue") + // ensure the data structure reflects the mandatory config + cfgCtlr.lockAndDigestConfigObjects(nil, nil) + fci := config.InformerFactory.Flowcontrol().V1beta3() + pli := fci.PriorityLevelConfigurations() + fsi := fci.FlowSchemas() + cfgCtlr.plLister = pli.Lister() + cfgCtlr.plInformerSynced = pli.Informer().HasSynced + cfgCtlr.fsLister = fsi.Lister() + cfgCtlr.fsInformerSynced = fsi.Informer().HasSynced + pli.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + pl := obj.(*flowcontrol.PriorityLevelConfiguration) + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to creation of PLC %s", cfgCtlr.name, pl.Name) + cfgCtlr.configQueue.Add(0) + }, + UpdateFunc: func(oldObj, newObj interface{}) { + newPL := newObj.(*flowcontrol.PriorityLevelConfiguration) + oldPL := oldObj.(*flowcontrol.PriorityLevelConfiguration) + if !apiequality.Semantic.DeepEqual(oldPL.Spec, newPL.Spec) { + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to spec update of PLC %s", cfgCtlr.name, newPL.Name) + cfgCtlr.configQueue.Add(0) + } else { + klog.V(7).Infof("No trigger API priority and fairness config reloading in %s due to spec non-change of PLC %s", cfgCtlr.name, newPL.Name) + } + }, + DeleteFunc: func(obj interface{}) { + name, _ := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to deletion of PLC %s", cfgCtlr.name, name) + cfgCtlr.configQueue.Add(0) + + }}) + fsi.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + fs := obj.(*flowcontrol.FlowSchema) + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to creation of FS %s", cfgCtlr.name, fs.Name) + cfgCtlr.configQueue.Add(0) + }, + UpdateFunc: func(oldObj, newObj interface{}) { + newFS := newObj.(*flowcontrol.FlowSchema) + oldFS := oldObj.(*flowcontrol.FlowSchema) + // Changes to either Spec or Status are relevant. The + // concern is that we might, in some future release, want + // different behavior than is implemented now. One of the + // hardest questions is how does an operator roll out the + // new release in a cluster with multiple kube-apiservers + // --- in a way that works no matter what servers crash + // and restart when. If this handler reacts only to + // changes in Spec then we have a scenario in which the + // rollout leaves the old Status in place. The scenario + // ends with this subsequence: deploy the last new server + // before deleting the last old server, and in between + // those two operations the last old server crashes and + // recovers. The chosen solution is making this controller + // insist on maintaining the particular state that it + // establishes. + if !(apiequality.Semantic.DeepEqual(oldFS.Spec, newFS.Spec) && + apiequality.Semantic.DeepEqual(oldFS.Status, newFS.Status)) { + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to spec and/or status update of FS %s", cfgCtlr.name, newFS.Name) + cfgCtlr.configQueue.Add(0) + } else { + klog.V(7).Infof("No trigger of API priority and fairness config reloading in %s due to spec and status non-change of FS %s", cfgCtlr.name, newFS.Name) + } + }, + DeleteFunc: func(obj interface{}) { + name, _ := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + klog.V(7).Infof("Triggered API priority and fairness config reloading in %s due to deletion of FS %s", cfgCtlr.name, name) + cfgCtlr.configQueue.Add(0) + + }}) + return cfgCtlr +} + +func (cfgCtlr *configController) Run(stopCh <-chan struct{}) error { + defer utilruntime.HandleCrash() + + // Let the config worker stop when we are done + defer cfgCtlr.configQueue.ShutDown() + + klog.Info("Starting API Priority and Fairness config controller") + if ok := cache.WaitForCacheSync(stopCh, cfgCtlr.plInformerSynced, cfgCtlr.fsInformerSynced); !ok { + return fmt.Errorf("Never achieved initial sync") + } + + klog.Info("Running API Priority and Fairness config worker") + go wait.Until(cfgCtlr.runWorker, time.Second, stopCh) + + klog.Info("Running API Priority and Fairness periodic rebalancing process") + go wait.Until(cfgCtlr.updateBorrowing, borrowingAdjustmentPeriod, stopCh) + + <-stopCh + klog.Info("Shutting down API Priority and Fairness config worker") + return nil +} + +func (cfgCtlr *configController) updateBorrowing() { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + cfgCtlr.updateBorrowingLocked(true, cfgCtlr.priorityLevelStates) +} + +func (cfgCtlr *configController) updateBorrowingLocked(setCompleters bool, plStates map[string]*priorityLevelState) { + items := make([]allocProblemItem, 0, len(plStates)) + plNames := make([]string, 0, len(plStates)) + for plName, plState := range plStates { + if plState.pl.Spec.Limited == nil { + continue + } + obs := plState.seatDemandIntegrator.Reset() + plState.seatDemandStats.update(obs) + // Lower bound on this priority level's adjusted concurreny limit is the lesser of: + // - its seat demamd high watermark over the last adjustment period, and + // - its configured concurrency limit. + // BUT: we do not want this to be lower than the lower bound from configuration. + // See KEP-1040 for a more detailed explanation. + minCurrentCL := math.Max(float64(plState.minCL), math.Min(float64(plState.nominalCL), plState.seatDemandStats.highWatermark)) + plNames = append(plNames, plName) + items = append(items, allocProblemItem{ + lowerBound: minCurrentCL, + upperBound: float64(plState.maxCL), + target: math.Max(minCurrentCL, plState.seatDemandStats.smoothed), + }) + } + if len(items) == 0 && cfgCtlr.nominalCLSum > 0 { + klog.ErrorS(nil, "Impossible: no non-exempt priority levels", "plStates", cfgCtlr.priorityLevelStates) + return + } + allocs, fairFrac, err := computeConcurrencyAllocation(cfgCtlr.nominalCLSum, items) + if err != nil { + klog.ErrorS(err, "Unable to derive new concurrency limits", "plNames", plNames, "items", items) + allocs = make([]float64, len(items)) + for idx, plName := range plNames { + plState := plStates[plName] + if plState.pl.Spec.Limited == nil { + continue + } + allocs[idx] = float64(plState.currentCL) + } + } + for idx, plName := range plNames { + plState := plStates[plName] + if plState.pl.Spec.Limited == nil { + continue + } + if setCompleters { + qsCompleter, err := queueSetCompleterForPL(cfgCtlr.queueSetFactory, plState.queues, + plState.pl, cfgCtlr.requestWaitLimit, plState.reqsGaugePair, plState.execSeatsObs, + metrics.NewUnionGauge(plState.seatDemandIntegrator, plState.seatDemandRatioedGauge)) + if err != nil { + klog.ErrorS(err, "Inconceivable! Configuration error in existing priority level", "pl", plState.pl) + continue + } + plState.qsCompleter = qsCompleter + } + currentCL := int(math.Round(float64(allocs[idx]))) + relChange := relDiff(float64(currentCL), float64(plState.currentCL)) + plState.currentCL = currentCL + metrics.NotePriorityLevelConcurrencyAdjustment(plState.pl.Name, plState.seatDemandStats.highWatermark, plState.seatDemandStats.avg, plState.seatDemandStats.stdDev, plState.seatDemandStats.smoothed, float64(items[idx].target), currentCL) + logLevel := klog.Level(4) + if relChange >= 0.05 { + logLevel = 2 + } + klog.V(logLevel).InfoS("Update CurrentCL", "plName", plName, "seatDemandHighWatermark", plState.seatDemandStats.highWatermark, "seatDemandAvg", plState.seatDemandStats.avg, "seatDemandStdev", plState.seatDemandStats.stdDev, "seatDemandSmoothed", plState.seatDemandStats.smoothed, "fairFrac", fairFrac, "currentCL", currentCL, "backstop", err != nil) + plState.queues = plState.qsCompleter.Complete(fq.DispatchingConfig{ConcurrencyLimit: currentCL}) + } + metrics.SetFairFrac(float64(fairFrac)) +} + +// runWorker is the logic of the one and only worker goroutine. We +// limit the number to one in order to obviate explicit +// synchronization around access to `cfgCtlr.mostRecentUpdates`. +func (cfgCtlr *configController) runWorker() { + for cfgCtlr.processNextWorkItem() { + } +} + +// processNextWorkItem works on one entry from the work queue. +// Only invoke this in the one and only worker goroutine. +func (cfgCtlr *configController) processNextWorkItem() bool { + obj, shutdown := cfgCtlr.configQueue.Get() + if shutdown { + return false + } + + func(obj interface{}) { + defer cfgCtlr.configQueue.Done(obj) + specificDelay, err := cfgCtlr.syncOne() + switch { + case err != nil: + klog.Error(err) + cfgCtlr.configQueue.AddRateLimited(obj) + case specificDelay > 0: + cfgCtlr.configQueue.AddAfter(obj, specificDelay) + default: + cfgCtlr.configQueue.Forget(obj) + } + }(obj) + + return true +} + +// syncOne does one full synchronization. It reads all the API +// objects that configure API Priority and Fairness and updates the +// local configController accordingly. +// Only invoke this in the one and only worker goroutine +func (cfgCtlr *configController) syncOne() (specificDelay time.Duration, err error) { + klog.V(5).Infof("%s syncOne at %s", cfgCtlr.name, cfgCtlr.clock.Now().Format(timeFmt)) + all := labels.Everything() + newPLs, err := cfgCtlr.plLister.List(all) + if err != nil { + return 0, fmt.Errorf("unable to list PriorityLevelConfiguration objects: %w", err) + } + newFSs, err := cfgCtlr.fsLister.List(all) + if err != nil { + return 0, fmt.Errorf("unable to list FlowSchema objects: %w", err) + } + return cfgCtlr.digestConfigObjects(newPLs, newFSs) +} + +// cfgMeal is the data involved in the process of digesting the API +// objects that configure API Priority and Fairness. All the config +// objects are digested together, because this is the simplest way to +// cope with the various dependencies between objects. The process of +// digestion is done in four passes over config objects --- three +// passes over PriorityLevelConfigurations and one pass over the +// FlowSchemas --- with the work dvided among the passes according to +// those dependencies. +type cfgMeal struct { + cfgCtlr *configController + + newPLStates map[string]*priorityLevelState + + // The sum of the concurrency shares of the priority levels in the + // new configuration + shareSum float64 + + // These keep track of which mandatory priority level config + // objects have been digested + haveExemptPL, haveCatchAllPL bool + + // Buffered FlowSchema status updates to do. Do them when the + // lock is not held, to avoid a deadlock due to such a request + // provoking a call into this controller while the lock held + // waiting on that request to complete. + fsStatusUpdates []fsStatusUpdate + + maxWaitingRequests, maxExecutingRequests int +} + +// A buffered set of status updates for FlowSchemas +type fsStatusUpdate struct { + flowSchema *flowcontrol.FlowSchema + condition flowcontrol.FlowSchemaCondition + oldValue flowcontrol.FlowSchemaCondition +} + +// digestConfigObjects is given all the API objects that configure +// cfgCtlr and writes its consequent new configState. +// Only invoke this in the one and only worker goroutine +func (cfgCtlr *configController) digestConfigObjects(newPLs []*flowcontrol.PriorityLevelConfiguration, newFSs []*flowcontrol.FlowSchema) (time.Duration, error) { + fsStatusUpdates := cfgCtlr.lockAndDigestConfigObjects(newPLs, newFSs) + var errs []error + currResult := updateAttempt{ + timeUpdated: cfgCtlr.clock.Now(), + updatedItems: sets.String{}, + } + var suggestedDelay time.Duration + for _, fsu := range fsStatusUpdates { + // if we should skip this name, indicate we will need a delay, but continue with other entries + if cfgCtlr.shouldDelayUpdate(fsu.flowSchema.Name) { + if suggestedDelay == 0 { + suggestedDelay = time.Duration(30+rand.Intn(45)) * time.Second + } + continue + } + + // if we are going to issue an update, be sure we track every name we update so we know if we update it too often. + currResult.updatedItems.Insert(fsu.flowSchema.Name) + if klogV := klog.V(4); klogV.Enabled() { + klogV.Infof("%s writing Condition %s to FlowSchema %s, which had ResourceVersion=%s, because its previous value was %s, diff: %s", + cfgCtlr.name, fsu.condition, fsu.flowSchema.Name, fsu.flowSchema.ResourceVersion, fcfmt.Fmt(fsu.oldValue), cmp.Diff(fsu.oldValue, fsu.condition)) + } + + if err := apply(cfgCtlr.flowcontrolClient.FlowSchemas(), fsu, cfgCtlr.asFieldManager); err != nil { + if apierrors.IsNotFound(err) { + // This object has been deleted. A notification is coming + // and nothing more needs to be done here. + klog.V(5).Infof("%s at %s: attempted update of concurrently deleted FlowSchema %s; nothing more needs to be done", cfgCtlr.name, cfgCtlr.clock.Now().Format(timeFmt), fsu.flowSchema.Name) + } else { + errs = append(errs, fmt.Errorf("failed to set a status.condition for FlowSchema %s: %w", fsu.flowSchema.Name, err)) + } + } + } + cfgCtlr.addUpdateResult(currResult) + + return suggestedDelay, utilerrors.NewAggregate(errs) +} + +func apply(client flowcontrolclient.FlowSchemaInterface, fsu fsStatusUpdate, asFieldManager string) error { + applyOptions := metav1.ApplyOptions{FieldManager: asFieldManager, Force: true} + + // the condition field in fsStatusUpdate holds the new condition we want to update. + // TODO: this will break when we have multiple conditions for a flowschema + _, err := client.ApplyStatus(context.TODO(), toFlowSchemaApplyConfiguration(fsu), applyOptions) + return err +} + +func toFlowSchemaApplyConfiguration(fsUpdate fsStatusUpdate) *flowcontrolapplyconfiguration.FlowSchemaApplyConfiguration { + condition := flowcontrolapplyconfiguration.FlowSchemaCondition(). + WithType(fsUpdate.condition.Type). + WithStatus(fsUpdate.condition.Status). + WithReason(fsUpdate.condition.Reason). + WithLastTransitionTime(fsUpdate.condition.LastTransitionTime). + WithMessage(fsUpdate.condition.Message) + + return flowcontrolapplyconfiguration.FlowSchema(fsUpdate.flowSchema.Name). + WithStatus(flowcontrolapplyconfiguration.FlowSchemaStatus(). + WithConditions(condition), + ) +} + +// shouldDelayUpdate checks to see if a flowschema has been updated too often and returns true if a delay is needed. +// Only invoke this in the one and only worker goroutine +func (cfgCtlr *configController) shouldDelayUpdate(flowSchemaName string) bool { + numUpdatesInPastMinute := 0 + oneMinuteAgo := cfgCtlr.clock.Now().Add(-1 * time.Minute) + for idx, update := range cfgCtlr.mostRecentUpdates { + if oneMinuteAgo.After(update.timeUpdated) { + // this and the remaining items are no longer relevant + cfgCtlr.mostRecentUpdates = cfgCtlr.mostRecentUpdates[:idx] + return false + } + if update.updatedItems.Has(flowSchemaName) { + numUpdatesInPastMinute++ + if numUpdatesInPastMinute > 5 { + return true + } + } + } + return false +} + +// addUpdateResult adds the result. It isn't a ring buffer because +// this is small and rate limited. +// Only invoke this in the one and only worker goroutine +func (cfgCtlr *configController) addUpdateResult(result updateAttempt) { + cfgCtlr.mostRecentUpdates = append([]updateAttempt{result}, cfgCtlr.mostRecentUpdates...) +} + +func (cfgCtlr *configController) lockAndDigestConfigObjects(newPLs []*flowcontrol.PriorityLevelConfiguration, newFSs []*flowcontrol.FlowSchema) []fsStatusUpdate { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + meal := cfgMeal{ + cfgCtlr: cfgCtlr, + newPLStates: make(map[string]*priorityLevelState), + } + + meal.digestNewPLsLocked(newPLs) + meal.digestFlowSchemasLocked(newFSs) + meal.processOldPLsLocked() + + // Supply missing mandatory PriorityLevelConfiguration objects + if !meal.haveExemptPL { + meal.imaginePL(fcboot.MandatoryPriorityLevelConfigurationExempt, cfgCtlr.requestWaitLimit) + } + if !meal.haveCatchAllPL { + meal.imaginePL(fcboot.MandatoryPriorityLevelConfigurationCatchAll, cfgCtlr.requestWaitLimit) + } + + meal.finishQueueSetReconfigsLocked() + + // The new config has been constructed + cfgCtlr.priorityLevelStates = meal.newPLStates + klog.V(5).InfoS("Switched to new API Priority and Fairness configuration", "maxWaitingRequests", meal.maxWaitingRequests, "maxExecutinRequests", meal.maxExecutingRequests) + + metrics.GetWaitingReadonlyConcurrency().SetDenominator(float64(meal.maxWaitingRequests)) + metrics.GetWaitingMutatingConcurrency().SetDenominator(float64(meal.maxWaitingRequests)) + metrics.GetExecutingReadonlyConcurrency().SetDenominator(float64(meal.maxExecutingRequests)) + metrics.GetExecutingMutatingConcurrency().SetDenominator(float64(meal.maxExecutingRequests)) + + return meal.fsStatusUpdates +} + +// Digest the new set of PriorityLevelConfiguration objects. +// Pretend broken ones do not exist. +func (meal *cfgMeal) digestNewPLsLocked(newPLs []*flowcontrol.PriorityLevelConfiguration) { + for _, pl := range newPLs { + state := meal.cfgCtlr.priorityLevelStates[pl.Name] + if state == nil { + labelValues := []string{pl.Name} + state = &priorityLevelState{ + reqsGaugePair: metrics.RatioedGaugeVecPhasedElementPair(meal.cfgCtlr.reqsGaugeVec, 1, 1, labelValues), + execSeatsObs: meal.cfgCtlr.execSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelValues), + seatDemandIntegrator: fq.NewNamedIntegrator(meal.cfgCtlr.clock, pl.Name), + seatDemandRatioedGauge: metrics.ApiserverSeatDemands.NewForLabelValuesSafe(0, 1, []string{pl.Name}), + } + } + qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, state.queues, + pl, meal.cfgCtlr.requestWaitLimit, state.reqsGaugePair, state.execSeatsObs, + metrics.NewUnionGauge(state.seatDemandIntegrator, state.seatDemandRatioedGauge)) + if err != nil { + klog.Warningf("Ignoring PriorityLevelConfiguration object %s because its spec (%s) is broken: %s", pl.Name, fcfmt.Fmt(pl.Spec), err) + continue + } + meal.newPLStates[pl.Name] = state + state.pl = pl + state.qsCompleter = qsCompleter + if state.quiescing { // it was undesired, but no longer + klog.V(3).Infof("Priority level %q was undesired and has become desired again", pl.Name) + state.quiescing = false + } + if state.pl.Spec.Limited != nil { + meal.shareSum += float64(state.pl.Spec.Limited.NominalConcurrencyShares) + } + meal.haveExemptPL = meal.haveExemptPL || pl.Name == flowcontrol.PriorityLevelConfigurationNameExempt + meal.haveCatchAllPL = meal.haveCatchAllPL || pl.Name == flowcontrol.PriorityLevelConfigurationNameCatchAll + } +} + +// Digest the given FlowSchema objects. Ones that reference a missing +// or broken priority level are not to be passed on to the filter for +// use. We do this before holding over old priority levels so that +// requests stop going to those levels and FlowSchemaStatus values +// reflect this. This function also adds any missing mandatory +// FlowSchema objects. The given objects must all have distinct +// names. +func (meal *cfgMeal) digestFlowSchemasLocked(newFSs []*flowcontrol.FlowSchema) { + fsSeq := make(apihelpers.FlowSchemaSequence, 0, len(newFSs)) + fsMap := make(map[string]*flowcontrol.FlowSchema, len(newFSs)) + var haveExemptFS, haveCatchAllFS bool + for i, fs := range newFSs { + otherFS := fsMap[fs.Name] + if otherFS != nil { + // This client is forbidden to do this. + panic(fmt.Sprintf("Given two FlowSchema objects with the same name: %s and %s", fcfmt.Fmt(otherFS), fcfmt.Fmt(fs))) + } + fsMap[fs.Name] = fs + _, goodPriorityRef := meal.newPLStates[fs.Spec.PriorityLevelConfiguration.Name] + + // Ensure the object's status reflects whether its priority + // level reference is broken. + // + // TODO: consider not even trying if server is not handling + // requests yet. + meal.presyncFlowSchemaStatus(fs, meal.cfgCtlr.foundToDangling(goodPriorityRef), fs.Spec.PriorityLevelConfiguration.Name) + + if !goodPriorityRef { + klog.V(6).Infof("Ignoring FlowSchema %s because of bad priority level reference %q", fs.Name, fs.Spec.PriorityLevelConfiguration.Name) + continue + } + fsSeq = append(fsSeq, newFSs[i]) + haveExemptFS = haveExemptFS || fs.Name == flowcontrol.FlowSchemaNameExempt + haveCatchAllFS = haveCatchAllFS || fs.Name == flowcontrol.FlowSchemaNameCatchAll + } + // sort into the order to be used for matching + sort.Sort(fsSeq) + + // Supply missing mandatory FlowSchemas, in correct position + if !haveExemptFS { + fsSeq = append(apihelpers.FlowSchemaSequence{fcboot.MandatoryFlowSchemaExempt}, fsSeq...) + } + if !haveCatchAllFS { + fsSeq = append(fsSeq, fcboot.MandatoryFlowSchemaCatchAll) + } + + meal.cfgCtlr.flowSchemas = fsSeq + klogV := klog.V(5) + if klogV.Enabled() { + for _, fs := range fsSeq { + klogV.Infof("Using FlowSchema %s", fcfmt.Fmt(fs)) + } + } +} + +// Consider all the priority levels in the previous configuration. +// Keep the ones that are in the new config, supply mandatory +// behavior, or are still busy; for the rest: drop it if it has no +// queues, otherwise start the quiescing process if that has not +// already been started. +func (meal *cfgMeal) processOldPLsLocked() { + for plName, plState := range meal.cfgCtlr.priorityLevelStates { + if meal.newPLStates[plName] != nil { + // Still desired and already updated + continue + } + if plName == flowcontrol.PriorityLevelConfigurationNameExempt && !meal.haveExemptPL || plName == flowcontrol.PriorityLevelConfigurationNameCatchAll && !meal.haveCatchAllPL { + // BTW, we know the Spec has not changed because the + // mandatory objects have immutable Specs + klog.V(3).Infof("Retaining mandatory priority level %q despite lack of API object", plName) + } else { + if plState.queues == nil || plState.numPending == 0 && plState.queues.IsIdle() { + // Either there are no queues or they are done + // draining and no use is coming from another + // goroutine + klog.V(3).Infof("Removing undesired priority level %q (nilQueues=%v), Type=%v", plName, plState.queues == nil, plState.pl.Spec.Type) + continue + } + if !plState.quiescing { + klog.V(3).Infof("Priority level %q became undesired", plName) + plState.quiescing = true + } + } + var err error + plState.qsCompleter, err = queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, plState.queues, + plState.pl, meal.cfgCtlr.requestWaitLimit, plState.reqsGaugePair, plState.execSeatsObs, + metrics.NewUnionGauge(plState.seatDemandIntegrator, plState.seatDemandRatioedGauge)) + if err != nil { + // This can not happen because queueSetCompleterForPL already approved this config + panic(fmt.Sprintf("%s from name=%q spec=%s", err, plName, fcfmt.Fmt(plState.pl.Spec))) + } + if plState.pl.Spec.Limited != nil { + // We deliberately include the lingering priority levels + // here so that their queues get some concurrency and they + // continue to drain. During this interim a lingering + // priority level continues to get a concurrency + // allocation determined by all the share values in the + // regular way. + meal.shareSum += float64(plState.pl.Spec.Limited.NominalConcurrencyShares) + } + meal.haveExemptPL = meal.haveExemptPL || plName == flowcontrol.PriorityLevelConfigurationNameExempt + meal.haveCatchAllPL = meal.haveCatchAllPL || plName == flowcontrol.PriorityLevelConfigurationNameCatchAll + meal.newPLStates[plName] = plState + } +} + +// For all the priority levels of the new config, divide up the +// server's total concurrency limit among them and create/update their +// QueueSets. +func (meal *cfgMeal) finishQueueSetReconfigsLocked() { + for plName, plState := range meal.newPLStates { + if plState.pl.Spec.Limited == nil { + klog.V(5).Infof("Using exempt priority level %q: quiescing=%v", plName, plState.quiescing) + continue + } + + limited := plState.pl.Spec.Limited + // The use of math.Ceil here means that the results might sum + // to a little more than serverConcurrencyLimit but the + // difference will be negligible. + concurrencyLimit := int(math.Ceil(float64(meal.cfgCtlr.serverConcurrencyLimit) * float64(limited.NominalConcurrencyShares) / meal.shareSum)) + var lendableCL, borrowingCL int + if limited.LendablePercent != nil { + lendableCL = int(math.Round(float64(concurrencyLimit) * float64(*limited.LendablePercent) / 100)) + } + if limited.BorrowingLimitPercent != nil { + borrowingCL = int(math.Round(float64(concurrencyLimit) * float64(*limited.BorrowingLimitPercent) / 100)) + } else { + borrowingCL = meal.cfgCtlr.serverConcurrencyLimit + } + metrics.SetPriorityLevelConfiguration(plName, concurrencyLimit, concurrencyLimit-lendableCL, concurrencyLimit+borrowingCL) + plState.seatDemandRatioedGauge.SetDenominator(float64(concurrencyLimit)) + cfgChanged := plState.nominalCL != concurrencyLimit || plState.minCL != concurrencyLimit-lendableCL || plState.maxCL != concurrencyLimit+borrowingCL + plState.nominalCL = concurrencyLimit + plState.minCL = concurrencyLimit - lendableCL + plState.maxCL = concurrencyLimit + borrowingCL + meal.maxExecutingRequests += concurrencyLimit + var waitLimit int + if qCfg := limited.LimitResponse.Queuing; qCfg != nil { + waitLimit = int(qCfg.Queues * qCfg.QueueLengthLimit) + } + meal.maxWaitingRequests += waitLimit + + if plState.queues == nil { + initialCL := concurrencyLimit - lendableCL/2 + klog.V(2).Infof("Introducing queues for priority level %q: config=%s, nominalCL=%d, lendableCL=%d, borrowingCL=%d, currentCL=%d, quiescing=%v (shares=%v, shareSum=%v)", plName, fcfmt.Fmt(plState.pl.Spec), concurrencyLimit, lendableCL, borrowingCL, initialCL, plState.quiescing, plState.pl.Spec.Limited.NominalConcurrencyShares, meal.shareSum) + plState.seatDemandStats = seatDemandStats{} + plState.currentCL = initialCL + } else { + logLevel := klog.Level(5) + if cfgChanged { + logLevel = 2 + } + klog.V(logLevel).Infof("Retaining queues for priority level %q: config=%s, nominalCL=%d, lendableCL=%d, borrowingCL=%d, currentCL=%d, quiescing=%v, numPending=%d (shares=%v, shareSum=%v)", plName, fcfmt.Fmt(plState.pl.Spec), concurrencyLimit, lendableCL, borrowingCL, plState.currentCL, plState.quiescing, plState.numPending, plState.pl.Spec.Limited.NominalConcurrencyShares, meal.shareSum) + } + } + meal.cfgCtlr.nominalCLSum = meal.maxExecutingRequests + meal.cfgCtlr.updateBorrowingLocked(false, meal.newPLStates) +} + +// queueSetCompleterForPL returns an appropriate QueueSetCompleter for the +// given priority level configuration. Returns nil if that config +// does not call for limiting. Returns nil and an error if the given +// object is malformed in a way that is a problem for this package. +func queueSetCompleterForPL(qsf fq.QueueSetFactory, queues fq.QueueSet, pl *flowcontrol.PriorityLevelConfiguration, requestWaitLimit time.Duration, reqsIntPair metrics.RatioedGaugePair, execSeatsObs metrics.RatioedGauge, seatDemandGauge metrics.Gauge) (fq.QueueSetCompleter, error) { + if (pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt) != (pl.Spec.Limited == nil) { + return nil, errors.New("broken union structure at the top") + } + if (pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt) != (pl.Name == flowcontrol.PriorityLevelConfigurationNameExempt) { + // This package does not attempt to cope with a priority level dynamically switching between exempt and not. + return nil, errors.New("non-alignment between name and type") + } + if pl.Spec.Limited == nil { + return nil, nil + } + if (pl.Spec.Limited.LimitResponse.Type == flowcontrol.LimitResponseTypeReject) != (pl.Spec.Limited.LimitResponse.Queuing == nil) { + return nil, errors.New("broken union structure for limit response") + } + qcAPI := pl.Spec.Limited.LimitResponse.Queuing + qcQS := fq.QueuingConfig{Name: pl.Name} + if qcAPI != nil { + qcQS = fq.QueuingConfig{Name: pl.Name, + DesiredNumQueues: int(qcAPI.Queues), + QueueLengthLimit: int(qcAPI.QueueLengthLimit), + HandSize: int(qcAPI.HandSize), + RequestWaitLimit: requestWaitLimit, + } + } + var qsc fq.QueueSetCompleter + var err error + if queues != nil { + qsc, err = queues.BeginConfigChange(qcQS) + } else { + qsc, err = qsf.BeginConstruction(qcQS, reqsIntPair, execSeatsObs, seatDemandGauge) + } + if err != nil { + err = fmt.Errorf("priority level %q has QueuingConfiguration %#+v, which is invalid: %w", pl.Name, qcAPI, err) + } + return qsc, err +} + +func (meal *cfgMeal) presyncFlowSchemaStatus(fs *flowcontrol.FlowSchema, isDangling bool, plName string) { + danglingCondition := apihelpers.GetFlowSchemaConditionByType(fs, flowcontrol.FlowSchemaConditionDangling) + if danglingCondition == nil { + danglingCondition = &flowcontrol.FlowSchemaCondition{ + Type: flowcontrol.FlowSchemaConditionDangling, + } + } + desiredStatus := flowcontrol.ConditionFalse + var desiredReason, desiredMessage string + if isDangling { + desiredStatus = flowcontrol.ConditionTrue + desiredReason = "NotFound" + desiredMessage = fmt.Sprintf("This FlowSchema references the PriorityLevelConfiguration object named %q but there is no such object", plName) + } else { + desiredReason = "Found" + desiredMessage = fmt.Sprintf("This FlowSchema references the PriorityLevelConfiguration object named %q and it exists", plName) + } + if danglingCondition.Status == desiredStatus && danglingCondition.Reason == desiredReason && danglingCondition.Message == desiredMessage { + return + } + now := meal.cfgCtlr.clock.Now() + meal.fsStatusUpdates = append(meal.fsStatusUpdates, fsStatusUpdate{ + flowSchema: fs, + condition: flowcontrol.FlowSchemaCondition{ + Type: flowcontrol.FlowSchemaConditionDangling, + Status: desiredStatus, + LastTransitionTime: metav1.NewTime(now), + Reason: desiredReason, + Message: desiredMessage, + }, + oldValue: *danglingCondition}) +} + +// imaginePL adds a priority level based on one of the mandatory ones +// that does not actually exist (right now) as a real API object. +func (meal *cfgMeal) imaginePL(proto *flowcontrol.PriorityLevelConfiguration, requestWaitLimit time.Duration) { + klog.V(3).Infof("No %s PriorityLevelConfiguration found, imagining one", proto.Name) + labelValues := []string{proto.Name} + reqsGaugePair := metrics.RatioedGaugeVecPhasedElementPair(meal.cfgCtlr.reqsGaugeVec, 1, 1, labelValues) + execSeatsObs := meal.cfgCtlr.execSeatsGaugeVec.NewForLabelValuesSafe(0, 1, labelValues) + seatDemandIntegrator := fq.NewNamedIntegrator(meal.cfgCtlr.clock, proto.Name) + seatDemandRatioedGauge := metrics.ApiserverSeatDemands.NewForLabelValuesSafe(0, 1, []string{proto.Name}) + qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, nil, proto, + requestWaitLimit, reqsGaugePair, execSeatsObs, + metrics.NewUnionGauge(seatDemandIntegrator, seatDemandRatioedGauge)) + if err != nil { + // This can not happen because proto is one of the mandatory + // objects and these are not erroneous + panic(err) + } + meal.newPLStates[proto.Name] = &priorityLevelState{ + pl: proto, + qsCompleter: qsCompleter, + reqsGaugePair: reqsGaugePair, + execSeatsObs: execSeatsObs, + seatDemandIntegrator: seatDemandIntegrator, + seatDemandRatioedGauge: seatDemandRatioedGauge, + } + if proto.Spec.Limited != nil { + meal.shareSum += float64(proto.Spec.Limited.NominalConcurrencyShares) + } +} + +type immediateRequest struct{} + +func (immediateRequest) Finish(execute func()) bool { + execute() + return false +} + +// startRequest classifies and, if appropriate, enqueues the request. +// Returns a nil Request if and only if the request is to be rejected. +// The returned bool indicates whether the request is exempt from +// limitation. The startWaitingTime is when the request started +// waiting in its queue, or `Time{}` if this did not happen. +func (cfgCtlr *configController) startRequest(ctx context.Context, rd RequestDigest, + noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, flowDistinguisher string), + workEstimator func() fcrequest.WorkEstimate, + queueNoteFn fq.QueueNoteFn) (fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, isExempt bool, req fq.Request, startWaitingTime time.Time) { + klog.V(7).Infof("startRequest(%#+v)", rd) + cfgCtlr.lock.RLock() + defer cfgCtlr.lock.RUnlock() + var selectedFlowSchema, catchAllFlowSchema *flowcontrol.FlowSchema + for _, fs := range cfgCtlr.flowSchemas { + if matchesFlowSchema(rd, fs) { + selectedFlowSchema = fs + break + } + if fs.Name == flowcontrol.FlowSchemaNameCatchAll { + catchAllFlowSchema = fs + } + } + if selectedFlowSchema == nil { + // This should never happen. If the requestDigest's User is a part of + // system:authenticated or system:unauthenticated, the catch-all flow + // schema should match it. However, if that invariant somehow fails, + // fallback to the catch-all flow schema anyway. + if catchAllFlowSchema == nil { + // This should absolutely never, ever happen! APF guarantees two + // undeletable flow schemas at all times: an exempt flow schema and a + // catch-all flow schema. + panic(fmt.Sprintf("no fallback catch-all flow schema found for request %#+v and user %#+v", rd.RequestInfo, rd.User)) + } + selectedFlowSchema = catchAllFlowSchema + klog.Warningf("no match found for request %#+v and user %#+v; selecting catchAll=%s as fallback flow schema", rd.RequestInfo, rd.User, fcfmt.Fmt(selectedFlowSchema)) + } + plName := selectedFlowSchema.Spec.PriorityLevelConfiguration.Name + plState := cfgCtlr.priorityLevelStates[plName] + if plState.pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt { + noteFn(selectedFlowSchema, plState.pl, "") + klog.V(7).Infof("startRequest(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, immediate", rd, selectedFlowSchema.Name, selectedFlowSchema.Spec.DistinguisherMethod, plName) + return selectedFlowSchema, plState.pl, true, immediateRequest{}, time.Time{} + } + var numQueues int32 + if plState.pl.Spec.Limited.LimitResponse.Type == flowcontrol.LimitResponseTypeQueue { + numQueues = plState.pl.Spec.Limited.LimitResponse.Queuing.Queues + } + var flowDistinguisher string + var hashValue uint64 + if numQueues > 1 { + flowDistinguisher = computeFlowDistinguisher(rd, selectedFlowSchema.Spec.DistinguisherMethod) + hashValue = hashFlowID(selectedFlowSchema.Name, flowDistinguisher) + } + + noteFn(selectedFlowSchema, plState.pl, flowDistinguisher) + workEstimate := workEstimator() + + startWaitingTime = time.Now() + klog.V(7).Infof("startRequest(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, numQueues=%d", rd, selectedFlowSchema.Name, selectedFlowSchema.Spec.DistinguisherMethod, plName, numQueues) + req, idle := plState.queues.StartRequest(ctx, &workEstimate, hashValue, flowDistinguisher, selectedFlowSchema.Name, rd.RequestInfo, rd.User, queueNoteFn) + if idle { + cfgCtlr.maybeReapReadLocked(plName, plState) + } + return selectedFlowSchema, plState.pl, false, req, startWaitingTime +} + +// maybeReap will remove the last internal traces of the named +// priority level if it has no more use. Call this after getting a +// clue that the given priority level is undesired and idle. +func (cfgCtlr *configController) maybeReap(plName string) { + cfgCtlr.lock.RLock() + defer cfgCtlr.lock.RUnlock() + plState := cfgCtlr.priorityLevelStates[plName] + if plState == nil { + klog.V(7).Infof("plName=%s, plState==nil", plName) + return + } + if plState.queues == nil { + klog.V(7).Infof("plName=%s, plState.queues==nil", plName) + return + } + useless := plState.quiescing && plState.numPending == 0 && plState.queues.IsIdle() + klog.V(7).Infof("plState.quiescing=%v, plState.numPending=%d, useless=%v", plState.quiescing, plState.numPending, useless) + if !useless { + return + } + klog.V(3).Infof("Triggered API priority and fairness config reloading because priority level %s is undesired and idle", plName) + cfgCtlr.configQueue.Add(0) +} + +// maybeReapLocked requires the cfgCtlr's lock to already be held and +// will remove the last internal traces of the named priority level if +// it has no more use. Call this if both (1) plState.queues is +// non-nil and reported being idle, and (2) cfgCtlr's lock has not +// been released since then. +func (cfgCtlr *configController) maybeReapReadLocked(plName string, plState *priorityLevelState) { + if !(plState.quiescing && plState.numPending == 0) { + return + } + klog.V(3).Infof("Triggered API priority and fairness config reloading because priority level %s is undesired and idle", plName) + cfgCtlr.configQueue.Add(0) +} + +// computeFlowDistinguisher extracts the flow distinguisher according to the given method +func computeFlowDistinguisher(rd RequestDigest, method *flowcontrol.FlowDistinguisherMethod) string { + if method == nil { + return "" + } + switch method.Type { + case flowcontrol.FlowDistinguisherMethodByUserType: + return rd.User.GetName() + case flowcontrol.FlowDistinguisherMethodByNamespaceType: + return rd.RequestInfo.Namespace + default: + // this line shall never reach + panic("invalid flow-distinguisher method") + } +} + +func hashFlowID(fsName, fDistinguisher string) uint64 { + hash := sha256.New() + var sep = [1]byte{0} + hash.Write([]byte(fsName)) + hash.Write(sep[:]) + hash.Write([]byte(fDistinguisher)) + var sum [32]byte + hash.Sum(sum[:0]) + return binary.LittleEndian.Uint64(sum[:8]) +} + +func relDiff(x, y float64) float64 { + diff := math.Abs(x - y) + den := math.Max(math.Abs(x), math.Abs(y)) + if den == 0 { + return 0 + } + return diff / den +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go new file mode 100644 index 000000000..91c49a4be --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go @@ -0,0 +1,265 @@ +/* +Copyright 2019 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 flowcontrol + +import ( + "fmt" + "io" + "net/http" + "strconv" + "strings" + "text/tabwriter" + "time" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apiserver/pkg/server/mux" +) + +const ( + queryIncludeRequestDetails = "includeRequestDetails" +) + +func (cfgCtlr *configController) Install(c *mux.PathRecorderMux) { + // TODO(yue9944882): handle "Accept" header properly + // debugging dumps a CSV content for three levels of granularity + // 1. row per priority-level + c.UnlistedHandleFunc("/debug/api_priority_and_fairness/dump_priority_levels", cfgCtlr.dumpPriorityLevels) + // 2. row per queue + c.UnlistedHandleFunc("/debug/api_priority_and_fairness/dump_queues", cfgCtlr.dumpQueues) + // 3. row per request + c.UnlistedHandleFunc("/debug/api_priority_and_fairness/dump_requests", cfgCtlr.dumpRequests) +} + +func (cfgCtlr *configController) dumpPriorityLevels(w http.ResponseWriter, r *http.Request) { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + tabWriter := tabwriter.NewWriter(w, 8, 0, 1, ' ', 0) + columnHeaders := []string{ + "PriorityLevelName", // 1 + "ActiveQueues", // 2 + "IsIdle", // 3 + "IsQuiescing", // 4 + "WaitingRequests", // 5 + "ExecutingRequests", // 6 + } + tabPrint(tabWriter, rowForHeaders(columnHeaders)) + endLine(tabWriter) + for _, plState := range cfgCtlr.priorityLevelStates { + if plState.queues == nil { + tabPrint(tabWriter, row( + plState.pl.Name, // 1 + "", // 2 + "", // 3 + "", // 4 + "", // 5 + "", // 6 + )) + endLine(tabWriter) + continue + } + queueSetDigest := plState.queues.Dump(false) + activeQueueNum := 0 + for _, q := range queueSetDigest.Queues { + if len(q.Requests) > 0 { + activeQueueNum++ + } + } + + tabPrint(tabWriter, rowForPriorityLevel( + plState.pl.Name, // 1 + activeQueueNum, // 2 + plState.queues.IsIdle(), // 3 + plState.quiescing, // 4 + queueSetDigest.Waiting, // 5 + queueSetDigest.Executing, // 6 + )) + endLine(tabWriter) + } + runtime.HandleError(tabWriter.Flush()) +} + +func (cfgCtlr *configController) dumpQueues(w http.ResponseWriter, r *http.Request) { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + tabWriter := tabwriter.NewWriter(w, 8, 0, 1, ' ', 0) + columnHeaders := []string{ + "PriorityLevelName", // 1 + "Index", // 2 + "PendingRequests", // 3 + "ExecutingRequests", // 4 + "SeatsInUse", // 5 + "NextDispatchR", // 6 + "InitialSeatsSum", // 7 + "MaxSeatsSum", // 8 + "TotalWorkSum", // 9 + } + tabPrint(tabWriter, rowForHeaders(columnHeaders)) + endLine(tabWriter) + for _, plState := range cfgCtlr.priorityLevelStates { + if plState.queues == nil { + tabPrint(tabWriter, row( + plState.pl.Name, // 1 + "", // 2 + "", // 3 + "", // 4 + "", // 5 + "", // 6 + "", // 7 + "", // 8 + "", // 9 + )) + endLine(tabWriter) + continue + } + queueSetDigest := plState.queues.Dump(false) + for i, q := range queueSetDigest.Queues { + tabPrint(tabWriter, row( + plState.pl.Name, // 1 - "PriorityLevelName" + strconv.Itoa(i), // 2 - "Index" + strconv.Itoa(len(q.Requests)), // 3 - "PendingRequests" + strconv.Itoa(q.ExecutingRequests), // 4 - "ExecutingRequests" + strconv.Itoa(q.SeatsInUse), // 5 - "SeatsInUse" + q.NextDispatchR, // 6 - "NextDispatchR" + strconv.Itoa(q.QueueSum.InitialSeatsSum), // 7 - "InitialSeatsSum" + strconv.Itoa(q.QueueSum.MaxSeatsSum), // 8 - "MaxSeatsSum" + q.QueueSum.TotalWorkSum, // 9 - "TotalWorkSum" + )) + endLine(tabWriter) + } + } + runtime.HandleError(tabWriter.Flush()) +} + +func (cfgCtlr *configController) dumpRequests(w http.ResponseWriter, r *http.Request) { + cfgCtlr.lock.Lock() + defer cfgCtlr.lock.Unlock() + + includeRequestDetails := len(r.URL.Query().Get(queryIncludeRequestDetails)) > 0 + + tabWriter := tabwriter.NewWriter(w, 8, 0, 1, ' ', 0) + tabPrint(tabWriter, rowForHeaders([]string{ + "PriorityLevelName", // 1 + "FlowSchemaName", // 2 + "QueueIndex", // 3 + "RequestIndexInQueue", // 4 + "FlowDistingsher", // 5 + "ArriveTime", // 6 + "InitialSeats", // 7 + "FinalSeats", // 8 + "AdditionalLatency", // 9 + })) + if includeRequestDetails { + continueLine(tabWriter) + tabPrint(tabWriter, rowForHeaders([]string{ + "UserName", // 10 + "Verb", // 11 + "APIPath", // 12 + "Namespace", // 13 + "Name", // 14 + "APIVersion", // 15 + "Resource", // 16 + "SubResource", // 17 + })) + } + endLine(tabWriter) + for _, plState := range cfgCtlr.priorityLevelStates { + if plState.queues == nil { + continue + } + queueSetDigest := plState.queues.Dump(includeRequestDetails) + for iq, q := range queueSetDigest.Queues { + for ir, r := range q.Requests { + tabPrint(tabWriter, row( + plState.pl.Name, // 1 + r.MatchedFlowSchema, // 2 + strconv.Itoa(iq), // 3 + strconv.Itoa(ir), // 4 + r.FlowDistinguisher, // 5 + r.ArriveTime.UTC().Format(time.RFC3339Nano), // 6 + strconv.Itoa(int(r.WorkEstimate.InitialSeats)), // 7 + strconv.Itoa(int(r.WorkEstimate.FinalSeats)), // 8 + r.WorkEstimate.AdditionalLatency.String(), // 9 + )) + if includeRequestDetails { + continueLine(tabWriter) + tabPrint(tabWriter, rowForRequestDetails( + r.UserName, // 10 + r.RequestInfo.Verb, // 11 + r.RequestInfo.Path, // 12 + r.RequestInfo.Namespace, // 13 + r.RequestInfo.Name, // 14 + schema.GroupVersion{ + Group: r.RequestInfo.APIGroup, + Version: r.RequestInfo.APIVersion, + }.String(), // 15 + r.RequestInfo.Resource, // 16 + r.RequestInfo.Subresource, // 17 + )) + } + endLine(tabWriter) + } + } + } + runtime.HandleError(tabWriter.Flush()) +} + +func tabPrint(w io.Writer, row string) { + _, err := fmt.Fprint(w, row) + runtime.HandleError(err) +} + +func continueLine(w io.Writer) { + _, err := fmt.Fprint(w, ",\t") + runtime.HandleError(err) +} +func endLine(w io.Writer) { + _, err := fmt.Fprint(w, "\n") + runtime.HandleError(err) +} + +func rowForHeaders(headers []string) string { + return row(headers...) +} + +func rowForPriorityLevel(plName string, activeQueues int, isIdle, isQuiescing bool, waitingRequests, executingRequests int) string { + return row( + plName, + strconv.Itoa(activeQueues), + strconv.FormatBool(isIdle), + strconv.FormatBool(isQuiescing), + strconv.Itoa(waitingRequests), + strconv.Itoa(executingRequests), + ) +} + +func rowForRequestDetails(username, verb, path, namespace, name, apiVersion, resource, subResource string) string { + return row( + username, + verb, + path, + namespace, + name, + apiVersion, + resource, + subResource, + ) +} + +func row(columns ...string) string { + return strings.Join(columns, ",\t") +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go new file mode 100644 index 000000000..037ac0db1 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go @@ -0,0 +1,197 @@ +/* +Copyright 2019 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 flowcontrol + +import ( + "context" + "strconv" + "time" + + "k8s.io/apiserver/pkg/server/httplog" + "k8s.io/apiserver/pkg/server/mux" + fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" + "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock" + fqs "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" + kubeinformers "k8s.io/client-go/informers" + "k8s.io/klog/v2" + "k8s.io/utils/clock" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" + flowcontrolclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta3" +) + +// ConfigConsumerAsFieldManager is how the config consuminng +// controller appears in an ObjectMeta ManagedFieldsEntry.Manager +const ConfigConsumerAsFieldManager = "api-priority-and-fairness-config-consumer-v1" + +// Interface defines how the API Priority and Fairness filter interacts with the underlying system. +type Interface interface { + // Handle takes care of queuing and dispatching a request + // characterized by the given digest. The given `noteFn` will be + // invoked with the results of request classification. + // The given `workEstimator` is called, if at all, after noteFn. + // `workEstimator` will be invoked only when the request + // is classified as non 'exempt'. + // 'workEstimator', when invoked, must return the + // work parameters for the request. + // If the request is queued then `queueNoteFn` will be called twice, + // first with `true` and then with `false`; otherwise + // `queueNoteFn` will not be called at all. If Handle decides + // that the request should be executed then `execute()` will be + // invoked once to execute the request; otherwise `execute()` will + // not be invoked. + // Handle() should never return while execute() is running, even if + // ctx is cancelled or times out. + Handle(ctx context.Context, + requestDigest RequestDigest, + noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, flowDistinguisher string), + workEstimator func() fcrequest.WorkEstimate, + queueNoteFn fq.QueueNoteFn, + execFn func(), + ) + + // Run monitors config objects from the main apiservers and causes + // any needed changes to local behavior. This method ceases + // activity and returns after the given channel is closed. + Run(stopCh <-chan struct{}) error + + // Install installs debugging endpoints to the web-server. + Install(c *mux.PathRecorderMux) + + // WatchTracker provides the WatchTracker interface. + WatchTracker +} + +// This request filter implements https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/1040-priority-and-fairness/README.md + +// New creates a new instance to implement API priority and fairness +func New( + informerFactory kubeinformers.SharedInformerFactory, + flowcontrolClient flowcontrolclient.FlowcontrolV1beta3Interface, + serverConcurrencyLimit int, + requestWaitLimit time.Duration, +) Interface { + clk := eventclock.Real{} + return NewTestable(TestableConfig{ + Name: "Controller", + Clock: clk, + AsFieldManager: ConfigConsumerAsFieldManager, + FoundToDangling: func(found bool) bool { return !found }, + InformerFactory: informerFactory, + FlowcontrolClient: flowcontrolClient, + ServerConcurrencyLimit: serverConcurrencyLimit, + RequestWaitLimit: requestWaitLimit, + ReqsGaugeVec: metrics.PriorityLevelConcurrencyGaugeVec, + ExecSeatsGaugeVec: metrics.PriorityLevelExecutionSeatsGaugeVec, + QueueSetFactory: fqs.NewQueueSetFactory(clk), + }) +} + +// TestableConfig carries the parameters to an implementation that is testable +type TestableConfig struct { + // Name of the controller + Name string + + // Clock to use in timing deliberate delays + Clock clock.PassiveClock + + // AsFieldManager is the string to use in the metadata for + // server-side apply. Normally this is + // `ConfigConsumerAsFieldManager`. This is exposed as a parameter + // so that a test of competing controllers can supply different + // values. + AsFieldManager string + + // FoundToDangling maps the boolean indicating whether a + // FlowSchema's referenced PLC exists to the boolean indicating + // that FlowSchema's status should indicate a dangling reference. + // This is a parameter so that we can write tests of what happens + // when servers disagree on that bit of Status. + FoundToDangling func(bool) bool + + // InformerFactory to use in building the controller + InformerFactory kubeinformers.SharedInformerFactory + + // FlowcontrolClient to use for manipulating config objects + FlowcontrolClient flowcontrolclient.FlowcontrolV1beta3Interface + + // ServerConcurrencyLimit for the controller to enforce + ServerConcurrencyLimit int + + // RequestWaitLimit configured on the server + RequestWaitLimit time.Duration + + // GaugeVec for metrics about requests, broken down by phase and priority_level + ReqsGaugeVec metrics.RatioedGaugeVec + + // RatioedGaugePairVec for metrics about seats occupied by all phases of execution + ExecSeatsGaugeVec metrics.RatioedGaugeVec + + // QueueSetFactory for the queuing implementation + QueueSetFactory fq.QueueSetFactory +} + +// NewTestable is extra flexible to facilitate testing +func NewTestable(config TestableConfig) Interface { + return newTestableController(config) +} + +func (cfgCtlr *configController) Handle(ctx context.Context, requestDigest RequestDigest, + noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, flowDistinguisher string), + workEstimator func() fcrequest.WorkEstimate, + queueNoteFn fq.QueueNoteFn, + execFn func()) { + fs, pl, isExempt, req, startWaitingTime := cfgCtlr.startRequest(ctx, requestDigest, noteFn, workEstimator, queueNoteFn) + queued := startWaitingTime != time.Time{} + if req == nil { + if queued { + metrics.ObserveWaitingDuration(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime)) + } + klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, reject", requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt) + return + } + klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, queued=%v", requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt, queued) + var executed bool + idle, panicking := true, true + defer func() { + klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, queued=%v, Finish() => panicking=%v idle=%v", + requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt, queued, panicking, idle) + if idle { + cfgCtlr.maybeReap(pl.Name) + } + }() + idle = req.Finish(func() { + if queued { + metrics.ObserveWaitingDuration(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime)) + } + metrics.AddDispatch(ctx, pl.Name, fs.Name) + executed = true + startExecutionTime := time.Now() + defer func() { + executionTime := time.Since(startExecutionTime) + httplog.AddKeyValue(ctx, "apf_execution_time", executionTime) + metrics.ObserveExecutionDuration(ctx, pl.Name, fs.Name, executionTime) + }() + execFn() + }) + if queued && !executed { + metrics.ObserveWaitingDuration(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime)) + } + panicking = false +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go new file mode 100644 index 000000000..436039071 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go @@ -0,0 +1,256 @@ +/* +Copyright 2022 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 flowcontrol + +import ( + "errors" + "fmt" + "math" + "sort" +) + +// allocProblemItem is one of the classes to which computeConcurrencyAllocation should make an allocation +type allocProblemItem struct { + target float64 + lowerBound float64 + upperBound float64 +} + +// relativeAllocItem is like allocProblemItem but with target avoiding zero and the bounds divided by the target +type relativeAllocItem struct { + target float64 + relativeLowerBound float64 + relativeUpperBound float64 +} + +// relativeAllocProblem collects together all the classes and holds the result of sorting by increasing bounds. +// For J <= K, ascendingIndices[J] identifies a bound that is <= the one of ascendingIndices[K]. +// When ascendingIndices[J] = 2*N + 0, this identifies the lower bound of items[N]. +// When ascendingIndices[J] = 2*N + 1, this identifies the upper bound of items[N]. +type relativeAllocProblem struct { + items []relativeAllocItem + ascendingIndices []int +} + +// initIndices fills in ascendingIndices and sorts them +func (rap *relativeAllocProblem) initIndices() *relativeAllocProblem { + rap.ascendingIndices = make([]int, len(rap.items)*2) + for idx := 0; idx < len(rap.ascendingIndices); idx++ { + rap.ascendingIndices[idx] = idx + } + sort.Sort(rap) + return rap +} + +func (rap *relativeAllocProblem) getItemIndex(idx int) (int, bool) { + packedIndex := rap.ascendingIndices[idx] + itemIndex := packedIndex / 2 + return itemIndex, packedIndex == itemIndex*2 +} + +// decode(J) returns the bound associated with ascendingIndices[J], the associated items index, +// and a bool indicating whether the bound is the item's lower bound. +func (rap *relativeAllocProblem) decode(idx int) (float64, int, bool) { + itemIdx, lower := rap.getItemIndex(idx) + if lower { + return rap.items[itemIdx].relativeLowerBound, itemIdx, lower + } + return rap.items[itemIdx].relativeUpperBound, itemIdx, lower +} + +func (rap *relativeAllocProblem) getProportion(idx int) float64 { + prop, _, _ := rap.decode(idx) + return prop +} + +func (rap *relativeAllocProblem) Len() int { return len(rap.items) * 2 } + +func (rap *relativeAllocProblem) Less(i, j int) bool { + return rap.getProportion(i) < rap.getProportion(j) +} + +func (rap *relativeAllocProblem) Swap(i, j int) { + rap.ascendingIndices[i], rap.ascendingIndices[j] = rap.ascendingIndices[j], rap.ascendingIndices[i] +} + +// minMax records the minimum and maximum value seen while scanning a set of numbers +type minMax struct { + min float64 + max float64 +} + +// note scans one more number +func (mm *minMax) note(x float64) { + mm.min = math.Min(mm.min, x) + mm.max = math.Max(mm.max, x) +} + +const MinTarget = 0.001 +const epsilon = 0.0000001 + +// computeConcurrencyAllocation returns the unique `allocs []float64`, and +// an associated `fairProp float64`, that jointly have +// all of the following properties (to the degree that floating point calculations allow) +// if possible otherwise returns an error saying why it is impossible. +// `allocs` sums to `requiredSum`. +// For each J in [0, len(classes)): +// (1) `classes[J].lowerBound <= allocs[J] <= classes[J].upperBound` and +// (2) exactly one of the following is true: +// (2a) `allocs[J] == fairProp * classes[J].target`, +// (2b) `allocs[J] == classes[J].lowerBound && classes[J].lowerBound > fairProp * classes[J].target`, or +// (2c) `allocs[J] == classes[J].upperBound && classes[J].upperBound < fairProp * classes[J].target`. +// Each allocProblemItem is required to have `target >= lowerBound >= 0` and `upperBound >= lowerBound`. +// A target smaller than MinTarget is treated as if it were MinTarget. +func computeConcurrencyAllocation(requiredSum int, classes []allocProblemItem) ([]float64, float64, error) { + if requiredSum < 0 { + return nil, 0, errors.New("negative sums are not supported") + } + requiredSumF := float64(requiredSum) + var lowSum, highSum, targetSum float64 + ubRange := minMax{min: float64(math.MaxFloat32)} + lbRange := minMax{min: float64(math.MaxFloat32)} + relativeItems := make([]relativeAllocItem, len(classes)) + for idx, item := range classes { + target := item.target + if item.lowerBound < 0 { + return nil, 0, fmt.Errorf("lower bound %d is %v but negative lower bounds are not allowed", idx, item.lowerBound) + } + if target < item.lowerBound { + return nil, 0, fmt.Errorf("target %d is %v, which is below its lower bound of %v", idx, target, item.lowerBound) + } + if item.upperBound < item.lowerBound { + return nil, 0, fmt.Errorf("upper bound %d is %v but should not be less than the lower bound %v", idx, item.upperBound, item.lowerBound) + } + if target < MinTarget { + // tweak this to a non-zero value so avoid dividing by zero + target = MinTarget + } + lowSum += item.lowerBound + highSum += item.upperBound + targetSum += target + relativeItem := relativeAllocItem{ + target: target, + relativeLowerBound: item.lowerBound / target, + relativeUpperBound: item.upperBound / target, + } + ubRange.note(relativeItem.relativeUpperBound) + lbRange.note(relativeItem.relativeLowerBound) + relativeItems[idx] = relativeItem + } + if lbRange.max > 1 { + return nil, 0, fmt.Errorf("lbRange.max-1=%v, which is impossible because lbRange.max can not be greater than 1", lbRange.max-1) + } + if lowSum-requiredSumF > epsilon { + return nil, 0, fmt.Errorf("lower bounds sum to %v, which is higher than the required sum of %v", lowSum, requiredSum) + } + if requiredSumF-highSum > epsilon { + return nil, 0, fmt.Errorf("upper bounds sum to %v, which is lower than the required sum of %v", highSum, requiredSum) + } + ans := make([]float64, len(classes)) + if requiredSum == 0 { + return ans, 0, nil + } + if lowSum-requiredSumF > -epsilon { // no wiggle room, constrained from below + for idx, item := range classes { + ans[idx] = item.lowerBound + } + return ans, lbRange.min, nil + } + if requiredSumF-highSum > -epsilon { // no wiggle room, constrained from above + for idx, item := range classes { + ans[idx] = item.upperBound + } + return ans, ubRange.max, nil + } + // Now we know the solution is a unique fairProp in [lbRange.min, ubRange.max]. + // See if the solution does not run into any bounds. + fairProp := requiredSumF / targetSum + if lbRange.max <= fairProp && fairProp <= ubRange.min { // no bounds matter + for idx := range classes { + ans[idx] = relativeItems[idx].target * fairProp + } + return ans, fairProp, nil + } + // Sadly, some bounds matter. + // We find the solution by sorting the bounds and considering progressively + // higher values of fairProp, starting from lbRange.min. + rap := (&relativeAllocProblem{items: relativeItems}).initIndices() + sumSoFar := lowSum + fairProp = lbRange.min + var sensitiveTargetSum, deltaSensitiveTargetSum float64 + var numSensitiveClasses, deltaSensitiveClasses int + var nextIdx int + // `nextIdx` is the next `rap` index to consider. + // `sumSoFar` is what the allocs would sum to if the current + // value of `fairProp` solves the problem. + // If the current value of fairProp were the answer then + // `sumSoFar == requiredSum`. + // Otherwise the next increment in fairProp involves changing the allocations + // of `numSensitiveClasses` classes whose targets sum to `sensitiveTargetSum`; + // for the other classes, an upper or lower bound has applied and will continue to apply. + // The last increment of nextIdx calls for adding `deltaSensitiveClasses` + // to `numSensitiveClasses` and adding `deltaSensitiveTargetSum` to `sensitiveTargetSum`. + for sumSoFar < requiredSumF { + // There might be more than one bound that is equal to the current value + // of fairProp; find all of them because they will all be relevant to + // the next change in fairProp. + // Set nextBound to the next bound that is NOT equal to fairProp, + // and advance nextIdx to the index of that bound. + var nextBound float64 + for { + sensitiveTargetSum += deltaSensitiveTargetSum + numSensitiveClasses += deltaSensitiveClasses + if nextIdx >= rap.Len() { + return nil, 0, fmt.Errorf("impossible: ran out of bounds to consider in bound-constrained problem") + } + var itemIdx int + var lower bool + nextBound, itemIdx, lower = rap.decode(nextIdx) + if lower { + deltaSensitiveClasses = 1 + deltaSensitiveTargetSum = rap.items[itemIdx].target + } else { + deltaSensitiveClasses = -1 + deltaSensitiveTargetSum = -rap.items[itemIdx].target + } + nextIdx++ + if nextBound > fairProp { + break + } + } + // fairProp can increase to nextBound without passing any intermediate bounds. + if numSensitiveClasses == 0 { + // No classes are affected by the next range of fairProp; skip right past it + fairProp = nextBound + continue + } + // See whether fairProp can increase to the solution before passing the next bound. + deltaFairProp := (requiredSumF - sumSoFar) / sensitiveTargetSum + nextProp := fairProp + deltaFairProp + if nextProp <= nextBound { + fairProp = nextProp + break + } + // No, fairProp has to increase above nextBound + sumSoFar += (nextBound - fairProp) * sensitiveTargetSum + fairProp = nextBound + } + for idx, item := range classes { + ans[idx] = math.Max(item.lowerBound, math.Min(item.upperBound, fairProp*relativeItems[idx].target)) + } + return ans, fairProp, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go new file mode 100644 index 000000000..439d48c45 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go @@ -0,0 +1,60 @@ +/* +Copyright 2016 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 debug + +import ( + "time" + + "k8s.io/apiserver/pkg/endpoints/request" + flowcontrolrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" +) + +// QueueSetDump is an instant dump of queue-set. +type QueueSetDump struct { + Queues []QueueDump + Waiting int + Executing int + SeatsInUse int + SeatsWaiting int +} + +// QueueDump is an instant dump of one queue in a queue-set. +type QueueDump struct { + QueueSum QueueSum + Requests []RequestDump + NextDispatchR string + ExecutingRequests int + SeatsInUse int +} + +type QueueSum struct { + InitialSeatsSum int + MaxSeatsSum int + TotalWorkSum string +} + +// RequestDump is an instant dump of one requests pending in the queue. +type RequestDump struct { + MatchedFlowSchema string + FlowDistinguisher string + ArriveTime time.Time + StartTime time.Time + WorkEstimate flowcontrolrequest.WorkEstimate + // request details + UserName string + RequestInfo request.RequestInfo +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/interface.go new file mode 100644 index 000000000..58f88b992 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/interface.go @@ -0,0 +1,47 @@ +/* +Copyright 2021 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 eventclock + +import ( + "time" + + baseclock "k8s.io/utils/clock" +) + +// EventFunc does some work that needs to be done at or after the +// given time. +type EventFunc func(time.Time) + +// EventClock is an active clock abstraction for use in code that is +// testable with a fake clock that itself determines how time may be +// advanced. The timing paradigm is invoking EventFuncs rather than +// synchronizing through channels, so that the fake clock has a handle +// on when associated activity is done. +type Interface interface { + baseclock.PassiveClock + + // Sleep returns after the given duration (or more). + Sleep(d time.Duration) + + // EventAfterDuration invokes the given EventFunc after the given duration (or more), + // passing the time when the invocation was launched. + EventAfterDuration(f EventFunc, d time.Duration) + + // EventAfterTime invokes the given EventFunc at the given time or later, + // passing the time when the invocation was launched. + EventAfterTime(f EventFunc, t time.Time) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/real.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/real.go new file mode 100644 index 000000000..d567a0f45 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock/real.go @@ -0,0 +1,44 @@ +/* +Copyright 2021 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 eventclock + +import ( + "time" + + "k8s.io/utils/clock" +) + +// RealEventClock fires event on real world time +type Real struct { + clock.RealClock +} + +var _ Interface = Real{} + +// EventAfterDuration schedules an EventFunc +func (Real) EventAfterDuration(f EventFunc, d time.Duration) { + ch := time.After(d) + go func() { + t := <-ch + f(t) + }() +} + +// EventAfterTime schedules an EventFunc +func (r Real) EventAfterTime(f EventFunc, t time.Time) { + r.EventAfterDuration(f, time.Until(t)) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/integrator.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/integrator.go new file mode 100644 index 000000000..f421a6425 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/integrator.go @@ -0,0 +1,191 @@ +/* +Copyright 2019 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 fairqueuing + +import ( + "math" + "sync" + "time" + + fcmetrics "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + + "k8s.io/utils/clock" +) + +// Integrator computes the moments of some variable X over time as +// read from a particular clock. The integrals start when the +// Integrator is created, and ends at the latest operation on the +// Integrator. +type Integrator interface { + fcmetrics.Gauge + + GetResults() IntegratorResults + + // Return the results of integrating to now, and reset integration to start now + Reset() IntegratorResults +} + +// IntegratorResults holds statistical abstracts of the integration +type IntegratorResults struct { + Duration float64 //seconds + Average float64 //time-weighted + Deviation float64 //standard deviation: sqrt(avg((value-avg)^2)) + Min, Max float64 +} + +// Equal tests for semantic equality. +// This considers all NaN values to be equal to each other. +func (x *IntegratorResults) Equal(y *IntegratorResults) bool { + return x == y || x != nil && y != nil && x.Duration == y.Duration && x.Min == y.Min && x.Max == y.Max && (x.Average == y.Average || math.IsNaN(x.Average) && math.IsNaN(y.Average)) && (x.Deviation == y.Deviation || math.IsNaN(x.Deviation) && math.IsNaN(y.Deviation)) +} + +type integrator struct { + name string + clock clock.PassiveClock + sync.Mutex + lastTime time.Time + x float64 + moments Moments + min, max float64 +} + +// NewNamedIntegrator makes one that uses the given clock and name +func NewNamedIntegrator(clock clock.PassiveClock, name string) Integrator { + return &integrator{ + name: name, + clock: clock, + lastTime: clock.Now(), + } +} + +func (igr *integrator) Set(x float64) { + igr.Lock() + igr.setLocked(x) + igr.Unlock() +} + +func (igr *integrator) Add(deltaX float64) { + igr.Lock() + igr.setLocked(igr.x + deltaX) + igr.Unlock() +} + +func (igr *integrator) Inc() { + igr.Add(1) +} + +func (igr *integrator) Dec() { + igr.Add(-1) +} + +func (igr *integrator) SetToCurrentTime() { + igr.Set(float64(time.Now().UnixNano())) +} + +func (igr *integrator) setLocked(x float64) { + igr.updateLocked() + igr.x = x + if x < igr.min { + igr.min = x + } + if x > igr.max { + igr.max = x + } +} + +func (igr *integrator) updateLocked() { + now := igr.clock.Now() + dt := now.Sub(igr.lastTime).Seconds() + igr.lastTime = now + igr.moments = igr.moments.Add(ConstantMoments(dt, igr.x)) +} + +func (igr *integrator) GetResults() IntegratorResults { + igr.Lock() + defer igr.Unlock() + return igr.getResultsLocked() +} + +func (igr *integrator) Reset() IntegratorResults { + igr.Lock() + defer igr.Unlock() + results := igr.getResultsLocked() + igr.moments = Moments{} + igr.min = igr.x + igr.max = igr.x + return results +} + +func (igr *integrator) getResultsLocked() (results IntegratorResults) { + igr.updateLocked() + results.Min, results.Max = igr.min, igr.max + results.Duration = igr.moments.ElapsedSeconds + results.Average, results.Deviation = igr.moments.AvgAndStdDev() + return +} + +// Moments are the integrals of the 0, 1, and 2 powers of some +// variable X over some range of time. +type Moments struct { + ElapsedSeconds float64 // integral of dt + IntegralX float64 // integral of x dt + IntegralXX float64 // integral of x*x dt +} + +// ConstantMoments is for a constant X +func ConstantMoments(dt, x float64) Moments { + return Moments{ + ElapsedSeconds: dt, + IntegralX: x * dt, + IntegralXX: x * x * dt, + } +} + +// Add combines over two ranges of time +func (igr Moments) Add(ogr Moments) Moments { + return Moments{ + ElapsedSeconds: igr.ElapsedSeconds + ogr.ElapsedSeconds, + IntegralX: igr.IntegralX + ogr.IntegralX, + IntegralXX: igr.IntegralXX + ogr.IntegralXX, + } +} + +// Sub finds the difference between a range of time and a subrange +func (igr Moments) Sub(ogr Moments) Moments { + return Moments{ + ElapsedSeconds: igr.ElapsedSeconds - ogr.ElapsedSeconds, + IntegralX: igr.IntegralX - ogr.IntegralX, + IntegralXX: igr.IntegralXX - ogr.IntegralXX, + } +} + +// AvgAndStdDev returns the average and standard devation +func (igr Moments) AvgAndStdDev() (float64, float64) { + if igr.ElapsedSeconds <= 0 { + return math.NaN(), math.NaN() + } + avg := igr.IntegralX / igr.ElapsedSeconds + // standard deviation is sqrt( average( (x - xbar)^2 ) ) + // = sqrt( Integral( x^2 + xbar^2 -2*x*xbar dt ) / Duration ) + // = sqrt( ( Integral( x^2 dt ) + Duration * xbar^2 - 2*xbar*Integral(x dt) ) / Duration) + // = sqrt( Integral(x^2 dt)/Duration - xbar^2 ) + variance := igr.IntegralXX/igr.ElapsedSeconds - avg*avg + if variance >= 0 { + return avg, math.Sqrt(variance) + } + return avg, math.NaN() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go new file mode 100644 index 000000000..5522bb455 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/interface.go @@ -0,0 +1,136 @@ +/* +Copyright 2019 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 fairqueuing + +import ( + "context" + "time" + + "k8s.io/apiserver/pkg/util/flowcontrol/debug" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + "k8s.io/apiserver/pkg/util/flowcontrol/request" +) + +// QueueSetFactory is used to create QueueSet objects. Creation, like +// config update, is done in two phases: the first phase consumes the +// QueuingConfig and the second consumes the DispatchingConfig. They +// are separated so that errors from the first phase can be found +// before committing to a concurrency allotment for the second. +type QueueSetFactory interface { + // BeginConstruction does the first phase of creating a QueueSet. + // The RatioedGaugePair observes number of requests, + // execution covering just the regular phase. + // The RatioedGauge observes number of seats occupied through all phases of execution. + // The Gauge observes the seat demand (executing + queued seats). + BeginConstruction(QueuingConfig, metrics.RatioedGaugePair, metrics.RatioedGauge, metrics.Gauge) (QueueSetCompleter, error) +} + +// QueueSetCompleter finishes the two-step process of creating or +// reconfiguring a QueueSet +type QueueSetCompleter interface { + // Complete returns a QueueSet configured by the given + // dispatching configuration. + Complete(DispatchingConfig) QueueSet +} + +// QueueSet is the abstraction for the queuing and dispatching +// functionality of one non-exempt priority level. It covers the +// functionality described in the "Assignment to a Queue", "Queuing", +// and "Dispatching" sections of +// https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/1040-priority-and-fairness/README.md +// . Some day we may have connections between priority levels, but +// today is not that day. +type QueueSet interface { + // BeginConfigChange starts the two-step process of updating the + // configuration. No change is made until Complete is called. If + // `C := X.BeginConstruction(q)` then `C.Complete(d)` returns the + // same value `X`. If the QueuingConfig's DesiredNumQueues field + // is zero then the other queuing-specific config parameters are + // not changed, so that the queues continue draining as before. + // In any case, reconfiguration does not discard any queue unless + // and until it is undesired and empty. + BeginConfigChange(QueuingConfig) (QueueSetCompleter, error) + + // IsIdle returns a bool indicating whether the QueueSet was idle + // at the moment of the return. Idle means the QueueSet has zero + // requests queued and zero executing. This bit can change only + // (1) during a call to StartRequest and (2) during a call to + // Request::Finish. In the latter case idleness can only change + // from false to true. + IsIdle() bool + + // StartRequest begins the process of handling a request. If the + // request gets queued and the number of queues is greater than 1 + // then StartRequest uses the given hashValue as the source of + // entropy as it shuffle-shards the request into a queue. The + // descr1 and descr2 values play no role in the logic but appear + // in log messages. This method always returns quickly (without + // waiting for the request to be dequeued). If this method + // returns a nil Request value then caller should reject the + // request and the returned bool indicates whether the QueueSet + // was idle at the moment of the return. Otherwise idle==false + // and the client must call the Finish method of the Request + // exactly once. + StartRequest(ctx context.Context, width *request.WorkEstimate, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn QueueNoteFn) (req Request, idle bool) + + // Dump saves and returns the instant internal state of the queue-set. + // Note that dumping process will stop the queue-set from proceeding + // any requests. + // For debugging only. + Dump(includeRequestDetails bool) debug.QueueSetDump +} + +// QueueNoteFn is called when a request enters and leaves a queue +type QueueNoteFn func(inQueue bool) + +// Request represents the remainder of the handling of one request +type Request interface { + // Finish determines whether to execute or reject the request and + // invokes `execute` if the decision is to execute the request. + // The returned `idle bool` value indicates whether the QueueSet + // was idle when the value was calculated, but might no longer be + // accurate by the time the client examines that value. + Finish(execute func()) (idle bool) +} + +// QueuingConfig defines the configuration of the queuing aspect of a QueueSet. +type QueuingConfig struct { + // Name is used to identify a queue set, allowing for descriptive information about its intended use + Name string + + // DesiredNumQueues is the number of queues that the API says + // should exist now. This may be zero, in which case + // QueueLengthLimit, HandSize, and RequestWaitLimit are ignored. + DesiredNumQueues int + + // QueueLengthLimit is the maximum number of requests that may be waiting in a given queue at a time + QueueLengthLimit int + + // HandSize is a parameter of shuffle sharding. Upon arrival of a request, a queue is chosen by randomly + // dealing a "hand" of this many queues and then picking one of minimum length. + HandSize int + + // RequestWaitLimit is the maximum amount of time that a request may wait in a queue. + // If, by the end of that time, the request has not been dispatched then it is rejected. + RequestWaitLimit time.Duration +} + +// DispatchingConfig defines the configuration of the dispatching aspect of a QueueSet. +type DispatchingConfig struct { + // ConcurrencyLimit is the maximum number of requests of this QueueSet that may be executing at a time + ConcurrencyLimit int +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go new file mode 100644 index 000000000..b2e3adbdc --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/interface.go @@ -0,0 +1,34 @@ +/* +Copyright 2019 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 promise + +// WriteOnce represents a variable that is initially not set and can +// be set once and is readable. This is the common meaning for +// "promise". +type WriteOnce interface { + // Get reads the current value of this variable. If this + // variable is not set yet then this call blocks until this + // variable gets a value. + Get() interface{} + + // Set normally writes a value into this variable, unblocks every + // goroutine waiting for this variable to have a value, and + // returns true. In the unhappy case that this variable is + // already set, this method returns false without modifying the + // variable's value. + Set(interface{}) bool +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/promise.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/promise.go new file mode 100644 index 000000000..d3bda40aa --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise/promise.go @@ -0,0 +1,70 @@ +/* +Copyright 2019 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 promise + +import ( + "sync" +) + +// promise implements the WriteOnce interface. +type promise struct { + doneCh <-chan struct{} + doneVal interface{} + setCh chan struct{} + onceler sync.Once + value interface{} +} + +var _ WriteOnce = &promise{} + +// NewWriteOnce makes a new thread-safe WriteOnce. +// +// If `initial` is non-nil then that value is Set at creation time. +// +// If a `Get` is waiting soon after `doneCh` becomes selectable (which +// never happens for the nil channel) then `Set(doneVal)` effectively +// happens at that time. +func NewWriteOnce(initial interface{}, doneCh <-chan struct{}, doneVal interface{}) WriteOnce { + p := &promise{ + doneCh: doneCh, + doneVal: doneVal, + setCh: make(chan struct{}), + } + if initial != nil { + p.Set(initial) + } + return p +} + +func (p *promise) Get() interface{} { + select { + case <-p.setCh: + case <-p.doneCh: + p.Set(p.doneVal) + } + return p.value +} + +func (p *promise) Set(value interface{}) bool { + var ans bool + p.onceler.Do(func() { + p.value = value + close(p.setCh) + ans = true + }) + return ans +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/doc.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/doc.go new file mode 100644 index 000000000..fc30ebfd5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/doc.go @@ -0,0 +1,119 @@ +/* +Copyright 2019 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 queueset implements a technique called "fair queuing for +// server requests". One QueueSet is a set of queues operating +// according to this technique. +// +// Fair queuing for server requests is inspired by the fair queuing +// technique from the world of networking. You can find a good paper +// on that at https://dl.acm.org/citation.cfm?doid=75247.75248 or +// http://people.csail.mit.edu/imcgraw/links/research/pubs/networks/WFQ.pdf +// and there is an implementation outline in the Wikipedia article at +// https://en.wikipedia.org/wiki/Fair_queuing . +// +// Fair queuing for server requests differs from traditional fair +// queuing in three ways: (1) we are dispatching application layer +// requests to a server rather than transmitting packets on a network +// link, (2) multiple requests can be executing at once, and (3) the +// service time (execution duration) is not known until the execution +// completes. +// +// The first two differences can easily be handled by straightforward +// adaptation of the concept called "R(t)" in the original paper and +// "virtual time" in the implementation outline. In that +// implementation outline, the notation now() is used to mean reading +// the virtual clock. In the original paper’s terms, "R(t)" is the +// number of "rounds" that have been completed at real time t --- +// where a round consists of virtually transmitting one bit from every +// non-empty queue in the router (regardless of which queue holds the +// packet that is really being transmitted at the moment); in this +// conception, a packet is considered to be "in" its queue until the +// packet’s transmission is finished. For our problem, we can define a +// round to be giving one nanosecond of CPU to every non-empty queue +// in the apiserver (where emptiness is judged based on both queued +// and executing requests from that queue), and define R(t) = (server +// start time) + (1 ns) * (number of rounds since server start). Let +// us write NEQ(t) for that number of non-empty queues in the +// apiserver at time t. Let us also write C for the concurrency +// limit. In the original paper, the partial derivative of R(t) with +// respect to t is +// +// 1 / NEQ(t) . +// +// To generalize from transmitting one packet at a time to executing C +// requests at a time, that derivative becomes +// +// C / NEQ(t) . +// +// However, sometimes there are fewer than C requests available to +// execute. For a given queue "q", let us also write "reqs(q, t)" for +// the number of requests of that queue that are executing at that +// time. The total number of requests executing is sum[over q] +// reqs(q, t) and if that is less than C then virtual time is not +// advancing as fast as it would if all C seats were occupied; in this +// case the numerator of the quotient in that derivative should be +// adjusted proportionally. Putting it all together for fair queing +// for server requests: at a particular time t, the partial derivative +// of R(t) with respect to t is +// +// min( C, sum[over q] reqs(q, t) ) / NEQ(t) . +// +// In terms of the implementation outline, this is the rate at which +// virtual time is advancing at time t (in virtual nanoseconds per +// real nanosecond). Where the networking implementation outline adds +// packet size to a virtual time, in our version this corresponds to +// adding a service time (i.e., duration) to virtual time. +// +// The third difference is handled by modifying the algorithm to +// dispatch based on an initial guess at the request’s service time +// (duration) and then make the corresponding adjustments once the +// request’s actual service time is known. This is similar, although +// not exactly isomorphic, to the original paper’s adjustment by +// `$\delta$` for the sake of promptness. +// +// For implementation simplicity (see below), let us use the same +// initial service time guess for every request; call that duration +// G. A good choice might be the service time limit (1 +// minute). Different guesses will give slightly different dynamics, +// but any positive number can be used for G without ruining the +// long-term behavior. +// +// As in ordinary fair queuing, there is a bound on divergence from +// the ideal. In plain fair queuing the bound is one packet; in our +// version it is C requests. +// +// To support efficiently making the necessary adjustments once a +// request’s actual service time is known, the virtual finish time of +// a request and the last virtual finish time of a queue are not +// represented directly but instead computed from queue length, +// request position in the queue, and an alternate state variable that +// holds the queue’s virtual start time. While the queue is empty and +// has no requests executing: the value of its virtual start time +// variable is ignored and its last virtual finish time is considered +// to be in the virtual past. When a request arrives to an empty queue +// with no requests executing, the queue’s virtual start time is set +// to the current virtual time. The virtual finish time of request +// number J in the queue (counting from J=1 for the head) is J * G + +// (queue's virtual start time). While the queue is non-empty: the +// last virtual finish time of the queue is the virtual finish time of +// the last request in the queue. While the queue is empty and has a +// request executing: the last virtual finish time is the queue’s +// virtual start time. When a request is dequeued for service the +// queue’s virtual start time is advanced by G. When a request +// finishes being served, and the actual service time was S, the +// queue’s virtual start time is decremented by G - S. +package queueset diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/fifo_list.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/fifo_list.go new file mode 100644 index 000000000..eb56e1e94 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/fifo_list.go @@ -0,0 +1,156 @@ +/* +Copyright 2021 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 queueset + +import ( + "container/list" +) + +// removeFromFIFOFunc removes a designated element from the list +// if that element is in the list. +// The complexity of the runtime cost is O(1). +// The returned value is the element removed, if indeed one was removed, +// otherwise `nil`. +type removeFromFIFOFunc func() *request + +// walkFunc is called for each request in the list in the +// oldest -> newest order. +// ok: if walkFunc returns false then the iteration stops immediately. +// walkFunc may remove the given request from the fifo, +// but may not mutate the fifo in any othe way. +type walkFunc func(*request) (ok bool) + +// Internal interface to abstract out the implementation details +// of the underlying list used to maintain the requests. +// +// Note that a fifo, including the removeFromFIFOFuncs returned from Enqueue, +// is not safe for concurrent use by multiple goroutines. +type fifo interface { + // Enqueue enqueues the specified request into the list and + // returns a removeFromFIFOFunc function that can be used to remove the + // request from the list + Enqueue(*request) removeFromFIFOFunc + + // Dequeue pulls out the oldest request from the list. + Dequeue() (*request, bool) + + // Peek returns the oldest request without removing it. + Peek() (*request, bool) + + // Length returns the number of requests in the list. + Length() int + + // QueueSum returns the sum of initial seats, final seats, and + // additional latency aggregated from all requests in this queue. + QueueSum() queueSum + + // Walk iterates through the list in order of oldest -> newest + // and executes the specified walkFunc for each request in that order. + // + // if the specified walkFunc returns false the Walk function + // stops the walk an returns immediately. + Walk(walkFunc) +} + +// the FIFO list implementation is not safe for concurrent use by multiple +// goroutines. +type requestFIFO struct { + *list.List + + sum queueSum +} + +func newRequestFIFO() fifo { + return &requestFIFO{ + List: list.New(), + } +} + +func (l *requestFIFO) Length() int { + return l.Len() +} + +func (l *requestFIFO) QueueSum() queueSum { + return l.sum +} + +func (l *requestFIFO) Enqueue(req *request) removeFromFIFOFunc { + e := l.PushBack(req) + addToQueueSum(&l.sum, req) + + return func() *request { + if e.Value == nil { + return nil + } + l.Remove(e) + e.Value = nil + deductFromQueueSum(&l.sum, req) + return req + } +} + +func (l *requestFIFO) Dequeue() (*request, bool) { + return l.getFirst(true) +} + +func (l *requestFIFO) Peek() (*request, bool) { + return l.getFirst(false) +} + +func (l *requestFIFO) getFirst(remove bool) (*request, bool) { + e := l.Front() + if e == nil { + return nil, false + } + + if remove { + defer func() { + l.Remove(e) + e.Value = nil + }() + } + + request, ok := e.Value.(*request) + if remove && ok { + deductFromQueueSum(&l.sum, request) + } + return request, ok +} + +func (l *requestFIFO) Walk(f walkFunc) { + var next *list.Element + for current := l.Front(); current != nil; current = next { + next = current.Next() // f is allowed to remove current + if r, ok := current.Value.(*request); ok { + if !f(r) { + return + } + } + } +} + +func addToQueueSum(sum *queueSum, req *request) { + sum.InitialSeatsSum += req.InitialSeats() + sum.MaxSeatsSum += req.MaxSeats() + sum.TotalWorkSum += req.totalWork() +} + +func deductFromQueueSum(sum *queueSum, req *request) { + sum.InitialSeatsSum -= req.InitialSeats() + sum.MaxSeatsSum -= req.MaxSeats() + sum.TotalWorkSum -= req.totalWork() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go new file mode 100644 index 000000000..9106a033e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go @@ -0,0 +1,1046 @@ +/* +Copyright 2019 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 queueset + +import ( + "context" + "errors" + "fmt" + "math" + "sync" + "time" + + "k8s.io/apiserver/pkg/util/flowcontrol/debug" + fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" + "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock" + "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" + fqrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" + "k8s.io/apiserver/pkg/util/shufflesharding" + "k8s.io/klog/v2" + + // The following hack is needed to work around a tooling deficiency. + // Packages imported only for test code are not included in vendor. + // See https://kubernetes.slack.com/archives/C0EG7JC6T/p1626985671458800?thread_ts=1626983387.450800&cid=C0EG7JC6T + _ "k8s.io/utils/clock/testing" +) + +const nsTimeFmt = "2006-01-02 15:04:05.000000000" + +// queueSetFactory implements the QueueSetFactory interface +// queueSetFactory makes QueueSet objects. +type queueSetFactory struct { + clock eventclock.Interface + promiseFactoryFactory promiseFactoryFactory +} + +// promiseFactory returns a WriteOnce +// - whose Set method is invoked with the queueSet locked, and +// - whose Get method is invoked with the queueSet not locked. +// The parameters are the same as for `promise.NewWriteOnce`. +type promiseFactory func(initial interface{}, doneCh <-chan struct{}, doneVal interface{}) promise.WriteOnce + +// promiseFactoryFactory returns the promiseFactory to use for the given queueSet +type promiseFactoryFactory func(*queueSet) promiseFactory + +// `*queueSetCompleter` implements QueueSetCompleter. Exactly one of +// the fields `factory` and `theSet` is non-nil. +type queueSetCompleter struct { + factory *queueSetFactory + reqsGaugePair metrics.RatioedGaugePair + execSeatsGauge metrics.RatioedGauge + seatDemandIntegrator metrics.Gauge + theSet *queueSet + qCfg fq.QueuingConfig + dealer *shufflesharding.Dealer +} + +// queueSet implements the Fair Queuing for Server Requests technique +// described in this package's doc, and a pointer to one implements +// the QueueSet interface. The fields listed before the lock +// should not be changed; the fields listed after the +// lock must be accessed only while holding the lock. +// +// The methods of this type follow the naming convention that the +// suffix "Locked" means the caller must hold the lock; for a method +// whose name does not end in "Locked" either acquires the lock or +// does not care about locking. +// +// The methods of this type also follow the convention that the suffix +// "ToBoundLocked" means that the caller may have to follow up with a +// call to `boundNextDispatchLocked`. This is so for a method that +// changes what request is oldest in a queue, because that change means +// that the anti-windup hack in boundNextDispatchLocked needs to be +// applied wrt the revised oldest request in the queue. +type queueSet struct { + clock eventclock.Interface + estimatedServiceDuration time.Duration + + reqsGaugePair metrics.RatioedGaugePair // .RequestsExecuting covers regular phase only + + execSeatsGauge metrics.RatioedGauge // for all phases of execution + + seatDemandIntegrator metrics.Gauge + + promiseFactory promiseFactory + + lock sync.Mutex + + // qCfg holds the current queuing configuration. Its + // DesiredNumQueues may be less than the current number of queues. + // If its DesiredNumQueues is zero then its other queuing + // parameters retain the settings they had when DesiredNumQueues + // was last non-zero (if ever). + qCfg fq.QueuingConfig + + // the current dispatching configuration. + dCfg fq.DispatchingConfig + + // If `qCfg.DesiredNumQueues` is non-zero then dealer is not nil + // and is good for `qCfg`. + dealer *shufflesharding.Dealer + + // queues may be longer than the desired number, while the excess + // queues are still draining. + queues []*queue + + // currentR is the amount of seat-seconds allocated per queue since process startup. + // This is our generalization of the progress meter named R in the original fair queuing work. + currentR fqrequest.SeatSeconds + + // lastRealTime is what `clock.Now()` yielded when `virtualTime` was last updated + lastRealTime time.Time + + // robinIndex is the index of the last queue dispatched + robinIndex int + + // totRequestsWaiting is the sum, over all the queues, of the + // number of requests waiting in that queue + totRequestsWaiting int + + // totRequestsExecuting is the total number of requests of this + // queueSet that are currently executing. That is the same as the + // sum, over all the queues, of the number of requests executing + // from that queue. + totRequestsExecuting int + + // totSeatsInUse is the number of total "seats" in use by all the + // request(s) that are currently executing in this queueset. + totSeatsInUse int + + // totSeatsWaiting is the sum, over all the waiting requests, of their + // max width. + totSeatsWaiting int + + // enqueues is the number of requests that have ever been enqueued + enqueues int +} + +// NewQueueSetFactory creates a new QueueSetFactory object +func NewQueueSetFactory(c eventclock.Interface) fq.QueueSetFactory { + return newTestableQueueSetFactory(c, ordinaryPromiseFactoryFactory) +} + +// newTestableQueueSetFactory creates a new QueueSetFactory object with the given promiseFactoryFactory +func newTestableQueueSetFactory(c eventclock.Interface, promiseFactoryFactory promiseFactoryFactory) fq.QueueSetFactory { + return &queueSetFactory{ + clock: c, + promiseFactoryFactory: promiseFactoryFactory, + } +} + +func (qsf *queueSetFactory) BeginConstruction(qCfg fq.QueuingConfig, reqsGaugePair metrics.RatioedGaugePair, execSeatsGauge metrics.RatioedGauge, seatDemandIntegrator metrics.Gauge) (fq.QueueSetCompleter, error) { + dealer, err := checkConfig(qCfg) + if err != nil { + return nil, err + } + return &queueSetCompleter{ + factory: qsf, + reqsGaugePair: reqsGaugePair, + execSeatsGauge: execSeatsGauge, + seatDemandIntegrator: seatDemandIntegrator, + qCfg: qCfg, + dealer: dealer}, nil +} + +// checkConfig returns a non-nil Dealer if the config is valid and +// calls for one, and returns a non-nil error if the given config is +// invalid. +func checkConfig(qCfg fq.QueuingConfig) (*shufflesharding.Dealer, error) { + if qCfg.DesiredNumQueues == 0 { + return nil, nil + } + dealer, err := shufflesharding.NewDealer(qCfg.DesiredNumQueues, qCfg.HandSize) + if err != nil { + err = fmt.Errorf("the QueueSetConfig implies an invalid shuffle sharding config (DesiredNumQueues is deckSize): %w", err) + } + return dealer, err +} + +func (qsc *queueSetCompleter) Complete(dCfg fq.DispatchingConfig) fq.QueueSet { + qs := qsc.theSet + if qs == nil { + qs = &queueSet{ + clock: qsc.factory.clock, + estimatedServiceDuration: 3 * time.Millisecond, + reqsGaugePair: qsc.reqsGaugePair, + execSeatsGauge: qsc.execSeatsGauge, + seatDemandIntegrator: qsc.seatDemandIntegrator, + qCfg: qsc.qCfg, + currentR: 0, + lastRealTime: qsc.factory.clock.Now(), + } + qs.promiseFactory = qsc.factory.promiseFactoryFactory(qs) + } + qs.setConfiguration(context.Background(), qsc.qCfg, qsc.dealer, dCfg) + return qs +} + +// createQueues is a helper method for initializing an array of n queues +func createQueues(n, baseIndex int) []*queue { + fqqueues := make([]*queue, n) + for i := 0; i < n; i++ { + fqqueues[i] = &queue{index: baseIndex + i, requests: newRequestFIFO()} + } + return fqqueues +} + +func (qs *queueSet) BeginConfigChange(qCfg fq.QueuingConfig) (fq.QueueSetCompleter, error) { + dealer, err := checkConfig(qCfg) + if err != nil { + return nil, err + } + return &queueSetCompleter{ + theSet: qs, + qCfg: qCfg, + dealer: dealer}, nil +} + +// setConfiguration is used to set the configuration for a queueSet. +// Update handling for when fields are updated is handled here as well - +// eg: if DesiredNum is increased, setConfiguration reconciles by +// adding more queues. +func (qs *queueSet) setConfiguration(ctx context.Context, qCfg fq.QueuingConfig, dealer *shufflesharding.Dealer, dCfg fq.DispatchingConfig) { + qs.lockAndSyncTime(ctx) + defer qs.lock.Unlock() + + if qCfg.DesiredNumQueues > 0 { + // Adding queues is the only thing that requires immediate action + // Removing queues is handled by attrition, removing a queue when + // it goes empty and there are too many. + numQueues := len(qs.queues) + if qCfg.DesiredNumQueues > numQueues { + qs.queues = append(qs.queues, + createQueues(qCfg.DesiredNumQueues-numQueues, len(qs.queues))...) + } + } else { + qCfg.QueueLengthLimit = qs.qCfg.QueueLengthLimit + qCfg.HandSize = qs.qCfg.HandSize + qCfg.RequestWaitLimit = qs.qCfg.RequestWaitLimit + } + + qs.qCfg = qCfg + qs.dCfg = dCfg + qs.dealer = dealer + qll := qCfg.QueueLengthLimit + if qll < 1 { + qll = 1 + } + if qCfg.DesiredNumQueues > 0 { + qll *= qCfg.DesiredNumQueues + } + qs.reqsGaugePair.RequestsWaiting.SetDenominator(float64(qll)) + qs.reqsGaugePair.RequestsExecuting.SetDenominator(float64(dCfg.ConcurrencyLimit)) + qs.execSeatsGauge.SetDenominator(float64(dCfg.ConcurrencyLimit)) + + qs.dispatchAsMuchAsPossibleLocked() +} + +// A decision about a request +type requestDecision int + +// Values passed through a request's decision +const ( + // Serve this one + decisionExecute requestDecision = iota + + // Reject this one due to APF queuing considerations + decisionReject + + // This one's context timed out / was canceled + decisionCancel +) + +// StartRequest begins the process of handling a request. We take the +// approach of updating the metrics about total requests queued and +// executing at each point where there is a change in that quantity, +// because the metrics --- and only the metrics --- track that +// quantity per FlowSchema. +// The queueSet's promiseFactory is invoked once if the returned Request is non-nil, +// not invoked if the Request is nil. +func (qs *queueSet) StartRequest(ctx context.Context, workEstimate *fqrequest.WorkEstimate, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn fq.QueueNoteFn) (fq.Request, bool) { + qs.lockAndSyncTime(ctx) + defer qs.lock.Unlock() + var req *request + + // ======================================================================== + // Step 0: + // Apply only concurrency limit, if zero queues desired + if qs.qCfg.DesiredNumQueues < 1 { + if !qs.canAccommodateSeatsLocked(workEstimate.MaxSeats()) { + klog.V(5).Infof("QS(%s): rejecting request %q %#+v %#+v because %d seats are asked for, %d seats are in use (%d are executing) and the limit is %d", + qs.qCfg.Name, fsName, descr1, descr2, workEstimate, qs.totSeatsInUse, qs.totRequestsExecuting, qs.dCfg.ConcurrencyLimit) + metrics.AddReject(ctx, qs.qCfg.Name, fsName, "concurrency-limit") + return nil, qs.isIdleLocked() + } + req = qs.dispatchSansQueueLocked(ctx, workEstimate, flowDistinguisher, fsName, descr1, descr2) + return req, false + } + + // ======================================================================== + // Step 1: + // 1) Start with shuffle sharding, to pick a queue. + // 2) Reject old requests that have been waiting too long + // 3) Reject current request if there is not enough concurrency shares and + // we are at max queue length + // 4) If not rejected, create a request and enqueue + req = qs.timeoutOldRequestsAndRejectOrEnqueueLocked(ctx, workEstimate, hashValue, flowDistinguisher, fsName, descr1, descr2, queueNoteFn) + // req == nil means that the request was rejected - no remaining + // concurrency shares and at max queue length already + if req == nil { + klog.V(5).Infof("QS(%s): rejecting request %q %#+v %#+v due to queue full", qs.qCfg.Name, fsName, descr1, descr2) + metrics.AddReject(ctx, qs.qCfg.Name, fsName, "queue-full") + return nil, qs.isIdleLocked() + } + + // ======================================================================== + // Step 2: + // The next step is to invoke the method that dequeues as much + // as possible. + // This method runs a loop, as long as there are non-empty + // queues and the number currently executing is less than the + // assured concurrency value. The body of the loop uses the + // fair queuing technique to pick a queue and dispatch a + // request from that queue. + qs.dispatchAsMuchAsPossibleLocked() + + return req, false +} + +// ordinaryPromiseFactoryFactory is the promiseFactoryFactory that +// a queueSetFactory would ordinarily use. +// Test code might use something different. +func ordinaryPromiseFactoryFactory(qs *queueSet) promiseFactory { + return promise.NewWriteOnce +} + +// MaxSeats returns the maximum number of seats this request requires, it is +// the maxumum of the two - WorkEstimate.InitialSeats, WorkEstimate.FinalSeats. +func (req *request) MaxSeats() int { + return req.workEstimate.MaxSeats() +} + +func (req *request) InitialSeats() int { + return int(req.workEstimate.InitialSeats) +} + +func (req *request) NoteQueued(inQueue bool) { + if req.queueNoteFn != nil { + req.queueNoteFn(inQueue) + } +} + +func (req *request) Finish(execFn func()) bool { + exec, idle := req.wait() + if !exec { + return idle + } + func() { + defer func() { + idle = req.qs.finishRequestAndDispatchAsMuchAsPossible(req) + }() + + execFn() + }() + + return idle +} + +func (req *request) wait() (bool, bool) { + qs := req.qs + + // ======================================================================== + // Step 3: + // The final step is to wait on a decision from + // somewhere and then act on it. + decisionAny := req.decision.Get() + qs.lockAndSyncTime(req.ctx) + defer qs.lock.Unlock() + if req.waitStarted { + // This can not happen, because the client is forbidden to + // call Wait twice on the same request + klog.Errorf("Duplicate call to the Wait method! Immediately returning execute=false. QueueSet=%s, startTime=%s, descr1=%#+v, descr2=%#+v", req.qs.qCfg.Name, req.startTime, req.descr1, req.descr2) + return false, qs.isIdleLocked() + } + req.waitStarted = true + switch decisionAny { + case decisionReject: + klog.V(5).Infof("QS(%s): request %#+v %#+v timed out after being enqueued\n", qs.qCfg.Name, req.descr1, req.descr2) + metrics.AddReject(req.ctx, qs.qCfg.Name, req.fsName, "time-out") + return false, qs.isIdleLocked() + case decisionCancel: + case decisionExecute: + klog.V(5).Infof("QS(%s): Dispatching request %#+v %#+v from its queue", qs.qCfg.Name, req.descr1, req.descr2) + return true, false + default: + // This can not happen, all possible values are handled above + klog.Errorf("QS(%s): Impossible decision (type %T, value %#+v) for request %#+v %#+v! Treating as cancel", qs.qCfg.Name, decisionAny, decisionAny, req.descr1, req.descr2) + } + // TODO(aaron-prindle) add metrics for this case + klog.V(5).Infof("QS(%s): Ejecting request %#+v %#+v from its queue", qs.qCfg.Name, req.descr1, req.descr2) + // remove the request from the queue as it has timed out + queue := req.queue + if req.removeFromQueueLocked() != nil { + defer qs.boundNextDispatchLocked(queue) + qs.totRequestsWaiting-- + qs.totSeatsWaiting -= req.MaxSeats() + metrics.AddReject(req.ctx, qs.qCfg.Name, req.fsName, "cancelled") + metrics.AddRequestsInQueues(req.ctx, qs.qCfg.Name, req.fsName, -1) + req.NoteQueued(false) + qs.reqsGaugePair.RequestsWaiting.Add(-1) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + } + return false, qs.isIdleLocked() +} + +func (qs *queueSet) IsIdle() bool { + qs.lock.Lock() + defer qs.lock.Unlock() + return qs.isIdleLocked() +} + +func (qs *queueSet) isIdleLocked() bool { + return qs.totRequestsWaiting == 0 && qs.totRequestsExecuting == 0 +} + +// lockAndSyncTime acquires the lock and updates the virtual time. +// Doing them together avoids the mistake of modifying some queue state +// before calling syncTimeLocked. +func (qs *queueSet) lockAndSyncTime(ctx context.Context) { + qs.lock.Lock() + qs.syncTimeLocked(ctx) +} + +// syncTimeLocked updates the virtual time based on the assumption +// that the current state of the queues has been in effect since +// `qs.lastRealTime`. Thus, it should be invoked after acquiring the +// lock and before modifying the state of any queue. +func (qs *queueSet) syncTimeLocked(ctx context.Context) { + realNow := qs.clock.Now() + timeSinceLast := realNow.Sub(qs.lastRealTime) + qs.lastRealTime = realNow + prevR := qs.currentR + incrR := fqrequest.SeatsTimesDuration(qs.getVirtualTimeRatioLocked(), timeSinceLast) + qs.currentR = prevR + incrR + switch { + case prevR > qs.currentR: + klog.ErrorS(errors.New("queueset::currentR overflow"), "Overflow", "QS", qs.qCfg.Name, "when", realNow.Format(nsTimeFmt), "prevR", prevR, "incrR", incrR, "currentR", qs.currentR) + case qs.currentR >= highR: + qs.advanceEpoch(ctx, realNow, incrR) + } + metrics.SetCurrentR(qs.qCfg.Name, qs.currentR.ToFloat()) +} + +// rDecrement is the amount by which the progress meter R is wound backwards +// when needed to avoid overflow. +const rDecrement = fqrequest.MaxSeatSeconds / 2 + +// highR is the threshold that triggers advance of the epoch. +// That is, decrementing the global progress meter R by rDecrement. +const highR = rDecrement + rDecrement/2 + +// advanceEpoch subtracts rDecrement from the global progress meter R +// and all the readings that have been taked from that meter. +// The now and incrR parameters are only used to add info to the log messages. +func (qs *queueSet) advanceEpoch(ctx context.Context, now time.Time, incrR fqrequest.SeatSeconds) { + oldR := qs.currentR + qs.currentR -= rDecrement + klog.InfoS("Advancing epoch", "QS", qs.qCfg.Name, "when", now.Format(nsTimeFmt), "oldR", oldR, "newR", qs.currentR, "incrR", incrR) + success := true + for qIdx, queue := range qs.queues { + if queue.requests.Length() == 0 && queue.requestsExecuting == 0 { + // Do not just decrement, the value could be quite outdated. + // It is safe to reset to zero in this case, because the next request + // will overwrite the zero with `qs.currentR`. + queue.nextDispatchR = 0 + continue + } + oldNextDispatchR := queue.nextDispatchR + queue.nextDispatchR -= rDecrement + if queue.nextDispatchR > oldNextDispatchR { + klog.ErrorS(errors.New("queue::nextDispatchR underflow"), "Underflow", "QS", qs.qCfg.Name, "queue", qIdx, "oldNextDispatchR", oldNextDispatchR, "newNextDispatchR", queue.nextDispatchR, "incrR", incrR) + success = false + } + queue.requests.Walk(func(req *request) bool { + oldArrivalR := req.arrivalR + req.arrivalR -= rDecrement + if req.arrivalR > oldArrivalR { + klog.ErrorS(errors.New("request::arrivalR underflow"), "Underflow", "QS", qs.qCfg.Name, "queue", qIdx, "request", *req, "oldArrivalR", oldArrivalR, "incrR", incrR) + success = false + } + return true + }) + } + metrics.AddEpochAdvance(ctx, qs.qCfg.Name, success) +} + +// getVirtualTimeRatio calculates the rate at which virtual time has +// been advancing, according to the logic in `doc.go`. +func (qs *queueSet) getVirtualTimeRatioLocked() float64 { + activeQueues := 0 + seatsRequested := 0 + for _, queue := range qs.queues { + // here we want the sum of the maximum width of the requests in this queue since our + // goal is to find the maximum rate at which the queue could work. + seatsRequested += (queue.seatsInUse + queue.requests.QueueSum().MaxSeatsSum) + if queue.requests.Length() > 0 || queue.requestsExecuting > 0 { + activeQueues++ + } + } + if activeQueues == 0 { + return 0 + } + return math.Min(float64(seatsRequested), float64(qs.dCfg.ConcurrencyLimit)) / float64(activeQueues) +} + +// timeoutOldRequestsAndRejectOrEnqueueLocked encapsulates the logic required +// to validate and enqueue a request for the queueSet/QueueSet: +// 1) Start with shuffle sharding, to pick a queue. +// 2) Reject old requests that have been waiting too long +// 3) Reject current request if there is not enough concurrency shares and +// we are at max queue length +// 4) If not rejected, create a request and enqueue +// returns the enqueud request on a successful enqueue +// returns nil in the case that there is no available concurrency or +// the queuelengthlimit has been reached +func (qs *queueSet) timeoutOldRequestsAndRejectOrEnqueueLocked(ctx context.Context, workEstimate *fqrequest.WorkEstimate, hashValue uint64, flowDistinguisher, fsName string, descr1, descr2 interface{}, queueNoteFn fq.QueueNoteFn) *request { + // Start with the shuffle sharding, to pick a queue. + queueIdx := qs.shuffleShardLocked(hashValue, descr1, descr2) + queue := qs.queues[queueIdx] + // The next step is the logic to reject requests that have been waiting too long + qs.removeTimedOutRequestsFromQueueToBoundLocked(queue, fsName) + // NOTE: currently timeout is only checked for each new request. This means that there can be + // requests that are in the queue longer than the timeout if there are no new requests + // We prefer the simplicity over the promptness, at least for now. + + defer qs.boundNextDispatchLocked(queue) + + // Create a request and enqueue + req := &request{ + qs: qs, + fsName: fsName, + flowDistinguisher: flowDistinguisher, + ctx: ctx, + decision: qs.promiseFactory(nil, ctx.Done(), decisionCancel), + arrivalTime: qs.clock.Now(), + arrivalR: qs.currentR, + queue: queue, + descr1: descr1, + descr2: descr2, + queueNoteFn: queueNoteFn, + workEstimate: qs.completeWorkEstimate(workEstimate), + } + if ok := qs.rejectOrEnqueueToBoundLocked(req); !ok { + return nil + } + metrics.ObserveQueueLength(ctx, qs.qCfg.Name, fsName, queue.requests.Length()) + return req +} + +// shuffleShardLocked uses shuffle sharding to select a queue index +// using the given hashValue and the shuffle sharding parameters of the queueSet. +func (qs *queueSet) shuffleShardLocked(hashValue uint64, descr1, descr2 interface{}) int { + var backHand [8]int + // Deal into a data structure, so that the order of visit below is not necessarily the order of the deal. + // This removes bias in the case of flows with overlapping hands. + hand := qs.dealer.DealIntoHand(hashValue, backHand[:]) + handSize := len(hand) + offset := qs.enqueues % handSize + qs.enqueues++ + bestQueueIdx := -1 + minQueueSeatSeconds := fqrequest.MaxSeatSeconds + for i := 0; i < handSize; i++ { + queueIdx := hand[(offset+i)%handSize] + queue := qs.queues[queueIdx] + queueSum := queue.requests.QueueSum() + + // this is the total amount of work in seat-seconds for requests + // waiting in this queue, we will select the queue with the minimum. + thisQueueSeatSeconds := queueSum.TotalWorkSum + klog.V(7).Infof("QS(%s): For request %#+v %#+v considering queue %d with sum: %#v and %d seats in use, nextDispatchR=%v", qs.qCfg.Name, descr1, descr2, queueIdx, queueSum, queue.seatsInUse, queue.nextDispatchR) + if thisQueueSeatSeconds < minQueueSeatSeconds { + minQueueSeatSeconds = thisQueueSeatSeconds + bestQueueIdx = queueIdx + } + } + if klogV := klog.V(6); klogV.Enabled() { + chosenQueue := qs.queues[bestQueueIdx] + klogV.Infof("QS(%s) at t=%s R=%v: For request %#+v %#+v chose queue %d, with sum: %#v & %d seats in use & nextDispatchR=%v", qs.qCfg.Name, qs.clock.Now().Format(nsTimeFmt), qs.currentR, descr1, descr2, bestQueueIdx, chosenQueue.requests.QueueSum(), chosenQueue.seatsInUse, chosenQueue.nextDispatchR) + } + return bestQueueIdx +} + +// removeTimedOutRequestsFromQueueToBoundLocked rejects old requests that have been enqueued +// past the requestWaitLimit +func (qs *queueSet) removeTimedOutRequestsFromQueueToBoundLocked(queue *queue, fsName string) { + timeoutCount := 0 + disqueueSeats := 0 + now := qs.clock.Now() + reqs := queue.requests + // reqs are sorted oldest -> newest + // can short circuit loop (break) if oldest requests are not timing out + // as newer requests also will not have timed out + + // now - requestWaitLimit = arrivalLimit + arrivalLimit := now.Add(-qs.qCfg.RequestWaitLimit) + reqs.Walk(func(req *request) bool { + if arrivalLimit.After(req.arrivalTime) { + if req.decision.Set(decisionReject) && req.removeFromQueueLocked() != nil { + timeoutCount++ + disqueueSeats += req.MaxSeats() + req.NoteQueued(false) + metrics.AddRequestsInQueues(req.ctx, qs.qCfg.Name, req.fsName, -1) + } + // we need to check if the next request has timed out. + return true + } + // since reqs are sorted oldest -> newest, we are done here. + return false + }) + + // remove timed out requests from queue + if timeoutCount > 0 { + qs.totRequestsWaiting -= timeoutCount + qs.totSeatsWaiting -= disqueueSeats + qs.reqsGaugePair.RequestsWaiting.Add(float64(-timeoutCount)) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + } +} + +// rejectOrEnqueueToBoundLocked rejects or enqueues the newly arrived +// request, which has been assigned to a queue. If up against the +// queue length limit and the concurrency limit then returns false. +// Otherwise enqueues and returns true. +func (qs *queueSet) rejectOrEnqueueToBoundLocked(request *request) bool { + queue := request.queue + curQueueLength := queue.requests.Length() + // rejects the newly arrived request if resource criteria not met + if qs.totSeatsInUse >= qs.dCfg.ConcurrencyLimit && + curQueueLength >= qs.qCfg.QueueLengthLimit { + return false + } + + qs.enqueueToBoundLocked(request) + return true +} + +// enqueues a request into its queue. +func (qs *queueSet) enqueueToBoundLocked(request *request) { + queue := request.queue + now := qs.clock.Now() + if queue.requests.Length() == 0 && queue.requestsExecuting == 0 { + // the queue’s start R is set to the virtual time. + queue.nextDispatchR = qs.currentR + klogV := klog.V(6) + if klogV.Enabled() { + klogV.Infof("QS(%s) at t=%s R=%v: initialized queue %d start R due to request %#+v %#+v", qs.qCfg.Name, now.Format(nsTimeFmt), queue.nextDispatchR, queue.index, request.descr1, request.descr2) + } + } + request.removeFromQueueLocked = queue.requests.Enqueue(request) + qs.totRequestsWaiting++ + qs.totSeatsWaiting += request.MaxSeats() + metrics.AddRequestsInQueues(request.ctx, qs.qCfg.Name, request.fsName, 1) + request.NoteQueued(true) + qs.reqsGaugePair.RequestsWaiting.Add(1) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) +} + +// dispatchAsMuchAsPossibleLocked does as many dispatches as possible now. +func (qs *queueSet) dispatchAsMuchAsPossibleLocked() { + for qs.totRequestsWaiting != 0 && qs.totSeatsInUse < qs.dCfg.ConcurrencyLimit && qs.dispatchLocked() { + } +} + +func (qs *queueSet) dispatchSansQueueLocked(ctx context.Context, workEstimate *fqrequest.WorkEstimate, flowDistinguisher, fsName string, descr1, descr2 interface{}) *request { + // does not call metrics.SetDispatchMetrics because there is no queuing and thus no interesting virtual world + now := qs.clock.Now() + req := &request{ + qs: qs, + fsName: fsName, + flowDistinguisher: flowDistinguisher, + ctx: ctx, + startTime: now, + decision: qs.promiseFactory(decisionExecute, ctx.Done(), decisionCancel), + arrivalTime: now, + arrivalR: qs.currentR, + descr1: descr1, + descr2: descr2, + workEstimate: qs.completeWorkEstimate(workEstimate), + } + qs.totRequestsExecuting++ + qs.totSeatsInUse += req.MaxSeats() + metrics.AddRequestsExecuting(ctx, qs.qCfg.Name, fsName, 1) + metrics.AddRequestConcurrencyInUse(qs.qCfg.Name, fsName, req.MaxSeats()) + qs.reqsGaugePair.RequestsExecuting.Add(1) + qs.execSeatsGauge.Add(float64(req.MaxSeats())) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + klogV := klog.V(5) + if klogV.Enabled() { + klogV.Infof("QS(%s) at t=%s R=%v: immediate dispatch of request %q %#+v %#+v, qs will have %d executing", qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, fsName, descr1, descr2, qs.totRequestsExecuting) + } + return req +} + +// dispatchLocked uses the Fair Queuing for Server Requests method to +// select a queue and dispatch the oldest request in that queue. The +// return value indicates whether a request was dequeued; this will +// be false when either all queues are empty or the request at the head +// of the next queue cannot be dispatched. +func (qs *queueSet) dispatchLocked() bool { + queue, request := qs.findDispatchQueueToBoundLocked() + if queue == nil { + return false + } + if request == nil { // This should never happen. But if it does... + return false + } + qs.totRequestsWaiting-- + qs.totSeatsWaiting -= request.MaxSeats() + metrics.AddRequestsInQueues(request.ctx, qs.qCfg.Name, request.fsName, -1) + request.NoteQueued(false) + qs.reqsGaugePair.RequestsWaiting.Add(-1) + defer qs.boundNextDispatchLocked(queue) + if !request.decision.Set(decisionExecute) { + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + return true + } + request.startTime = qs.clock.Now() + // At this moment the request leaves its queue and starts + // executing. We do not recognize any interim state between + // "queued" and "executing". While that means "executing" + // includes a little overhead from this package, this is not a + // problem because other overhead is also included. + qs.totRequestsExecuting++ + qs.totSeatsInUse += request.MaxSeats() + queue.requestsExecuting++ + queue.seatsInUse += request.MaxSeats() + metrics.AddRequestsExecuting(request.ctx, qs.qCfg.Name, request.fsName, 1) + metrics.AddRequestConcurrencyInUse(qs.qCfg.Name, request.fsName, request.MaxSeats()) + qs.reqsGaugePair.RequestsExecuting.Add(1) + qs.execSeatsGauge.Add(float64(request.MaxSeats())) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + klogV := klog.V(6) + if klogV.Enabled() { + klogV.Infof("QS(%s) at t=%s R=%v: dispatching request %#+v %#+v work %v from queue %d with start R %v, queue will have %d waiting & %d requests occupying %d seats, set will have %d seats occupied", + qs.qCfg.Name, request.startTime.Format(nsTimeFmt), qs.currentR, request.descr1, request.descr2, + request.workEstimate, queue.index, queue.nextDispatchR, queue.requests.Length(), queue.requestsExecuting, queue.seatsInUse, qs.totSeatsInUse) + } + // When a request is dequeued for service -> qs.virtualStart += G * width + if request.totalWork() > rDecrement/100 { // A single increment should never be so big + klog.Errorf("QS(%s) at t=%s R=%v: dispatching request %#+v %#+v with implausibly high work %v from queue %d with start R %v", + qs.qCfg.Name, request.startTime.Format(nsTimeFmt), qs.currentR, request.descr1, request.descr2, + request.workEstimate, queue.index, queue.nextDispatchR) + } + queue.nextDispatchR += request.totalWork() + return true +} + +// canAccommodateSeatsLocked returns true if this queueSet has enough +// seats available to accommodate a request with the given number of seats, +// otherwise it returns false. +func (qs *queueSet) canAccommodateSeatsLocked(seats int) bool { + switch { + case seats > qs.dCfg.ConcurrencyLimit: + // we have picked the queue with the minimum virtual finish time, but + // the number of seats this request asks for exceeds the concurrency limit. + // TODO: this is a quick fix for now, once we have borrowing in place we will not need it + if qs.totRequestsExecuting == 0 { + // TODO: apply additional lateny associated with this request, as described in the KEP + return true + } + // wait for all "currently" executing requests in this queueSet + // to finish before we can execute this request. + return false + case qs.totSeatsInUse+seats > qs.dCfg.ConcurrencyLimit: + return false + } + + return true +} + +// findDispatchQueueToBoundLocked examines the queues in round robin order and +// returns the first one of those for which the virtual finish time of +// the oldest waiting request is minimal, and also returns that request. +// Returns nils if the head of the selected queue can not be dispatched now, +// in which case the caller does not need to follow up with`qs.boundNextDispatchLocked`. +func (qs *queueSet) findDispatchQueueToBoundLocked() (*queue, *request) { + minVirtualFinish := fqrequest.MaxSeatSeconds + sMin := fqrequest.MaxSeatSeconds + dsMin := fqrequest.MaxSeatSeconds + sMax := fqrequest.MinSeatSeconds + dsMax := fqrequest.MinSeatSeconds + var minQueue *queue + var minIndex int + nq := len(qs.queues) + for range qs.queues { + qs.robinIndex = (qs.robinIndex + 1) % nq + queue := qs.queues[qs.robinIndex] + oldestWaiting, _ := queue.requests.Peek() + if oldestWaiting != nil { + sMin = ssMin(sMin, queue.nextDispatchR) + sMax = ssMax(sMax, queue.nextDispatchR) + estimatedWorkInProgress := fqrequest.SeatsTimesDuration(float64(queue.seatsInUse), qs.estimatedServiceDuration) + dsMin = ssMin(dsMin, queue.nextDispatchR-estimatedWorkInProgress) + dsMax = ssMax(dsMax, queue.nextDispatchR-estimatedWorkInProgress) + currentVirtualFinish := queue.nextDispatchR + oldestWaiting.totalWork() + klog.V(11).InfoS("Considering queue to dispatch", "queueSet", qs.qCfg.Name, "queue", qs.robinIndex, "finishR", currentVirtualFinish) + if currentVirtualFinish < minVirtualFinish { + minVirtualFinish = currentVirtualFinish + minQueue = queue + minIndex = qs.robinIndex + } + } + } + + oldestReqFromMinQueue, _ := minQueue.requests.Peek() + if oldestReqFromMinQueue == nil { + // This cannot happen + klog.ErrorS(errors.New("selected queue is empty"), "Impossible", "queueSet", qs.qCfg.Name) + return nil, nil + } + if !qs.canAccommodateSeatsLocked(oldestReqFromMinQueue.MaxSeats()) { + // since we have not picked the queue with the minimum virtual finish + // time, we are not going to advance the round robin index here. + klogV := klog.V(4) + if klogV.Enabled() { + klogV.Infof("QS(%s): request %v %v seats %d cannot be dispatched from queue %d, waiting for currently executing requests to complete, %d requests are occupying %d seats and the limit is %d", + qs.qCfg.Name, oldestReqFromMinQueue.descr1, oldestReqFromMinQueue.descr2, oldestReqFromMinQueue.MaxSeats(), minQueue.index, qs.totRequestsExecuting, qs.totSeatsInUse, qs.dCfg.ConcurrencyLimit) + } + metrics.AddDispatchWithNoAccommodation(qs.qCfg.Name, oldestReqFromMinQueue.fsName) + return nil, nil + } + oldestReqFromMinQueue.removeFromQueueLocked() + + // If the requested final seats exceed capacity of that queue, + // we reduce them to current capacity and adjust additional latency + // to preserve the total amount of work. + if oldestReqFromMinQueue.workEstimate.FinalSeats > uint64(qs.dCfg.ConcurrencyLimit) { + finalSeats := uint64(qs.dCfg.ConcurrencyLimit) + additionalLatency := oldestReqFromMinQueue.workEstimate.finalWork.DurationPerSeat(float64(finalSeats)) + oldestReqFromMinQueue.workEstimate.FinalSeats = finalSeats + oldestReqFromMinQueue.workEstimate.AdditionalLatency = additionalLatency + } + + // we set the round robin indexing to start at the chose queue + // for the next round. This way the non-selected queues + // win in the case that the virtual finish times are the same + qs.robinIndex = minIndex + + if minQueue.nextDispatchR < oldestReqFromMinQueue.arrivalR { + klog.ErrorS(errors.New("dispatch before arrival"), "Inconceivable!", "QS", qs.qCfg.Name, "queue", minQueue.index, "dispatchR", minQueue.nextDispatchR, "request", oldestReqFromMinQueue) + } + metrics.SetDispatchMetrics(qs.qCfg.Name, qs.currentR.ToFloat(), minQueue.nextDispatchR.ToFloat(), sMin.ToFloat(), sMax.ToFloat(), dsMin.ToFloat(), dsMax.ToFloat()) + return minQueue, oldestReqFromMinQueue +} + +func ssMin(a, b fqrequest.SeatSeconds) fqrequest.SeatSeconds { + if a > b { + return b + } + return a +} + +func ssMax(a, b fqrequest.SeatSeconds) fqrequest.SeatSeconds { + if a < b { + return b + } + return a +} + +// finishRequestAndDispatchAsMuchAsPossible is a convenience method +// which calls finishRequest for a given request and then dispatches +// as many requests as possible. This is all of what needs to be done +// once a request finishes execution or is canceled. This returns a bool +// indicating whether the QueueSet is now idle. +func (qs *queueSet) finishRequestAndDispatchAsMuchAsPossible(req *request) bool { + qs.lockAndSyncTime(req.ctx) + defer qs.lock.Unlock() + + qs.finishRequestLocked(req) + qs.dispatchAsMuchAsPossibleLocked() + return qs.isIdleLocked() +} + +// finishRequestLocked is a callback that should be used when a +// previously dispatched request has completed it's service. This +// callback updates important state in the queueSet +func (qs *queueSet) finishRequestLocked(r *request) { + now := qs.clock.Now() + qs.totRequestsExecuting-- + metrics.AddRequestsExecuting(r.ctx, qs.qCfg.Name, r.fsName, -1) + qs.reqsGaugePair.RequestsExecuting.Add(-1) + + actualServiceDuration := now.Sub(r.startTime) + + // TODO: for now we keep the logic localized so it is easier to see + // how the counters are tracked for queueset and queue, in future we + // can refactor to move this function. + releaseSeatsLocked := func() { + defer qs.removeQueueIfEmptyLocked(r) + + qs.totSeatsInUse -= r.MaxSeats() + metrics.AddRequestConcurrencyInUse(qs.qCfg.Name, r.fsName, -r.MaxSeats()) + qs.execSeatsGauge.Add(-float64(r.MaxSeats())) + qs.seatDemandIntegrator.Set(float64(qs.totSeatsInUse + qs.totSeatsWaiting)) + if r.queue != nil { + r.queue.seatsInUse -= r.MaxSeats() + } + } + + defer func() { + klogV := klog.V(6) + if r.workEstimate.AdditionalLatency <= 0 { + // release the seats allocated to this request immediately + releaseSeatsLocked() + if !klogV.Enabled() { + } else if r.queue != nil { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished all use of %d seats, adjusted queue %d start R to %v due to service time %.9fs, queue will have %d requests with %#v waiting & %d requests occupying %d seats", + qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.MaxSeats(), r.queue.index, + r.queue.nextDispatchR, actualServiceDuration.Seconds(), r.queue.requests.Length(), r.queue.requests.QueueSum(), r.queue.requestsExecuting, r.queue.seatsInUse) + } else { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished all use of %d seats, qs will have %d requests occupying %d seats", qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.InitialSeats, qs.totRequestsExecuting, qs.totSeatsInUse) + } + return + } + + additionalLatency := r.workEstimate.AdditionalLatency + if !klogV.Enabled() { + } else if r.queue != nil { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished main use of %d seats but lingering on %d seats for %v seconds, adjusted queue %d start R to %v due to service time %.9fs, queue will have %d requests with %#v waiting & %d requests occupying %d seats", + qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.InitialSeats, r.workEstimate.FinalSeats, additionalLatency.Seconds(), r.queue.index, + r.queue.nextDispatchR, actualServiceDuration.Seconds(), r.queue.requests.Length(), r.queue.requests.QueueSum(), r.queue.requestsExecuting, r.queue.seatsInUse) + } else { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished main use of %d seats but lingering on %d seats for %v seconds, qs will have %d requests occupying %d seats", qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.InitialSeats, r.workEstimate.FinalSeats, additionalLatency.Seconds(), qs.totRequestsExecuting, qs.totSeatsInUse) + } + // EventAfterDuration will execute the event func in a new goroutine, + // so the seats allocated to this request will be released after + // AdditionalLatency elapses, this ensures that the additional + // latency has no impact on the user experience. + qs.clock.EventAfterDuration(func(_ time.Time) { + qs.lockAndSyncTime(r.ctx) + defer qs.lock.Unlock() + now := qs.clock.Now() + releaseSeatsLocked() + if !klogV.Enabled() { + } else if r.queue != nil { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished lingering on %d seats, queue %d will have %d requests with %#v waiting & %d requests occupying %d seats", + qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.FinalSeats, r.queue.index, + r.queue.requests.Length(), r.queue.requests.QueueSum(), r.queue.requestsExecuting, r.queue.seatsInUse) + } else { + klogV.Infof("QS(%s) at t=%s R=%v: request %#+v %#+v finished lingering on %d seats, qs will have %d requests occupying %d seats", qs.qCfg.Name, now.Format(nsTimeFmt), qs.currentR, r.descr1, r.descr2, r.workEstimate.FinalSeats, qs.totRequestsExecuting, qs.totSeatsInUse) + } + qs.dispatchAsMuchAsPossibleLocked() + }, additionalLatency) + }() + + if r.queue != nil { + // request has finished, remove from requests executing + r.queue.requestsExecuting-- + + // When a request finishes being served, and the actual service time was S, + // the queue’s start R is decremented by (G - S)*width. + r.queue.nextDispatchR -= fqrequest.SeatsTimesDuration(float64(r.InitialSeats()), qs.estimatedServiceDuration-actualServiceDuration) + qs.boundNextDispatchLocked(r.queue) + } +} + +// boundNextDispatchLocked applies the anti-windup hack. +// We need a hack because all non-empty queues are allocated the same +// number of seats. A queue that can not use all those seats and does +// not go empty accumulates a progresively earlier `virtualStart` compared +// to queues that are using more than they are allocated. +// The following hack addresses the first side of that inequity, +// by insisting that dispatch in the virtual world not precede arrival. +func (qs *queueSet) boundNextDispatchLocked(queue *queue) { + oldestReqFromMinQueue, _ := queue.requests.Peek() + if oldestReqFromMinQueue == nil { + return + } + var virtualStartBound = oldestReqFromMinQueue.arrivalR + if queue.nextDispatchR < virtualStartBound { + if klogV := klog.V(4); klogV.Enabled() { + klogV.InfoS("AntiWindup tweaked queue", "QS", qs.qCfg.Name, "queue", queue.index, "time", qs.clock.Now().Format(nsTimeFmt), "requestDescr1", oldestReqFromMinQueue.descr1, "requestDescr2", oldestReqFromMinQueue.descr2, "newVirtualStart", virtualStartBound, "deltaVirtualStart", (virtualStartBound - queue.nextDispatchR)) + } + queue.nextDispatchR = virtualStartBound + } +} + +func (qs *queueSet) removeQueueIfEmptyLocked(r *request) { + if r.queue == nil { + return + } + + // If there are more queues than desired and this one has no + // requests then remove it + if len(qs.queues) > qs.qCfg.DesiredNumQueues && + r.queue.requests.Length() == 0 && + r.queue.requestsExecuting == 0 { + qs.queues = removeQueueAndUpdateIndexes(qs.queues, r.queue.index) + + // decrement here to maintain the invariant that (qs.robinIndex+1) % numQueues + // is the index of the next queue after the one last dispatched from + if qs.robinIndex >= r.queue.index { + qs.robinIndex-- + } + } +} + +// removeQueueAndUpdateIndexes uses reslicing to remove an index from a slice +// and then updates the 'index' field of the queues to be correct +func removeQueueAndUpdateIndexes(queues []*queue, index int) []*queue { + keptQueues := append(queues[:index], queues[index+1:]...) + for i := index; i < len(keptQueues); i++ { + keptQueues[i].index-- + } + return keptQueues +} + +func (qs *queueSet) Dump(includeRequestDetails bool) debug.QueueSetDump { + qs.lock.Lock() + defer qs.lock.Unlock() + d := debug.QueueSetDump{ + Queues: make([]debug.QueueDump, len(qs.queues)), + Waiting: qs.totRequestsWaiting, + Executing: qs.totRequestsExecuting, + SeatsInUse: qs.totSeatsInUse, + SeatsWaiting: qs.totSeatsWaiting, + } + for i, q := range qs.queues { + d.Queues[i] = q.dumpLocked(includeRequestDetails) + } + return d +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/types.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/types.go new file mode 100644 index 000000000..f1073b96b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/types.go @@ -0,0 +1,183 @@ +/* +Copyright 2019 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 queueset + +import ( + "context" + "time" + + genericrequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/util/flowcontrol/debug" + fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" + "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise" + fcrequest "k8s.io/apiserver/pkg/util/flowcontrol/request" +) + +// request is a temporary container for "requests" with additional +// tracking fields required for QueueSet functionality. +type request struct { + ctx context.Context + + qs *queueSet + + flowDistinguisher string + fsName string + + // The relevant queue. Is nil if this request did not go through + // a queue. + queue *queue + + // estimated amount of work of the request + workEstimate completedWorkEstimate + + // decision gets set to a `requestDecision` indicating what to do + // with this request. It gets set exactly once, when the request + // is removed from its queue. The value will be decisionReject, + // decisionCancel, or decisionExecute. + // + // decision.Set is called with the queueSet locked. + // decision.Get is called without the queueSet locked. + decision promise.WriteOnce + + // arrivalTime is the real time when the request entered this system + arrivalTime time.Time + + // descr1 and descr2 are not used in any logic but they appear in + // log messages + descr1, descr2 interface{} + + queueNoteFn fq.QueueNoteFn + + // The preceding fields are filled in at creation and not modified since; + // the following fields may be modified later and must only be accessed while + // holding the queueSet's lock. + + // Removes this request from its queue. If the request is not put into a + // a queue it will be nil. + removeFromQueueLocked removeFromFIFOFunc + + // arrivalR is R(arrivalTime). R is, confusingly, also called "virtual time". + // This field is meaningful only while the request is waiting in the virtual world. + arrivalR fcrequest.SeatSeconds + + // startTime is the real time when the request began executing + startTime time.Time + + // Indicates whether client has called Request::Wait() + waitStarted bool +} + +type completedWorkEstimate struct { + fcrequest.WorkEstimate + totalWork fcrequest.SeatSeconds // initial plus final work + finalWork fcrequest.SeatSeconds // only final work +} + +// queue is a sequence of requests that have arrived but not yet finished +// execution in both the real and virtual worlds. +type queue struct { + // The requests not yet executing in the real world are stored in a FIFO list. + requests fifo + + // nextDispatchR is the R progress meter reading at + // which the next request will be dispatched in the virtual world. + nextDispatchR fcrequest.SeatSeconds + + // requestsExecuting is the count in the real world. + requestsExecuting int + + // index is the position of this queue among those in its queueSet. + index int + + // seatsInUse is the total number of "seats" currently occupied + // by all the requests that are currently executing in this queue. + seatsInUse int +} + +// queueSum tracks the sum of initial seats, max seats, and +// totalWork from all requests in a given queue +type queueSum struct { + // InitialSeatsSum is the sum of InitialSeats + // associated with all requests in a given queue. + InitialSeatsSum int + + // MaxSeatsSum is the sum of MaxSeats + // associated with all requests in a given queue. + MaxSeatsSum int + + // TotalWorkSum is the sum of totalWork of the waiting requests + TotalWorkSum fcrequest.SeatSeconds +} + +func (req *request) totalWork() fcrequest.SeatSeconds { + return req.workEstimate.totalWork +} + +func (qs *queueSet) completeWorkEstimate(we *fcrequest.WorkEstimate) completedWorkEstimate { + finalWork := qs.computeFinalWork(we) + return completedWorkEstimate{ + WorkEstimate: *we, + totalWork: qs.computeInitialWork(we) + finalWork, + finalWork: finalWork, + } +} + +func (qs *queueSet) computeInitialWork(we *fcrequest.WorkEstimate) fcrequest.SeatSeconds { + return fcrequest.SeatsTimesDuration(float64(we.InitialSeats), qs.estimatedServiceDuration) +} + +func (qs *queueSet) computeFinalWork(we *fcrequest.WorkEstimate) fcrequest.SeatSeconds { + return fcrequest.SeatsTimesDuration(float64(we.FinalSeats), we.AdditionalLatency) +} + +func (q *queue) dumpLocked(includeDetails bool) debug.QueueDump { + digest := make([]debug.RequestDump, q.requests.Length()) + i := 0 + q.requests.Walk(func(r *request) bool { + // dump requests. + digest[i].MatchedFlowSchema = r.fsName + digest[i].FlowDistinguisher = r.flowDistinguisher + digest[i].ArriveTime = r.arrivalTime + digest[i].StartTime = r.startTime + digest[i].WorkEstimate = r.workEstimate.WorkEstimate + if includeDetails { + userInfo, _ := genericrequest.UserFrom(r.ctx) + digest[i].UserName = userInfo.GetName() + requestInfo, ok := genericrequest.RequestInfoFrom(r.ctx) + if ok { + digest[i].RequestInfo = *requestInfo + } + } + i++ + return true + }) + + sum := q.requests.QueueSum() + queueSum := debug.QueueSum{ + InitialSeatsSum: sum.InitialSeatsSum, + MaxSeatsSum: sum.MaxSeatsSum, + TotalWorkSum: sum.TotalWorkSum.String(), + } + + return debug.QueueDump{ + NextDispatchR: q.nextDispatchR.String(), + Requests: digest, + ExecutingRequests: q.requestsExecuting, + SeatsInUse: q.seatsInUse, + QueueSum: queueSum, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/format/formatting.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/format/formatting.go new file mode 100644 index 000000000..494442373 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/format/formatting.go @@ -0,0 +1,231 @@ +/* +Copyright 2019 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 format + +import ( + "bytes" + "encoding/json" + "fmt" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" +) + +// This file provides an easy way to mark a value for formatting to +// `%s` in full detail IF it is printed but without costing a lot of +// CPU or memory if the value is NOT printed. The API Priority and +// Fairness API objects are formatted into JSON. The other types of +// objects here are formatted into golang source. + +// Stringer marks the given value for custom formatting by this package. +type Stringer struct{ val interface{} } + +// Fmt marks the given value for custom formatting by this package. +func Fmt(val interface{}) Stringer { + return Stringer{val} +} + +// String formats to a string in full detail +func (sr Stringer) String() string { + if sr.val == nil { + return "nil" + } + switch typed := sr.val.(type) { + case *flowcontrol.FlowSchema, + flowcontrol.FlowSchema, + flowcontrol.FlowSchemaSpec, + flowcontrol.FlowDistinguisherMethod, + *flowcontrol.FlowDistinguisherMethod, + *flowcontrol.PolicyRulesWithSubjects, + flowcontrol.PolicyRulesWithSubjects, + flowcontrol.Subject, + flowcontrol.ResourcePolicyRule, + flowcontrol.NonResourcePolicyRule, + flowcontrol.FlowSchemaCondition, + *flowcontrol.PriorityLevelConfiguration, + flowcontrol.PriorityLevelConfiguration, + flowcontrol.PriorityLevelConfigurationSpec, + *flowcontrol.LimitedPriorityLevelConfiguration, + flowcontrol.LimitedPriorityLevelConfiguration, + flowcontrol.LimitResponse, + *flowcontrol.QueuingConfiguration, + flowcontrol.QueuingConfiguration: + return ToJSON(sr.val) + case []user.Info: + return FmtUsers(typed) + case []*request.RequestInfo: + return FmtRequests(typed) + default: + return fmt.Sprintf("%#+v", sr.val) + } +} + +// ToJSON converts using encoding/json and handles errors by +// formatting them +func ToJSON(val interface{}) string { + bs, err := json.Marshal(val) + str := string(bs) + if err != nil { + str = str + "<" + err.Error() + ">" + } + return str +} + +// FmtPriorityLevelConfiguration returns a golang source expression +// equivalent to the given value +func FmtPriorityLevelConfiguration(pl *flowcontrol.PriorityLevelConfiguration) string { + if pl == nil { + return "nil" + } + var buf bytes.Buffer + buf.WriteString(fmt.Sprintf("&flowcontrolv1beta3.PriorityLevelConfiguration{ObjectMeta: %#+v, Spec: ", + pl.ObjectMeta)) + BufferPriorityLevelConfigurationSpec(&buf, &pl.Spec) + buf.WriteString(fmt.Sprintf(", Status: %#+v}", pl.Status)) + return buf.String() +} + +// FmtPriorityLevelConfigurationSpec returns a golang source +// expression equivalent to the given value +func FmtPriorityLevelConfigurationSpec(plSpec *flowcontrol.PriorityLevelConfigurationSpec) string { + var buf bytes.Buffer + BufferPriorityLevelConfigurationSpec(&buf, plSpec) + return buf.String() +} + +// BufferPriorityLevelConfigurationSpec writes a golang source +// expression for the given value to the given buffer +func BufferPriorityLevelConfigurationSpec(buf *bytes.Buffer, plSpec *flowcontrol.PriorityLevelConfigurationSpec) { + buf.WriteString(fmt.Sprintf("flowcontrolv1beta3.PriorityLevelConfigurationSpec{Type: %#v", plSpec.Type)) + if plSpec.Limited != nil { + buf.WriteString(fmt.Sprintf(", Limited: &flowcontrol.LimitedPriorityLevelConfiguration{NominalConcurrencyShares:%d, LimitResponse:flowcontrol.LimitResponse{Type:%#v", plSpec.Limited.NominalConcurrencyShares, plSpec.Limited.LimitResponse.Type)) + if plSpec.Limited.LimitResponse.Queuing != nil { + buf.WriteString(fmt.Sprintf(", Queuing:&%#+v", *plSpec.Limited.LimitResponse.Queuing)) + } + buf.WriteString(" } }") + } + buf.WriteString("}") +} + +// FmtFlowSchema produces a golang source expression of the value. +func FmtFlowSchema(fs *flowcontrol.FlowSchema) string { + if fs == nil { + return "nil" + } + var buf bytes.Buffer + buf.WriteString(fmt.Sprintf("&flowcontrolv1beta3.FlowSchema{ObjectMeta: %#+v, Spec: ", + fs.ObjectMeta)) + BufferFlowSchemaSpec(&buf, &fs.Spec) + buf.WriteString(fmt.Sprintf(", Status: %#+v}", fs.Status)) + return buf.String() +} + +// FmtFlowSchemaSpec produces a golang source expression equivalent to +// the given spec +func FmtFlowSchemaSpec(fsSpec *flowcontrol.FlowSchemaSpec) string { + var buf bytes.Buffer + BufferFlowSchemaSpec(&buf, fsSpec) + return buf.String() +} + +// BufferFlowSchemaSpec writes a golang source expression for the +// given value to the given buffer +func BufferFlowSchemaSpec(buf *bytes.Buffer, fsSpec *flowcontrol.FlowSchemaSpec) { + buf.WriteString(fmt.Sprintf("flowcontrolv1beta3.FlowSchemaSpec{PriorityLevelConfiguration: %#+v, MatchingPrecedence: %d, DistinguisherMethod: ", + fsSpec.PriorityLevelConfiguration, + fsSpec.MatchingPrecedence)) + if fsSpec.DistinguisherMethod == nil { + buf.WriteString("nil") + } else { + buf.WriteString(fmt.Sprintf("&%#+v", *fsSpec.DistinguisherMethod)) + } + buf.WriteString(", Rules: []flowcontrol.PolicyRulesWithSubjects{") + for idx, rule := range fsSpec.Rules { + if idx > 0 { + buf.WriteString(", ") + } + BufferFmtPolicyRulesWithSubjectsSlim(buf, rule) + } + buf.WriteString("}}") +} + +// FmtPolicyRulesWithSubjects produces a golang source expression of the value. +func FmtPolicyRulesWithSubjects(rule flowcontrol.PolicyRulesWithSubjects) string { + return "flowcontrolv1beta3.PolicyRulesWithSubjects" + FmtPolicyRulesWithSubjectsSlim(rule) +} + +// FmtPolicyRulesWithSubjectsSlim produces a golang source expression +// of the value but without the leading type name. See above for an +// example context where this is useful. +func FmtPolicyRulesWithSubjectsSlim(rule flowcontrol.PolicyRulesWithSubjects) string { + var buf bytes.Buffer + BufferFmtPolicyRulesWithSubjectsSlim(&buf, rule) + return buf.String() +} + +// BufferFmtPolicyRulesWithSubjectsSlim writes a golang source +// expression for the given value to the given buffer but excludes the +// leading type name +func BufferFmtPolicyRulesWithSubjectsSlim(buf *bytes.Buffer, rule flowcontrol.PolicyRulesWithSubjects) { + buf.WriteString("{Subjects: []flowcontrolv1beta3.Subject{") + for jdx, subj := range rule.Subjects { + if jdx > 0 { + buf.WriteString(", ") + } + buf.WriteString(fmt.Sprintf("{Kind: %q", subj.Kind)) + if subj.User != nil { + buf.WriteString(fmt.Sprintf(", User: &%#+v", *subj.User)) + } + if subj.Group != nil { + buf.WriteString(fmt.Sprintf(", Group: &%#+v", *subj.Group)) + } + if subj.ServiceAccount != nil { + buf.WriteString(fmt.Sprintf(", ServiceAccount: &%#+v", *subj.ServiceAccount)) + } + buf.WriteString("}") + } + buf.WriteString(fmt.Sprintf("}, ResourceRules: %#+v, NonResourceRules: %#+v}", rule.ResourceRules, rule.NonResourceRules)) +} + +// FmtUsers produces a golang source expression of the value. +func FmtUsers(list []user.Info) string { + var buf bytes.Buffer + buf.WriteString("[]user.Info{") + for idx, member := range list { + if idx > 0 { + buf.WriteString(", ") + } + buf.WriteString(fmt.Sprintf("%#+v", member)) + } + buf.WriteString("}") + return buf.String() +} + +// FmtRequests produces a golang source expression of the value. +func FmtRequests(list []*request.RequestInfo) string { + var buf bytes.Buffer + buf.WriteString("[]*request.RequestInfo{") + for idx, member := range list { + if idx > 0 { + buf.WriteString(", ") + } + buf.WriteString(fmt.Sprintf("%#+v", member)) + } + buf.WriteString("}") + return buf.String() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/formatting.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/formatting.go new file mode 100644 index 000000000..5b5b367bd --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/formatting.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 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 flowcontrol + +import ( + "fmt" + + fcfmt "k8s.io/apiserver/pkg/util/flowcontrol/format" +) + +var _ fmt.GoStringer = RequestDigest{} + +// GoString produces a golang source expression of the value. +func (rd RequestDigest) GoString() string { + return fmt.Sprintf("RequestDigest{RequestInfo: %#+v, User: %#+v}", rd.RequestInfo, rd.User) +} + +var _ fmt.GoStringer = (*priorityLevelState)(nil) + +// GoString produces a golang source expression of the value. +func (pls *priorityLevelState) GoString() string { + if pls == nil { + return "nil" + } + return fmt.Sprintf("&priorityLevelState{pl:%s, qsCompleter:%#+v, queues:%#+v, quiescing:%#v, numPending:%d}", fcfmt.Fmt(pls.pl), pls.qsCompleter, pls.queues, pls.quiescing, pls.numPending) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/interface.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/interface.go new file mode 100644 index 000000000..1f33f02b0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/interface.go @@ -0,0 +1,67 @@ +/* +Copyright 2019 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 metrics + +// Gauge is the methods of a gauge that are used by instrumented code. +type Gauge interface { + Set(float64) + Inc() + Dec() + Add(float64) + SetToCurrentTime() +} + +// RatioedGauge tracks ratios. +// The numerator is set/changed through the Gauge methods, +// and the denominator can be updated through the SetDenominator method. +// A ratio is tracked whenever the numerator or denominator is set/changed. +type RatioedGauge interface { + Gauge + + // SetDenominator sets the denominator to use until it is changed again + SetDenominator(float64) +} + +// RatioedGaugeVec creates related observers that are +// differentiated by a series of label values +type RatioedGaugeVec interface { + // NewForLabelValuesSafe makes a new vector member for the given tuple of label values, + // initialized with the given numerator and denominator. + // Unlike the usual Vec WithLabelValues method, this is intended to be called only + // once per vector member (at the start of its lifecycle). + // The "Safe" part is saying that the returned object will function properly after metric registration + // even if this method is called before registration. + NewForLabelValuesSafe(initialNumerator, initialDenominator float64, labelValues []string) RatioedGauge +} + +//////////////////////////////// Pairs //////////////////////////////// +// +// API Priority and Fairness tends to use RatioedGaugeVec members in pairs, +// one for requests waiting in a queue and one for requests being executed. +// The following definitions are a convenience layer that adds support for that +// particular pattern of usage. + +// RatioedGaugePair is a corresponding pair of gauges, one for the +// number of requests waiting in queue(s) and one for the number of +// requests being executed. +type RatioedGaugePair struct { + // RequestsWaiting is given observations of the number of currently queued requests + RequestsWaiting RatioedGauge + + // RequestsExecuting is given observations of the number of requests currently executing + RequestsExecuting RatioedGauge +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/metrics.go new file mode 100644 index 000000000..7cb05df6c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/metrics.go @@ -0,0 +1,600 @@ +/* +Copyright 2019 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 metrics + +import ( + "context" + "strconv" + "strings" + "sync" + "time" + + epmetrics "k8s.io/apiserver/pkg/endpoints/metrics" + apirequest "k8s.io/apiserver/pkg/endpoints/request" + compbasemetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" + basemetricstestutil "k8s.io/component-base/metrics/testutil" +) + +const ( + namespace = "apiserver" + subsystem = "flowcontrol" +) + +const ( + requestKind = "request_kind" + priorityLevel = "priority_level" + flowSchema = "flow_schema" + phase = "phase" + LabelNamePhase = "phase" + LabelValueWaiting = "waiting" + LabelValueExecuting = "executing" +) + +var ( + queueLengthBuckets = []float64{0, 10, 25, 50, 100, 250, 500, 1000} + requestDurationSecondsBuckets = []float64{0, 0.005, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30} +) + +var registerMetrics sync.Once + +// Register all metrics. +func Register() { + registerMetrics.Do(func() { + for _, metric := range metrics { + legacyregistry.MustRegister(metric) + } + }) +} + +type resettable interface { + Reset() +} + +// Reset all resettable metrics to zero +func Reset() { + for _, metric := range metrics { + if rm, ok := metric.(resettable); ok { + rm.Reset() + } + } +} + +// GatherAndCompare the given metrics with the given Prometheus syntax expected value +func GatherAndCompare(expected string, metricNames ...string) error { + return basemetricstestutil.GatherAndCompare(legacyregistry.DefaultGatherer, strings.NewReader(expected), metricNames...) +} + +// Registerables is a slice of Registerable +type Registerables []compbasemetrics.Registerable + +// Append adds more +func (rs Registerables) Append(more ...compbasemetrics.Registerable) Registerables { + return append(rs, more...) +} + +var ( + apiserverRejectedRequestsTotal = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "rejected_requests_total", + Help: "Number of requests rejected by API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema, "reason"}, + ) + apiserverDispatchedRequestsTotal = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dispatched_requests_total", + Help: "Number of requests executed by API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + // PriorityLevelExecutionSeatsGaugeVec creates observers of seats occupied throughout execution for priority levels + PriorityLevelExecutionSeatsGaugeVec = NewTimingRatioHistogramVec( + &compbasemetrics.TimingHistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "priority_level_seat_utilization", + Help: "Observations, at the end of every nanosecond, of utilization of seats for any stage of execution (but only initial stage for WATCHes)", + // Buckets for both 0.99 and 1.0 mean PromQL's histogram_quantile will reveal saturation + Buckets: []float64{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1}, + ConstLabels: map[string]string{phase: "executing"}, + StabilityLevel: compbasemetrics.ALPHA, + }, + priorityLevel, + ) + // PriorityLevelConcurrencyGaugeVec creates gauges of concurrency broken down by phase, priority level + PriorityLevelConcurrencyGaugeVec = NewTimingRatioHistogramVec( + &compbasemetrics.TimingHistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "priority_level_request_utilization", + Help: "Observations, at the end of every nanosecond, of number of requests (as a fraction of the relevant limit) waiting or in any stage of execution (but only initial stage for WATCHes)", + // For executing: the denominator will be seats, so this metric will skew low. + // For waiting: total queue capacity is generally quite generous, so this metric will skew low. + Buckets: []float64{0, 0.001, 0.003, 0.01, 0.03, 0.1, 0.25, 0.5, 0.75, 1}, + StabilityLevel: compbasemetrics.ALPHA, + }, + LabelNamePhase, priorityLevel, + ) + // readWriteConcurrencyGaugeVec creates ratioed gauges of requests/limit broken down by phase and mutating vs readonly + readWriteConcurrencyGaugeVec = NewTimingRatioHistogramVec( + &compbasemetrics.TimingHistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "read_vs_write_current_requests", + Help: "Observations, at the end of every nanosecond, of the number of requests (as a fraction of the relevant limit) waiting or in regular stage of execution", + // This metric will skew low for the same reason as the priority level metrics + // and also because APF has a combined limit for mutating and readonly. + Buckets: []float64{0, 0.001, 0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1}, + StabilityLevel: compbasemetrics.ALPHA, + }, + LabelNamePhase, requestKind, + ) + apiserverCurrentR = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "current_r", + Help: "R(time of last change)", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverDispatchR = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "dispatch_r", + Help: "R(time of last dispatch)", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverLatestS = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "latest_s", + Help: "S(most recently dispatched request)", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverNextSBounds = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "next_s_bounds", + Help: "min and max, over queues, of S(oldest waiting request in queue)", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, "bound"}, + ) + apiserverNextDiscountedSBounds = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "next_discounted_s_bounds", + Help: "min and max, over queues, of S(oldest waiting request in queue) - estimated work in progress", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, "bound"}, + ) + apiserverCurrentInqueueRequests = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "current_inqueue_requests", + Help: "Number of requests currently pending in queues of the API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverRequestQueueLength = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_queue_length_after_enqueue", + Help: "Length of queue in the API Priority and Fairness subsystem, as seen by each request after it is enqueued", + Buckets: queueLengthBuckets, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverRequestConcurrencyLimit = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_concurrency_limit", + Help: "Shared concurrency limit in the API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverCurrentExecutingRequests = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "current_executing_requests", + Help: "Number of requests in initial (for a WATCH) or any (for a non-WATCH) execution stage in the API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverRequestConcurrencyInUse = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_concurrency_in_use", + Help: "Concurrency (number of seats) occupied by the currently executing (initial stage for a WATCH, any stage otherwise) requests in the API Priority and Fairness subsystem", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverRequestWaitingSeconds = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_wait_duration_seconds", + Help: "Length of time a request spent waiting in its queue", + Buckets: requestDurationSecondsBuckets, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema, "execute"}, + ) + apiserverRequestExecutionSeconds = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_execution_seconds", + Help: "Duration of initial stage (for a WATCH) or any (for a non-WATCH) stage of request execution in the API Priority and Fairness subsystem", + Buckets: requestDurationSecondsBuckets, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema, "type"}, + ) + watchCountSamples = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "watch_count_samples", + Help: "count of watchers for mutating requests in API Priority and Fairness", + Buckets: []float64{0, 1, 10, 100, 1000, 10000}, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverEpochAdvances = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "epoch_advance_total", + Help: "Number of times the queueset's progress meter jumped backward", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, "success"}, + ) + apiserverWorkEstimatedSeats = compbasemetrics.NewHistogramVec( + &compbasemetrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "work_estimated_seats", + Help: "Number of estimated seats (maximum of initial and final seats) associated with requests in API Priority and Fairness", + // the upper bound comes from the maximum number of seats a request + // can occupy which is currently set at 10. + Buckets: []float64{1, 2, 4, 10}, + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverDispatchWithNoAccommodation = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_dispatch_no_accommodation_total", + Help: "Number of times a dispatch attempt resulted in a non accommodation due to lack of available seats", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel, flowSchema}, + ) + apiserverNominalConcurrencyLimits = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "nominal_limit_seats", + Help: "Nominal number of execution seats configured for each priority level", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverMinimumConcurrencyLimits = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "lower_limit_seats", + Help: "Configured lower bound on number of execution seats available to each priority level", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverMaximumConcurrencyLimits = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "upper_limit_seats", + Help: "Configured upper bound on number of execution seats available to each priority level", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + ApiserverSeatDemands = NewTimingRatioHistogramVec( + &compbasemetrics.TimingHistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats", + Help: "Observations, at the end of every nanosecond, of (the number of seats each priority level could use) / (nominal number of seats for that level)", + // Rationale for the bucket boundaries: + // For 0--1, evenly spaced and not too many; + // For 1--2, roughly powers of sqrt(sqrt(2)); + // For 2--6, roughly powers of sqrt(2); + // We need coverage over 1, but do not want too many buckets. + Buckets: []float64{0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.7, 2, 2.8, 4, 6}, + StabilityLevel: compbasemetrics.ALPHA, + }, + priorityLevel, + ) + apiserverSeatDemandHighWatermarks = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats_high_watermark", + Help: "High watermark, over last adjustment period, of demand_seats", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverSeatDemandAverages = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats_average", + Help: "Time-weighted average, over last adjustment period, of demand_seats", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverSeatDemandStandardDeviations = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats_stdev", + Help: "Time-weighted standard deviation, over last adjustment period, of demand_seats", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverSeatDemandSmootheds = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "demand_seats_smoothed", + Help: "Smoothed seat demands", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverSeatDemandTargets = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "target_seats", + Help: "Seat allocation targets", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + apiserverFairFracs = compbasemetrics.NewGauge( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "seat_fair_frac", + Help: "Fair fraction of server's concurrency to allocate to each priority level that can use it", + StabilityLevel: compbasemetrics.ALPHA, + }) + apiserverCurrentConcurrencyLimits = compbasemetrics.NewGaugeVec( + &compbasemetrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "current_limit_seats", + Help: "current derived number of execution seats available to each priority level", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{priorityLevel}, + ) + + metrics = Registerables{ + apiserverRejectedRequestsTotal, + apiserverDispatchedRequestsTotal, + apiserverCurrentR, + apiserverDispatchR, + apiserverLatestS, + apiserverNextSBounds, + apiserverNextDiscountedSBounds, + apiserverCurrentInqueueRequests, + apiserverRequestQueueLength, + apiserverRequestConcurrencyLimit, + apiserverRequestConcurrencyInUse, + apiserverCurrentExecutingRequests, + apiserverRequestWaitingSeconds, + apiserverRequestExecutionSeconds, + watchCountSamples, + apiserverEpochAdvances, + apiserverWorkEstimatedSeats, + apiserverDispatchWithNoAccommodation, + apiserverNominalConcurrencyLimits, + apiserverMinimumConcurrencyLimits, + apiserverMaximumConcurrencyLimits, + apiserverSeatDemandHighWatermarks, + apiserverSeatDemandAverages, + apiserverSeatDemandStandardDeviations, + apiserverSeatDemandSmootheds, + apiserverSeatDemandTargets, + apiserverFairFracs, + apiserverCurrentConcurrencyLimits, + }. + Append(PriorityLevelExecutionSeatsGaugeVec.metrics()...). + Append(PriorityLevelConcurrencyGaugeVec.metrics()...). + Append(readWriteConcurrencyGaugeVec.metrics()...). + Append(ApiserverSeatDemands.metrics()...) +) + +type indexOnce struct { + labelValues []string + once sync.Once + gauge RatioedGauge +} + +func (io *indexOnce) getGauge() RatioedGauge { + io.once.Do(func() { + io.gauge = readWriteConcurrencyGaugeVec.NewForLabelValuesSafe(0, 1, io.labelValues) + }) + return io.gauge +} + +var waitingReadonly = indexOnce{labelValues: []string{LabelValueWaiting, epmetrics.ReadOnlyKind}} +var executingReadonly = indexOnce{labelValues: []string{LabelValueExecuting, epmetrics.ReadOnlyKind}} +var waitingMutating = indexOnce{labelValues: []string{LabelValueWaiting, epmetrics.MutatingKind}} +var executingMutating = indexOnce{labelValues: []string{LabelValueExecuting, epmetrics.MutatingKind}} + +// GetWaitingReadonlyConcurrency returns the gauge of number of readonly requests waiting / limit on those. +var GetWaitingReadonlyConcurrency = waitingReadonly.getGauge + +// GetExecutingReadonlyConcurrency returns the gauge of number of executing readonly requests / limit on those. +var GetExecutingReadonlyConcurrency = executingReadonly.getGauge + +// GetWaitingMutatingConcurrency returns the gauge of number of mutating requests waiting / limit on those. +var GetWaitingMutatingConcurrency = waitingMutating.getGauge + +// GetExecutingMutatingConcurrency returns the gauge of number of executing mutating requests / limit on those. +var GetExecutingMutatingConcurrency = executingMutating.getGauge + +// AddRequestsInQueues adds the given delta to the gauge of the # of requests in the queues of the specified flowSchema and priorityLevel +func AddRequestsInQueues(ctx context.Context, priorityLevel, flowSchema string, delta int) { + apiserverCurrentInqueueRequests.WithLabelValues(priorityLevel, flowSchema).Add(float64(delta)) +} + +// AddRequestsExecuting adds the given delta to the gauge of executing requests of the given flowSchema and priorityLevel +func AddRequestsExecuting(ctx context.Context, priorityLevel, flowSchema string, delta int) { + apiserverCurrentExecutingRequests.WithLabelValues(priorityLevel, flowSchema).Add(float64(delta)) +} + +// SetCurrentR sets the current-R (virtualTime) gauge for the given priority level +func SetCurrentR(priorityLevel string, r float64) { + apiserverCurrentR.WithLabelValues(priorityLevel).Set(r) +} + +// SetLatestS sets the latest-S (virtual time of dispatched request) gauge for the given priority level +func SetDispatchMetrics(priorityLevel string, r, s, sMin, sMax, discountedSMin, discountedSMax float64) { + apiserverDispatchR.WithLabelValues(priorityLevel).Set(r) + apiserverLatestS.WithLabelValues(priorityLevel).Set(s) + apiserverNextSBounds.WithLabelValues(priorityLevel, "min").Set(sMin) + apiserverNextSBounds.WithLabelValues(priorityLevel, "max").Set(sMax) + apiserverNextDiscountedSBounds.WithLabelValues(priorityLevel, "min").Set(discountedSMin) + apiserverNextDiscountedSBounds.WithLabelValues(priorityLevel, "max").Set(discountedSMax) +} + +// AddRequestConcurrencyInUse adds the given delta to the gauge of concurrency in use by +// the currently executing requests of the given flowSchema and priorityLevel +func AddRequestConcurrencyInUse(priorityLevel, flowSchema string, delta int) { + apiserverRequestConcurrencyInUse.WithLabelValues(priorityLevel, flowSchema).Add(float64(delta)) +} + +// AddReject increments the # of rejected requests for flow control +func AddReject(ctx context.Context, priorityLevel, flowSchema, reason string) { + apiserverRejectedRequestsTotal.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema, reason).Add(1) +} + +// AddDispatch increments the # of dispatched requests for flow control +func AddDispatch(ctx context.Context, priorityLevel, flowSchema string) { + apiserverDispatchedRequestsTotal.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema).Add(1) +} + +// ObserveQueueLength observes the queue length for flow control +func ObserveQueueLength(ctx context.Context, priorityLevel, flowSchema string, length int) { + apiserverRequestQueueLength.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema).Observe(float64(length)) +} + +// ObserveWaitingDuration observes the queue length for flow control +func ObserveWaitingDuration(ctx context.Context, priorityLevel, flowSchema, execute string, waitTime time.Duration) { + apiserverRequestWaitingSeconds.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema, execute).Observe(waitTime.Seconds()) +} + +// ObserveExecutionDuration observes the execution duration for flow control +func ObserveExecutionDuration(ctx context.Context, priorityLevel, flowSchema string, executionTime time.Duration) { + reqType := "regular" + if requestInfo, ok := apirequest.RequestInfoFrom(ctx); ok && requestInfo.Verb == "watch" { + reqType = requestInfo.Verb + } + apiserverRequestExecutionSeconds.WithContext(ctx).WithLabelValues(priorityLevel, flowSchema, reqType).Observe(executionTime.Seconds()) +} + +// ObserveWatchCount notes a sampling of a watch count +func ObserveWatchCount(ctx context.Context, priorityLevel, flowSchema string, count int) { + watchCountSamples.WithLabelValues(priorityLevel, flowSchema).Observe(float64(count)) +} + +// AddEpochAdvance notes an advance of the progress meter baseline for a given priority level +func AddEpochAdvance(ctx context.Context, priorityLevel string, success bool) { + apiserverEpochAdvances.WithContext(ctx).WithLabelValues(priorityLevel, strconv.FormatBool(success)).Inc() +} + +// ObserveWorkEstimatedSeats notes a sampling of estimated seats associated with a request +func ObserveWorkEstimatedSeats(priorityLevel, flowSchema string, seats int) { + apiserverWorkEstimatedSeats.WithLabelValues(priorityLevel, flowSchema).Observe(float64(seats)) +} + +// AddDispatchWithNoAccommodation keeps track of number of times dispatch attempt results +// in a non accommodation due to lack of available seats. +func AddDispatchWithNoAccommodation(priorityLevel, flowSchema string) { + apiserverDispatchWithNoAccommodation.WithLabelValues(priorityLevel, flowSchema).Inc() +} + +func SetPriorityLevelConfiguration(priorityLevel string, nominalCL, minCL, maxCL int) { + apiserverRequestConcurrencyLimit.WithLabelValues(priorityLevel).Set(float64(nominalCL)) + apiserverNominalConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(nominalCL)) + apiserverMinimumConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(minCL)) + apiserverMaximumConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(maxCL)) +} + +func NotePriorityLevelConcurrencyAdjustment(priorityLevel string, seatDemandHWM, seatDemandAvg, seatDemandStdev, seatDemandSmoothed, seatDemandTarget float64, currentCL int) { + apiserverSeatDemandHighWatermarks.WithLabelValues(priorityLevel).Set(seatDemandHWM) + apiserverSeatDemandAverages.WithLabelValues(priorityLevel).Set(seatDemandAvg) + apiserverSeatDemandStandardDeviations.WithLabelValues(priorityLevel).Set(seatDemandStdev) + apiserverSeatDemandSmootheds.WithLabelValues(priorityLevel).Set(seatDemandSmoothed) + apiserverSeatDemandTargets.WithLabelValues(priorityLevel).Set(seatDemandTarget) + apiserverCurrentConcurrencyLimits.WithLabelValues(priorityLevel).Set(float64(currentCL)) +} + +func SetFairFrac(fairFrac float64) { + apiserverFairFracs.Set(fairFrac) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go new file mode 100644 index 000000000..cd32782a4 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go @@ -0,0 +1,225 @@ +/* +Copyright 2022 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 metrics + +import ( + "context" + "sync" + "time" + + compbasemetrics "k8s.io/component-base/metrics" + "k8s.io/klog/v2" +) + +// TimingRatioHistogram is essentially a gauge for a ratio where the client +// independently controls the numerator and denominator. +// When scraped it produces a histogram of samples of the ratio +// taken at the end of every nanosecond. +// `*TimingRatioHistogram` implements both Registerable and RatioedGauge. +type TimingRatioHistogram struct { + // The implementation is layered on TimingHistogram, + // adding the division by an occasionally adjusted denominator. + + // Registerable is the registerable aspect. + // That is the registerable aspect of the underlying TimingHistogram. + compbasemetrics.Registerable + + // timingRatioHistogramInner implements the RatioedGauge aspect. + timingRatioHistogramInner +} + +// TimingRatioHistogramOpts is the constructor parameters of a TimingRatioHistogram. +// The `TimingHistogramOpts.InitialValue` is the initial numerator. +type TimingRatioHistogramOpts struct { + compbasemetrics.TimingHistogramOpts + InitialDenominator float64 +} + +// timingRatioHistogramInner implements the instrumentation aspect +type timingRatioHistogramInner struct { + nowFunc func() time.Time + getGaugeOfRatio func() Gauge + sync.Mutex + // access only with mutex locked + numerator, denominator float64 +} + +var _ RatioedGauge = &timingRatioHistogramInner{} +var _ RatioedGauge = &TimingRatioHistogram{} +var _ compbasemetrics.Registerable = &TimingRatioHistogram{} + +// NewTimingHistogram returns an object which is TimingHistogram-like. However, nothing +// will be measured until the histogram is registered in at least one registry. +func NewTimingRatioHistogram(opts *TimingRatioHistogramOpts) *TimingRatioHistogram { + return NewTestableTimingRatioHistogram(time.Now, opts) +} + +// NewTestableTimingHistogram adds injection of the clock +func NewTestableTimingRatioHistogram(nowFunc func() time.Time, opts *TimingRatioHistogramOpts) *TimingRatioHistogram { + ratioedOpts := opts.TimingHistogramOpts + ratioedOpts.InitialValue /= opts.InitialDenominator + th := compbasemetrics.NewTestableTimingHistogram(nowFunc, &ratioedOpts) + return &TimingRatioHistogram{ + Registerable: th, + timingRatioHistogramInner: timingRatioHistogramInner{ + nowFunc: nowFunc, + getGaugeOfRatio: func() Gauge { return th }, + numerator: opts.InitialValue, + denominator: opts.InitialDenominator, + }} +} + +func (trh *timingRatioHistogramInner) Set(numerator float64) { + trh.Lock() + defer trh.Unlock() + trh.numerator = numerator + ratio := numerator / trh.denominator + trh.getGaugeOfRatio().Set(ratio) +} + +func (trh *timingRatioHistogramInner) Add(deltaNumerator float64) { + trh.Lock() + defer trh.Unlock() + numerator := trh.numerator + deltaNumerator + trh.numerator = numerator + ratio := numerator / trh.denominator + trh.getGaugeOfRatio().Set(ratio) +} + +func (trh *timingRatioHistogramInner) Sub(deltaNumerator float64) { + trh.Add(-deltaNumerator) +} + +func (trh *timingRatioHistogramInner) Inc() { + trh.Add(1) +} + +func (trh *timingRatioHistogramInner) Dec() { + trh.Add(-1) +} + +func (trh *timingRatioHistogramInner) SetToCurrentTime() { + trh.Set(float64(trh.nowFunc().Sub(time.Unix(0, 0)))) +} + +func (trh *timingRatioHistogramInner) SetDenominator(denominator float64) { + trh.Lock() + defer trh.Unlock() + trh.denominator = denominator + ratio := trh.numerator / denominator + trh.getGaugeOfRatio().Set(ratio) +} + +// WithContext allows the normal TimingHistogram metric to pass in context. +// The context is no-op at the current level of development. +func (trh *timingRatioHistogramInner) WithContext(ctx context.Context) RatioedGauge { + return trh +} + +// TimingRatioHistogramVec is a collection of TimingRatioHistograms that differ +// only in label values. +// `*TimingRatioHistogramVec` implements both Registerable and RatioedGaugeVec. +type TimingRatioHistogramVec struct { + // promote only the Registerable methods + compbasemetrics.Registerable + // delegate is TimingHistograms of the ratio + delegate compbasemetrics.GaugeVecMetric +} + +var _ RatioedGaugeVec = &TimingRatioHistogramVec{} +var _ compbasemetrics.Registerable = &TimingRatioHistogramVec{} + +// NewTimingHistogramVec constructs a new vector. +// `opts.InitialValue` is the initial ratio, but this applies +// only for the tiny period of time until NewForLabelValuesSafe sets +// the ratio based on the given initial numerator and denominator. +// Thus there is a tiny splinter of time during member construction when +// its underlying TimingHistogram is given the initial numerator rather than +// the initial ratio (which is obviously a non-issue when both are zero). +// Note the difficulties associated with extracting a member +// before registering the vector. +func NewTimingRatioHistogramVec(opts *compbasemetrics.TimingHistogramOpts, labelNames ...string) *TimingRatioHistogramVec { + return NewTestableTimingRatioHistogramVec(time.Now, opts, labelNames...) +} + +// NewTestableTimingHistogramVec adds injection of the clock. +func NewTestableTimingRatioHistogramVec(nowFunc func() time.Time, opts *compbasemetrics.TimingHistogramOpts, labelNames ...string) *TimingRatioHistogramVec { + delegate := compbasemetrics.NewTestableTimingHistogramVec(nowFunc, opts, labelNames) + return &TimingRatioHistogramVec{ + Registerable: delegate, + delegate: delegate, + } +} + +func (v *TimingRatioHistogramVec) metrics() Registerables { + return Registerables{v} +} + +// NewForLabelValuesChecked will return an error if this vec is not hidden and not yet registered +// or there is a syntactic problem with the labelValues. +func (v *TimingRatioHistogramVec) NewForLabelValuesChecked(initialNumerator, initialDenominator float64, labelValues []string) (RatioedGauge, error) { + underMember, err := v.delegate.WithLabelValuesChecked(labelValues...) + if err != nil { + return noopRatioed{}, err + } + underMember.Set(initialNumerator / initialDenominator) + return &timingRatioHistogramInner{ + getGaugeOfRatio: func() Gauge { return underMember }, + numerator: initialNumerator, + denominator: initialDenominator, + }, nil +} + +// NewForLabelValuesSafe is the same as NewForLabelValuesChecked in cases where that does not +// return an error. When the unsafe version returns an error due to the vector not being +// registered yet, the safe version returns an object that implements its methods +// by looking up the relevant vector member in each call (thus getting a non-noop after registration). +// In the other error cases the object returned here is a noop. +func (v *TimingRatioHistogramVec) NewForLabelValuesSafe(initialNumerator, initialDenominator float64, labelValues []string) RatioedGauge { + tro, err := v.NewForLabelValuesChecked(initialNumerator, initialDenominator, labelValues) + if err == nil { + klog.V(3).InfoS("TimingRatioHistogramVec.NewForLabelValuesSafe hit the efficient case", "fqName", v.FQName(), "labelValues", labelValues) + return tro + } + if !compbasemetrics.ErrIsNotRegistered(err) { + klog.ErrorS(err, "Failed to extract TimingRatioHistogramVec member, using noop instead", "vectorname", v.FQName(), "labelValues", labelValues) + return tro + } + klog.V(3).InfoS("TimingRatioHistogramVec.NewForLabelValuesSafe hit the inefficient case", "fqName", v.FQName(), "labelValues", labelValues) + // At this point we know v.NewForLabelValuesChecked(..) returns a permanent noop, + // which we precisely want to avoid using. Instead, make our own gauge that + // fetches the element on every Set. + return &timingRatioHistogramInner{ + getGaugeOfRatio: func() Gauge { return v.delegate.WithLabelValues(labelValues...) }, + numerator: initialNumerator, + denominator: initialDenominator, + } +} + +type noopRatioed struct{} + +func (noopRatioed) Set(float64) {} +func (noopRatioed) Add(float64) {} +func (noopRatioed) Sub(float64) {} +func (noopRatioed) Inc() {} +func (noopRatioed) Dec() {} +func (noopRatioed) SetToCurrentTime() {} +func (noopRatioed) SetDenominator(float64) {} + +func (v *TimingRatioHistogramVec) Reset() { + v.delegate.Reset() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/union_gauge.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/union_gauge.go new file mode 100644 index 000000000..b01daaaaa --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/union_gauge.go @@ -0,0 +1,56 @@ +/* +Copyright 2022 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 metrics + +type unionGauge []Gauge + +var _ Gauge = unionGauge(nil) + +// NewUnionGauge constructs a Gauge that delegates to all of the given Gauges +func NewUnionGauge(elts ...Gauge) Gauge { + return unionGauge(elts) +} + +func (ug unionGauge) Set(x float64) { + for _, gauge := range ug { + gauge.Set(x) + } +} + +func (ug unionGauge) Add(x float64) { + for _, gauge := range ug { + gauge.Add(x) + } +} + +func (ug unionGauge) Inc() { + for _, gauge := range ug { + gauge.Inc() + } +} + +func (ug unionGauge) Dec() { + for _, gauge := range ug { + gauge.Dec() + } +} + +func (ug unionGauge) SetToCurrentTime() { + for _, gauge := range ug { + gauge.SetToCurrentTime() + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/vec_element_pair.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/vec_element_pair.go new file mode 100644 index 000000000..6dcef12c2 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/vec_element_pair.go @@ -0,0 +1,25 @@ +/* +Copyright 2019 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 metrics + +// RatioedGaugeVecPhasedElementPair extracts a pair of elements that differ in handling phase +func RatioedGaugeVecPhasedElementPair(vec RatioedGaugeVec, initialWaitingDenominator, initialExecutingDenominator float64, labelValues []string) RatioedGaugePair { + return RatioedGaugePair{ + RequestsWaiting: vec.NewForLabelValuesSafe(0, initialWaitingDenominator, append([]string{LabelValueWaiting}, labelValues...)), + RequestsExecuting: vec.NewForLabelValuesSafe(0, initialExecutingDenominator, append([]string{LabelValueExecuting}, labelValues...)), + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/config.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/config.go new file mode 100644 index 000000000..b6db19209 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/config.go @@ -0,0 +1,92 @@ +/* +Copyright 2022 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 request + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + minimumSeats = 1 + maximumSeats = 10 + objectsPerSeat = 100.0 + watchesPerSeat = 10.0 + enableMutatingWorkEstimator = true +) + +var eventAdditionalDuration = 5 * time.Millisecond + +// WorkEstimatorConfig holds work estimator parameters. +type WorkEstimatorConfig struct { + *ListWorkEstimatorConfig `json:"listWorkEstimatorConfig,omitempty"` + *MutatingWorkEstimatorConfig `json:"mutatingWorkEstimatorConfig,omitempty"` + + // MinimumSeats is the minimum number of seats a request must occupy. + MinimumSeats uint64 `json:"minimumSeats,omitempty"` + // MaximumSeats is the maximum number of seats a request can occupy + // + // NOTE: work_estimate_seats_samples metric uses the value of maximumSeats + // as the upper bound, so when we change maximumSeats we should also + // update the buckets of the metric. + MaximumSeats uint64 `json:"maximumSeats,omitempty"` +} + +// ListWorkEstimatorConfig holds work estimator parameters related to list requests. +type ListWorkEstimatorConfig struct { + ObjectsPerSeat float64 `json:"objectsPerSeat,omitempty"` +} + +// MutatingWorkEstimatorConfig holds work estimator +// parameters related to watches of mutating objects. +type MutatingWorkEstimatorConfig struct { + // TODO(wojtekt): Remove it once we tune the algorithm to not fail + // scalability tests. + Enabled bool `json:"enable,omitempty"` + EventAdditionalDuration metav1.Duration `json:"eventAdditionalDurationMs,omitempty"` + WatchesPerSeat float64 `json:"watchesPerSeat,omitempty"` +} + +// DefaultWorkEstimatorConfig creates a new WorkEstimatorConfig with default values. +func DefaultWorkEstimatorConfig() *WorkEstimatorConfig { + return &WorkEstimatorConfig{ + MinimumSeats: minimumSeats, + MaximumSeats: maximumSeats, + ListWorkEstimatorConfig: defaultListWorkEstimatorConfig(), + MutatingWorkEstimatorConfig: defaultMutatingWorkEstimatorConfig(), + } +} + +// defaultListWorkEstimatorConfig creates a new ListWorkEstimatorConfig with default values. +func defaultListWorkEstimatorConfig() *ListWorkEstimatorConfig { + return &ListWorkEstimatorConfig{ObjectsPerSeat: objectsPerSeat} +} + +// defaultMutatingWorkEstimatorConfig creates a new MutatingWorkEstimatorConfig with default values. +func defaultMutatingWorkEstimatorConfig() *MutatingWorkEstimatorConfig { + return &MutatingWorkEstimatorConfig{ + Enabled: enableMutatingWorkEstimator, + EventAdditionalDuration: metav1.Duration{Duration: eventAdditionalDuration}, + WatchesPerSeat: watchesPerSeat, + } +} + +// eventAdditionalDuration converts eventAdditionalDurationMs to a time.Duration type. +func (c *MutatingWorkEstimatorConfig) eventAdditionalDuration() time.Duration { + return c.EventAdditionalDuration.Duration +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go new file mode 100644 index 000000000..75d70a0ad --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go @@ -0,0 +1,154 @@ +/* +Copyright 2021 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 request + +import ( + "math" + "net/http" + "net/url" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + apirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/klog/v2" +) + +func newListWorkEstimator(countFn objectCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc { + estimator := &listWorkEstimator{ + config: config, + countGetterFn: countFn, + } + return estimator.estimate +} + +type listWorkEstimator struct { + config *WorkEstimatorConfig + countGetterFn objectCountGetterFunc +} + +func (e *listWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate { + requestInfo, ok := apirequest.RequestInfoFrom(r.Context()) + if !ok { + // no RequestInfo should never happen, but to be on the safe side + // let's return maximumSeats + return WorkEstimate{InitialSeats: e.config.MaximumSeats} + } + + if requestInfo.Name != "" { + // Requests with metadata.name specified are usually executed as get + // requests in storage layer so their width should be 1. + // Example of such list requests: + // /apis/certificates.k8s.io/v1/certificatesigningrequests?fieldSelector=metadata.name%3Dcsr-xxs4m + // /api/v1/namespaces/test/configmaps?fieldSelector=metadata.name%3Dbig-deployment-1&limit=500&resourceVersion=0 + return WorkEstimate{InitialSeats: e.config.MinimumSeats} + } + + query := r.URL.Query() + listOptions := metav1.ListOptions{} + if err := metav1.Convert_url_Values_To_v1_ListOptions(&query, &listOptions, nil); err != nil { + klog.ErrorS(err, "Failed to convert options while estimating work for the list request") + + // This request is destined to fail in the validation layer, + // return maximumSeats for this request to be consistent. + return WorkEstimate{InitialSeats: e.config.MaximumSeats} + } + isListFromCache := !shouldListFromStorage(query, &listOptions) + + numStored, err := e.countGetterFn(key(requestInfo)) + switch { + case err == ObjectCountStaleErr: + // object count going stale is indicative of degradation, so we should + // be conservative here and allocate maximum seats to this list request. + // NOTE: if a CRD is removed, its count will go stale first and then the + // pruner will eventually remove the CRD from the cache. + return WorkEstimate{InitialSeats: e.config.MaximumSeats} + case err == ObjectCountNotFoundErr: + // there are multiple scenarios in which we can see this error: + // a. the type is truly unknown, a typo on the caller's part. + // b. the count has gone stale for too long and the pruner + // has removed the type from the cache. + // c. the type is an aggregated resource that is served by a + // different apiserver (thus its object count is not updated) + // we don't have a way to distinguish between those situations. + // However, in case c, the request is delegated to a different apiserver, + // and thus its cost for our server is minimal. To avoid the situation + // when aggregated API calls are overestimated, we allocate the minimum + // possible seats (see #109106 as an example when being more conservative + // led to problems). + return WorkEstimate{InitialSeats: e.config.MinimumSeats} + case err != nil: + // we should never be here since Get returns either ObjectCountStaleErr or + // ObjectCountNotFoundErr, return maximumSeats to be on the safe side. + klog.ErrorS(err, "Unexpected error from object count tracker") + return WorkEstimate{InitialSeats: e.config.MaximumSeats} + } + + limit := numStored + if utilfeature.DefaultFeatureGate.Enabled(features.APIListChunking) && listOptions.Limit > 0 && + listOptions.Limit < numStored { + limit = listOptions.Limit + } + + var estimatedObjectsToBeProcessed int64 + + switch { + case isListFromCache: + // TODO: For resources that implement indexes at the watchcache level, + // we need to adjust the cost accordingly + estimatedObjectsToBeProcessed = numStored + case listOptions.FieldSelector != "" || listOptions.LabelSelector != "": + estimatedObjectsToBeProcessed = numStored + limit + default: + estimatedObjectsToBeProcessed = 2 * limit + } + + // for now, our rough estimate is to allocate one seat to each 100 obejcts that + // will be processed by the list request. + // we will come up with a different formula for the transformation function and/or + // fine tune this number in future iteratons. + seats := uint64(math.Ceil(float64(estimatedObjectsToBeProcessed) / e.config.ObjectsPerSeat)) + + // make sure we never return a seat of zero + if seats < e.config.MinimumSeats { + seats = e.config.MinimumSeats + } + if seats > e.config.MaximumSeats { + seats = e.config.MaximumSeats + } + return WorkEstimate{InitialSeats: seats} +} + +func key(requestInfo *apirequest.RequestInfo) string { + groupResource := &schema.GroupResource{ + Group: requestInfo.APIGroup, + Resource: requestInfo.Resource, + } + return groupResource.String() +} + +// NOTICE: Keep in sync with shouldDelegateList function in +// +// staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go +func shouldListFromStorage(query url.Values, opts *metav1.ListOptions) bool { + resourceVersion := opts.ResourceVersion + pagingEnabled := utilfeature.DefaultFeatureGate.Enabled(features.APIListChunking) + hasContinuation := pagingEnabled && len(opts.Continue) > 0 + hasLimit := pagingEnabled && opts.Limit > 0 && resourceVersion != "0" + return resourceVersion == "" || hasContinuation || hasLimit || opts.ResourceVersionMatch == metav1.ResourceVersionMatchExact +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/mutating_work_estimator.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/mutating_work_estimator.go new file mode 100644 index 000000000..305f8e1eb --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/mutating_work_estimator.go @@ -0,0 +1,149 @@ +/* +Copyright 2021 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 request + +import ( + "math" + "net/http" + "time" + + apirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/util/flowcontrol/metrics" +) + +func newMutatingWorkEstimator(countFn watchCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc { + estimator := &mutatingWorkEstimator{ + config: config, + countFn: countFn, + } + return estimator.estimate +} + +type mutatingWorkEstimator struct { + config *WorkEstimatorConfig + countFn watchCountGetterFunc +} + +func (e *mutatingWorkEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate { + // TODO(wojtekt): Remove once we tune the algorithm to not fail + // scalability tests. + if !e.config.Enabled { + return WorkEstimate{ + InitialSeats: 1, + } + } + + requestInfo, ok := apirequest.RequestInfoFrom(r.Context()) + if !ok { + // no RequestInfo should never happen, but to be on the safe side + // let's return a large value. + return WorkEstimate{ + InitialSeats: 1, + FinalSeats: e.config.MaximumSeats, + AdditionalLatency: e.config.eventAdditionalDuration(), + } + } + + if isRequestExemptFromWatchEvents(requestInfo) { + return WorkEstimate{ + InitialSeats: e.config.MinimumSeats, + FinalSeats: 0, + AdditionalLatency: time.Duration(0), + } + } + + watchCount := e.countFn(requestInfo) + metrics.ObserveWatchCount(r.Context(), priorityLevelName, flowSchemaName, watchCount) + + // The cost of the request associated with the watchers of that event + // consists of three parts: + // - cost of going through the event change logic + // - cost of serialization of the event + // - cost of processing an event object for each watcher (e.g. filtering, + // sending data over network) + // We're starting simple to get some operational experience with it and + // we will work on tuning the algorithm later. Given that the actual work + // associated with processing watch events is happening in multiple + // goroutines (proportional to the number of watchers) that are all + // resumed at once, as a starting point we assume that each such goroutine + // is taking 1/Nth of a seat for M milliseconds. + // We allow the accounting of that work in P&F to be reshaped into another + // rectangle of equal area for practical reasons. + var finalSeats uint64 + var additionalLatency time.Duration + + // TODO: Make this unconditional after we tune the algorithm better. + // Technically, there is an overhead connected to processing an event after + // the request finishes even if there is a small number of watches. + // However, until we tune the estimation we want to stay on the safe side + // an avoid introducing additional latency for almost every single request. + if watchCount >= int(e.config.WatchesPerSeat) { + // TODO: As described in the KEP, we should take into account that not all + // events are equal and try to estimate the cost of a single event based on + // some historical data about size of events. + finalSeats = uint64(math.Ceil(float64(watchCount) / e.config.WatchesPerSeat)) + finalWork := SeatsTimesDuration(float64(finalSeats), e.config.eventAdditionalDuration()) + + // While processing individual events is highly parallel, + // the design/implementation of P&F has a couple limitations that + // make using this assumption in the P&F implementation very + // inefficient because: + // - we reserve max(initialSeats, finalSeats) for time of executing + // both phases of the request + // - even more importantly, when a given `wide` request is the one to + // be dispatched, we are not dispatching any other request until + // we accumulate enough seats to dispatch the nominated one, even + // if currently unoccupied seats would allow for dispatching some + // other requests in the meantime + // As a consequence of these, the wider the request, the more capacity + // will effectively be blocked and unused during dispatching and + // executing this request. + // + // To mitigate the impact of it, we're capping the maximum number of + // seats that can be assigned to a given request. Thanks to it: + // 1) we reduce the amount of seat-seconds that are "wasted" during + // dispatching and executing initial phase of the request + // 2) we are not changing the finalWork estimate - just potentially + // reshaping it to be narrower and longer. As long as the maximum + // seats setting will prevent dispatching too many requests at once + // to prevent overloading kube-apiserver (and/or etcd or the VM or + // a physical machine it is running on), we believe the relaxed + // version should be good enough to achieve the P&F goals. + // + // TODO: Confirm that the current cap of maximumSeats allow us to + // achieve the above. + if finalSeats > e.config.MaximumSeats { + finalSeats = e.config.MaximumSeats + } + additionalLatency = finalWork.DurationPerSeat(float64(finalSeats)) + } + + return WorkEstimate{ + InitialSeats: 1, + FinalSeats: finalSeats, + AdditionalLatency: additionalLatency, + } +} + +func isRequestExemptFromWatchEvents(requestInfo *apirequest.RequestInfo) bool { + // Creating token for service account does not produce any event, + // but still serviceaccounts can have multiple watchers. + if requestInfo.Resource == "serviceaccounts" && requestInfo.Subresource == "token" { + return true + } + return false +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/object_count_tracker.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/object_count_tracker.go new file mode 100644 index 000000000..62a5e4f2d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/object_count_tracker.go @@ -0,0 +1,169 @@ +/* +Copyright 2021 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 request + +import ( + "errors" + "sync" + "time" + + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/klog/v2" + "k8s.io/utils/clock" +) + +const ( + // type deletion (it applies mostly to CRD) is not a very frequent + // operation so we can afford to prune the cache at a large interval. + // at the same time, we also want to make sure that the scalability + // tests hit this code path. + pruneInterval = 1 * time.Hour + + // the storage layer polls for object count at every 1m interval, we will allow + // up to 2-3 transient failures to get the latest count for a given resource. + staleTolerationThreshold = 3 * time.Minute +) + +var ( + // ObjectCountNotFoundErr is returned when the object count for + // a given resource is not being tracked. + ObjectCountNotFoundErr = errors.New("object count not found for the given resource") + + // ObjectCountStaleErr is returned when the object count for a + // given resource has gone stale due to transient failures. + ObjectCountStaleErr = errors.New("object count has gone stale for the given resource") +) + +// StorageObjectCountTracker is an interface that is used to keep track of +// of the total number of objects for each resource. +// {group}.{resource} is used as the key name to update and retrieve +// the total number of objects for a given resource. +type StorageObjectCountTracker interface { + // Set is invoked to update the current number of total + // objects for the given resource + Set(string, int64) + + // Get returns the total number of objects for the given resource. + // The following errors are returned: + // - if the count has gone stale for a given resource due to transient + // failures ObjectCountStaleErr is returned. + // - if the given resource is not being tracked then + // ObjectCountNotFoundErr is returned. + Get(string) (int64, error) + + // RunUntil starts all the necessary maintenance. + RunUntil(stopCh <-chan struct{}) +} + +// NewStorageObjectCountTracker returns an instance of +// StorageObjectCountTracker interface that can be used to +// keep track of the total number of objects for each resource. +func NewStorageObjectCountTracker() StorageObjectCountTracker { + return &objectCountTracker{ + clock: &clock.RealClock{}, + counts: map[string]*timestampedCount{}, + } +} + +// timestampedCount stores the count of a given resource with a last updated +// timestamp so we can prune it after it goes stale for certain threshold. +type timestampedCount struct { + count int64 + lastUpdatedAt time.Time +} + +// objectCountTracker implements StorageObjectCountTracker with +// reader/writer mutual exclusion lock. +type objectCountTracker struct { + clock clock.PassiveClock + + lock sync.RWMutex + counts map[string]*timestampedCount +} + +func (t *objectCountTracker) Set(groupResource string, count int64) { + if count <= -1 { + // a value of -1 indicates that the 'Count' call failed to contact + // the storage layer, in most cases this error can be transient. + // we will continue to work with the count that is in the cache + // up to a certain threshold defined by staleTolerationThreshold. + // in case this becomes a non transient error then the count for + // the given resource will will eventually be removed from + // the cache by the pruner. + return + } + + now := t.clock.Now() + + // lock for writing + t.lock.Lock() + defer t.lock.Unlock() + + if item, ok := t.counts[groupResource]; ok { + item.count = count + item.lastUpdatedAt = now + return + } + + t.counts[groupResource] = ×tampedCount{ + count: count, + lastUpdatedAt: now, + } +} + +func (t *objectCountTracker) Get(groupResource string) (int64, error) { + staleThreshold := t.clock.Now().Add(-staleTolerationThreshold) + + t.lock.RLock() + defer t.lock.RUnlock() + + if item, ok := t.counts[groupResource]; ok { + if item.lastUpdatedAt.Before(staleThreshold) { + return item.count, ObjectCountStaleErr + } + return item.count, nil + } + return 0, ObjectCountNotFoundErr +} + +// RunUntil runs all the necessary maintenance. +func (t *objectCountTracker) RunUntil(stopCh <-chan struct{}) { + wait.PollUntil( + pruneInterval, + func() (bool, error) { + // always prune at every pruneInterval + return false, t.prune(pruneInterval) + }, stopCh) + klog.InfoS("StorageObjectCountTracker pruner is exiting") +} + +func (t *objectCountTracker) prune(threshold time.Duration) error { + oldestLastUpdatedAtAllowed := t.clock.Now().Add(-threshold) + + // lock for writing + t.lock.Lock() + defer t.lock.Unlock() + + for groupResource, count := range t.counts { + if count.lastUpdatedAt.After(oldestLastUpdatedAtAllowed) { + continue + } + delete(t.counts, groupResource) + } + + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/seat_seconds.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/seat_seconds.go new file mode 100644 index 000000000..e3a401745 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/seat_seconds.go @@ -0,0 +1,65 @@ +/* +Copyright 2021 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 request + +import ( + "fmt" + "math" + "time" +) + +// SeatSeconds is a measure of work, in units of seat-seconds, using a fixed-point representation. +// `SeatSeconds(n)` represents `n/ssScale` seat-seconds. +// The `ssScale` constant is private to the implementation here, +// no other code should use it. +type SeatSeconds uint64 + +// MaxSeatsSeconds is the maximum representable value of SeatSeconds +const MaxSeatSeconds = SeatSeconds(math.MaxUint64) + +// MinSeatSeconds is the lowest representable value of SeatSeconds +const MinSeatSeconds = SeatSeconds(0) + +// SeatsTimeDuration produces the SeatSeconds value for the given factors. +// This is intended only to produce small values, increments in work +// rather than amount of work done since process start. +func SeatsTimesDuration(seats float64, duration time.Duration) SeatSeconds { + return SeatSeconds(math.Round(seats * float64(duration/time.Nanosecond) / (1e9 / ssScale))) +} + +// ToFloat converts to a floating-point representation. +// This conversion may lose precision. +func (ss SeatSeconds) ToFloat() float64 { + return float64(ss) / ssScale +} + +// DurationPerSeat returns duration per seat. +// This division may lose precision. +func (ss SeatSeconds) DurationPerSeat(seats float64) time.Duration { + return time.Duration(float64(ss) / seats * (float64(time.Second) / ssScale)) +} + +// String converts to a string. +// This is suitable for large as well as small values. +func (ss SeatSeconds) String() string { + const div = SeatSeconds(ssScale) + quo := ss / div + rem := ss - quo*div + return fmt.Sprintf("%d.%08dss", quo, rem) +} + +const ssScale = 1e8 diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/width.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/width.go new file mode 100644 index 000000000..86f042584 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/width.go @@ -0,0 +1,113 @@ +/* +Copyright 2021 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 request + +import ( + "fmt" + "net/http" + "time" + + apirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/klog/v2" +) + +// WorkEstimate carries three of the four parameters that determine the work in a request. +// The fourth parameter is the duration of the initial phase of execution. +type WorkEstimate struct { + // InitialSeats is the number of seats occupied while the server is + // executing this request. + InitialSeats uint64 + + // FinalSeats is the number of seats occupied at the end, + // during the AdditionalLatency. + FinalSeats uint64 + + // AdditionalLatency specifies the additional duration the seats allocated + // to this request must be reserved after the given request had finished. + // AdditionalLatency should not have any impact on the user experience, the + // caller must not experience this additional latency. + AdditionalLatency time.Duration +} + +// MaxSeats returns the maximum number of seats the request occupies over the +// phases of being served. +func (we *WorkEstimate) MaxSeats() int { + if we.InitialSeats >= we.FinalSeats { + return int(we.InitialSeats) + } + + return int(we.FinalSeats) +} + +// objectCountGetterFunc represents a function that gets the total +// number of objects for a given resource. +type objectCountGetterFunc func(string) (int64, error) + +// watchCountGetterFunc represents a function that gets the total +// number of watchers potentially interested in a given request. +type watchCountGetterFunc func(*apirequest.RequestInfo) int + +// NewWorkEstimator estimates the work that will be done by a given request, +// if no WorkEstimatorFunc matches the given request then the default +// work estimate of 1 seat is allocated to the request. +func NewWorkEstimator(objectCountFn objectCountGetterFunc, watchCountFn watchCountGetterFunc, config *WorkEstimatorConfig) WorkEstimatorFunc { + estimator := &workEstimator{ + minimumSeats: config.MinimumSeats, + maximumSeats: config.MaximumSeats, + listWorkEstimator: newListWorkEstimator(objectCountFn, config), + mutatingWorkEstimator: newMutatingWorkEstimator(watchCountFn, config), + } + return estimator.estimate +} + +// WorkEstimatorFunc returns the estimated work of a given request. +// This function will be used by the Priority & Fairness filter to +// estimate the work of of incoming requests. +type WorkEstimatorFunc func(request *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate + +func (e WorkEstimatorFunc) EstimateWork(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate { + return e(r, flowSchemaName, priorityLevelName) +} + +type workEstimator struct { + // the minimum number of seats a request must occupy + minimumSeats uint64 + // the maximum number of seats a request can occupy + maximumSeats uint64 + // listWorkEstimator estimates work for list request(s) + listWorkEstimator WorkEstimatorFunc + // mutatingWorkEstimator calculates the width of mutating request(s) + mutatingWorkEstimator WorkEstimatorFunc +} + +func (e *workEstimator) estimate(r *http.Request, flowSchemaName, priorityLevelName string) WorkEstimate { + requestInfo, ok := apirequest.RequestInfoFrom(r.Context()) + if !ok { + klog.ErrorS(fmt.Errorf("no RequestInfo found in context"), "Failed to estimate work for the request", "URI", r.RequestURI) + // no RequestInfo should never happen, but to be on the safe side let's return maximumSeats + return WorkEstimate{InitialSeats: e.maximumSeats} + } + + switch requestInfo.Verb { + case "list": + return e.listWorkEstimator.EstimateWork(r, flowSchemaName, priorityLevelName) + case "create", "update", "patch", "delete": + return e.mutatingWorkEstimator.EstimateWork(r, flowSchemaName, priorityLevelName) + } + + return WorkEstimate{InitialSeats: e.minimumSeats} +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/rule.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/rule.go new file mode 100644 index 000000000..a404d3286 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/rule.go @@ -0,0 +1,203 @@ +/* +Copyright 2019 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 flowcontrol + +import ( + "strings" + + flowcontrol "k8s.io/api/flowcontrol/v1beta3" + "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" +) + +// Tests whether a given request and FlowSchema match. Nobody mutates +// either input. +func matchesFlowSchema(digest RequestDigest, flowSchema *flowcontrol.FlowSchema) bool { + for _, policyRule := range flowSchema.Spec.Rules { + if matchesPolicyRule(digest, &policyRule) { + return true + } + } + return false +} + +func matchesPolicyRule(digest RequestDigest, policyRule *flowcontrol.PolicyRulesWithSubjects) bool { + if !matchesASubject(digest.User, policyRule.Subjects) { + return false + } + if digest.RequestInfo.IsResourceRequest { + return matchesAResourceRule(digest.RequestInfo, policyRule.ResourceRules) + } + return matchesANonResourceRule(digest.RequestInfo, policyRule.NonResourceRules) +} + +func matchesASubject(user user.Info, subjects []flowcontrol.Subject) bool { + for _, subject := range subjects { + if matchesSubject(user, subject) { + return true + } + } + return false +} + +func matchesSubject(user user.Info, subject flowcontrol.Subject) bool { + switch subject.Kind { + case flowcontrol.SubjectKindUser: + return subject.User != nil && (subject.User.Name == flowcontrol.NameAll || subject.User.Name == user.GetName()) + case flowcontrol.SubjectKindGroup: + if subject.Group == nil { + return false + } + seek := subject.Group.Name + if seek == "*" { + return true + } + for _, userGroup := range user.GetGroups() { + if userGroup == seek { + return true + } + } + return false + case flowcontrol.SubjectKindServiceAccount: + if subject.ServiceAccount == nil { + return false + } + if subject.ServiceAccount.Name == flowcontrol.NameAll { + return serviceAccountMatchesNamespace(subject.ServiceAccount.Namespace, user.GetName()) + } + return serviceaccount.MatchesUsername(subject.ServiceAccount.Namespace, subject.ServiceAccount.Name, user.GetName()) + default: + return false + } +} + +// serviceAccountMatchesNamespace checks whether the provided service account username matches the namespace, without +// allocating. Use this when checking a service account namespace against a known string. +// This is copied from `k8s.io/apiserver/pkg/authentication/serviceaccount::MatchesUsername` and simplified to not check the name part. +func serviceAccountMatchesNamespace(namespace string, username string) bool { + const ( + ServiceAccountUsernamePrefix = "system:serviceaccount:" + ServiceAccountUsernameSeparator = ":" + ) + if !strings.HasPrefix(username, ServiceAccountUsernamePrefix) { + return false + } + username = username[len(ServiceAccountUsernamePrefix):] + + if !strings.HasPrefix(username, namespace) { + return false + } + username = username[len(namespace):] + + return strings.HasPrefix(username, ServiceAccountUsernameSeparator) +} + +func matchesAResourceRule(ri *request.RequestInfo, rules []flowcontrol.ResourcePolicyRule) bool { + for _, rr := range rules { + if matchesResourcePolicyRule(ri, rr) { + return true + } + } + return false +} + +func matchesResourcePolicyRule(ri *request.RequestInfo, policyRule flowcontrol.ResourcePolicyRule) bool { + if !matchPolicyRuleVerb(policyRule.Verbs, ri.Verb) { + return false + } + if !matchPolicyRuleResource(policyRule.Resources, ri.Resource, ri.Subresource) { + return false + } + if !matchPolicyRuleAPIGroup(policyRule.APIGroups, ri.APIGroup) { + return false + } + if len(ri.Namespace) == 0 { + return policyRule.ClusterScope + } + return containsString(ri.Namespace, policyRule.Namespaces, flowcontrol.NamespaceEvery) +} + +func matchesANonResourceRule(ri *request.RequestInfo, rules []flowcontrol.NonResourcePolicyRule) bool { + for _, rr := range rules { + if matchesNonResourcePolicyRule(ri, rr) { + return true + } + } + return false +} + +func matchesNonResourcePolicyRule(ri *request.RequestInfo, policyRule flowcontrol.NonResourcePolicyRule) bool { + if !matchPolicyRuleVerb(policyRule.Verbs, ri.Verb) { + return false + } + return matchPolicyRuleNonResourceURL(policyRule.NonResourceURLs, ri.Path) +} + +func matchPolicyRuleVerb(policyRuleVerbs []string, requestVerb string) bool { + return containsString(requestVerb, policyRuleVerbs, flowcontrol.VerbAll) +} + +func matchPolicyRuleNonResourceURL(policyRuleRequestURLs []string, requestPath string) bool { + for _, rulePath := range policyRuleRequestURLs { + if rulePath == flowcontrol.NonResourceAll || rulePath == requestPath { + return true + } + rulePrefix := strings.TrimSuffix(rulePath, "*") + if !strings.HasSuffix(rulePrefix, "/") { + rulePrefix = rulePrefix + "/" + } + if strings.HasPrefix(requestPath, rulePrefix) { + return true + } + } + return false +} + +func matchPolicyRuleAPIGroup(policyRuleAPIGroups []string, requestAPIGroup string) bool { + return containsString(requestAPIGroup, policyRuleAPIGroups, flowcontrol.APIGroupAll) +} + +func rsJoin(requestResource, requestSubresource string) string { + seekString := requestResource + if requestSubresource != "" { + seekString = requestResource + "/" + requestSubresource + } + return seekString +} + +func matchPolicyRuleResource(policyRuleRequestResources []string, requestResource, requestSubresource string) bool { + return containsString(rsJoin(requestResource, requestSubresource), policyRuleRequestResources, flowcontrol.ResourceAll) +} + +// containsString returns true if either `x` or `wildcard` is in +// `list`. The wildcard is not a pattern to match against `x`; rather +// the presence of the wildcard in the list is the caller's way of +// saying that all values of `x` should match the list. This function +// assumes that if `wildcard` is in `list` then it is the only member +// of the list, which is enforced by validation. +func containsString(x string, list []string, wildcard string) bool { + if len(list) == 1 && list[0] == wildcard { + return true + } + for _, y := range list { + if x == y { + return true + } + } + return false +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go new file mode 100644 index 000000000..287b100cf --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go @@ -0,0 +1,234 @@ +/* +Copyright 2021 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 flowcontrol + +import ( + "net/http" + "sync" + + metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" + "k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/endpoints/request" + + "k8s.io/klog/v2" +) + +// readOnlyVerbs contains verbs for read-only requests. +var readOnlyVerbs = sets.NewString("get", "list", "watch", "proxy") + +// watchIdentifier identifies group of watches that are similar. +// As described in the "Priority and Fairness" KEP, we consider +// watches similar if they have the same resourceType, namespace +// and name. We ignore selectors as they have to be evaluated +// when processing an even anyway. +// +// TODO: For now we only track the number of watches registered +// in our kube-apiserver. Eventually we should consider sharing +// this information with other kube-apiserver as described in the +// KEP, but this isn't part of the first version. +type watchIdentifier struct { + apiGroup string + resource string + namespace string + name string +} + +// ForgetWatchFunc is a function that should be called to forget +// the previously registered watch from the watch tracker. +type ForgetWatchFunc func() + +// WatchTracker is an interface that allows tracking the number +// of watches in the system for the purpose of estimating the +// cost of incoming mutating requests. +type WatchTracker interface { + // RegisterWatch reqisters a watch based on the provided http.Request + // in the tracker. It returns the function that should be called + // to forget the watcher once it is finished. + RegisterWatch(r *http.Request) ForgetWatchFunc + + // GetInterestedWatchCount returns the number of watches that are + // potentially interested in a request with a given RequestInfo + // for the purpose of estimating cost of that request. + GetInterestedWatchCount(requestInfo *request.RequestInfo) int +} + +// builtinIndexes represents of set of indexes registered in +// watchcache that are indexing watches and increase speed of +// their processing. +// We define the indexes as a map from a resource to the path +// to the field in the object on which the index is built. +type builtinIndexes map[string]string + +func getBuiltinIndexes() builtinIndexes { + // The only existing indexes as of now are: + // - spec.nodeName for pods + // - metadata.Name for nodes, secrets and configmaps + // However, we can ignore the latter, because the requestInfo.Name + // is set for them (i.e. we already catch them correctly). + return map[string]string{ + "pods": "spec.nodeName", + } +} + +// watchTracker tracks the number of watches in the system for +// the purpose of estimating the cost of incoming mutating requests. +type watchTracker struct { + // indexes represents a set of registered indexes. + // It can't change after creation. + indexes builtinIndexes + + lock sync.Mutex + watchCount map[watchIdentifier]int +} + +func NewWatchTracker() WatchTracker { + return &watchTracker{ + indexes: getBuiltinIndexes(), + watchCount: make(map[watchIdentifier]int), + } +} + +const ( + unsetValue = "" +) + +func getIndexValue(r *http.Request, field string) string { + opts := metainternalversion.ListOptions{} + if err := scheme.ParameterCodec.DecodeParameters(r.URL.Query(), metav1.SchemeGroupVersion, &opts); err != nil { + klog.Warningf("Couldn't parse list options for %v: %v", r.URL.Query(), err) + return unsetValue + } + if opts.FieldSelector == nil { + return unsetValue + } + if value, ok := opts.FieldSelector.RequiresExactMatch(field); ok { + return value + } + return unsetValue +} + +type indexValue struct { + resource string + value string +} + +// RegisterWatch implements WatchTracker interface. +func (w *watchTracker) RegisterWatch(r *http.Request) ForgetWatchFunc { + requestInfo, ok := request.RequestInfoFrom(r.Context()) + if !ok || requestInfo == nil || requestInfo.Verb != "watch" { + return nil + } + + var index *indexValue + if indexField, ok := w.indexes[requestInfo.Resource]; ok { + index = &indexValue{ + resource: requestInfo.Resource, + value: getIndexValue(r, indexField), + } + } + + identifier := &watchIdentifier{ + apiGroup: requestInfo.APIGroup, + resource: requestInfo.Resource, + namespace: requestInfo.Namespace, + name: requestInfo.Name, + } + + w.lock.Lock() + defer w.lock.Unlock() + w.updateIndexLocked(identifier, index, 1) + return w.forgetWatch(identifier, index) +} + +func (w *watchTracker) updateIndexLocked(identifier *watchIdentifier, index *indexValue, incr int) { + if index == nil { + w.watchCount[*identifier] += incr + } else { + // For resources with defined index, for a given watch event we are + // only processing the watchers that: + // (a) do not specify field selector for an index field + // (b) do specify field selector with the value equal to the value + // coming from the processed object + // + // TODO(wojtek-t): For the sake of making progress and initially + // simplifying the implementation, we approximate (b) for all values + // as the value for an empty string. The assumption we're making here + // is that the difference between the actual number of watchers that + // will be processed, i.e. (a)+(b) above and the one from our + // approximation i.e. (a)+[(b) for field value of ""] will be small. + // This seem to be true in almost all production clusters, which makes + // it a reasonable first step simplification to unblock progres on it. + if index.value == unsetValue || index.value == "" { + w.watchCount[*identifier] += incr + } + } +} + +func (w *watchTracker) forgetWatch(identifier *watchIdentifier, index *indexValue) ForgetWatchFunc { + return func() { + w.lock.Lock() + defer w.lock.Unlock() + + w.updateIndexLocked(identifier, index, -1) + if w.watchCount[*identifier] == 0 { + delete(w.watchCount, *identifier) + } + } +} + +// GetInterestedWatchCount implements WatchTracker interface. +// +// TODO(wojtek-t): As of now, requestInfo for object creation (POST) doesn't +// +// contain the Name field set. Figure out if we can somehow get it for the +// more accurate cost estimation. +// +// TODO(wojtek-t): Figure out how to approach DELETECOLLECTION calls. +func (w *watchTracker) GetInterestedWatchCount(requestInfo *request.RequestInfo) int { + if requestInfo == nil || readOnlyVerbs.Has(requestInfo.Verb) { + return 0 + } + + result := 0 + // The watches that we're interested in include: + // - watches for all objects of a resource type (no namespace and name specified) + // - watches for all objects of a resource type in the same namespace (no name specified) + // - watched interested in this particular object + identifier := &watchIdentifier{ + apiGroup: requestInfo.APIGroup, + resource: requestInfo.Resource, + } + + w.lock.Lock() + defer w.lock.Unlock() + + result += w.watchCount[*identifier] + + if requestInfo.Namespace != "" { + identifier.namespace = requestInfo.Namespace + result += w.watchCount[*identifier] + } + + if requestInfo.Name != "" { + identifier.name = requestInfo.Name + result += w.watchCount[*identifier] + } + + return result +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flushwriter/doc.go b/vendor/k8s.io/apiserver/pkg/util/flushwriter/doc.go new file mode 100644 index 000000000..f81e09a29 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flushwriter/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2014 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 flushwriter implements a wrapper for a writer that flushes on every +// write if that writer implements the io.Flusher interface +package flushwriter // import "k8s.io/apiserver/pkg/util/flushwriter" diff --git a/vendor/k8s.io/apiserver/pkg/util/flushwriter/writer.go b/vendor/k8s.io/apiserver/pkg/util/flushwriter/writer.go new file mode 100644 index 000000000..748bd0108 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/flushwriter/writer.go @@ -0,0 +1,53 @@ +/* +Copyright 2014 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 flushwriter + +import ( + "io" + "net/http" +) + +// Wrap wraps an io.Writer into a writer that flushes after every write if +// the writer implements the Flusher interface. +func Wrap(w io.Writer) io.Writer { + fw := &flushWriter{ + writer: w, + } + if flusher, ok := w.(http.Flusher); ok { + fw.flusher = flusher + } + return fw +} + +// flushWriter provides wrapper for responseWriter with HTTP streaming capabilities +type flushWriter struct { + flusher http.Flusher + writer io.Writer +} + +// Write is a FlushWriter implementation of the io.Writer that sends any buffered +// data to the client. +func (fw *flushWriter) Write(p []byte) (n int, err error) { + n, err = fw.writer.Write(p) + if err != nil { + return + } + if fw.flusher != nil { + fw.flusher.Flush() + } + return +} diff --git a/vendor/k8s.io/apiserver/pkg/util/openapi/enablement.go b/vendor/k8s.io/apiserver/pkg/util/openapi/enablement.go new file mode 100644 index 000000000..693821ac0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/openapi/enablement.go @@ -0,0 +1,83 @@ +/* +Copyright 2021 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 openapi + +import ( + "strings" + + genericfeatures "k8s.io/apiserver/pkg/features" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/schemamutation" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// enumTypeDescriptionHeader is the header of enum section in schema description. +const enumTypeDescriptionHeader = "Possible enum values:" + +// GetOpenAPIDefinitionsWithoutDisabledFeatures wraps a GetOpenAPIDefinitions to revert +// any change to the schema that was made by disabled features. +func GetOpenAPIDefinitionsWithoutDisabledFeatures(GetOpenAPIDefinitions common.GetOpenAPIDefinitions) common.GetOpenAPIDefinitions { + return func(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { + defs := GetOpenAPIDefinitions(ref) + restoreDefinitions(defs) + return defs + } +} + +// restoreDefinitions restores any changes by disabled features from definition map. +func restoreDefinitions(defs map[string]common.OpenAPIDefinition) { + // revert changes from OpenAPIEnums + if !utilfeature.DefaultFeatureGate.Enabled(genericfeatures.OpenAPIEnums) { + for gvk, def := range defs { + orig := &def.Schema + if ret := pruneEnums(orig); ret != orig { + def.Schema = *ret + defs[gvk] = def + } + } + } +} + +func pruneEnums(schema *spec.Schema) *spec.Schema { + walker := schemamutation.Walker{ + SchemaCallback: func(schema *spec.Schema) *spec.Schema { + orig := schema + clone := func() { + if orig == schema { // if schema has not been mutated yet + schema = new(spec.Schema) + *schema = *orig // make a clone from orig to schema + } + } + if headerIndex := strings.Index(schema.Description, enumTypeDescriptionHeader); headerIndex != -1 { + // remove the enum section from description. + // note that the new lines before the header should be removed too, + // thus the slice range. + clone() + schema.Description = schema.Description[:headerIndex] + } + if len(schema.Enum) != 0 { + // remove the enum field + clone() + schema.Enum = nil + } + return schema + }, + RefCallback: schemamutation.RefCallbackNoop, + } + return walker.WalkSchema(schema) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/openapi/proto.go b/vendor/k8s.io/apiserver/pkg/util/openapi/proto.go new file mode 100644 index 000000000..162812f14 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/openapi/proto.go @@ -0,0 +1,46 @@ +/* +Copyright 2018 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 openapi + +import ( + "encoding/json" + + openapi_v2 "github.com/google/gnostic/openapiv2" + + "k8s.io/kube-openapi/pkg/util/proto" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// ToProtoModels builds the proto formatted models from OpenAPI spec +func ToProtoModels(openAPISpec *spec.Swagger) (proto.Models, error) { + specBytes, err := json.MarshalIndent(openAPISpec, " ", " ") + if err != nil { + return nil, err + } + + doc, err := openapi_v2.ParseDocument(specBytes) + if err != nil { + return nil, err + } + + models, err := proto.NewOpenAPIData(doc) + if err != nil { + return nil, err + } + + return models, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/util/shufflesharding/shufflesharding.go b/vendor/k8s.io/apiserver/pkg/util/shufflesharding/shufflesharding.go new file mode 100644 index 000000000..6ef4ed890 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/shufflesharding/shufflesharding.go @@ -0,0 +1,107 @@ +/* +Copyright 2019 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 shufflesharding + +import ( + "fmt" + "math" +) + +// MaxHashBits is the max bit length which can be used from hash value. +// If we use all bits of hash value, the critical(last) card shuffled by +// Dealer will be uneven to 2:3 (first half:second half) at most, +// in order to reduce this unevenness to 32:33, we set MaxHashBits to 60 here. +const MaxHashBits = 60 + +// RequiredEntropyBits makes a quick and slightly conservative estimate of the number +// of bits of hash value that are consumed in shuffle sharding a deck of the given size +// to a hand of the given size. The result is meaningful only if +// 1 <= handSize <= deckSize <= 1<<26. +func RequiredEntropyBits(deckSize, handSize int) int { + return int(math.Ceil(math.Log2(float64(deckSize)) * float64(handSize))) +} + +// Dealer contains some necessary parameters and provides some methods for shuffle sharding. +// Dealer is thread-safe. +type Dealer struct { + deckSize int + handSize int +} + +// NewDealer will create a Dealer with the given deckSize and handSize, will return error when +// deckSize or handSize is invalid as below. +// 1. deckSize or handSize is not positive +// 2. handSize is greater than deckSize +// 3. deckSize is impractically large (greater than 1<<26) +// 4. required entropy bits of deckSize and handSize is greater than MaxHashBits +func NewDealer(deckSize, handSize int) (*Dealer, error) { + if deckSize <= 0 || handSize <= 0 { + return nil, fmt.Errorf("deckSize %d or handSize %d is not positive", deckSize, handSize) + } + if handSize > deckSize { + return nil, fmt.Errorf("handSize %d is greater than deckSize %d", handSize, deckSize) + } + if deckSize > 1<<26 { + return nil, fmt.Errorf("deckSize %d is impractically large", deckSize) + } + if RequiredEntropyBits(deckSize, handSize) > MaxHashBits { + return nil, fmt.Errorf("required entropy bits of deckSize %d and handSize %d is greater than %d", deckSize, handSize, MaxHashBits) + } + + return &Dealer{ + deckSize: deckSize, + handSize: handSize, + }, nil +} + +// Deal shuffles a card deck and deals a hand of cards, using the given hashValue as the source of entropy. +// The deck size and hand size are properties of the Dealer. +// This function synchronously makes sequential calls to pick, one for each dealt card. +// Each card is identified by an integer in the range [0, deckSize). +// For example, for deckSize=128 and handSize=4 this function might call pick(14); pick(73); pick(119); pick(26). +func (d *Dealer) Deal(hashValue uint64, pick func(int)) { + // 15 is the largest possible value of handSize + var remainders [15]int + + for i := 0; i < d.handSize; i++ { + hashValueNext := hashValue / uint64(d.deckSize-i) + remainders[i] = int(hashValue - uint64(d.deckSize-i)*hashValueNext) + hashValue = hashValueNext + } + + for i := 0; i < d.handSize; i++ { + card := remainders[i] + for j := i; j > 0; j-- { + if card >= remainders[j-1] { + card++ + } + } + pick(card) + } +} + +// DealIntoHand shuffles and deals according to the Dealer's parameters, +// using the given hashValue as the source of entropy and then +// returns the dealt cards as a slice of `int`. +// If `hand` has the correct length as Dealer's handSize, it will be used as-is and no allocations will be made. +// If `hand` is nil or too small, it will be extended (performing an allocation). +// If `hand` is too large, a sub-slice will be returned. +func (d *Dealer) DealIntoHand(hashValue uint64, hand []int) []int { + h := hand[:0] + d.Deal(hashValue, func(card int) { h = append(h, card) }) + return h +} diff --git a/vendor/k8s.io/apiserver/pkg/util/wsstream/conn.go b/vendor/k8s.io/apiserver/pkg/util/wsstream/conn.go new file mode 100644 index 000000000..09f54a49c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/wsstream/conn.go @@ -0,0 +1,350 @@ +/* +Copyright 2015 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 wsstream + +import ( + "encoding/base64" + "fmt" + "io" + "net/http" + "regexp" + "strings" + "time" + + "golang.org/x/net/websocket" + "k8s.io/klog/v2" + + "k8s.io/apimachinery/pkg/util/runtime" +) + +// The Websocket subprotocol "channel.k8s.io" prepends each binary message with a byte indicating +// the channel number (zero indexed) the message was sent on. Messages in both directions should +// prefix their messages with this channel byte. When used for remote execution, the channel numbers +// are by convention defined to match the POSIX file-descriptors assigned to STDIN, STDOUT, and STDERR +// (0, 1, and 2). No other conversion is performed on the raw subprotocol - writes are sent as they +// are received by the server. +// +// Example client session: +// +// CONNECT http://server.com with subprotocol "channel.k8s.io" +// WRITE []byte{0, 102, 111, 111, 10} # send "foo\n" on channel 0 (STDIN) +// READ []byte{1, 10} # receive "\n" on channel 1 (STDOUT) +// CLOSE +const ChannelWebSocketProtocol = "channel.k8s.io" + +// The Websocket subprotocol "base64.channel.k8s.io" base64 encodes each message with a character +// indicating the channel number (zero indexed) the message was sent on. Messages in both directions +// should prefix their messages with this channel char. When used for remote execution, the channel +// numbers are by convention defined to match the POSIX file-descriptors assigned to STDIN, STDOUT, +// and STDERR ('0', '1', and '2'). The data received on the server is base64 decoded (and must be +// be valid) and data written by the server to the client is base64 encoded. +// +// Example client session: +// +// CONNECT http://server.com with subprotocol "base64.channel.k8s.io" +// WRITE []byte{48, 90, 109, 57, 118, 67, 103, 111, 61} # send "foo\n" (base64: "Zm9vCgo=") on channel '0' (STDIN) +// READ []byte{49, 67, 103, 61, 61} # receive "\n" (base64: "Cg==") on channel '1' (STDOUT) +// CLOSE +const Base64ChannelWebSocketProtocol = "base64.channel.k8s.io" + +type codecType int + +const ( + rawCodec codecType = iota + base64Codec +) + +type ChannelType int + +const ( + IgnoreChannel ChannelType = iota + ReadChannel + WriteChannel + ReadWriteChannel +) + +var ( + // connectionUpgradeRegex matches any Connection header value that includes upgrade + connectionUpgradeRegex = regexp.MustCompile("(^|.*,\\s*)upgrade($|\\s*,)") +) + +// IsWebSocketRequest returns true if the incoming request contains connection upgrade headers +// for WebSockets. +func IsWebSocketRequest(req *http.Request) bool { + if !strings.EqualFold(req.Header.Get("Upgrade"), "websocket") { + return false + } + return connectionUpgradeRegex.MatchString(strings.ToLower(req.Header.Get("Connection"))) +} + +// IgnoreReceives reads from a WebSocket until it is closed, then returns. If timeout is set, the +// read and write deadlines are pushed every time a new message is received. +func IgnoreReceives(ws *websocket.Conn, timeout time.Duration) { + defer runtime.HandleCrash() + var data []byte + for { + resetTimeout(ws, timeout) + if err := websocket.Message.Receive(ws, &data); err != nil { + return + } + } +} + +// handshake ensures the provided user protocol matches one of the allowed protocols. It returns +// no error if no protocol is specified. +func handshake(config *websocket.Config, req *http.Request, allowed []string) error { + protocols := config.Protocol + if len(protocols) == 0 { + protocols = []string{""} + } + + for _, protocol := range protocols { + for _, allow := range allowed { + if allow == protocol { + config.Protocol = []string{protocol} + return nil + } + } + } + + return fmt.Errorf("requested protocol(s) are not supported: %v; supports %v", config.Protocol, allowed) +} + +// ChannelProtocolConfig describes a websocket subprotocol with channels. +type ChannelProtocolConfig struct { + Binary bool + Channels []ChannelType +} + +// NewDefaultChannelProtocols returns a channel protocol map with the +// subprotocols "", "channel.k8s.io", "base64.channel.k8s.io" and the given +// channels. +func NewDefaultChannelProtocols(channels []ChannelType) map[string]ChannelProtocolConfig { + return map[string]ChannelProtocolConfig{ + "": {Binary: true, Channels: channels}, + ChannelWebSocketProtocol: {Binary: true, Channels: channels}, + Base64ChannelWebSocketProtocol: {Binary: false, Channels: channels}, + } +} + +// Conn supports sending multiple binary channels over a websocket connection. +type Conn struct { + protocols map[string]ChannelProtocolConfig + selectedProtocol string + channels []*websocketChannel + codec codecType + ready chan struct{} + ws *websocket.Conn + timeout time.Duration +} + +// NewConn creates a WebSocket connection that supports a set of channels. Channels begin each +// web socket message with a single byte indicating the channel number (0-N). 255 is reserved for +// future use. The channel types for each channel are passed as an array, supporting the different +// duplex modes. Read and Write refer to whether the channel can be used as a Reader or Writer. +// +// The protocols parameter maps subprotocol names to ChannelProtocols. The empty string subprotocol +// name is used if websocket.Config.Protocol is empty. +func NewConn(protocols map[string]ChannelProtocolConfig) *Conn { + return &Conn{ + ready: make(chan struct{}), + protocols: protocols, + } +} + +// SetIdleTimeout sets the interval for both reads and writes before timeout. If not specified, +// there is no timeout on the connection. +func (conn *Conn) SetIdleTimeout(duration time.Duration) { + conn.timeout = duration +} + +// Open the connection and create channels for reading and writing. It returns +// the selected subprotocol, a slice of channels and an error. +func (conn *Conn) Open(w http.ResponseWriter, req *http.Request) (string, []io.ReadWriteCloser, error) { + go func() { + defer runtime.HandleCrash() + defer conn.Close() + websocket.Server{Handshake: conn.handshake, Handler: conn.handle}.ServeHTTP(w, req) + }() + <-conn.ready + rwc := make([]io.ReadWriteCloser, len(conn.channels)) + for i := range conn.channels { + rwc[i] = conn.channels[i] + } + return conn.selectedProtocol, rwc, nil +} + +func (conn *Conn) initialize(ws *websocket.Conn) { + negotiated := ws.Config().Protocol + conn.selectedProtocol = negotiated[0] + p := conn.protocols[conn.selectedProtocol] + if p.Binary { + conn.codec = rawCodec + } else { + conn.codec = base64Codec + } + conn.ws = ws + conn.channels = make([]*websocketChannel, len(p.Channels)) + for i, t := range p.Channels { + switch t { + case ReadChannel: + conn.channels[i] = newWebsocketChannel(conn, byte(i), true, false) + case WriteChannel: + conn.channels[i] = newWebsocketChannel(conn, byte(i), false, true) + case ReadWriteChannel: + conn.channels[i] = newWebsocketChannel(conn, byte(i), true, true) + case IgnoreChannel: + conn.channels[i] = newWebsocketChannel(conn, byte(i), false, false) + } + } + + close(conn.ready) +} + +func (conn *Conn) handshake(config *websocket.Config, req *http.Request) error { + supportedProtocols := make([]string, 0, len(conn.protocols)) + for p := range conn.protocols { + supportedProtocols = append(supportedProtocols, p) + } + return handshake(config, req, supportedProtocols) +} + +func (conn *Conn) resetTimeout() { + if conn.timeout > 0 { + conn.ws.SetDeadline(time.Now().Add(conn.timeout)) + } +} + +// Close is only valid after Open has been called +func (conn *Conn) Close() error { + <-conn.ready + for _, s := range conn.channels { + s.Close() + } + conn.ws.Close() + return nil +} + +// handle implements a websocket handler. +func (conn *Conn) handle(ws *websocket.Conn) { + defer conn.Close() + conn.initialize(ws) + + for { + conn.resetTimeout() + var data []byte + if err := websocket.Message.Receive(ws, &data); err != nil { + if err != io.EOF { + klog.Errorf("Error on socket receive: %v", err) + } + break + } + if len(data) == 0 { + continue + } + channel := data[0] + if conn.codec == base64Codec { + channel = channel - '0' + } + data = data[1:] + if int(channel) >= len(conn.channels) { + klog.V(6).Infof("Frame is targeted for a reader %d that is not valid, possible protocol error", channel) + continue + } + if _, err := conn.channels[channel].DataFromSocket(data); err != nil { + klog.Errorf("Unable to write frame to %d: %v\n%s", channel, err, string(data)) + continue + } + } +} + +// write multiplexes the specified channel onto the websocket +func (conn *Conn) write(num byte, data []byte) (int, error) { + conn.resetTimeout() + switch conn.codec { + case rawCodec: + frame := make([]byte, len(data)+1) + frame[0] = num + copy(frame[1:], data) + if err := websocket.Message.Send(conn.ws, frame); err != nil { + return 0, err + } + case base64Codec: + frame := string('0'+num) + base64.StdEncoding.EncodeToString(data) + if err := websocket.Message.Send(conn.ws, frame); err != nil { + return 0, err + } + } + return len(data), nil +} + +// websocketChannel represents a channel in a connection +type websocketChannel struct { + conn *Conn + num byte + r io.Reader + w io.WriteCloser + + read, write bool +} + +// newWebsocketChannel creates a pipe for writing to a websocket. Do not write to this pipe +// prior to the connection being opened. It may be no, half, or full duplex depending on +// read and write. +func newWebsocketChannel(conn *Conn, num byte, read, write bool) *websocketChannel { + r, w := io.Pipe() + return &websocketChannel{conn, num, r, w, read, write} +} + +func (p *websocketChannel) Write(data []byte) (int, error) { + if !p.write { + return len(data), nil + } + return p.conn.write(p.num, data) +} + +// DataFromSocket is invoked by the connection receiver to move data from the connection +// into a specific channel. +func (p *websocketChannel) DataFromSocket(data []byte) (int, error) { + if !p.read { + return len(data), nil + } + + switch p.conn.codec { + case rawCodec: + return p.w.Write(data) + case base64Codec: + dst := make([]byte, len(data)) + n, err := base64.StdEncoding.Decode(dst, data) + if err != nil { + return 0, err + } + return p.w.Write(dst[:n]) + } + return 0, nil +} + +func (p *websocketChannel) Read(data []byte) (int, error) { + if !p.read { + return 0, io.EOF + } + return p.r.Read(data) +} + +func (p *websocketChannel) Close() error { + return p.w.Close() +} diff --git a/vendor/k8s.io/apiserver/pkg/util/wsstream/doc.go b/vendor/k8s.io/apiserver/pkg/util/wsstream/doc.go new file mode 100644 index 000000000..694ce81d2 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/wsstream/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2015 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 wsstream contains utilities for streaming content over WebSockets. +// The Conn type allows callers to multiplex multiple read/write channels over +// a single websocket. The Reader type allows an io.Reader to be copied over +// a websocket channel as binary content. +package wsstream // import "k8s.io/apiserver/pkg/util/wsstream" diff --git a/vendor/k8s.io/apiserver/pkg/util/wsstream/stream.go b/vendor/k8s.io/apiserver/pkg/util/wsstream/stream.go new file mode 100644 index 000000000..ba7e6a519 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/util/wsstream/stream.go @@ -0,0 +1,177 @@ +/* +Copyright 2015 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 wsstream + +import ( + "encoding/base64" + "io" + "net/http" + "sync" + "time" + + "golang.org/x/net/websocket" + + "k8s.io/apimachinery/pkg/util/runtime" +) + +// The WebSocket subprotocol "binary.k8s.io" will only send messages to the +// client and ignore messages sent to the server. The received messages are +// the exact bytes written to the stream. Zero byte messages are possible. +const binaryWebSocketProtocol = "binary.k8s.io" + +// The WebSocket subprotocol "base64.binary.k8s.io" will only send messages to the +// client and ignore messages sent to the server. The received messages are +// a base64 version of the bytes written to the stream. Zero byte messages are +// possible. +const base64BinaryWebSocketProtocol = "base64.binary.k8s.io" + +// ReaderProtocolConfig describes a websocket subprotocol with one stream. +type ReaderProtocolConfig struct { + Binary bool +} + +// NewDefaultReaderProtocols returns a stream protocol map with the +// subprotocols "", "channel.k8s.io", "base64.channel.k8s.io". +func NewDefaultReaderProtocols() map[string]ReaderProtocolConfig { + return map[string]ReaderProtocolConfig{ + "": {Binary: true}, + binaryWebSocketProtocol: {Binary: true}, + base64BinaryWebSocketProtocol: {Binary: false}, + } +} + +// Reader supports returning an arbitrary byte stream over a websocket channel. +type Reader struct { + err chan error + r io.Reader + ping bool + timeout time.Duration + protocols map[string]ReaderProtocolConfig + selectedProtocol string + + handleCrash func(additionalHandlers ...func(interface{})) // overridable for testing +} + +// NewReader creates a WebSocket pipe that will copy the contents of r to a provided +// WebSocket connection. If ping is true, a zero length message will be sent to the client +// before the stream begins reading. +// +// The protocols parameter maps subprotocol names to StreamProtocols. The empty string +// subprotocol name is used if websocket.Config.Protocol is empty. +func NewReader(r io.Reader, ping bool, protocols map[string]ReaderProtocolConfig) *Reader { + return &Reader{ + r: r, + err: make(chan error), + ping: ping, + protocols: protocols, + handleCrash: runtime.HandleCrash, + } +} + +// SetIdleTimeout sets the interval for both reads and writes before timeout. If not specified, +// there is no timeout on the reader. +func (r *Reader) SetIdleTimeout(duration time.Duration) { + r.timeout = duration +} + +func (r *Reader) handshake(config *websocket.Config, req *http.Request) error { + supportedProtocols := make([]string, 0, len(r.protocols)) + for p := range r.protocols { + supportedProtocols = append(supportedProtocols, p) + } + return handshake(config, req, supportedProtocols) +} + +// Copy the reader to the response. The created WebSocket is closed after this +// method completes. +func (r *Reader) Copy(w http.ResponseWriter, req *http.Request) error { + go func() { + defer r.handleCrash() + websocket.Server{Handshake: r.handshake, Handler: r.handle}.ServeHTTP(w, req) + }() + return <-r.err +} + +// handle implements a WebSocket handler. +func (r *Reader) handle(ws *websocket.Conn) { + // Close the connection when the client requests it, or when we finish streaming, whichever happens first + closeConnOnce := &sync.Once{} + closeConn := func() { + closeConnOnce.Do(func() { + ws.Close() + }) + } + + negotiated := ws.Config().Protocol + r.selectedProtocol = negotiated[0] + defer close(r.err) + defer closeConn() + + go func() { + defer runtime.HandleCrash() + // This blocks until the connection is closed. + // Client should not send anything. + IgnoreReceives(ws, r.timeout) + // Once the client closes, we should also close + closeConn() + }() + + r.err <- messageCopy(ws, r.r, !r.protocols[r.selectedProtocol].Binary, r.ping, r.timeout) +} + +func resetTimeout(ws *websocket.Conn, timeout time.Duration) { + if timeout > 0 { + ws.SetDeadline(time.Now().Add(timeout)) + } +} + +func messageCopy(ws *websocket.Conn, r io.Reader, base64Encode, ping bool, timeout time.Duration) error { + buf := make([]byte, 2048) + if ping { + resetTimeout(ws, timeout) + if base64Encode { + if err := websocket.Message.Send(ws, ""); err != nil { + return err + } + } else { + if err := websocket.Message.Send(ws, []byte{}); err != nil { + return err + } + } + } + for { + resetTimeout(ws, timeout) + n, err := r.Read(buf) + if err != nil { + if err == io.EOF { + return nil + } + return err + } + if n > 0 { + if base64Encode { + if err := websocket.Message.Send(ws, base64.StdEncoding.EncodeToString(buf[:n])); err != nil { + return err + } + } else { + if err := websocket.Message.Send(ws, buf[:n]); err != nil { + return err + } + } + } + } +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/buffered.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/buffered.go new file mode 100644 index 000000000..07f263b2e --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/buffered.go @@ -0,0 +1,290 @@ +/* +Copyright 2018 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 buffered + +import ( + "fmt" + "sync" + "time" + + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/audit" + "k8s.io/client-go/util/flowcontrol" +) + +// PluginName is the name reported in error metrics. +const PluginName = "buffered" + +// BatchConfig represents batching delegate audit backend configuration. +type BatchConfig struct { + // BufferSize defines a size of the buffering queue. + BufferSize int + // MaxBatchSize defines maximum size of a batch. + MaxBatchSize int + // MaxBatchWait indicates the maximum interval between two batches. + MaxBatchWait time.Duration + + // ThrottleEnable defines whether throttling will be applied to the batching process. + ThrottleEnable bool + // ThrottleQPS defines the allowed rate of batches per second sent to the delegate backend. + ThrottleQPS float32 + // ThrottleBurst defines the maximum number of requests sent to the delegate backend at the same moment in case + // the capacity defined by ThrottleQPS was not utilized. + ThrottleBurst int + + // Whether the delegate backend should be called asynchronously. + AsyncDelegate bool +} + +type bufferedBackend struct { + // The delegate backend that actually exports events. + delegateBackend audit.Backend + + // Channel to buffer events before sending to the delegate backend. + buffer chan *auditinternal.Event + // Maximum number of events in a batch sent to the delegate backend. + maxBatchSize int + // Amount of time to wait after sending a batch to the delegate backend before sending another one. + // + // Receiving maxBatchSize events will always trigger sending a batch, regardless of the amount of time passed. + maxBatchWait time.Duration + + // Whether the delegate backend should be called asynchronously. + asyncDelegate bool + + // Channel to signal that the batching routine has processed all remaining events and exited. + // Once `shutdownCh` is closed no new events will be sent to the delegate backend. + shutdownCh chan struct{} + + // WaitGroup to control the concurrency of sending batches to the delegate backend. + // Worker routine calls Add before sending a batch and + // then spawns a routine that calls Done after batch was processed by the delegate backend. + // This WaitGroup is used to wait for all sending routines to finish before shutting down audit backend. + wg sync.WaitGroup + + // Limits the number of batches sent to the delegate backend per second. + throttle flowcontrol.RateLimiter +} + +var _ audit.Backend = &bufferedBackend{} + +// NewBackend returns a buffered audit backend that wraps delegate backend. +// Buffered backend automatically runs and shuts down the delegate backend. +func NewBackend(delegate audit.Backend, config BatchConfig) audit.Backend { + var throttle flowcontrol.RateLimiter + if config.ThrottleEnable { + throttle = flowcontrol.NewTokenBucketRateLimiter(config.ThrottleQPS, config.ThrottleBurst) + } + return &bufferedBackend{ + delegateBackend: delegate, + buffer: make(chan *auditinternal.Event, config.BufferSize), + maxBatchSize: config.MaxBatchSize, + maxBatchWait: config.MaxBatchWait, + asyncDelegate: config.AsyncDelegate, + shutdownCh: make(chan struct{}), + wg: sync.WaitGroup{}, + throttle: throttle, + } +} + +func (b *bufferedBackend) Run(stopCh <-chan struct{}) error { + go func() { + // Signal that the working routine has exited. + defer close(b.shutdownCh) + + b.processIncomingEvents(stopCh) + + // Handle the events that were received after the last buffer + // scraping and before this line. Since the buffer is closed, no new + // events will come through. + allEventsProcessed := false + timer := make(chan time.Time) + for !allEventsProcessed { + allEventsProcessed = func() bool { + // Recover from any panic in order to try to process all remaining events. + // Note, that in case of a panic, the return value will be false and + // the loop execution will continue. + defer runtime.HandleCrash() + + events := b.collectEvents(timer, wait.NeverStop) + b.processEvents(events) + return len(events) == 0 + }() + } + }() + return b.delegateBackend.Run(stopCh) +} + +// Shutdown blocks until stopCh passed to the Run method is closed and all +// events added prior to that moment are batched and sent to the delegate backend. +func (b *bufferedBackend) Shutdown() { + // Wait until the routine spawned in Run method exits. + <-b.shutdownCh + + // Wait until all sending routines exit. + // + // - When b.shutdownCh is closed, we know that the goroutine in Run has terminated. + // - This means that processIncomingEvents has terminated. + // - Which means that b.buffer is closed and cannot accept any new events anymore. + // - Because processEvents is called synchronously from the Run goroutine, the waitgroup has its final value. + // Hence wg.Wait will not miss any more outgoing batches. + b.wg.Wait() + + b.delegateBackend.Shutdown() +} + +// processIncomingEvents runs a loop that collects events from the buffer. When +// b.stopCh is closed, processIncomingEvents stops and closes the buffer. +func (b *bufferedBackend) processIncomingEvents(stopCh <-chan struct{}) { + defer close(b.buffer) + + var ( + maxWaitChan <-chan time.Time + maxWaitTimer *time.Timer + ) + // Only use max wait batching if batching is enabled. + if b.maxBatchSize > 1 { + maxWaitTimer = time.NewTimer(b.maxBatchWait) + maxWaitChan = maxWaitTimer.C + defer maxWaitTimer.Stop() + } + + for { + func() { + // Recover from any panics caused by this function so a panic in the + // goroutine can't bring down the main routine. + defer runtime.HandleCrash() + + if b.maxBatchSize > 1 { + maxWaitTimer.Reset(b.maxBatchWait) + } + b.processEvents(b.collectEvents(maxWaitChan, stopCh)) + }() + + select { + case <-stopCh: + return + default: + } + } +} + +// collectEvents attempts to collect some number of events in a batch. +// +// The following things can cause collectEvents to stop and return the list +// of events: +// +// - Maximum number of events for a batch. +// - Timer has passed. +// - Buffer channel is closed and empty. +// - stopCh is closed. +func (b *bufferedBackend) collectEvents(timer <-chan time.Time, stopCh <-chan struct{}) []*auditinternal.Event { + var events []*auditinternal.Event + +L: + for i := 0; i < b.maxBatchSize; i++ { + select { + case ev, ok := <-b.buffer: + // Buffer channel was closed and no new events will follow. + if !ok { + break L + } + events = append(events, ev) + case <-timer: + // Timer has expired. Send currently accumulated batch. + break L + case <-stopCh: + // Backend has been stopped. Send currently accumulated batch. + break L + } + } + + return events +} + +// processEvents process the batch events in a goroutine using delegateBackend's ProcessEvents. +func (b *bufferedBackend) processEvents(events []*auditinternal.Event) { + if len(events) == 0 { + return + } + + // TODO(audit): Should control the number of active goroutines + // if one goroutine takes 5 seconds to finish, the number of goroutines can be 5 * defaultBatchThrottleQPS + if b.throttle != nil { + b.throttle.Accept() + } + + if b.asyncDelegate { + b.wg.Add(1) + go func() { + defer b.wg.Done() + defer runtime.HandleCrash() + + // Execute the real processing in a goroutine to keep it from blocking. + // This lets the batching routine continue draining the queue immediately. + b.delegateBackend.ProcessEvents(events...) + }() + } else { + func() { + defer runtime.HandleCrash() + + // Execute the real processing in a goroutine to keep it from blocking. + // This lets the batching routine continue draining the queue immediately. + b.delegateBackend.ProcessEvents(events...) + }() + } +} + +func (b *bufferedBackend) ProcessEvents(ev ...*auditinternal.Event) bool { + // The following mechanism is in place to support the situation when audit + // events are still coming after the backend was stopped. + var sendErr error + var evIndex int + + // If the delegateBackend was shutdown and the buffer channel was closed, an + // attempt to add an event to it will result in panic that we should + // recover from. + defer func() { + if err := recover(); err != nil { + sendErr = fmt.Errorf("audit backend shut down") + } + if sendErr != nil { + audit.HandlePluginError(PluginName, sendErr, ev[evIndex:]...) + } + }() + + for i, e := range ev { + evIndex = i + // Per the audit.Backend interface these events are reused after being + // sent to the Sink. Deep copy and send the copy to the queue. + event := e.DeepCopy() + + select { + case b.buffer <- event: + default: + sendErr = fmt.Errorf("audit buffer queue blocked") + return true + } + } + return true +} + +func (b *bufferedBackend) String() string { + return fmt.Sprintf("%s<%s>", PluginName, b.delegateBackend) +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/doc.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/doc.go new file mode 100644 index 000000000..a82599e42 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/buffered/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2018 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 buffered provides an implementation for the audit.Backend interface +// that batches incoming audit events and sends batches to the delegate audit.Backend. +package buffered // import "k8s.io/apiserver/plugin/pkg/audit/buffered" diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/log/backend.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/log/backend.go new file mode 100644 index 000000000..2ef2cc6ec --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/log/backend.go @@ -0,0 +1,104 @@ +/* +Copyright 2017 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 log + +import ( + "fmt" + "io" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/audit" +) + +const ( + // FormatLegacy saves event in 1-line text format. + FormatLegacy = "legacy" + // FormatJson saves event in structured json format. + FormatJson = "json" + + // PluginName is the name of this plugin, to be used in help and logs. + PluginName = "log" +) + +// AllowedFormats are the formats known by log backend. +var AllowedFormats = []string{ + FormatLegacy, + FormatJson, +} + +type backend struct { + out io.Writer + format string + encoder runtime.Encoder +} + +var _ audit.Backend = &backend{} + +func NewBackend(out io.Writer, format string, groupVersion schema.GroupVersion) audit.Backend { + return &backend{ + out: out, + format: format, + encoder: audit.Codecs.LegacyCodec(groupVersion), + } +} + +func (b *backend) ProcessEvents(events ...*auditinternal.Event) bool { + success := true + for _, ev := range events { + success = b.logEvent(ev) && success + } + return success +} + +func (b *backend) logEvent(ev *auditinternal.Event) bool { + line := "" + switch b.format { + case FormatLegacy: + line = audit.EventString(ev) + "\n" + case FormatJson: + bs, err := runtime.Encode(b.encoder, ev) + if err != nil { + audit.HandlePluginError(PluginName, err, ev) + return false + } + line = string(bs[:]) + default: + audit.HandlePluginError(PluginName, fmt.Errorf("log format %q is not in list of known formats (%s)", + b.format, strings.Join(AllowedFormats, ",")), ev) + return false + } + if _, err := fmt.Fprint(b.out, line); err != nil { + audit.HandlePluginError(PluginName, err, ev) + return false + } + return true +} + +func (b *backend) Run(stopCh <-chan struct{}) error { + return nil +} + +func (b *backend) Shutdown() { + // Nothing to do here. +} + +func (b *backend) String() string { + return PluginName +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/doc.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/doc.go new file mode 100644 index 000000000..9392ac314 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2018 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 truncate provides an implementation for the audit.Backend interface +// that truncates audit events and sends them to the delegate audit.Backend. +package truncate // import "k8s.io/apiserver/plugin/pkg/audit/truncate" diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/truncate.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/truncate.go new file mode 100644 index 000000000..42a40e3eb --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/truncate/truncate.go @@ -0,0 +1,165 @@ +/* +Copyright 2018 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 truncate + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/audit" +) + +const ( + // PluginName is the name reported in error metrics. + PluginName = "truncate" + + // annotationKey defines the name of the annotation used to indicate truncation. + annotationKey = "audit.k8s.io/truncated" + // annotationValue defines the value of the annotation used to indicate truncation. + annotationValue = "true" +) + +// Config represents truncating backend configuration. +type Config struct { + // MaxEventSize defines max allowed size of the event. If the event is larger, + // truncating will be performed. + MaxEventSize int64 + + // MaxBatchSize defined max allowed size of the batch of events, passed to the backend. + // If the total size of the batch is larger than this number, batch will be split. Actual + // size of the serialized request might be slightly higher, on the order of hundreds of bytes. + MaxBatchSize int64 +} + +type backend struct { + // The delegate backend that actually exports events. + delegateBackend audit.Backend + + // Configuration used for truncation. + c Config + + // Encoder used to calculate audit event sizes. + e runtime.Encoder +} + +var _ audit.Backend = &backend{} + +// NewBackend returns a new truncating backend, using configuration passed in the parameters. +// Truncate backend automatically runs and shut downs the delegate backend. +func NewBackend(delegateBackend audit.Backend, config Config, groupVersion schema.GroupVersion) audit.Backend { + return &backend{ + delegateBackend: delegateBackend, + c: config, + e: audit.Codecs.LegacyCodec(groupVersion), + } +} + +func (b *backend) ProcessEvents(events ...*auditinternal.Event) bool { + var errors []error + var impacted []*auditinternal.Event + var batch []*auditinternal.Event + var batchSize int64 + success := true + for _, event := range events { + size, err := b.calcSize(event) + // If event was correctly serialized, but the size is more than allowed + // and it makes sense to do trimming, i.e. there's a request and/or + // response present, try to strip away request and response. + if err == nil && size > b.c.MaxEventSize && event.Level.GreaterOrEqual(auditinternal.LevelRequest) { + event = truncate(event) + size, err = b.calcSize(event) + } + if err != nil { + errors = append(errors, err) + impacted = append(impacted, event) + continue + } + if size > b.c.MaxEventSize { + errors = append(errors, fmt.Errorf("event is too large even after truncating")) + impacted = append(impacted, event) + continue + } + + if len(batch) > 0 && batchSize+size > b.c.MaxBatchSize { + success = b.delegateBackend.ProcessEvents(batch...) && success + batch = []*auditinternal.Event{} + batchSize = 0 + } + + batchSize += size + batch = append(batch, event) + } + + if len(batch) > 0 { + success = b.delegateBackend.ProcessEvents(batch...) && success + } + + if len(impacted) > 0 { + audit.HandlePluginError(PluginName, utilerrors.NewAggregate(errors), impacted...) + } + return success +} + +// truncate removed request and response objects from the audit events, +// to try and keep at least metadata. +func truncate(e *auditinternal.Event) *auditinternal.Event { + // Make a shallow copy to avoid copying response/request objects. + newEvent := &auditinternal.Event{} + *newEvent = *e + + newEvent.RequestObject = nil + newEvent.ResponseObject = nil + + if newEvent.Annotations == nil { + newEvent.Annotations = make(map[string]string) + } + newEvent.Annotations[annotationKey] = annotationValue + + return newEvent +} + +func (b *backend) Run(stopCh <-chan struct{}) error { + return b.delegateBackend.Run(stopCh) +} + +func (b *backend) Shutdown() { + b.delegateBackend.Shutdown() +} + +func (b *backend) calcSize(e *auditinternal.Event) (int64, error) { + s := &sizer{} + if err := b.e.Encode(e, s); err != nil { + return 0, err + } + return s.Size, nil +} + +func (b *backend) String() string { + return fmt.Sprintf("%s<%s>", PluginName, b.delegateBackend) +} + +type sizer struct { + Size int64 +} + +func (s *sizer) Write(p []byte) (n int, err error) { + s.Size += int64(len(p)) + return len(p), nil +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/audit/webhook/webhook.go b/vendor/k8s.io/apiserver/plugin/pkg/audit/webhook/webhook.go new file mode 100644 index 000000000..6355df403 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/audit/webhook/webhook.go @@ -0,0 +1,146 @@ +/* +Copyright 2017 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 webhook implements the audit.Backend interface using HTTP webhooks. +package webhook + +import ( + "context" + "fmt" + "time" + + "go.opentelemetry.io/otel/attribute" + + "k8s.io/apimachinery/pkg/runtime/schema" + utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/pkg/util/wait" + auditinternal "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/apis/audit/install" + "k8s.io/apiserver/pkg/audit" + "k8s.io/apiserver/pkg/util/webhook" + "k8s.io/client-go/rest" + "k8s.io/component-base/tracing" +) + +const ( + // PluginName is the name of this plugin, to be used in help and logs. + PluginName = "webhook" + + // DefaultInitialBackoffDelay is the default amount of time to wait before + // retrying sending audit events through a webhook. + DefaultInitialBackoffDelay = 10 * time.Second +) + +func init() { + install.Install(audit.Scheme) +} + +// retryOnError enforces the webhook client to retry requests +// on error regardless of its nature. +// The default implementation considers a very limited set of +// 'retriable' errors, assuming correct use of HTTP codes by +// external webhooks. +// That may easily lead to dropped audit events. In fact, there is +// hardly any error that could be a justified reason NOT to retry +// sending audit events if there is even a slight chance that the +// receiving service gets back to normal at some point. +func retryOnError(err error) bool { + if err != nil { + return true + } + return false +} + +func loadWebhook(configFile string, groupVersion schema.GroupVersion, retryBackoff wait.Backoff, customDial utilnet.DialFunc) (*webhook.GenericWebhook, error) { + clientConfig, err := webhook.LoadKubeconfig(configFile, customDial) + if err != nil { + return nil, err + } + w, err := webhook.NewGenericWebhook(audit.Scheme, audit.Codecs, clientConfig, + []schema.GroupVersion{groupVersion}, retryBackoff) + if err != nil { + return nil, err + } + + w.ShouldRetry = retryOnError + return w, nil +} + +type backend struct { + w *webhook.GenericWebhook + name string +} + +// NewDynamicBackend returns an audit backend configured from a REST client that +// sends events over HTTP to an external service. +func NewDynamicBackend(rc *rest.RESTClient, retryBackoff wait.Backoff) audit.Backend { + return &backend{ + w: &webhook.GenericWebhook{ + RestClient: rc, + RetryBackoff: retryBackoff, + ShouldRetry: retryOnError, + }, + name: fmt.Sprintf("dynamic_%s", PluginName), + } +} + +// NewBackend returns an audit backend that sends events over HTTP to an external service. +func NewBackend(kubeConfigFile string, groupVersion schema.GroupVersion, retryBackoff wait.Backoff, customDial utilnet.DialFunc) (audit.Backend, error) { + w, err := loadWebhook(kubeConfigFile, groupVersion, retryBackoff, customDial) + if err != nil { + return nil, err + } + return &backend{w: w, name: PluginName}, nil +} + +func (b *backend) Run(stopCh <-chan struct{}) error { + return nil +} + +func (b *backend) Shutdown() { + // nothing to do here +} + +func (b *backend) ProcessEvents(ev ...*auditinternal.Event) bool { + if err := b.processEvents(ev...); err != nil { + audit.HandlePluginError(b.String(), err, ev...) + return false + } + return true +} + +func (b *backend) processEvents(ev ...*auditinternal.Event) error { + var list auditinternal.EventList + for _, e := range ev { + list.Items = append(list.Items, *e) + } + return b.w.WithExponentialBackoff(context.Background(), func() rest.Result { + ctx, span := tracing.Start(context.Background(), "Call Audit Events webhook", + attribute.String("name", b.name), + attribute.Int("event-count", len(list.Items)), + ) + // Only log audit webhook traces that exceed a 25ms per object limit plus a 50ms + // request overhead allowance. The high per object limit used here is primarily to + // allow enough time for the serialization/deserialization of audit events, which + // contain nested request and response objects plus additional event fields. + defer span.End(time.Duration(50+25*len(list.Items)) * time.Millisecond) + return b.w.RestClient.Post().Body(&list).Do(ctx) + }).Error() +} + +func (b *backend) String() string { + return b.name +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/metrics.go b/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/metrics.go new file mode 100644 index 000000000..32e469e80 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/metrics.go @@ -0,0 +1,35 @@ +/* +Copyright 2021 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 webhook + +import ( + "context" +) + +// AuthenticatorMetrics specifies a set of methods that are used to register various metrics +type AuthenticatorMetrics struct { + // RecordRequestTotal increments the total number of requests for webhooks + RecordRequestTotal func(ctx context.Context, code string) + + // RecordRequestLatency measures request latency in seconds for webhooks. Broken down by status code. + RecordRequestLatency func(ctx context.Context, code string, latency float64) +} + +type noopMetrics struct{} + +func (noopMetrics) RequestTotal(context.Context, string) {} +func (noopMetrics) RequestLatency(context.Context, string, float64) {} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go b/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go new file mode 100644 index 000000000..7d19b4b7a --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go @@ -0,0 +1,327 @@ +/* +Copyright 2016 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 webhook implements the authenticator.Token interface using HTTP webhooks. +package webhook + +import ( + "context" + "errors" + "fmt" + "strconv" + "time" + + authenticationv1 "k8s.io/api/authentication/v1" + authenticationv1beta1 "k8s.io/api/authentication/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/authentication/authenticator" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/util/webhook" + "k8s.io/client-go/kubernetes/scheme" + authenticationv1client "k8s.io/client-go/kubernetes/typed/authentication/v1" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" +) + +// DefaultRetryBackoff returns the default backoff parameters for webhook retry. +func DefaultRetryBackoff() *wait.Backoff { + backoff := webhook.DefaultRetryBackoffWithInitialDelay(500 * time.Millisecond) + return &backoff +} + +// Ensure WebhookTokenAuthenticator implements the authenticator.Token interface. +var _ authenticator.Token = (*WebhookTokenAuthenticator)(nil) + +type tokenReviewer interface { + Create(ctx context.Context, review *authenticationv1.TokenReview, _ metav1.CreateOptions) (*authenticationv1.TokenReview, int, error) +} + +type WebhookTokenAuthenticator struct { + tokenReview tokenReviewer + retryBackoff wait.Backoff + implicitAuds authenticator.Audiences + requestTimeout time.Duration + metrics AuthenticatorMetrics +} + +// NewFromInterface creates a webhook authenticator using the given tokenReview +// client. It is recommend to wrap this authenticator with the token cache +// authenticator implemented in +// k8s.io/apiserver/pkg/authentication/token/cache. +func NewFromInterface(tokenReview authenticationv1client.AuthenticationV1Interface, implicitAuds authenticator.Audiences, retryBackoff wait.Backoff, requestTimeout time.Duration, metrics AuthenticatorMetrics) (*WebhookTokenAuthenticator, error) { + tokenReviewClient := &tokenReviewV1Client{tokenReview.RESTClient()} + return newWithBackoff(tokenReviewClient, retryBackoff, implicitAuds, requestTimeout, metrics) +} + +// New creates a new WebhookTokenAuthenticator from the provided rest +// config. It is recommend to wrap this authenticator with the token cache +// authenticator implemented in +// k8s.io/apiserver/pkg/authentication/token/cache. +func New(config *rest.Config, version string, implicitAuds authenticator.Audiences, retryBackoff wait.Backoff) (*WebhookTokenAuthenticator, error) { + tokenReview, err := tokenReviewInterfaceFromConfig(config, version, retryBackoff) + if err != nil { + return nil, err + } + return newWithBackoff(tokenReview, retryBackoff, implicitAuds, time.Duration(0), AuthenticatorMetrics{ + RecordRequestTotal: noopMetrics{}.RequestTotal, + RecordRequestLatency: noopMetrics{}.RequestLatency, + }) +} + +// newWithBackoff allows tests to skip the sleep. +func newWithBackoff(tokenReview tokenReviewer, retryBackoff wait.Backoff, implicitAuds authenticator.Audiences, requestTimeout time.Duration, metrics AuthenticatorMetrics) (*WebhookTokenAuthenticator, error) { + return &WebhookTokenAuthenticator{ + tokenReview, + retryBackoff, + implicitAuds, + requestTimeout, + metrics, + }, nil +} + +// AuthenticateToken implements the authenticator.Token interface. +func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) { + // We take implicit audiences of the API server at WebhookTokenAuthenticator + // construction time. The outline of how we validate audience here is: + // + // * if the ctx is not audience limited, don't do any audience validation. + // * if ctx is audience-limited, add the audiences to the tokenreview spec + // * if the tokenreview returns with audiences in the status that intersect + // with the audiences in the ctx, copy into the response and return success + // * if the tokenreview returns without an audience in the status, ensure + // the ctx audiences intersect with the implicit audiences, and set the + // intersection in the response. + // * otherwise return unauthenticated. + wantAuds, checkAuds := authenticator.AudiencesFrom(ctx) + r := &authenticationv1.TokenReview{ + Spec: authenticationv1.TokenReviewSpec{ + Token: token, + Audiences: wantAuds, + }, + } + var ( + result *authenticationv1.TokenReview + auds authenticator.Audiences + cancel context.CancelFunc + ) + + // set a hard timeout if it was defined + // if the child has a shorter deadline then it will expire first, + // otherwise if the parent has a shorter deadline then the parent will expire and it will be propagate to the child + if w.requestTimeout > 0 { + ctx, cancel = context.WithTimeout(ctx, w.requestTimeout) + defer cancel() + } + + // WithExponentialBackoff will return tokenreview create error (tokenReviewErr) if any. + if err := webhook.WithExponentialBackoff(ctx, w.retryBackoff, func() error { + var tokenReviewErr error + var statusCode int + + start := time.Now() + result, statusCode, tokenReviewErr = w.tokenReview.Create(ctx, r, metav1.CreateOptions{}) + latency := time.Since(start) + + if statusCode != 0 { + w.metrics.RecordRequestTotal(ctx, strconv.Itoa(statusCode)) + w.metrics.RecordRequestLatency(ctx, strconv.Itoa(statusCode), latency.Seconds()) + return tokenReviewErr + } + + if tokenReviewErr != nil { + w.metrics.RecordRequestTotal(ctx, "") + w.metrics.RecordRequestLatency(ctx, "", latency.Seconds()) + } + return tokenReviewErr + }, webhook.DefaultShouldRetry); err != nil { + // An error here indicates bad configuration or an outage. Log for debugging. + klog.Errorf("Failed to make webhook authenticator request: %v", err) + return nil, false, err + } + + if checkAuds { + gotAuds := w.implicitAuds + if len(result.Status.Audiences) > 0 { + gotAuds = result.Status.Audiences + } + auds = wantAuds.Intersect(gotAuds) + if len(auds) == 0 { + return nil, false, nil + } + } + + r.Status = result.Status + if !r.Status.Authenticated { + var err error + if len(r.Status.Error) != 0 { + err = errors.New(r.Status.Error) + } + return nil, false, err + } + + var extra map[string][]string + if r.Status.User.Extra != nil { + extra = map[string][]string{} + for k, v := range r.Status.User.Extra { + extra[k] = v + } + } + + return &authenticator.Response{ + User: &user.DefaultInfo{ + Name: r.Status.User.Username, + UID: r.Status.User.UID, + Groups: r.Status.User.Groups, + Extra: extra, + }, + Audiences: auds, + }, true, nil +} + +// tokenReviewInterfaceFromConfig builds a client from the specified kubeconfig file, +// and returns a TokenReviewInterface that uses that client. Note that the client submits TokenReview +// requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted. +func tokenReviewInterfaceFromConfig(config *rest.Config, version string, retryBackoff wait.Backoff) (tokenReviewer, error) { + localScheme := runtime.NewScheme() + if err := scheme.AddToScheme(localScheme); err != nil { + return nil, err + } + + switch version { + case authenticationv1.SchemeGroupVersion.Version: + groupVersions := []schema.GroupVersion{authenticationv1.SchemeGroupVersion} + if err := localScheme.SetVersionPriority(groupVersions...); err != nil { + return nil, err + } + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, config, groupVersions, retryBackoff) + if err != nil { + return nil, err + } + return &tokenReviewV1ClientGW{gw.RestClient}, nil + + case authenticationv1beta1.SchemeGroupVersion.Version: + groupVersions := []schema.GroupVersion{authenticationv1beta1.SchemeGroupVersion} + if err := localScheme.SetVersionPriority(groupVersions...); err != nil { + return nil, err + } + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, config, groupVersions, retryBackoff) + if err != nil { + return nil, err + } + return &tokenReviewV1beta1ClientGW{gw.RestClient}, nil + + default: + return nil, fmt.Errorf( + "unsupported authentication webhook version %q, supported versions are %q, %q", + version, + authenticationv1.SchemeGroupVersion.Version, + authenticationv1beta1.SchemeGroupVersion.Version, + ) + } + +} + +type tokenReviewV1Client struct { + client rest.Interface +} + +// Create takes the representation of a tokenReview and creates it. Returns the server's representation of the tokenReview, HTTP status code and an error, if there is any. +func (c *tokenReviewV1Client) Create(ctx context.Context, tokenReview *authenticationv1.TokenReview, opts metav1.CreateOptions) (result *authenticationv1.TokenReview, statusCode int, err error) { + result = &authenticationv1.TokenReview{} + + restResult := c.client.Post(). + Resource("tokenreviews"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(tokenReview). + Do(ctx) + + restResult.StatusCode(&statusCode) + err = restResult.Into(result) + return +} + +// tokenReviewV1ClientGW used by the generic webhook, doesn't specify GVR. +type tokenReviewV1ClientGW struct { + client rest.Interface +} + +// Create takes the representation of a tokenReview and creates it. Returns the server's representation of the tokenReview, HTTP status code and an error, if there is any. +func (c *tokenReviewV1ClientGW) Create(ctx context.Context, tokenReview *authenticationv1.TokenReview, opts metav1.CreateOptions) (result *authenticationv1.TokenReview, statusCode int, err error) { + result = &authenticationv1.TokenReview{} + + restResult := c.client.Post(). + Body(tokenReview). + Do(ctx) + + restResult.StatusCode(&statusCode) + err = restResult.Into(result) + return +} + +// tokenReviewV1beta1ClientGW used by the generic webhook, doesn't specify GVR. +type tokenReviewV1beta1ClientGW struct { + client rest.Interface +} + +func (t *tokenReviewV1beta1ClientGW) Create(ctx context.Context, review *authenticationv1.TokenReview, _ metav1.CreateOptions) (*authenticationv1.TokenReview, int, error) { + var statusCode int + v1beta1Review := &authenticationv1beta1.TokenReview{Spec: v1SpecToV1beta1Spec(&review.Spec)} + v1beta1Result := &authenticationv1beta1.TokenReview{} + + restResult := t.client.Post().Body(v1beta1Review).Do(ctx) + restResult.StatusCode(&statusCode) + err := restResult.Into(v1beta1Result) + if err != nil { + return nil, statusCode, err + } + review.Status = v1beta1StatusToV1Status(&v1beta1Result.Status) + return review, statusCode, nil +} + +func v1SpecToV1beta1Spec(in *authenticationv1.TokenReviewSpec) authenticationv1beta1.TokenReviewSpec { + return authenticationv1beta1.TokenReviewSpec{ + Token: in.Token, + Audiences: in.Audiences, + } +} + +func v1beta1StatusToV1Status(in *authenticationv1beta1.TokenReviewStatus) authenticationv1.TokenReviewStatus { + return authenticationv1.TokenReviewStatus{ + Authenticated: in.Authenticated, + User: v1beta1UserToV1User(in.User), + Audiences: in.Audiences, + Error: in.Error, + } +} + +func v1beta1UserToV1User(u authenticationv1beta1.UserInfo) authenticationv1.UserInfo { + var extra map[string]authenticationv1.ExtraValue + if u.Extra != nil { + extra = make(map[string]authenticationv1.ExtraValue, len(u.Extra)) + for k, v := range u.Extra { + extra[k] = authenticationv1.ExtraValue(v) + } + } + return authenticationv1.UserInfo{ + Username: u.Username, + UID: u.UID, + Groups: u.Groups, + Extra: extra, + } +} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/gencerts.sh b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/gencerts.sh new file mode 100644 index 000000000..a66f8f381 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/gencerts.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash + +# Copyright 2016 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. + +set -e + +# gencerts.sh generates the certificates for the webhook authz plugin tests. +# +# It is not expected to be run often (there is no go generate rule), and mainly +# exists for documentation purposes. + +cat > server.conf << EOF +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth +subjectAltName = @alt_names +[alt_names] +IP.1 = 127.0.0.1 +EOF + +cat > client.conf << EOF +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth +EOF + +# Create a certificate authority +openssl genrsa -out caKey.pem 2048 +openssl req -x509 -new -nodes -key caKey.pem -days 100000 -out caCert.pem -subj "/CN=webhook_authz_ca" + +# Create a second certificate authority +openssl genrsa -out badCAKey.pem 2048 +openssl req -x509 -new -nodes -key badCAKey.pem -days 100000 -out badCACert.pem -subj "/CN=webhook_authz_ca" + +# Create a server certiticate +openssl genrsa -out serverKey.pem 2048 +openssl req -new -key serverKey.pem -out server.csr -subj "/CN=webhook_authz_server" -config server.conf +openssl x509 -req -in server.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out serverCert.pem -days 100000 -extensions v3_req -extfile server.conf + +# Create a client certiticate +openssl genrsa -out clientKey.pem 2048 +openssl req -new -key clientKey.pem -out client.csr -subj "/CN=webhook_authz_client" -config client.conf +openssl x509 -req -in client.csr -CA caCert.pem -CAkey caKey.pem -CAcreateserial -out clientCert.pem -days 100000 -extensions v3_req -extfile client.conf + +outfile=certs_test.go + +cat > $outfile << EOF +/* +Copyright 2016 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. +*/ + +// This file was generated using openssl by the gencerts.sh script +// and holds raw certificates for the webhook tests. + +package webhook +EOF + +for file in caKey caCert badCAKey badCACert serverKey serverCert clientKey clientCert; do + data=$(cat ${file}.pem) + echo "" >> $outfile + echo "var $file = []byte(\`$data\`)" >> $outfile +done + +# Clean up after we're done. +rm ./*.pem +rm ./*.csr +rm ./*.srl +rm ./*.conf diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics.go b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics.go new file mode 100644 index 000000000..0912378b1 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/metrics.go @@ -0,0 +1,35 @@ +/* +Copyright 2021 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 webhook + +import ( + "context" +) + +// AuthorizerMetrics specifies a set of methods that are used to register various metrics for the webhook authorizer +type AuthorizerMetrics struct { + // RecordRequestTotal increments the total number of requests for the webhook authorizer + RecordRequestTotal func(ctx context.Context, code string) + + // RecordRequestLatency measures request latency in seconds for webhooks. Broken down by status code. + RecordRequestLatency func(ctx context.Context, code string, latency float64) +} + +type noopMetrics struct{} + +func (noopMetrics) RecordRequestTotal(context.Context, string) {} +func (noopMetrics) RecordRequestLatency(context.Context, string, float64) {} diff --git a/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go new file mode 100644 index 000000000..191b37318 --- /dev/null +++ b/vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go @@ -0,0 +1,436 @@ +/* +Copyright 2016 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 webhook implements the authorizer.Authorizer interface using HTTP webhooks. +package webhook + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + "time" + + authorizationv1 "k8s.io/api/authorization/v1" + authorizationv1beta1 "k8s.io/api/authorization/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/cache" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/util/webhook" + "k8s.io/client-go/kubernetes/scheme" + authorizationv1client "k8s.io/client-go/kubernetes/typed/authorization/v1" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" +) + +const ( + // The maximum length of requester-controlled attributes to allow caching. + maxControlledAttrCacheSize = 10000 +) + +// DefaultRetryBackoff returns the default backoff parameters for webhook retry. +func DefaultRetryBackoff() *wait.Backoff { + backoff := webhook.DefaultRetryBackoffWithInitialDelay(500 * time.Millisecond) + return &backoff +} + +// Ensure Webhook implements the authorizer.Authorizer interface. +var _ authorizer.Authorizer = (*WebhookAuthorizer)(nil) + +type subjectAccessReviewer interface { + Create(context.Context, *authorizationv1.SubjectAccessReview, metav1.CreateOptions) (*authorizationv1.SubjectAccessReview, int, error) +} + +type WebhookAuthorizer struct { + subjectAccessReview subjectAccessReviewer + responseCache *cache.LRUExpireCache + authorizedTTL time.Duration + unauthorizedTTL time.Duration + retryBackoff wait.Backoff + decisionOnError authorizer.Decision + metrics AuthorizerMetrics +} + +// NewFromInterface creates a WebhookAuthorizer using the given subjectAccessReview client +func NewFromInterface(subjectAccessReview authorizationv1client.AuthorizationV1Interface, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, metrics AuthorizerMetrics) (*WebhookAuthorizer, error) { + return newWithBackoff(&subjectAccessReviewV1Client{subjectAccessReview.RESTClient()}, authorizedTTL, unauthorizedTTL, retryBackoff, metrics) +} + +// New creates a new WebhookAuthorizer from the provided kubeconfig file. +// The config's cluster field is used to refer to the remote service, user refers to the returned authorizer. +// +// # clusters refers to the remote service. +// clusters: +// - name: name-of-remote-authz-service +// cluster: +// certificate-authority: /path/to/ca.pem # CA for verifying the remote service. +// server: https://authz.example.com/authorize # URL of remote service to query. Must use 'https'. +// +// # users refers to the API server's webhook configuration. +// users: +// - name: name-of-api-server +// user: +// client-certificate: /path/to/cert.pem # cert for the webhook plugin to use +// client-key: /path/to/key.pem # key matching the cert +// +// For additional HTTP configuration, refer to the kubeconfig documentation +// https://kubernetes.io/docs/user-guide/kubeconfig-file/. +func New(config *rest.Config, version string, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff) (*WebhookAuthorizer, error) { + subjectAccessReview, err := subjectAccessReviewInterfaceFromConfig(config, version, retryBackoff) + if err != nil { + return nil, err + } + return newWithBackoff(subjectAccessReview, authorizedTTL, unauthorizedTTL, retryBackoff, AuthorizerMetrics{ + RecordRequestTotal: noopMetrics{}.RecordRequestTotal, + RecordRequestLatency: noopMetrics{}.RecordRequestLatency, + }) +} + +// newWithBackoff allows tests to skip the sleep. +func newWithBackoff(subjectAccessReview subjectAccessReviewer, authorizedTTL, unauthorizedTTL time.Duration, retryBackoff wait.Backoff, metrics AuthorizerMetrics) (*WebhookAuthorizer, error) { + return &WebhookAuthorizer{ + subjectAccessReview: subjectAccessReview, + responseCache: cache.NewLRUExpireCache(8192), + authorizedTTL: authorizedTTL, + unauthorizedTTL: unauthorizedTTL, + retryBackoff: retryBackoff, + decisionOnError: authorizer.DecisionNoOpinion, + metrics: metrics, + }, nil +} + +// Authorize makes a REST request to the remote service describing the attempted action as a JSON +// serialized api.authorization.v1beta1.SubjectAccessReview object. An example request body is +// provided below. +// +// { +// "apiVersion": "authorization.k8s.io/v1beta1", +// "kind": "SubjectAccessReview", +// "spec": { +// "resourceAttributes": { +// "namespace": "kittensandponies", +// "verb": "GET", +// "group": "group3", +// "resource": "pods" +// }, +// "user": "jane", +// "group": [ +// "group1", +// "group2" +// ] +// } +// } +// +// The remote service is expected to fill the SubjectAccessReviewStatus field to either allow or +// disallow access. A permissive response would return: +// +// { +// "apiVersion": "authorization.k8s.io/v1beta1", +// "kind": "SubjectAccessReview", +// "status": { +// "allowed": true +// } +// } +// +// To disallow access, the remote service would return: +// +// { +// "apiVersion": "authorization.k8s.io/v1beta1", +// "kind": "SubjectAccessReview", +// "status": { +// "allowed": false, +// "reason": "user does not have read access to the namespace" +// } +// } +// +// TODO(mikedanese): We should eventually support failing closed when we +// encounter an error. We are failing open now to preserve backwards compatible +// behavior. +func (w *WebhookAuthorizer) Authorize(ctx context.Context, attr authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { + r := &authorizationv1.SubjectAccessReview{} + if user := attr.GetUser(); user != nil { + r.Spec = authorizationv1.SubjectAccessReviewSpec{ + User: user.GetName(), + UID: user.GetUID(), + Groups: user.GetGroups(), + Extra: convertToSARExtra(user.GetExtra()), + } + } + + if attr.IsResourceRequest() { + r.Spec.ResourceAttributes = &authorizationv1.ResourceAttributes{ + Namespace: attr.GetNamespace(), + Verb: attr.GetVerb(), + Group: attr.GetAPIGroup(), + Version: attr.GetAPIVersion(), + Resource: attr.GetResource(), + Subresource: attr.GetSubresource(), + Name: attr.GetName(), + } + } else { + r.Spec.NonResourceAttributes = &authorizationv1.NonResourceAttributes{ + Path: attr.GetPath(), + Verb: attr.GetVerb(), + } + } + key, err := json.Marshal(r.Spec) + if err != nil { + return w.decisionOnError, "", err + } + if entry, ok := w.responseCache.Get(string(key)); ok { + r.Status = entry.(authorizationv1.SubjectAccessReviewStatus) + } else { + var result *authorizationv1.SubjectAccessReview + // WithExponentialBackoff will return SAR create error (sarErr) if any. + if err := webhook.WithExponentialBackoff(ctx, w.retryBackoff, func() error { + var sarErr error + var statusCode int + + start := time.Now() + result, statusCode, sarErr = w.subjectAccessReview.Create(ctx, r, metav1.CreateOptions{}) + latency := time.Since(start) + + if statusCode != 0 { + w.metrics.RecordRequestTotal(ctx, strconv.Itoa(statusCode)) + w.metrics.RecordRequestLatency(ctx, strconv.Itoa(statusCode), latency.Seconds()) + return sarErr + } + + if sarErr != nil { + w.metrics.RecordRequestTotal(ctx, "") + w.metrics.RecordRequestLatency(ctx, "", latency.Seconds()) + } + + return sarErr + }, webhook.DefaultShouldRetry); err != nil { + klog.Errorf("Failed to make webhook authorizer request: %v", err) + return w.decisionOnError, "", err + } + + r.Status = result.Status + if shouldCache(attr) { + if r.Status.Allowed { + w.responseCache.Add(string(key), r.Status, w.authorizedTTL) + } else { + w.responseCache.Add(string(key), r.Status, w.unauthorizedTTL) + } + } + } + switch { + case r.Status.Denied && r.Status.Allowed: + return authorizer.DecisionDeny, r.Status.Reason, fmt.Errorf("webhook subject access review returned both allow and deny response") + case r.Status.Denied: + return authorizer.DecisionDeny, r.Status.Reason, nil + case r.Status.Allowed: + return authorizer.DecisionAllow, r.Status.Reason, nil + default: + return authorizer.DecisionNoOpinion, r.Status.Reason, nil + } + +} + +// TODO: need to finish the method to get the rules when using webhook mode +func (w *WebhookAuthorizer) RulesFor(user user.Info, namespace string) ([]authorizer.ResourceRuleInfo, []authorizer.NonResourceRuleInfo, bool, error) { + var ( + resourceRules []authorizer.ResourceRuleInfo + nonResourceRules []authorizer.NonResourceRuleInfo + ) + incomplete := true + return resourceRules, nonResourceRules, incomplete, fmt.Errorf("webhook authorizer does not support user rule resolution") +} + +func convertToSARExtra(extra map[string][]string) map[string]authorizationv1.ExtraValue { + if extra == nil { + return nil + } + ret := map[string]authorizationv1.ExtraValue{} + for k, v := range extra { + ret[k] = authorizationv1.ExtraValue(v) + } + + return ret +} + +// subjectAccessReviewInterfaceFromConfig builds a client from the specified kubeconfig file, +// and returns a SubjectAccessReviewInterface that uses that client. Note that the client submits SubjectAccessReview +// requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted. +func subjectAccessReviewInterfaceFromConfig(config *rest.Config, version string, retryBackoff wait.Backoff) (subjectAccessReviewer, error) { + localScheme := runtime.NewScheme() + if err := scheme.AddToScheme(localScheme); err != nil { + return nil, err + } + + switch version { + case authorizationv1.SchemeGroupVersion.Version: + groupVersions := []schema.GroupVersion{authorizationv1.SchemeGroupVersion} + if err := localScheme.SetVersionPriority(groupVersions...); err != nil { + return nil, err + } + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, config, groupVersions, retryBackoff) + if err != nil { + return nil, err + } + return &subjectAccessReviewV1ClientGW{gw.RestClient}, nil + + case authorizationv1beta1.SchemeGroupVersion.Version: + groupVersions := []schema.GroupVersion{authorizationv1beta1.SchemeGroupVersion} + if err := localScheme.SetVersionPriority(groupVersions...); err != nil { + return nil, err + } + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, config, groupVersions, retryBackoff) + if err != nil { + return nil, err + } + return &subjectAccessReviewV1beta1ClientGW{gw.RestClient}, nil + + default: + return nil, fmt.Errorf( + "unsupported webhook authorizer version %q, supported versions are %q, %q", + version, + authorizationv1.SchemeGroupVersion.Version, + authorizationv1beta1.SchemeGroupVersion.Version, + ) + } +} + +type subjectAccessReviewV1Client struct { + client rest.Interface +} + +func (t *subjectAccessReviewV1Client) Create(ctx context.Context, subjectAccessReview *authorizationv1.SubjectAccessReview, opts metav1.CreateOptions) (result *authorizationv1.SubjectAccessReview, statusCode int, err error) { + result = &authorizationv1.SubjectAccessReview{} + + restResult := t.client.Post(). + Resource("subjectaccessreviews"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(subjectAccessReview). + Do(ctx) + + restResult.StatusCode(&statusCode) + err = restResult.Into(result) + return +} + +// subjectAccessReviewV1ClientGW used by the generic webhook, doesn't specify GVR. +type subjectAccessReviewV1ClientGW struct { + client rest.Interface +} + +func (t *subjectAccessReviewV1ClientGW) Create(ctx context.Context, subjectAccessReview *authorizationv1.SubjectAccessReview, _ metav1.CreateOptions) (*authorizationv1.SubjectAccessReview, int, error) { + var statusCode int + result := &authorizationv1.SubjectAccessReview{} + + restResult := t.client.Post().Body(subjectAccessReview).Do(ctx) + + restResult.StatusCode(&statusCode) + err := restResult.Into(result) + + return result, statusCode, err +} + +// subjectAccessReviewV1beta1ClientGW used by the generic webhook, doesn't specify GVR. +type subjectAccessReviewV1beta1ClientGW struct { + client rest.Interface +} + +func (t *subjectAccessReviewV1beta1ClientGW) Create(ctx context.Context, subjectAccessReview *authorizationv1.SubjectAccessReview, _ metav1.CreateOptions) (*authorizationv1.SubjectAccessReview, int, error) { + var statusCode int + v1beta1Review := &authorizationv1beta1.SubjectAccessReview{Spec: v1SpecToV1beta1Spec(&subjectAccessReview.Spec)} + v1beta1Result := &authorizationv1beta1.SubjectAccessReview{} + + restResult := t.client.Post().Body(v1beta1Review).Do(ctx) + + restResult.StatusCode(&statusCode) + err := restResult.Into(v1beta1Result) + if err == nil { + subjectAccessReview.Status = v1beta1StatusToV1Status(&v1beta1Result.Status) + } + return subjectAccessReview, statusCode, err +} + +// shouldCache determines whether it is safe to cache the given request attributes. If the +// requester-controlled attributes are too large, this may be a DoS attempt, so we skip the cache. +func shouldCache(attr authorizer.Attributes) bool { + controlledAttrSize := int64(len(attr.GetNamespace())) + + int64(len(attr.GetVerb())) + + int64(len(attr.GetAPIGroup())) + + int64(len(attr.GetAPIVersion())) + + int64(len(attr.GetResource())) + + int64(len(attr.GetSubresource())) + + int64(len(attr.GetName())) + + int64(len(attr.GetPath())) + return controlledAttrSize < maxControlledAttrCacheSize +} + +func v1beta1StatusToV1Status(in *authorizationv1beta1.SubjectAccessReviewStatus) authorizationv1.SubjectAccessReviewStatus { + return authorizationv1.SubjectAccessReviewStatus{ + Allowed: in.Allowed, + Denied: in.Denied, + Reason: in.Reason, + EvaluationError: in.EvaluationError, + } +} + +func v1SpecToV1beta1Spec(in *authorizationv1.SubjectAccessReviewSpec) authorizationv1beta1.SubjectAccessReviewSpec { + return authorizationv1beta1.SubjectAccessReviewSpec{ + ResourceAttributes: v1ResourceAttributesToV1beta1ResourceAttributes(in.ResourceAttributes), + NonResourceAttributes: v1NonResourceAttributesToV1beta1NonResourceAttributes(in.NonResourceAttributes), + User: in.User, + Groups: in.Groups, + Extra: v1ExtraToV1beta1Extra(in.Extra), + UID: in.UID, + } +} + +func v1ResourceAttributesToV1beta1ResourceAttributes(in *authorizationv1.ResourceAttributes) *authorizationv1beta1.ResourceAttributes { + if in == nil { + return nil + } + return &authorizationv1beta1.ResourceAttributes{ + Namespace: in.Namespace, + Verb: in.Verb, + Group: in.Group, + Version: in.Version, + Resource: in.Resource, + Subresource: in.Subresource, + Name: in.Name, + } +} + +func v1NonResourceAttributesToV1beta1NonResourceAttributes(in *authorizationv1.NonResourceAttributes) *authorizationv1beta1.NonResourceAttributes { + if in == nil { + return nil + } + return &authorizationv1beta1.NonResourceAttributes{ + Path: in.Path, + Verb: in.Verb, + } +} + +func v1ExtraToV1beta1Extra(in map[string]authorizationv1.ExtraValue) map[string]authorizationv1beta1.ExtraValue { + if in == nil { + return nil + } + ret := make(map[string]authorizationv1beta1.ExtraValue, len(in)) + for k, v := range in { + ret[k] = authorizationv1beta1.ExtraValue(v) + } + return ret +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go b/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go new file mode 100644 index 000000000..40878b400 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go @@ -0,0 +1,158 @@ +/* +Copyright 2018 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 dynamicinformer + +import ( + "context" + "sync" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/dynamic/dynamiclister" + "k8s.io/client-go/informers" + "k8s.io/client-go/tools/cache" +) + +// NewDynamicSharedInformerFactory constructs a new instance of dynamicSharedInformerFactory for all namespaces. +func NewDynamicSharedInformerFactory(client dynamic.Interface, defaultResync time.Duration) DynamicSharedInformerFactory { + return NewFilteredDynamicSharedInformerFactory(client, defaultResync, metav1.NamespaceAll, nil) +} + +// NewFilteredDynamicSharedInformerFactory constructs a new instance of dynamicSharedInformerFactory. +// Listers obtained via this factory will be subject to the same filters as specified here. +func NewFilteredDynamicSharedInformerFactory(client dynamic.Interface, defaultResync time.Duration, namespace string, tweakListOptions TweakListOptionsFunc) DynamicSharedInformerFactory { + return &dynamicSharedInformerFactory{ + client: client, + defaultResync: defaultResync, + namespace: namespace, + informers: map[schema.GroupVersionResource]informers.GenericInformer{}, + startedInformers: make(map[schema.GroupVersionResource]bool), + tweakListOptions: tweakListOptions, + } +} + +type dynamicSharedInformerFactory struct { + client dynamic.Interface + defaultResync time.Duration + namespace string + + lock sync.Mutex + informers map[schema.GroupVersionResource]informers.GenericInformer + // startedInformers is used for tracking which informers have been started. + // This allows Start() to be called multiple times safely. + startedInformers map[schema.GroupVersionResource]bool + tweakListOptions TweakListOptionsFunc +} + +var _ DynamicSharedInformerFactory = &dynamicSharedInformerFactory{} + +func (f *dynamicSharedInformerFactory) ForResource(gvr schema.GroupVersionResource) informers.GenericInformer { + f.lock.Lock() + defer f.lock.Unlock() + + key := gvr + informer, exists := f.informers[key] + if exists { + return informer + } + + informer = NewFilteredDynamicInformer(f.client, gvr, f.namespace, f.defaultResync, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + f.informers[key] = informer + + return informer +} + +// Start initializes all requested informers. +func (f *dynamicSharedInformerFactory) Start(stopCh <-chan struct{}) { + f.lock.Lock() + defer f.lock.Unlock() + + for informerType, informer := range f.informers { + if !f.startedInformers[informerType] { + go informer.Informer().Run(stopCh) + f.startedInformers[informerType] = true + } + } +} + +// WaitForCacheSync waits for all started informers' cache were synced. +func (f *dynamicSharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool { + informers := func() map[schema.GroupVersionResource]cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informers := map[schema.GroupVersionResource]cache.SharedIndexInformer{} + for informerType, informer := range f.informers { + if f.startedInformers[informerType] { + informers[informerType] = informer.Informer() + } + } + return informers + }() + + res := map[schema.GroupVersionResource]bool{} + for informType, informer := range informers { + res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + } + return res +} + +// NewFilteredDynamicInformer constructs a new informer for a dynamic type. +func NewFilteredDynamicInformer(client dynamic.Interface, gvr schema.GroupVersionResource, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions TweakListOptionsFunc) informers.GenericInformer { + return &dynamicInformer{ + gvr: gvr, + informer: cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Resource(gvr).Namespace(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.Resource(gvr).Namespace(namespace).Watch(context.TODO(), options) + }, + }, + &unstructured.Unstructured{}, + resyncPeriod, + indexers, + ), + } +} + +type dynamicInformer struct { + informer cache.SharedIndexInformer + gvr schema.GroupVersionResource +} + +var _ informers.GenericInformer = &dynamicInformer{} + +func (d *dynamicInformer) Informer() cache.SharedIndexInformer { + return d.informer +} + +func (d *dynamicInformer) Lister() cache.GenericLister { + return dynamiclister.NewRuntimeObjectShim(dynamiclister.New(d.informer.GetIndexer(), d.gvr)) +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go b/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go new file mode 100644 index 000000000..083977c30 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go @@ -0,0 +1,34 @@ +/* +Copyright 2018 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 dynamicinformer + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/informers" +) + +// DynamicSharedInformerFactory provides access to a shared informer and lister for dynamic client +type DynamicSharedInformerFactory interface { + Start(stopCh <-chan struct{}) + ForResource(gvr schema.GroupVersionResource) informers.GenericInformer + WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool +} + +// TweakListOptionsFunc defines the signature of a helper function +// that wants to provide more listing options to API +type TweakListOptionsFunc func(*metav1.ListOptions) diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go new file mode 100644 index 000000000..c39cbee92 --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go @@ -0,0 +1,40 @@ +/* +Copyright 2018 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 dynamiclister + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" +) + +// Lister helps list resources. +type Lister interface { + // List lists all resources in the indexer. + List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) + // Get retrieves a resource from the indexer with the given name + Get(name string) (*unstructured.Unstructured, error) + // Namespace returns an object that can list and get resources in a given namespace. + Namespace(namespace string) NamespaceLister +} + +// NamespaceLister helps list and get resources. +type NamespaceLister interface { + // List lists all resources in the indexer for a given namespace. + List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) + // Get retrieves a resource from the indexer for a given namespace and name. + Get(name string) (*unstructured.Unstructured, error) +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go new file mode 100644 index 000000000..a50fc471e --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go @@ -0,0 +1,91 @@ +/* +Copyright 2018 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 dynamiclister + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" +) + +var _ Lister = &dynamicLister{} +var _ NamespaceLister = &dynamicNamespaceLister{} + +// dynamicLister implements the Lister interface. +type dynamicLister struct { + indexer cache.Indexer + gvr schema.GroupVersionResource +} + +// New returns a new Lister. +func New(indexer cache.Indexer, gvr schema.GroupVersionResource) Lister { + return &dynamicLister{indexer: indexer, gvr: gvr} +} + +// List lists all resources in the indexer. +func (l *dynamicLister) List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) { + err = cache.ListAll(l.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*unstructured.Unstructured)) + }) + return ret, err +} + +// Get retrieves a resource from the indexer with the given name +func (l *dynamicLister) Get(name string) (*unstructured.Unstructured, error) { + obj, exists, err := l.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(l.gvr.GroupResource(), name) + } + return obj.(*unstructured.Unstructured), nil +} + +// Namespace returns an object that can list and get resources from a given namespace. +func (l *dynamicLister) Namespace(namespace string) NamespaceLister { + return &dynamicNamespaceLister{indexer: l.indexer, namespace: namespace, gvr: l.gvr} +} + +// dynamicNamespaceLister implements the NamespaceLister interface. +type dynamicNamespaceLister struct { + indexer cache.Indexer + namespace string + gvr schema.GroupVersionResource +} + +// List lists all resources in the indexer for a given namespace. +func (l *dynamicNamespaceLister) List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) { + err = cache.ListAllByNamespace(l.indexer, l.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*unstructured.Unstructured)) + }) + return ret, err +} + +// Get retrieves a resource from the indexer for a given namespace and name. +func (l *dynamicNamespaceLister) Get(name string) (*unstructured.Unstructured, error) { + obj, exists, err := l.indexer.GetByKey(l.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(l.gvr.GroupResource(), name) + } + return obj.(*unstructured.Unstructured), nil +} diff --git a/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go b/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go new file mode 100644 index 000000000..92a5f54af --- /dev/null +++ b/vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go @@ -0,0 +1,87 @@ +/* +Copyright 2018 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 dynamiclister + +import ( + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +var _ cache.GenericLister = &dynamicListerShim{} +var _ cache.GenericNamespaceLister = &dynamicNamespaceListerShim{} + +// dynamicListerShim implements the cache.GenericLister interface. +type dynamicListerShim struct { + lister Lister +} + +// NewRuntimeObjectShim returns a new shim for Lister. +// It wraps Lister so that it implements cache.GenericLister interface +func NewRuntimeObjectShim(lister Lister) cache.GenericLister { + return &dynamicListerShim{lister: lister} +} + +// List will return all objects across namespaces +func (s *dynamicListerShim) List(selector labels.Selector) (ret []runtime.Object, err error) { + objs, err := s.lister.List(selector) + if err != nil { + return nil, err + } + + ret = make([]runtime.Object, len(objs)) + for index, obj := range objs { + ret[index] = obj + } + return ret, err +} + +// Get will attempt to retrieve assuming that name==key +func (s *dynamicListerShim) Get(name string) (runtime.Object, error) { + return s.lister.Get(name) +} + +func (s *dynamicListerShim) ByNamespace(namespace string) cache.GenericNamespaceLister { + return &dynamicNamespaceListerShim{ + namespaceLister: s.lister.Namespace(namespace), + } +} + +// dynamicNamespaceListerShim implements the NamespaceLister interface. +// It wraps NamespaceLister so that it implements cache.GenericNamespaceLister interface +type dynamicNamespaceListerShim struct { + namespaceLister NamespaceLister +} + +// List will return all objects in this namespace +func (ns *dynamicNamespaceListerShim) List(selector labels.Selector) (ret []runtime.Object, err error) { + objs, err := ns.namespaceLister.List(selector) + if err != nil { + return nil, err + } + + ret = make([]runtime.Object, len(objs)) + for index, obj := range objs { + ret[index] = obj + } + return ret, err +} + +// Get will attempt to retrieve by namespace and name +func (ns *dynamicNamespaceListerShim) Get(name string) (runtime.Object, error) { + return ns.namespaceLister.Get(name) +} diff --git a/vendor/k8s.io/cloud-provider/app/config/config.go b/vendor/k8s.io/cloud-provider/app/config/config.go new file mode 100644 index 000000000..9e6c03266 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/app/config/config.go @@ -0,0 +1,79 @@ +/* +Copyright 2018 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 config + +import ( + apiserver "k8s.io/apiserver/pkg/server" + "k8s.io/client-go/informers" + clientset "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" + cloudprovider "k8s.io/cloud-provider" + "k8s.io/cloud-provider/config" +) + +// Config is the main context object for the cloud controller manager. +type Config struct { + ComponentConfig config.CloudControllerManagerConfiguration + + SecureServing *apiserver.SecureServingInfo + // LoopbackClientConfig is a config for a privileged loopback connection + LoopbackClientConfig *restclient.Config + + Authentication apiserver.AuthenticationInfo + Authorization apiserver.AuthorizationInfo + + // the general kube client + Client *clientset.Clientset + + // the rest config for the master + Kubeconfig *restclient.Config + + // EventBroadcaster is broadcaster events to all sinks. + EventBroadcaster record.EventBroadcaster + + // EventRecord is a sink for events. + EventRecorder record.EventRecorder + + // ClientBuilder will provide a client for this controller to use + ClientBuilder cloudprovider.ControllerClientBuilder + + // VersionedClient will provide a client for informers + VersionedClient clientset.Interface + + // SharedInformers gives access to informers for the controller. + SharedInformers informers.SharedInformerFactory +} + +type completedConfig struct { + *Config +} + +// CompletedConfig same as Config, just to swap private object. +type CompletedConfig struct { + // Embed a private pointer that cannot be instantiated outside of this package. + *completedConfig +} + +// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver. +func (c *Config) Complete() *CompletedConfig { + cc := completedConfig{c} + + apiserver.AuthorizeClientBearerToken(c.LoopbackClientConfig, &c.Authentication, &c.Authorization) + + return &CompletedConfig{&cc} +} diff --git a/vendor/k8s.io/cloud-provider/config/doc.go b/vendor/k8s.io/cloud-provider/config/doc.go new file mode 100644 index 000000000..73322994f --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2018 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. +*/ + +// +k8s:deepcopy-gen=package +// +groupName=cloudcontrollermanager.config.k8s.io + +package config // import "k8s.io/cloud-provider/config" diff --git a/vendor/k8s.io/cloud-provider/config/install/install.go b/vendor/k8s.io/cloud-provider/config/install/install.go new file mode 100644 index 000000000..b07a9f051 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/install/install.go @@ -0,0 +1,44 @@ +/* +Copyright 2018 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 install + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/cloud-provider/config" + "k8s.io/cloud-provider/config/v1alpha1" +) + +var ( + // Scheme defines methods for serializing and deserializing API objects. + Scheme = runtime.NewScheme() + // Codecs provides methods for retrieving codecs and serializers for specific + // versions and content types. + Codecs = serializer.NewCodecFactory(Scheme) +) + +func init() { + Install(Scheme) +} + +// Install adds the types of this group into the given scheme. +func Install(scheme *runtime.Scheme) { + utilruntime.Must(config.AddToScheme(scheme)) + utilruntime.Must(v1alpha1.AddToScheme(scheme)) + utilruntime.Must(scheme.SetVersionPriority(v1alpha1.SchemeGroupVersion)) +} diff --git a/vendor/k8s.io/cloud-provider/config/register.go b/vendor/k8s.io/cloud-provider/config/register.go new file mode 100644 index 000000000..3f14ec59b --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/register.go @@ -0,0 +1,42 @@ +/* +Copyright 2018 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 config + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name used in this package +const GroupName = "cloudcontrollermanager.config.k8s.io" + +var ( + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// addKnownTypes registers known types to the given scheme +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CloudControllerManagerConfiguration{}, + ) + return nil +} diff --git a/vendor/k8s.io/cloud-provider/config/types.go b/vendor/k8s.io/cloud-provider/config/types.go new file mode 100644 index 000000000..bcb523e91 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/types.go @@ -0,0 +1,86 @@ +/* +Copyright 2018 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 config + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + serviceconfig "k8s.io/cloud-provider/controllers/service/config" + cmconfig "k8s.io/controller-manager/config" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CloudControllerManagerConfiguration contains elements describing cloud-controller manager. +type CloudControllerManagerConfiguration struct { + metav1.TypeMeta + + // Generic holds configuration for a generic controller-manager + Generic cmconfig.GenericControllerManagerConfiguration + // KubeCloudSharedConfiguration holds configuration for shared related features + // both in cloud controller manager and kube-controller manager. + KubeCloudShared KubeCloudSharedConfiguration + + // ServiceControllerConfiguration holds configuration for ServiceController + // related features. + ServiceController serviceconfig.ServiceControllerConfiguration + + // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status + NodeStatusUpdateFrequency metav1.Duration +} + +// KubeCloudSharedConfiguration contains elements shared by both kube-controller manager +// and cloud-controller manager, but not genericconfig. +type KubeCloudSharedConfiguration struct { + // CloudProviderConfiguration holds configuration for CloudProvider related features. + CloudProvider CloudProviderConfiguration + // externalCloudVolumePlugin specifies the plugin to use when cloudProvider is "external". + // It is currently used by the in repo cloud providers to handle node and volume control in the KCM. + ExternalCloudVolumePlugin string + // useServiceAccountCredentials indicates whether controllers should be run with + // individual service account credentials. + UseServiceAccountCredentials bool + // run with untagged cloud instances + AllowUntaggedCloud bool + // routeReconciliationPeriod is the period for reconciling routes created for Nodes by cloud provider.. + RouteReconciliationPeriod metav1.Duration + // nodeMonitorPeriod is the period for syncing NodeStatus in NodeController. + NodeMonitorPeriod metav1.Duration + // clusterName is the instance prefix for the cluster. + ClusterName string + // clusterCIDR is CIDR Range for Pods in cluster. + ClusterCIDR string + // AllocateNodeCIDRs enables CIDRs for Pods to be allocated and, if + // ConfigureCloudRoutes is true, to be set on the cloud provider. + AllocateNodeCIDRs bool + // CIDRAllocatorType determines what kind of pod CIDR allocator will be used. + CIDRAllocatorType string + // configureCloudRoutes enables CIDRs allocated with allocateNodeCIDRs + // to be configured on the cloud provider. + ConfigureCloudRoutes bool + // nodeSyncPeriod is the period for syncing nodes from cloudprovider. Longer + // periods will result in fewer calls to cloud provider, but may delay addition + // of new nodes to cluster. + NodeSyncPeriod metav1.Duration +} + +// CloudProviderConfiguration contains basically elements about cloud provider. +type CloudProviderConfiguration struct { + // Name is the provider for cloud services. + Name string + // cloudConfigFile is the path to the cloud provider configuration file. + CloudConfigFile string +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/conversion.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/conversion.go new file mode 100644 index 000000000..41240f7af --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/conversion.go @@ -0,0 +1,49 @@ +/* +Copyright 2020 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + cpconfig "k8s.io/cloud-provider/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +// Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(in *KubeCloudSharedConfiguration, out *cpconfig.KubeCloudSharedConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(in, out, s) +} + +// Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration is an autogenerated conversion function. +func Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(in *cpconfig.KubeCloudSharedConfiguration, out *KubeCloudSharedConfiguration, s conversion.Scope) error { + return autoConvert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(in, out, s) +} + +// Convert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(in *CloudProviderConfiguration, out *cpconfig.CloudProviderConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(in, out, s) +} + +// Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration is an autogenerated conversion function. +func Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(in *cpconfig.CloudProviderConfiguration, out *CloudProviderConfiguration, s conversion.Scope) error { + return autoConvert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go new file mode 100644 index 000000000..a47cf5338 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go @@ -0,0 +1,68 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" + cmconfigv1alpha1 "k8s.io/controller-manager/config/v1alpha1" + utilpointer "k8s.io/utils/pointer" +) + +func addDefaultingFuncs(scheme *runtime.Scheme) error { + return RegisterDefaults(scheme) +} + +func SetDefaults_CloudControllerManagerConfiguration(obj *CloudControllerManagerConfiguration) { + zero := metav1.Duration{} + if obj.NodeStatusUpdateFrequency == zero { + obj.NodeStatusUpdateFrequency = metav1.Duration{Duration: 5 * time.Minute} + } + + // These defaults override the recommended defaults from the apimachineryconfigv1alpha1 package that are applied automatically + // These client-connection defaults are specific to the cloud-controller-manager + if obj.Generic.ClientConnection.QPS == 0 { + obj.Generic.ClientConnection.QPS = 20 + } + if obj.Generic.ClientConnection.Burst == 0 { + obj.Generic.ClientConnection.Burst = 30 + } + + // Use the default RecommendedDefaultGenericControllerManagerConfiguration options + cmconfigv1alpha1.RecommendedDefaultGenericControllerManagerConfiguration(&obj.Generic) + // Use the default RecommendedDefaultServiceControllerConfiguration options + serviceconfigv1alpha1.RecommendedDefaultServiceControllerConfiguration(&obj.ServiceController) +} + +func SetDefaults_KubeCloudSharedConfiguration(obj *KubeCloudSharedConfiguration) { + zero := metav1.Duration{} + if obj.NodeMonitorPeriod == zero { + obj.NodeMonitorPeriod = metav1.Duration{Duration: 5 * time.Second} + } + if obj.ClusterName == "" { + obj.ClusterName = "kubernetes" + } + if obj.ConfigureCloudRoutes == nil { + obj.ConfigureCloudRoutes = utilpointer.BoolPtr(true) + } + if obj.RouteReconciliationPeriod == zero { + obj.RouteReconciliationPeriod = metav1.Duration{Duration: 10 * time.Second} + } +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/doc.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/doc.go new file mode 100644 index 000000000..91df9c15b --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/doc.go @@ -0,0 +1,32 @@ +/* +Copyright 2018 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. +*/ + +// Note: The referenced generic ComponentConfig packages with conversions +// between the types (e.g. the external package) needs to be given as an +// input to conversion-gen for it to find the native conversation funcs to +// call. + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/component-base/config/v1alpha1 +// +k8s:conversion-gen=k8s.io/cloud-provider/config +// +k8s:conversion-gen=k8s.io/cloud-provider/config/v1alpha1 +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/service/config/v1alpha1 +// +k8s:conversion-gen=k8s.io/controller-manager/config/v1alpha1 +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta +// +groupName=cloudcontrollermanager.config.k8s.io + +package v1alpha1 // import "k8s.io/cloud-provider/config/v1alpha1" diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/register.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/register.go new file mode 100644 index 000000000..94320d37c --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/register.go @@ -0,0 +1,52 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "cloudcontrollermanager.config.k8s.io" + +var ( + // GroupName is the group name use in this package + SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder ïs a pointer to SchemeBuilder instance. Using localSchemeBuilder + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addDefaultingFuncs) +} + +// addKnownTypes registers known types to the given scheme +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CloudControllerManagerConfiguration{}, + ) + return nil +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go new file mode 100644 index 000000000..0aed1aa24 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go @@ -0,0 +1,83 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" + cmconfigv1alpha1 "k8s.io/controller-manager/config/v1alpha1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type CloudControllerManagerConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // Generic holds configuration for a generic controller-manager + Generic cmconfigv1alpha1.GenericControllerManagerConfiguration + // KubeCloudSharedConfiguration holds configuration for shared related features + // both in cloud controller manager and kube-controller manager. + KubeCloudShared KubeCloudSharedConfiguration + // ServiceControllerConfiguration holds configuration for ServiceController + // related features. + ServiceController serviceconfigv1alpha1.ServiceControllerConfiguration + // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status + NodeStatusUpdateFrequency metav1.Duration +} + +// KubeCloudSharedConfiguration contains elements shared by both kube-controller manager +// and cloud-controller manager, but not genericconfig. +type KubeCloudSharedConfiguration struct { + // CloudProviderConfiguration holds configuration for CloudProvider related features. + CloudProvider CloudProviderConfiguration + // externalCloudVolumePlugin specifies the plugin to use when cloudProvider is "external". + // It is currently used by the in repo cloud providers to handle node and volume control in the KCM. + ExternalCloudVolumePlugin string + // useServiceAccountCredentials indicates whether controllers should be run with + // individual service account credentials. + UseServiceAccountCredentials bool + // run with untagged cloud instances + AllowUntaggedCloud bool + // routeReconciliationPeriod is the period for reconciling routes created for Nodes by cloud provider.. + RouteReconciliationPeriod metav1.Duration + // nodeMonitorPeriod is the period for syncing NodeStatus in NodeController. + NodeMonitorPeriod metav1.Duration + // clusterName is the instance prefix for the cluster. + ClusterName string + // clusterCIDR is CIDR Range for Pods in cluster. + ClusterCIDR string + // AllocateNodeCIDRs enables CIDRs for Pods to be allocated and, if + // ConfigureCloudRoutes is true, to be set on the cloud provider. + AllocateNodeCIDRs bool + // CIDRAllocatorType determines what kind of pod CIDR allocator will be used. + CIDRAllocatorType string + // configureCloudRoutes enables CIDRs allocated with allocateNodeCIDRs + // to be configured on the cloud provider. + ConfigureCloudRoutes *bool + // nodeSyncPeriod is the period for syncing nodes from cloudprovider. Longer + // periods will result in fewer calls to cloud provider, but may delay addition + // of new nodes to cluster. + NodeSyncPeriod metav1.Duration +} + +// CloudProviderConfiguration contains basically elements about cloud provider. +type CloudProviderConfiguration struct { + // Name is the provider for cloud services. + Name string + // cloudConfigFile is the path to the cloud provider configuration file. + CloudConfigFile string +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 000000000..76acd4d41 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,161 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/cloud-provider/config" + serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" + configv1alpha1 "k8s.io/controller-manager/config/v1alpha1" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*CloudControllerManagerConfiguration)(nil), (*config.CloudControllerManagerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration(a.(*CloudControllerManagerConfiguration), b.(*config.CloudControllerManagerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.CloudControllerManagerConfiguration)(nil), (*CloudControllerManagerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration(a.(*config.CloudControllerManagerConfiguration), b.(*CloudControllerManagerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.CloudProviderConfiguration)(nil), (*CloudProviderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(a.(*config.CloudProviderConfiguration), b.(*CloudProviderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.KubeCloudSharedConfiguration)(nil), (*KubeCloudSharedConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(a.(*config.KubeCloudSharedConfiguration), b.(*KubeCloudSharedConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*CloudProviderConfiguration)(nil), (*config.CloudProviderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(a.(*CloudProviderConfiguration), b.(*config.CloudProviderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*KubeCloudSharedConfiguration)(nil), (*config.KubeCloudSharedConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(a.(*KubeCloudSharedConfiguration), b.(*config.KubeCloudSharedConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration(in *CloudControllerManagerConfiguration, out *config.CloudControllerManagerConfiguration, s conversion.Scope) error { + if err := configv1alpha1.Convert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(&in.Generic, &out.Generic, s); err != nil { + return err + } + if err := Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(&in.KubeCloudShared, &out.KubeCloudShared, s); err != nil { + return err + } + if err := serviceconfigv1alpha1.Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(&in.ServiceController, &out.ServiceController, s); err != nil { + return err + } + out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + return nil +} + +// Convert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration(in *CloudControllerManagerConfiguration, out *config.CloudControllerManagerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudControllerManagerConfiguration(in, out, s) +} + +func autoConvert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration(in *config.CloudControllerManagerConfiguration, out *CloudControllerManagerConfiguration, s conversion.Scope) error { + if err := configv1alpha1.Convert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(&in.Generic, &out.Generic, s); err != nil { + return err + } + if err := Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(&in.KubeCloudShared, &out.KubeCloudShared, s); err != nil { + return err + } + if err := serviceconfigv1alpha1.Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(&in.ServiceController, &out.ServiceController, s); err != nil { + return err + } + out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + return nil +} + +// Convert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration is an autogenerated conversion function. +func Convert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration(in *config.CloudControllerManagerConfiguration, out *CloudControllerManagerConfiguration, s conversion.Scope) error { + return autoConvert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudControllerManagerConfiguration(in, out, s) +} + +func autoConvert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(in *CloudProviderConfiguration, out *config.CloudProviderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.CloudConfigFile = in.CloudConfigFile + return nil +} + +func autoConvert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(in *config.CloudProviderConfiguration, out *CloudProviderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.CloudConfigFile = in.CloudConfigFile + return nil +} + +func autoConvert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(in *KubeCloudSharedConfiguration, out *config.KubeCloudSharedConfiguration, s conversion.Scope) error { + if err := Convert_v1alpha1_CloudProviderConfiguration_To_config_CloudProviderConfiguration(&in.CloudProvider, &out.CloudProvider, s); err != nil { + return err + } + out.ExternalCloudVolumePlugin = in.ExternalCloudVolumePlugin + out.UseServiceAccountCredentials = in.UseServiceAccountCredentials + out.AllowUntaggedCloud = in.AllowUntaggedCloud + out.RouteReconciliationPeriod = in.RouteReconciliationPeriod + out.NodeMonitorPeriod = in.NodeMonitorPeriod + out.ClusterName = in.ClusterName + out.ClusterCIDR = in.ClusterCIDR + out.AllocateNodeCIDRs = in.AllocateNodeCIDRs + out.CIDRAllocatorType = in.CIDRAllocatorType + if err := v1.Convert_Pointer_bool_To_bool(&in.ConfigureCloudRoutes, &out.ConfigureCloudRoutes, s); err != nil { + return err + } + out.NodeSyncPeriod = in.NodeSyncPeriod + return nil +} + +func autoConvert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(in *config.KubeCloudSharedConfiguration, out *KubeCloudSharedConfiguration, s conversion.Scope) error { + if err := Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(&in.CloudProvider, &out.CloudProvider, s); err != nil { + return err + } + out.ExternalCloudVolumePlugin = in.ExternalCloudVolumePlugin + out.UseServiceAccountCredentials = in.UseServiceAccountCredentials + out.AllowUntaggedCloud = in.AllowUntaggedCloud + out.RouteReconciliationPeriod = in.RouteReconciliationPeriod + out.NodeMonitorPeriod = in.NodeMonitorPeriod + out.ClusterName = in.ClusterName + out.ClusterCIDR = in.ClusterCIDR + out.AllocateNodeCIDRs = in.AllocateNodeCIDRs + out.CIDRAllocatorType = in.CIDRAllocatorType + if err := v1.Convert_bool_To_Pointer_bool(&in.ConfigureCloudRoutes, &out.ConfigureCloudRoutes, s); err != nil { + return err + } + out.NodeSyncPeriod = in.NodeSyncPeriod + return nil +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..06eca856e --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,96 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudControllerManagerConfiguration) DeepCopyInto(out *CloudControllerManagerConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.Generic.DeepCopyInto(&out.Generic) + in.KubeCloudShared.DeepCopyInto(&out.KubeCloudShared) + out.ServiceController = in.ServiceController + out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudControllerManagerConfiguration. +func (in *CloudControllerManagerConfiguration) DeepCopy() *CloudControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(CloudControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CloudControllerManagerConfiguration) 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 *CloudProviderConfiguration) DeepCopyInto(out *CloudProviderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudProviderConfiguration. +func (in *CloudProviderConfiguration) DeepCopy() *CloudProviderConfiguration { + if in == nil { + return nil + } + out := new(CloudProviderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeCloudSharedConfiguration) DeepCopyInto(out *KubeCloudSharedConfiguration) { + *out = *in + out.CloudProvider = in.CloudProvider + out.RouteReconciliationPeriod = in.RouteReconciliationPeriod + out.NodeMonitorPeriod = in.NodeMonitorPeriod + if in.ConfigureCloudRoutes != nil { + in, out := &in.ConfigureCloudRoutes, &out.ConfigureCloudRoutes + *out = new(bool) + **out = **in + } + out.NodeSyncPeriod = in.NodeSyncPeriod + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeCloudSharedConfiguration. +func (in *KubeCloudSharedConfiguration) DeepCopy() *KubeCloudSharedConfiguration { + if in == nil { + return nil + } + out := new(KubeCloudSharedConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.defaults.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.defaults.go new file mode 100644 index 000000000..96b18ded9 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.defaults.go @@ -0,0 +1,41 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by defaulter-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// RegisterDefaults adds defaulters functions to the given scheme. +// Public to allow building arbitrary schemes. +// All generated defaulters are covering - they call all nested defaulters. +func RegisterDefaults(scheme *runtime.Scheme) error { + scheme.AddTypeDefaultingFunc(&CloudControllerManagerConfiguration{}, func(obj interface{}) { + SetObjectDefaults_CloudControllerManagerConfiguration(obj.(*CloudControllerManagerConfiguration)) + }) + return nil +} + +func SetObjectDefaults_CloudControllerManagerConfiguration(in *CloudControllerManagerConfiguration) { + SetDefaults_CloudControllerManagerConfiguration(in) + SetDefaults_KubeCloudSharedConfiguration(&in.KubeCloudShared) +} diff --git a/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go new file mode 100644 index 000000000..dc3cc5307 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go @@ -0,0 +1,91 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package config + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudControllerManagerConfiguration) DeepCopyInto(out *CloudControllerManagerConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.Generic.DeepCopyInto(&out.Generic) + out.KubeCloudShared = in.KubeCloudShared + out.ServiceController = in.ServiceController + out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudControllerManagerConfiguration. +func (in *CloudControllerManagerConfiguration) DeepCopy() *CloudControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(CloudControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CloudControllerManagerConfiguration) 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 *CloudProviderConfiguration) DeepCopyInto(out *CloudProviderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudProviderConfiguration. +func (in *CloudProviderConfiguration) DeepCopy() *CloudProviderConfiguration { + if in == nil { + return nil + } + out := new(CloudProviderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeCloudSharedConfiguration) DeepCopyInto(out *KubeCloudSharedConfiguration) { + *out = *in + out.CloudProvider = in.CloudProvider + out.RouteReconciliationPeriod = in.RouteReconciliationPeriod + out.NodeMonitorPeriod = in.NodeMonitorPeriod + out.NodeSyncPeriod = in.NodeSyncPeriod + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeCloudSharedConfiguration. +func (in *KubeCloudSharedConfiguration) DeepCopy() *KubeCloudSharedConfiguration { + if in == nil { + return nil + } + out := new(KubeCloudSharedConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/OWNERS b/vendor/k8s.io/cloud-provider/controllers/service/config/OWNERS new file mode 100644 index 000000000..200d01f74 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/OWNERS @@ -0,0 +1,14 @@ +approvers: + - api-approvers + - deads2k + - luxas + - mtaufen + - sttts +reviewers: + - api-reviewers + - deads2k + - luxas + - mtaufen + - sttts +emeritus_approvers: + - stewart-yu diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/doc.go b/vendor/k8s.io/cloud-provider/controllers/service/config/doc.go new file mode 100644 index 000000000..4c3d3aae1 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2020 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. +*/ + +// +k8s:deepcopy-gen=package + +package config // import "k8s.io/cloud-provider/controllers/service/config" diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/types.go b/vendor/k8s.io/cloud-provider/controllers/service/config/types.go new file mode 100644 index 000000000..3afca1630 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/types.go @@ -0,0 +1,25 @@ +/* +Copyright 2019 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 config + +// ServiceControllerConfiguration contains elements describing ServiceController. +type ServiceControllerConfiguration struct { + // concurrentServiceSyncs is the number of services that are + // allowed to sync concurrently. Larger number = more responsive service + // management, but more CPU (and network) load. + ConcurrentServiceSyncs int32 +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/conversion.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/conversion.go new file mode 100644 index 000000000..1c9ccc641 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/conversion.go @@ -0,0 +1,39 @@ +/* +Copyright 2019 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + serviceconfig "k8s.io/cloud-provider/controllers/service/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +// Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(in *ServiceControllerConfiguration, out *serviceconfig.ServiceControllerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(in, out, s) +} + +// Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration is an autogenerated conversion function. +func Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(in *serviceconfig.ServiceControllerConfiguration, out *ServiceControllerConfiguration, s conversion.Scope) error { + return autoConvert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/defaults.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/defaults.go new file mode 100644 index 000000000..e4a8edb9e --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/defaults.go @@ -0,0 +1,32 @@ +/* +Copyright 2019 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 v1alpha1 + +// RecommendedDefaultServiceControllerConfiguration defaults a pointer to a +// ServiceControllerConfiguration struct. This will set the recommended default +// values, but they may be subject to change between API versions. This function +// is intentionally not registered in the scheme as a "normal" `SetDefaults_Foo` +// function to allow consumers of this type to set whatever defaults for their +// embedded configs. Forcing consumers to use these defaults would be problematic +// as defaulting in the scheme is done as part of the conversion, and there would +// be no easy way to opt-out. Instead, if you want to use this defaulting method +// run it in your wrapper struct of this type in its `SetDefaults_` method. +func RecommendedDefaultServiceControllerConfiguration(obj *ServiceControllerConfiguration) { + if obj.ConcurrentServiceSyncs == 0 { + obj.ConcurrentServiceSyncs = 1 + } +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/doc.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/doc.go new file mode 100644 index 000000000..3d71af8af --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/service/config +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/service/config/v1alpha1 + +package v1alpha1 // import "k8s.io/cloud-provider/controllers/service/config/v1alpha1" diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/register.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/register.go new file mode 100644 index 000000000..47e070782 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/register.go @@ -0,0 +1,31 @@ +/* +Copyright 2020 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder runtime.SchemeBuilder + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/types.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/types.go new file mode 100644 index 000000000..10ab1d2d9 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/types.go @@ -0,0 +1,25 @@ +/* +Copyright 2020 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 v1alpha1 + +// ServiceControllerConfiguration contains elements describing ServiceController. +type ServiceControllerConfiguration struct { + // concurrentServiceSyncs is the number of services that are + // allowed to sync concurrently. Larger number = more responsive service + // management, but more CPU (and network) load. + ConcurrentServiceSyncs int32 +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 000000000..5c4e7db7a --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,58 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/cloud-provider/controllers/service/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddConversionFunc((*config.ServiceControllerConfiguration)(nil), (*ServiceControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(a.(*config.ServiceControllerConfiguration), b.(*ServiceControllerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*ServiceControllerConfiguration)(nil), (*config.ServiceControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(a.(*ServiceControllerConfiguration), b.(*config.ServiceControllerConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(in *ServiceControllerConfiguration, out *config.ServiceControllerConfiguration, s conversion.Scope) error { + out.ConcurrentServiceSyncs = in.ConcurrentServiceSyncs + return nil +} + +func autoConvert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(in *config.ServiceControllerConfiguration, out *ServiceControllerConfiguration, s conversion.Scope) error { + out.ConcurrentServiceSyncs = in.ConcurrentServiceSyncs + return nil +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..49a9f7d2a --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,38 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceControllerConfiguration) DeepCopyInto(out *ServiceControllerConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceControllerConfiguration. +func (in *ServiceControllerConfiguration) DeepCopy() *ServiceControllerConfiguration { + if in == nil { + return nil + } + out := new(ServiceControllerConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/controllers/service/config/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/controllers/service/config/zz_generated.deepcopy.go new file mode 100644 index 000000000..53eb24296 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/service/config/zz_generated.deepcopy.go @@ -0,0 +1,38 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package config + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceControllerConfiguration) DeepCopyInto(out *ServiceControllerConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceControllerConfiguration. +func (in *ServiceControllerConfiguration) DeepCopy() *ServiceControllerConfiguration { + if in == nil { + return nil + } + out := new(ServiceControllerConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/options/cloudprovider.go b/vendor/k8s.io/cloud-provider/options/cloudprovider.go new file mode 100644 index 000000000..6b5034aba --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/cloudprovider.go @@ -0,0 +1,54 @@ +/* +Copyright 2018 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 options + +import ( + "github.com/spf13/pflag" + cpconfig "k8s.io/cloud-provider/config" +) + +// CloudProviderOptions holds the cloudprovider options. +type CloudProviderOptions struct { + *cpconfig.CloudProviderConfiguration +} + +// Validate checks validation of cloudprovider options. +func (s *CloudProviderOptions) Validate() []error { + allErrors := []error{} + return allErrors +} + +// AddFlags adds flags related to cloudprovider for controller manager to the specified FlagSet. +func (s *CloudProviderOptions) AddFlags(fs *pflag.FlagSet) { + fs.StringVar(&s.Name, "cloud-provider", s.Name, + "The provider for cloud services. Empty string for no provider.") + + fs.StringVar(&s.CloudConfigFile, "cloud-config", s.CloudConfigFile, + "The path to the cloud provider configuration file. Empty string for no configuration file.") +} + +// ApplyTo fills up cloudprovider config with options. +func (s *CloudProviderOptions) ApplyTo(cfg *cpconfig.CloudProviderConfiguration) error { + if s == nil { + return nil + } + + cfg.Name = s.Name + cfg.CloudConfigFile = s.CloudConfigFile + + return nil +} diff --git a/vendor/k8s.io/cloud-provider/options/kubecloudshared.go b/vendor/k8s.io/cloud-provider/options/kubecloudshared.go new file mode 100644 index 000000000..20bb03c09 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/kubecloudshared.go @@ -0,0 +1,106 @@ +/* +Copyright 2018 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 options + +import ( + "github.com/spf13/pflag" + cpconfig "k8s.io/cloud-provider/config" +) + +// KubeCloudSharedOptions holds the options shared between kube-controller-manager +// and cloud-controller-manager. +type KubeCloudSharedOptions struct { + *cpconfig.KubeCloudSharedConfiguration + CloudProvider *CloudProviderOptions +} + +// NewKubeCloudSharedOptions returns common/default configuration values for both +// the kube-controller-manager and the cloud-contoller-manager. Any common changes should +// be made here. Any individual changes should be made in that controller. +func NewKubeCloudSharedOptions(cfg *cpconfig.KubeCloudSharedConfiguration) *KubeCloudSharedOptions { + o := &KubeCloudSharedOptions{ + KubeCloudSharedConfiguration: cfg, + CloudProvider: &CloudProviderOptions{ + CloudProviderConfiguration: &cpconfig.CloudProviderConfiguration{}, + }, + } + + return o +} + +// AddFlags adds flags related to shared variable for controller manager to the specified FlagSet. +func (o *KubeCloudSharedOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + o.CloudProvider.AddFlags(fs) + fs.StringVar(&o.ExternalCloudVolumePlugin, "external-cloud-volume-plugin", o.ExternalCloudVolumePlugin, "The plugin to use when cloud provider is set to external. Can be empty, should only be set when cloud-provider is external. Currently used to allow node and volume controllers to work for in tree cloud providers.") + fs.BoolVar(&o.UseServiceAccountCredentials, "use-service-account-credentials", o.UseServiceAccountCredentials, "If true, use individual service account credentials for each controller.") + fs.BoolVar(&o.AllowUntaggedCloud, "allow-untagged-cloud", false, "Allow the cluster to run without the cluster-id on cloud instances. This is a legacy mode of operation and a cluster-id will be required in the future.") + fs.MarkDeprecated("allow-untagged-cloud", "This flag is deprecated and will be removed in a future release. A cluster-id will be required on cloud instances.") + fs.DurationVar(&o.RouteReconciliationPeriod.Duration, "route-reconciliation-period", o.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.") + fs.DurationVar(&o.NodeMonitorPeriod.Duration, "node-monitor-period", o.NodeMonitorPeriod.Duration, + "The period for syncing NodeStatus in NodeController.") + fs.StringVar(&o.ClusterName, "cluster-name", o.ClusterName, "The instance prefix for the cluster.") + fs.StringVar(&o.ClusterCIDR, "cluster-cidr", o.ClusterCIDR, "CIDR Range for Pods in cluster. Requires --allocate-node-cidrs to be true") + fs.BoolVar(&o.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.") + fs.StringVar(&o.CIDRAllocatorType, "cidr-allocator-type", "RangeAllocator", "Type of CIDR allocator to use") + fs.BoolVar(&o.ConfigureCloudRoutes, "configure-cloud-routes", true, "Should CIDRs allocated by allocate-node-cidrs be configured on the cloud provider.") + + fs.DurationVar(&o.NodeSyncPeriod.Duration, "node-sync-period", 0, ""+ + "This flag is deprecated and will be removed in future releases. See node-monitor-period for Node health checking or "+ + "route-reconciliation-period for cloud provider's route configuration settings.") + fs.MarkDeprecated("node-sync-period", "This flag is currently no-op and will be deleted.") +} + +// ApplyTo fills up KubeCloudShared config with options. +func (o *KubeCloudSharedOptions) ApplyTo(cfg *cpconfig.KubeCloudSharedConfiguration) error { + if o == nil { + return nil + } + + if err := o.CloudProvider.ApplyTo(&cfg.CloudProvider); err != nil { + return err + } + + cfg.ExternalCloudVolumePlugin = o.ExternalCloudVolumePlugin + cfg.UseServiceAccountCredentials = o.UseServiceAccountCredentials + cfg.AllowUntaggedCloud = o.AllowUntaggedCloud + cfg.RouteReconciliationPeriod = o.RouteReconciliationPeriod + cfg.NodeMonitorPeriod = o.NodeMonitorPeriod + cfg.ClusterName = o.ClusterName + cfg.ClusterCIDR = o.ClusterCIDR + cfg.AllocateNodeCIDRs = o.AllocateNodeCIDRs + cfg.CIDRAllocatorType = o.CIDRAllocatorType + cfg.ConfigureCloudRoutes = o.ConfigureCloudRoutes + cfg.NodeSyncPeriod = o.NodeSyncPeriod + + return nil +} + +// Validate checks validation of KubeCloudSharedOptions. +func (o *KubeCloudSharedOptions) Validate() []error { + if o == nil { + return nil + } + + errs := []error{} + errs = append(errs, o.CloudProvider.Validate()...) + + return errs +} diff --git a/vendor/k8s.io/cloud-provider/options/options.go b/vendor/k8s.io/cloud-provider/options/options.go new file mode 100644 index 000000000..908c79fc7 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/options.go @@ -0,0 +1,247 @@ +/* +Copyright 2016 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 options + +import ( + "fmt" + "math/rand" + "net" + "time" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + apiserveroptions "k8s.io/apiserver/pkg/server/options" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/client-go/informers" + clientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/record" + cloudprovider "k8s.io/cloud-provider" + "k8s.io/cloud-provider/app/config" + ccmconfig "k8s.io/cloud-provider/config" + ccmconfigscheme "k8s.io/cloud-provider/config/install" + ccmconfigv1alpha1 "k8s.io/cloud-provider/config/v1alpha1" + cliflag "k8s.io/component-base/cli/flag" + cmoptions "k8s.io/controller-manager/options" + "k8s.io/controller-manager/pkg/clientbuilder" + netutils "k8s.io/utils/net" + + // add the related feature gates + _ "k8s.io/controller-manager/pkg/features/register" +) + +const ( + // CloudControllerManagerUserAgent is the userAgent name when starting cloud-controller managers. + CloudControllerManagerUserAgent = "cloud-controller-manager" +) + +// CloudControllerManagerOptions is the main context object for the controller manager. +type CloudControllerManagerOptions struct { + Generic *cmoptions.GenericControllerManagerConfigurationOptions + KubeCloudShared *KubeCloudSharedOptions + ServiceController *ServiceControllerOptions + + SecureServing *apiserveroptions.SecureServingOptionsWithLoopback + Authentication *apiserveroptions.DelegatingAuthenticationOptions + Authorization *apiserveroptions.DelegatingAuthorizationOptions + + Master string + Kubeconfig string + + // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status + NodeStatusUpdateFrequency metav1.Duration +} + +// NewCloudControllerManagerOptions creates a new ExternalCMServer with a default config. +func NewCloudControllerManagerOptions() (*CloudControllerManagerOptions, error) { + componentConfig, err := NewDefaultComponentConfig() + if err != nil { + return nil, err + } + + s := CloudControllerManagerOptions{ + Generic: cmoptions.NewGenericControllerManagerConfigurationOptions(&componentConfig.Generic), + KubeCloudShared: NewKubeCloudSharedOptions(&componentConfig.KubeCloudShared), + ServiceController: &ServiceControllerOptions{ + ServiceControllerConfiguration: &componentConfig.ServiceController, + }, + SecureServing: apiserveroptions.NewSecureServingOptions().WithLoopback(), + Authentication: apiserveroptions.NewDelegatingAuthenticationOptions(), + Authorization: apiserveroptions.NewDelegatingAuthorizationOptions(), + NodeStatusUpdateFrequency: componentConfig.NodeStatusUpdateFrequency, + } + + s.Authentication.RemoteKubeConfigFileOptional = true + s.Authorization.RemoteKubeConfigFileOptional = true + + // Set the PairName but leave certificate directory blank to generate in-memory by default + s.SecureServing.ServerCert.CertDirectory = "" + s.SecureServing.ServerCert.PairName = "cloud-controller-manager" + s.SecureServing.BindPort = cloudprovider.CloudControllerManagerPort + + s.Generic.LeaderElection.ResourceName = "cloud-controller-manager" + s.Generic.LeaderElection.ResourceNamespace = "kube-system" + + return &s, nil +} + +// NewDefaultComponentConfig returns cloud-controller manager configuration object. +func NewDefaultComponentConfig() (*ccmconfig.CloudControllerManagerConfiguration, error) { + versioned := &ccmconfigv1alpha1.CloudControllerManagerConfiguration{} + ccmconfigscheme.Scheme.Default(versioned) + + internal := &ccmconfig.CloudControllerManagerConfiguration{} + if err := ccmconfigscheme.Scheme.Convert(versioned, internal, nil); err != nil { + return nil, err + } + return internal, nil +} + +// Flags returns flags for a specific CloudController by section name +func (o *CloudControllerManagerOptions) Flags(allControllers, disabledByDefaultControllers []string) cliflag.NamedFlagSets { + fss := cliflag.NamedFlagSets{} + o.Generic.AddFlags(&fss, allControllers, disabledByDefaultControllers) + o.KubeCloudShared.AddFlags(fss.FlagSet("generic")) + o.ServiceController.AddFlags(fss.FlagSet("service controller")) + + o.SecureServing.AddFlags(fss.FlagSet("secure serving")) + o.Authentication.AddFlags(fss.FlagSet("authentication")) + o.Authorization.AddFlags(fss.FlagSet("authorization")) + + fs := fss.FlagSet("misc") + fs.StringVar(&o.Master, "master", o.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig).") + fs.StringVar(&o.Kubeconfig, "kubeconfig", o.Kubeconfig, "Path to kubeconfig file with authorization and master location information.") + fs.DurationVar(&o.NodeStatusUpdateFrequency.Duration, "node-status-update-frequency", o.NodeStatusUpdateFrequency.Duration, "Specifies how often the controller updates nodes' status.") + + utilfeature.DefaultMutableFeatureGate.AddFlag(fss.FlagSet("generic")) + + return fss +} + +// ApplyTo fills up cloud controller manager config with options. +func (o *CloudControllerManagerOptions) ApplyTo(c *config.Config, userAgent string) error { + var err error + + // Build kubeconfig first to so that if it fails, it doesn't cause leaking + // goroutines (started from initializing secure serving - which underneath + // creates a queue which in its constructor starts a goroutine). + c.Kubeconfig, err = clientcmd.BuildConfigFromFlags(o.Master, o.Kubeconfig) + if err != nil { + return err + } + c.Kubeconfig.DisableCompression = true + c.Kubeconfig.ContentConfig.AcceptContentTypes = o.Generic.ClientConnection.AcceptContentTypes + c.Kubeconfig.ContentConfig.ContentType = o.Generic.ClientConnection.ContentType + c.Kubeconfig.QPS = o.Generic.ClientConnection.QPS + c.Kubeconfig.Burst = int(o.Generic.ClientConnection.Burst) + + if err = o.Generic.ApplyTo(&c.ComponentConfig.Generic); err != nil { + return err + } + if err = o.KubeCloudShared.ApplyTo(&c.ComponentConfig.KubeCloudShared); err != nil { + return err + } + if err = o.ServiceController.ApplyTo(&c.ComponentConfig.ServiceController); err != nil { + return err + } + if err = o.SecureServing.ApplyTo(&c.SecureServing, &c.LoopbackClientConfig); err != nil { + return err + } + if o.SecureServing.BindPort != 0 || o.SecureServing.Listener != nil { + if err = o.Authentication.ApplyTo(&c.Authentication, c.SecureServing, nil); err != nil { + return err + } + if err = o.Authorization.ApplyTo(&c.Authorization); err != nil { + return err + } + } + + c.Client, err = clientset.NewForConfig(restclient.AddUserAgent(c.Kubeconfig, userAgent)) + if err != nil { + return err + } + + c.EventBroadcaster = record.NewBroadcaster() + c.EventRecorder = c.EventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: userAgent}) + + rootClientBuilder := clientbuilder.SimpleControllerClientBuilder{ + ClientConfig: c.Kubeconfig, + } + if c.ComponentConfig.KubeCloudShared.UseServiceAccountCredentials { + c.ClientBuilder = clientbuilder.NewDynamicClientBuilder( + restclient.AnonymousClientConfig(c.Kubeconfig), + c.Client.CoreV1(), + metav1.NamespaceSystem) + } else { + c.ClientBuilder = rootClientBuilder + } + c.VersionedClient = rootClientBuilder.ClientOrDie("shared-informers") + c.SharedInformers = informers.NewSharedInformerFactory(c.VersionedClient, resyncPeriod(c)()) + + // sync back to component config + // TODO: find more elegant way than syncing back the values. + c.ComponentConfig.NodeStatusUpdateFrequency = o.NodeStatusUpdateFrequency + + return nil +} + +// Validate is used to validate config before launching the cloud controller manager +func (o *CloudControllerManagerOptions) Validate(allControllers, disabledByDefaultControllers []string) error { + errors := []error{} + + errors = append(errors, o.Generic.Validate(allControllers, disabledByDefaultControllers)...) + errors = append(errors, o.KubeCloudShared.Validate()...) + errors = append(errors, o.ServiceController.Validate()...) + errors = append(errors, o.SecureServing.Validate()...) + errors = append(errors, o.Authentication.Validate()...) + errors = append(errors, o.Authorization.Validate()...) + + if len(o.KubeCloudShared.CloudProvider.Name) == 0 { + errors = append(errors, fmt.Errorf("--cloud-provider cannot be empty")) + } + + return utilerrors.NewAggregate(errors) +} + +// resyncPeriod computes the time interval a shared informer waits before resyncing with the api server +func resyncPeriod(c *config.Config) func() time.Duration { + return func() time.Duration { + factor := rand.Float64() + 1 + return time.Duration(float64(c.ComponentConfig.Generic.MinResyncPeriod.Nanoseconds()) * factor) + } +} + +// Config return a cloud controller manager config objective +func (o *CloudControllerManagerOptions) Config(allControllers, disabledByDefaultControllers []string) (*config.Config, error) { + if err := o.Validate(allControllers, disabledByDefaultControllers); err != nil { + return nil, err + } + + if err := o.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{netutils.ParseIPSloppy("127.0.0.1")}); err != nil { + return nil, fmt.Errorf("error creating self-signed certificates: %v", err) + } + + c := &config.Config{} + if err := o.ApplyTo(c, CloudControllerManagerUserAgent); err != nil { + return nil, err + } + + return c, nil +} diff --git a/vendor/k8s.io/cloud-provider/options/servicecontroller.go b/vendor/k8s.io/cloud-provider/options/servicecontroller.go new file mode 100644 index 000000000..c63e43a98 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/servicecontroller.go @@ -0,0 +1,57 @@ +/* +Copyright 2018 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 options + +import ( + "github.com/spf13/pflag" + serviceconfig "k8s.io/cloud-provider/controllers/service/config" +) + +// ServiceControllerOptions holds the ServiceController options. +type ServiceControllerOptions struct { + *serviceconfig.ServiceControllerConfiguration +} + +// AddFlags adds flags related to ServiceController for controller manager to the specified FlagSet. +func (o *ServiceControllerOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + fs.Int32Var(&o.ConcurrentServiceSyncs, "concurrent-service-syncs", o.ConcurrentServiceSyncs, "The number of services that are allowed to sync concurrently. Larger number = more responsive service management, but more CPU (and network) load") +} + +// ApplyTo fills up ServiceController config with options. +func (o *ServiceControllerOptions) ApplyTo(cfg *serviceconfig.ServiceControllerConfiguration) error { + if o == nil { + return nil + } + + cfg.ConcurrentServiceSyncs = o.ConcurrentServiceSyncs + + return nil +} + +// Validate checks validation of ServiceControllerOptions. +func (o *ServiceControllerOptions) Validate() []error { + if o == nil { + return nil + } + + errs := []error{} + return errs +} diff --git a/vendor/k8s.io/component-base/config/options/leaderelectionconfig.go b/vendor/k8s.io/component-base/config/options/leaderelectionconfig.go new file mode 100644 index 000000000..bf2a44a0a --- /dev/null +++ b/vendor/k8s.io/component-base/config/options/leaderelectionconfig.go @@ -0,0 +1,53 @@ +/* +Copyright 2017 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 options + +import ( + "github.com/spf13/pflag" + "k8s.io/component-base/config" +) + +// BindLeaderElectionFlags binds the LeaderElectionConfiguration struct fields to a flagset +func BindLeaderElectionFlags(l *config.LeaderElectionConfiguration, fs *pflag.FlagSet) { + fs.BoolVar(&l.LeaderElect, "leader-elect", l.LeaderElect, ""+ + "Start a leader election client and gain leadership before "+ + "executing the main loop. Enable this when running replicated "+ + "components for high availability.") + fs.DurationVar(&l.LeaseDuration.Duration, "leader-elect-lease-duration", l.LeaseDuration.Duration, ""+ + "The duration that non-leader candidates will wait after observing a leadership "+ + "renewal until attempting to acquire leadership of a led but unrenewed leader "+ + "slot. This is effectively the maximum duration that a leader can be stopped "+ + "before it is replaced by another candidate. This is only applicable if leader "+ + "election is enabled.") + fs.DurationVar(&l.RenewDeadline.Duration, "leader-elect-renew-deadline", l.RenewDeadline.Duration, ""+ + "The interval between attempts by the acting master to renew a leadership slot "+ + "before it stops leading. This must be less than the lease duration. "+ + "This is only applicable if leader election is enabled.") + fs.DurationVar(&l.RetryPeriod.Duration, "leader-elect-retry-period", l.RetryPeriod.Duration, ""+ + "The duration the clients should wait between attempting acquisition and renewal "+ + "of a leadership. This is only applicable if leader election is enabled.") + fs.StringVar(&l.ResourceLock, "leader-elect-resource-lock", l.ResourceLock, ""+ + "The type of resource object that is used for locking during "+ + "leader election. Supported options are 'leases', 'endpointsleases' "+ + "and 'configmapsleases'.") + fs.StringVar(&l.ResourceName, "leader-elect-resource-name", l.ResourceName, ""+ + "The name of resource object that is used for locking during "+ + "leader election.") + fs.StringVar(&l.ResourceNamespace, "leader-elect-resource-namespace", l.ResourceNamespace, ""+ + "The namespace of resource object that is used for locking during "+ + "leader election.") +} diff --git a/vendor/k8s.io/component-base/logs/OWNERS b/vendor/k8s.io/component-base/logs/OWNERS new file mode 100644 index 000000000..57f049d79 --- /dev/null +++ b/vendor/k8s.io/component-base/logs/OWNERS @@ -0,0 +1,12 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - sig-instrumentation-approvers + - serathius + - pohly +reviewers: + - sig-instrumentation-reviewers + - serathius +labels: + - sig/instrumentation + - wg/structured-logging diff --git a/vendor/k8s.io/component-base/logs/logs.go b/vendor/k8s.io/component-base/logs/logs.go new file mode 100644 index 000000000..886c154e4 --- /dev/null +++ b/vendor/k8s.io/component-base/logs/logs.go @@ -0,0 +1,192 @@ +/* +Copyright 2014 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 logs contains support for logging options, flags and setup. +// Commands must explicitly enable command line flags. They no longer +// get added automatically when importing this package. +package logs + +import ( + "flag" + "fmt" + "log" + "time" + + "github.com/spf13/pflag" + logsapi "k8s.io/component-base/logs/api/v1" + "k8s.io/component-base/logs/klogflags" + "k8s.io/klog/v2" +) + +const vmoduleUsage = " (only works for the default text log format)" + +var ( + packageFlags = flag.NewFlagSet("logging", flag.ContinueOnError) + + // Periodic flushing gets configured either via the global flag + // in this file or via LoggingConfiguration. + logFlushFreq time.Duration +) + +func init() { + klogflags.Init(packageFlags) + packageFlags.DurationVar(&logFlushFreq, logsapi.LogFlushFreqFlagName, logsapi.LogFlushFreqDefault, "Maximum number of seconds between log flushes") +} + +type addFlagsOptions struct { + skipLoggingConfigurationFlags bool +} + +type Option func(*addFlagsOptions) + +// SkipLoggingConfigurationFlags must be used as option for AddFlags when +// the program also uses a LoggingConfiguration struct for configuring +// logging. Then only flags not covered by that get added. +func SkipLoggingConfigurationFlags() Option { + return func(o *addFlagsOptions) { + o.skipLoggingConfigurationFlags = true + } +} + +// Options is an alias for LoggingConfiguration to comply with component-base +// conventions. +type Options = logsapi.LoggingConfiguration + +// NewOptions is an alias for NewLoggingConfiguration. +var NewOptions = logsapi.NewLoggingConfiguration + +// AddFlags registers this package's flags on arbitrary FlagSets. This includes +// the klog flags, with the original underscore as separator between. If +// commands want hyphens as separators, they can set +// k8s.io/component-base/cli/flag/WordSepNormalizeFunc as normalization +// function on the flag set before calling AddFlags. +// +// May be called more than once. +func AddFlags(fs *pflag.FlagSet, opts ...Option) { + o := addFlagsOptions{} + for _, opt := range opts { + opt(&o) + } + + // Add all supported flags. + packageFlags.VisitAll(func(f *flag.Flag) { + pf := pflag.PFlagFromGoFlag(f) + switch f.Name { + case "v", logsapi.LogFlushFreqFlagName: + // unchanged, potentially skip it + if o.skipLoggingConfigurationFlags { + return + } + case "vmodule": + if o.skipLoggingConfigurationFlags { + return + } + pf.Usage += vmoduleUsage + } + if fs.Lookup(pf.Name) == nil { + fs.AddFlag(pf) + } + }) +} + +// AddGoFlags is a variant of AddFlags for traditional Go flag.FlagSet. +// Commands should use pflag whenever possible for the sake of consistency. +// Cases where this function is needed include tests (they have to set up flags +// in flag.CommandLine) and commands that for historic reasons use Go +// flag.Parse and cannot change to pflag because it would break their command +// line interface. +func AddGoFlags(fs *flag.FlagSet, opts ...Option) { + o := addFlagsOptions{} + for _, opt := range opts { + opt(&o) + } + + // Add flags with deprecation remark added to the usage text of + // some klog flags. + packageFlags.VisitAll(func(f *flag.Flag) { + usage := f.Usage + switch f.Name { + case "v", logsapi.LogFlushFreqFlagName: + // unchanged + if o.skipLoggingConfigurationFlags { + return + } + case "vmodule": + if o.skipLoggingConfigurationFlags { + return + } + usage += vmoduleUsage + } + fs.Var(f.Value, f.Name, usage) + }) +} + +// KlogWriter serves as a bridge between the standard log package and the glog package. +type KlogWriter struct{} + +// Write implements the io.Writer interface. +func (writer KlogWriter) Write(data []byte) (n int, err error) { + klog.InfoDepth(1, string(data)) + return len(data), nil +} + +// InitLogs initializes logs the way we want for Kubernetes. +// It should be called after parsing flags. If called before that, +// it will use the default log settings. +// +// InitLogs disables support for contextual logging in klog while +// that Kubernetes feature is not considered stable yet. Commands +// which want to support contextual logging can: +// - call klog.EnableContextualLogging after calling InitLogs, +// with a fixed `true` or depending on some command line flag or +// a feature gate check +// - set up a FeatureGate instance, the advanced logging configuration +// with Options and call Options.ValidateAndApply with the FeatureGate; +// k8s.io/component-base/logs/example/cmd demonstrates how to do that +func InitLogs() { + log.SetOutput(KlogWriter{}) + log.SetFlags(0) + + // Start flushing now. If LoggingConfiguration.ApplyAndValidate is + // used, it will restart the daemon with the log flush interval defined + // there. + klog.StartFlushDaemon(logFlushFreq) + + // This is the default in Kubernetes. Options.ValidateAndApply + // will override this with the result of a feature gate check. + klog.EnableContextualLogging(false) +} + +// FlushLogs flushes logs immediately. This should be called at the end of +// the main function via defer to ensure that all pending log messages +// are printed before exiting the program. +func FlushLogs() { + klog.Flush() +} + +// NewLogger creates a new log.Logger which sends logs to klog.Info. +func NewLogger(prefix string) *log.Logger { + return log.New(KlogWriter{}, prefix, 0) +} + +// GlogSetter is a setter to set glog level. +func GlogSetter(val string) (string, error) { + var level klog.Level + if err := level.Set(val); err != nil { + return "", fmt.Errorf("failed set klog.logging.verbosity %s: %v", val, err) + } + return fmt.Sprintf("successfully set klog.logging.verbosity to %s", val), nil +} diff --git a/vendor/k8s.io/component-base/metrics/features/kube_features.go b/vendor/k8s.io/component-base/metrics/features/kube_features.go new file mode 100644 index 000000000..3f1713214 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/features/kube_features.go @@ -0,0 +1,39 @@ +/* +Copyright 2022 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 features + +import ( + "k8s.io/component-base/featuregate" +) + +const ( + // owner: @logicalhan + // kep: https://kep.k8s.io/3466 + // alpha: v1.26 + ComponentSLIs featuregate.Feature = "ComponentSLIs" +) + +func featureGates() map[featuregate.Feature]featuregate.FeatureSpec { + return map[featuregate.Feature]featuregate.FeatureSpec{ + ComponentSLIs: {Default: false, PreRelease: featuregate.Alpha}, + } +} + +// AddFeatureGates adds all feature gates used by this package. +func AddFeatureGates(mutableFeatureGate featuregate.MutableFeatureGate) error { + return mutableFeatureGate.Add(featureGates()) +} diff --git a/vendor/k8s.io/component-base/metrics/prometheus/slis/metrics.go b/vendor/k8s.io/component-base/metrics/prometheus/slis/metrics.go new file mode 100644 index 000000000..7fb4a8e06 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/slis/metrics.go @@ -0,0 +1,76 @@ +/* +Copyright 2022 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 slis + +import ( + "context" + k8smetrics "k8s.io/component-base/metrics" +) + +type HealthcheckStatus string + +const ( + Success HealthcheckStatus = "success" + Error HealthcheckStatus = "error" +) + +type HealthcheckType string + +var ( + // healthcheck is a Prometheus Gauge metrics used for recording the results of a k8s healthcheck. + healthcheck = k8smetrics.NewGaugeVec( + &k8smetrics.GaugeOpts{ + Namespace: "kubernetes", + Name: "healthcheck", + Help: "This metric records the result of a single healthcheck.", + StabilityLevel: k8smetrics.ALPHA, + }, + []string{"name", "type"}, + ) + + // healthchecksTotal is a Prometheus Counter metrics used for counting the results of a k8s healthcheck. + healthchecksTotal = k8smetrics.NewCounterVec( + &k8smetrics.CounterOpts{ + Namespace: "kubernetes", + Name: "healthchecks_total", + Help: "This metric records the results of all healthcheck.", + StabilityLevel: k8smetrics.ALPHA, + }, + []string{"name", "type", "status"}, + ) +) + +func Register(registry k8smetrics.KubeRegistry) { + registry.Register(healthcheck) + registry.Register(healthchecksTotal) +} + +func ResetHealthMetrics() { + healthcheck.Reset() + healthchecksTotal.Reset() +} + +func ObserveHealthcheck(ctx context.Context, name string, healthcheckType string, status HealthcheckStatus) error { + if status == Success { + healthcheck.WithContext(ctx).WithLabelValues(name, healthcheckType).Set(1) + } else { + healthcheck.WithContext(ctx).WithLabelValues(name, healthcheckType).Set(0) + } + + healthchecksTotal.WithContext(ctx).WithLabelValues(name, healthcheckType, string(status)).Inc() + return nil +} diff --git a/vendor/k8s.io/component-base/metrics/prometheus/slis/registry.go b/vendor/k8s.io/component-base/metrics/prometheus/slis/registry.go new file mode 100644 index 000000000..f26340d3e --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/slis/registry.go @@ -0,0 +1,27 @@ +/* +Copyright 2020 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 slis + +import ( + "k8s.io/component-base/metrics" +) + +var ( + // Registry exposes the SLI registry so that additional SLIs can be + // added on a per-component basis. + Registry = metrics.NewKubeRegistry() +) diff --git a/vendor/k8s.io/component-base/metrics/prometheus/slis/routes.go b/vendor/k8s.io/component-base/metrics/prometheus/slis/routes.go new file mode 100644 index 000000000..4e88b7c24 --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/slis/routes.go @@ -0,0 +1,53 @@ +/* +Copyright 2020 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 slis + +import ( + "net/http" + "sync" + + "k8s.io/component-base/metrics" +) + +var ( + installOnce = sync.Once{} + installWithResetOnce = sync.Once{} +) + +type mux interface { + Handle(path string, handler http.Handler) +} + +type SLIMetrics struct{} + +// Install adds the DefaultMetrics handler +func (s SLIMetrics) Install(m mux) { + installOnce.Do(func() { + Register(Registry) + m.Handle("/metrics/slis", metrics.HandlerFor(Registry, metrics.HandlerOpts{})) + }) +} + +type SLIMetricsWithReset struct{} + +// Install adds the DefaultMetrics handler +func (s SLIMetricsWithReset) Install(m mux) { + installWithResetOnce.Do(func() { + Register(Registry) + m.Handle("/metrics/slis", metrics.HandlerWithReset(Registry, metrics.HandlerOpts{})) + }) +} diff --git a/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go b/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go new file mode 100644 index 000000000..59fd1cf6d --- /dev/null +++ b/vendor/k8s.io/component-base/metrics/prometheus/workqueue/metrics.go @@ -0,0 +1,137 @@ +/* +Copyright 2019 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 workqueue + +import ( + "k8s.io/client-go/util/workqueue" + k8smetrics "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" +) + +// Package prometheus sets the workqueue DefaultMetricsFactory to produce +// prometheus metrics. To use this package, you just have to import it. + +// Metrics subsystem and keys used by the workqueue. +const ( + WorkQueueSubsystem = "workqueue" + DepthKey = "depth" + AddsKey = "adds_total" + QueueLatencyKey = "queue_duration_seconds" + WorkDurationKey = "work_duration_seconds" + UnfinishedWorkKey = "unfinished_work_seconds" + LongestRunningProcessorKey = "longest_running_processor_seconds" + RetriesKey = "retries_total" +) + +var ( + depth = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: DepthKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "Current depth of workqueue", + }, []string{"name"}) + + adds = k8smetrics.NewCounterVec(&k8smetrics.CounterOpts{ + Subsystem: WorkQueueSubsystem, + Name: AddsKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "Total number of adds handled by workqueue", + }, []string{"name"}) + + latency = k8smetrics.NewHistogramVec(&k8smetrics.HistogramOpts{ + Subsystem: WorkQueueSubsystem, + Name: QueueLatencyKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "How long in seconds an item stays in workqueue before being requested.", + Buckets: k8smetrics.ExponentialBuckets(10e-9, 10, 10), + }, []string{"name"}) + + workDuration = k8smetrics.NewHistogramVec(&k8smetrics.HistogramOpts{ + Subsystem: WorkQueueSubsystem, + Name: WorkDurationKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "How long in seconds processing an item from workqueue takes.", + Buckets: k8smetrics.ExponentialBuckets(10e-9, 10, 10), + }, []string{"name"}) + + unfinished = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: UnfinishedWorkKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "How many seconds of work has done that " + + "is in progress and hasn't been observed by work_duration. Large " + + "values indicate stuck threads. One can deduce the number of stuck " + + "threads by observing the rate at which this increases.", + }, []string{"name"}) + + longestRunningProcessor = k8smetrics.NewGaugeVec(&k8smetrics.GaugeOpts{ + Subsystem: WorkQueueSubsystem, + Name: LongestRunningProcessorKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "How many seconds has the longest running " + + "processor for workqueue been running.", + }, []string{"name"}) + + retries = k8smetrics.NewCounterVec(&k8smetrics.CounterOpts{ + Subsystem: WorkQueueSubsystem, + Name: RetriesKey, + StabilityLevel: k8smetrics.ALPHA, + Help: "Total number of retries handled by workqueue", + }, []string{"name"}) + + metrics = []k8smetrics.Registerable{ + depth, adds, latency, workDuration, unfinished, longestRunningProcessor, retries, + } +) + +type prometheusMetricsProvider struct { +} + +func init() { + for _, m := range metrics { + legacyregistry.MustRegister(m) + } + workqueue.SetProvider(prometheusMetricsProvider{}) +} + +func (prometheusMetricsProvider) NewDepthMetric(name string) workqueue.GaugeMetric { + return depth.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewAddsMetric(name string) workqueue.CounterMetric { + return adds.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewLatencyMetric(name string) workqueue.HistogramMetric { + return latency.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewWorkDurationMetric(name string) workqueue.HistogramMetric { + return workDuration.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewUnfinishedWorkSecondsMetric(name string) workqueue.SettableGaugeMetric { + return unfinished.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewLongestRunningProcessorSecondsMetric(name string) workqueue.SettableGaugeMetric { + return longestRunningProcessor.WithLabelValues(name) +} + +func (prometheusMetricsProvider) NewRetriesMetric(name string) workqueue.CounterMetric { + return retries.WithLabelValues(name) +} diff --git a/vendor/k8s.io/controller-manager/LICENSE b/vendor/k8s.io/controller-manager/LICENSE new file mode 100644 index 000000000..8dada3eda --- /dev/null +++ b/vendor/k8s.io/controller-manager/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/vendor/k8s.io/controller-manager/config/OWNERS b/vendor/k8s.io/controller-manager/config/OWNERS new file mode 100644 index 000000000..200d01f74 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/OWNERS @@ -0,0 +1,14 @@ +approvers: + - api-approvers + - deads2k + - luxas + - mtaufen + - sttts +reviewers: + - api-reviewers + - deads2k + - luxas + - mtaufen + - sttts +emeritus_approvers: + - stewart-yu diff --git a/vendor/k8s.io/controller-manager/config/doc.go b/vendor/k8s.io/controller-manager/config/doc.go new file mode 100644 index 000000000..a98a0c8cd --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2019 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. +*/ + +// +k8s:deepcopy-gen=package + +package config // import "k8s.io/controller-manager/config" diff --git a/vendor/k8s.io/controller-manager/config/register.go b/vendor/k8s.io/controller-manager/config/register.go new file mode 100644 index 000000000..1f1a4a3c6 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/register.go @@ -0,0 +1,46 @@ +/* +Copyright 2020 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 config + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the "group" that is needed to uniquely identify the API +const GroupName = "controllermanager.config.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &LeaderMigrationConfiguration{}, + ) + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/types.go b/vendor/k8s.io/controller-manager/config/types.go new file mode 100644 index 000000000..e8d2470ee --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/types.go @@ -0,0 +1,82 @@ +/* +Copyright 2020 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 config should only include generic configurations +package config + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + componentbaseconfig "k8s.io/component-base/config" +) + +// GenericControllerManagerConfiguration holds configuration for a generic controller-manager +type GenericControllerManagerConfiguration struct { + // port is the port that the controller-manager's http service runs on. + Port int32 + // address is the IP address to serve on (set to 0.0.0.0 for all interfaces). + Address string + // minResyncPeriod is the resync period in reflectors; will be random between + // minResyncPeriod and 2*minResyncPeriod. + MinResyncPeriod metav1.Duration + // ClientConnection specifies the kubeconfig file and client connection + // settings for the proxy server to use when communicating with the apiserver. + ClientConnection componentbaseconfig.ClientConnectionConfiguration + // How long to wait between starting controller managers + ControllerStartInterval metav1.Duration + // leaderElection defines the configuration of leader election client. + LeaderElection componentbaseconfig.LeaderElectionConfiguration + // Controllers is the list of controllers to enable or disable + // '*' means "all enabled by default controllers" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Controllers []string + // DebuggingConfiguration holds configuration for Debugging related features. + Debugging componentbaseconfig.DebuggingConfiguration + // LeaderMigrationEnabled indicates whether Leader Migration should be enabled for the controller manager. + LeaderMigrationEnabled bool + // LeaderMigration holds the configuration for Leader Migration. + LeaderMigration LeaderMigrationConfiguration +} + +// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LeaderMigrationConfiguration struct { + metav1.TypeMeta + + // LeaderName is the name of the leader election resource that protects the migration + // E.g. 1-20-KCM-to-1-21-CCM + LeaderName string + + // ResourceLock indicates the resource object type that will be used to lock + // Should be "leases" or "endpoints" + ResourceLock string + + // ControllerLeaders contains a list of migrating leader lock configurations + ControllerLeaders []ControllerLeaderConfiguration +} + +// ControllerLeaderConfiguration provides the configuration for a migrating leader lock. +type ControllerLeaderConfiguration struct { + // Name is the name of the controller being migrated + // E.g. service-controller, route-controller, cloud-node-controller, etc + Name string + + // Component is the name of the component in which the controller should be running. + // E.g. kube-controller-manager, cloud-controller-manager, etc + // Or '*' meaning the controller can be run under any component that participates in the migration + Component string +} diff --git a/vendor/k8s.io/controller-manager/config/v1/conversion.go b/vendor/k8s.io/controller-manager/config/v1/conversion.go new file mode 100644 index 000000000..4ba5bd8a8 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/conversion.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 + +import ( + "unsafe" + + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/controller-manager/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +const ResourceLockLeases = "leases" + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*ControllerLeaderConfiguration)(nil), (*config.ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(a.(*ControllerLeaderConfiguration), b.(*config.ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.ControllerLeaderConfiguration)(nil), (*ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ControllerLeaderConfiguration_To_v1_ControllerLeaderConfiguration(a.(*config.ControllerLeaderConfiguration), b.(*ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LeaderMigrationConfiguration)(nil), (*config.LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(a.(*LeaderMigrationConfiguration), b.(*config.LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.LeaderMigrationConfiguration)(nil), (*LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_LeaderMigrationConfiguration_To_v1_LeaderMigrationConfiguration(a.(*config.LeaderMigrationConfiguration), b.(*LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func Convert_config_LeaderMigrationConfiguration_To_v1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ControllerLeaders = *(*[]ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +func Convert_v1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ControllerLeaders = *(*[]config.ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + out.ResourceLock = ResourceLockLeases + return nil +} + +func Convert_v1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +func Convert_config_ControllerLeaderConfiguration_To_v1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1/doc.go b/vendor/k8s.io/controller-manager/config/v1/doc.go new file mode 100644 index 000000000..037cfb785 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2022 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. +*/ + +// +k8s:deepcopy-gen=package +// +groupName=controllermanager.config.k8s.io + +package v1 // import "k8s.io/controller-manager/config/v1" diff --git a/vendor/k8s.io/controller-manager/config/v1/register.go b/vendor/k8s.io/controller-manager/config/v1/register.go new file mode 100644 index 000000000..e48f90a7c --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/register.go @@ -0,0 +1,48 @@ +/* +Copyright 2022 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 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the "group" that is needed to uniquely identify the API +const GroupName = "controllermanager.config.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &LeaderMigrationConfiguration{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1/types.go b/vendor/k8s.io/controller-manager/config/v1/types.go new file mode 100644 index 000000000..e20278686 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/types.go @@ -0,0 +1,47 @@ +/* +Copyright 2022 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 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LeaderMigrationConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // LeaderName is the name of the leader election resource that protects the migration + // E.g. 1-20-KCM-to-1-21-CCM + LeaderName string `json:"leaderName"` + + // ControllerLeaders contains a list of migrating leader lock configurations + // +listType=atomic + ControllerLeaders []ControllerLeaderConfiguration `json:"controllerLeaders"` +} + +// ControllerLeaderConfiguration provides the configuration for a migrating leader lock. +type ControllerLeaderConfiguration struct { + // Name is the name of the controller being migrated + // E.g. service-controller, route-controller, cloud-node-controller, etc + Name string `json:"name"` + + // Component is the name of the component in which the controller should be running. + // E.g. kube-controller-manager, cloud-controller-manager, etc + // Or '*' meaning the controller can be run under any component that participates in the migration + Component string `json:"component"` +} diff --git a/vendor/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go b/vendor/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go new file mode 100644 index 000000000..d5b54b0b2 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1/zz_generated.deepcopy.go @@ -0,0 +1,72 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration. +func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration { + if in == nil { + return nil + } + out := new(ControllerLeaderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.ControllerLeaders != nil { + in, out := &in.ControllerLeaders, &out.ControllerLeaders + *out = make([]ControllerLeaderConfiguration, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration. +func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration { + if in == nil { + return nil + } + out := new(LeaderMigrationConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/conversion.go b/vendor/k8s.io/controller-manager/config/v1alpha1/conversion.go new file mode 100644 index 000000000..d006429e7 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/conversion.go @@ -0,0 +1,39 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + cmconfig "k8s.io/controller-manager/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +// Convert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(in *GenericControllerManagerConfiguration, out *cmconfig.GenericControllerManagerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(in, out, s) +} + +// Convert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration is an autogenerated conversion function. +func Convert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(in *cmconfig.GenericControllerManagerConfiguration, out *GenericControllerManagerConfiguration, s conversion.Scope) error { + return autoConvert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/defaults.go b/vendor/k8s.io/controller-manager/config/v1alpha1/defaults.go new file mode 100644 index 000000000..82a920c70 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/defaults.go @@ -0,0 +1,51 @@ +/* +Copyright 2019 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 v1alpha1 + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +func RecommendedDefaultGenericControllerManagerConfiguration(obj *GenericControllerManagerConfiguration) { + zero := metav1.Duration{} + if obj.Address == "" { + obj.Address = "0.0.0.0" + } + if obj.MinResyncPeriod == zero { + obj.MinResyncPeriod = metav1.Duration{Duration: 12 * time.Hour} + } + if obj.ControllerStartInterval == zero { + obj.ControllerStartInterval = metav1.Duration{Duration: 0 * time.Second} + } + if len(obj.Controllers) == 0 { + obj.Controllers = []string{"*"} + } + + if len(obj.LeaderElection.ResourceLock) == 0 { + // Use lease-based leader election to reduce cost. + // We migrated for EndpointsLease lock in 1.17 and starting in 1.20 we + // migrated to Lease lock. + obj.LeaderElection.ResourceLock = "leases" + } + + // Use the default ClientConnectionConfiguration and LeaderElectionConfiguration options + componentbaseconfigv1alpha1.RecommendedDefaultClientConnectionConfiguration(&obj.ClientConnection) + componentbaseconfigv1alpha1.RecommendedDefaultLeaderElectionConfiguration(&obj.LeaderElection) +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/doc.go b/vendor/k8s.io/controller-manager/config/v1alpha1/doc.go new file mode 100644 index 000000000..b01cf385d --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2019 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/controller-manager/config +// +k8s:conversion-gen=k8s.io/controller-manager/config/v1alpha1 +// +k8s:openapi-gen=true +// +groupName=controllermanager.config.k8s.io + +package v1alpha1 // import "k8s.io/controller-manager/config/v1alpha1" diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/register.go b/vendor/k8s.io/controller-manager/config/v1alpha1/register.go new file mode 100644 index 000000000..59603396d --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/register.go @@ -0,0 +1,48 @@ +/* +Copyright 2019 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the "group" that is needed to uniquely identify the API +const GroupName = "controllermanager.config.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &LeaderMigrationConfiguration{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/types.go b/vendor/k8s.io/controller-manager/config/v1alpha1/types.go new file mode 100644 index 000000000..9cd9eee9c --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/types.go @@ -0,0 +1,81 @@ +/* +Copyright 2020 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +// GenericControllerManagerConfiguration holds configuration for a generic controller-manager. +type GenericControllerManagerConfiguration struct { + // port is the port that the controller-manager's http service runs on. + Port int32 + // address is the IP address to serve on (set to 0.0.0.0 for all interfaces). + Address string + // minResyncPeriod is the resync period in reflectors; will be random between + // minResyncPeriod and 2*minResyncPeriod. + MinResyncPeriod metav1.Duration + // ClientConnection specifies the kubeconfig file and client connection + // settings for the proxy server to use when communicating with the apiserver. + ClientConnection componentbaseconfigv1alpha1.ClientConnectionConfiguration + // How long to wait between starting controller managers + ControllerStartInterval metav1.Duration + // leaderElection defines the configuration of leader election client. + LeaderElection componentbaseconfigv1alpha1.LeaderElectionConfiguration + // Controllers is the list of controllers to enable or disable + // '*' means "all enabled by default controllers" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Controllers []string + // DebuggingConfiguration holds configuration for Debugging related features. + Debugging componentbaseconfigv1alpha1.DebuggingConfiguration + // LeaderMigrationEnabled indicates whether Leader Migration should be enabled for the controller manager. + LeaderMigrationEnabled bool + // LeaderMigration holds the configuration for Leader Migration. + LeaderMigration LeaderMigrationConfiguration +} + +// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LeaderMigrationConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // LeaderName is the name of the leader election resource that protects the migration + // E.g. 1-20-KCM-to-1-21-CCM + LeaderName string `json:"leaderName"` + + // ResourceLock indicates the resource object type that will be used to lock + // Should be "leases" or "endpoints" + ResourceLock string `json:"resourceLock"` + + // ControllerLeaders contains a list of migrating leader lock configurations + ControllerLeaders []ControllerLeaderConfiguration `json:"controllerLeaders"` +} + +// ControllerLeaderConfiguration provides the configuration for a migrating leader lock. +type ControllerLeaderConfiguration struct { + // Name is the name of the controller being migrated + // E.g. service-controller, route-controller, cloud-node-controller, etc + Name string `json:"name"` + + // Component is the name of the component in which the controller should be running. + // E.g. kube-controller-manager, cloud-controller-manager, etc + // Or '*' meaning the controller can be run under any component that participates in the migration + Component string `json:"component"` +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 000000000..40da2f91d --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,161 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + unsafe "unsafe" + + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + configv1alpha1 "k8s.io/component-base/config/v1alpha1" + config "k8s.io/controller-manager/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*ControllerLeaderConfiguration)(nil), (*config.ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(a.(*ControllerLeaderConfiguration), b.(*config.ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.ControllerLeaderConfiguration)(nil), (*ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration(a.(*config.ControllerLeaderConfiguration), b.(*ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LeaderMigrationConfiguration)(nil), (*config.LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(a.(*LeaderMigrationConfiguration), b.(*config.LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.LeaderMigrationConfiguration)(nil), (*LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(a.(*config.LeaderMigrationConfiguration), b.(*LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.GenericControllerManagerConfiguration)(nil), (*GenericControllerManagerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(a.(*config.GenericControllerManagerConfiguration), b.(*GenericControllerManagerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*GenericControllerManagerConfiguration)(nil), (*config.GenericControllerManagerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(a.(*GenericControllerManagerConfiguration), b.(*config.GenericControllerManagerConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +// Convert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in, out, s) +} + +func autoConvert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +// Convert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration is an autogenerated conversion function. +func Convert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + return autoConvert_config_ControllerLeaderConfiguration_To_v1alpha1_ControllerLeaderConfiguration(in, out, s) +} + +func autoConvert_v1alpha1_GenericControllerManagerConfiguration_To_config_GenericControllerManagerConfiguration(in *GenericControllerManagerConfiguration, out *config.GenericControllerManagerConfiguration, s conversion.Scope) error { + out.Port = in.Port + out.Address = in.Address + out.MinResyncPeriod = in.MinResyncPeriod + if err := configv1alpha1.Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { + return err + } + out.ControllerStartInterval = in.ControllerStartInterval + if err := configv1alpha1.Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(&in.LeaderElection, &out.LeaderElection, s); err != nil { + return err + } + out.Controllers = *(*[]string)(unsafe.Pointer(&in.Controllers)) + if err := configv1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.Debugging, &out.Debugging, s); err != nil { + return err + } + out.LeaderMigrationEnabled = in.LeaderMigrationEnabled + if err := Convert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(&in.LeaderMigration, &out.LeaderMigration, s); err != nil { + return err + } + return nil +} + +func autoConvert_config_GenericControllerManagerConfiguration_To_v1alpha1_GenericControllerManagerConfiguration(in *config.GenericControllerManagerConfiguration, out *GenericControllerManagerConfiguration, s conversion.Scope) error { + out.Port = in.Port + out.Address = in.Address + out.MinResyncPeriod = in.MinResyncPeriod + if err := configv1alpha1.Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { + return err + } + out.ControllerStartInterval = in.ControllerStartInterval + if err := configv1alpha1.Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(&in.LeaderElection, &out.LeaderElection, s); err != nil { + return err + } + out.Controllers = *(*[]string)(unsafe.Pointer(&in.Controllers)) + if err := configv1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.Debugging, &out.Debugging, s); err != nil { + return err + } + out.LeaderMigrationEnabled = in.LeaderMigrationEnabled + if err := Convert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(&in.LeaderMigration, &out.LeaderMigration, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ResourceLock = in.ResourceLock + out.ControllerLeaders = *(*[]config.ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +// Convert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in, out, s) +} + +func autoConvert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ResourceLock = in.ResourceLock + out.ControllerLeaders = *(*[]ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +// Convert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration is an autogenerated conversion function. +func Convert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + return autoConvert_config_LeaderMigrationConfiguration_To_v1alpha1_LeaderMigrationConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..5d0eea247 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,99 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration. +func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration { + if in == nil { + return nil + } + out := new(ControllerLeaderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericControllerManagerConfiguration) DeepCopyInto(out *GenericControllerManagerConfiguration) { + *out = *in + out.MinResyncPeriod = in.MinResyncPeriod + out.ClientConnection = in.ClientConnection + out.ControllerStartInterval = in.ControllerStartInterval + in.LeaderElection.DeepCopyInto(&out.LeaderElection) + if in.Controllers != nil { + in, out := &in.Controllers, &out.Controllers + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.Debugging.DeepCopyInto(&out.Debugging) + in.LeaderMigration.DeepCopyInto(&out.LeaderMigration) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericControllerManagerConfiguration. +func (in *GenericControllerManagerConfiguration) DeepCopy() *GenericControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(GenericControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.ControllerLeaders != nil { + in, out := &in.ControllerLeaders, &out.ControllerLeaders + *out = make([]ControllerLeaderConfiguration, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration. +func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration { + if in == nil { + return nil + } + out := new(LeaderMigrationConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/doc.go b/vendor/k8s.io/controller-manager/config/v1beta1/doc.go new file mode 100644 index 000000000..94cd3f128 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2021 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/controller-manager/config +// +k8s:openapi-gen=true +// +groupName=controllermanager.config.k8s.io + +package v1beta1 // import "k8s.io/controller-manager/config/v1beta1" diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/register.go b/vendor/k8s.io/controller-manager/config/v1beta1/register.go new file mode 100644 index 000000000..c812dcd3b --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/register.go @@ -0,0 +1,48 @@ +/* +Copyright 2021 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 v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the "group" that is needed to uniquely identify the API +const GroupName = "controllermanager.config.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &LeaderMigrationConfiguration{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/types.go b/vendor/k8s.io/controller-manager/config/v1beta1/types.go new file mode 100644 index 000000000..91467c006 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/types.go @@ -0,0 +1,51 @@ +/* +Copyright 2021 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 v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// LeaderMigrationConfiguration provides versioned configuration for all migrating leader locks. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type LeaderMigrationConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // LeaderName is the name of the leader election resource that protects the migration + // E.g. 1-20-KCM-to-1-21-CCM + LeaderName string `json:"leaderName"` + + // ResourceLock indicates the resource object type that will be used to lock + // Should be "leases" or "endpoints" + ResourceLock string `json:"resourceLock"` + + // ControllerLeaders contains a list of migrating leader lock configurations + // +listType=atomic + ControllerLeaders []ControllerLeaderConfiguration `json:"controllerLeaders"` +} + +// ControllerLeaderConfiguration provides the configuration for a migrating leader lock. +type ControllerLeaderConfiguration struct { + // Name is the name of the controller being migrated + // E.g. service-controller, route-controller, cloud-node-controller, etc + Name string `json:"name"` + + // Component is the name of the component in which the controller should be running. + // E.g. kube-controller-manager, cloud-controller-manager, etc + // Or '*' meaning the controller can be run under any component that participates in the migration + Component string `json:"component"` +} diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.conversion.go new file mode 100644 index 000000000..37a633085 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.conversion.go @@ -0,0 +1,106 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1beta1 + +import ( + unsafe "unsafe" + + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/controller-manager/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*ControllerLeaderConfiguration)(nil), (*config.ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(a.(*ControllerLeaderConfiguration), b.(*config.ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.ControllerLeaderConfiguration)(nil), (*ControllerLeaderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration(a.(*config.ControllerLeaderConfiguration), b.(*ControllerLeaderConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LeaderMigrationConfiguration)(nil), (*config.LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(a.(*LeaderMigrationConfiguration), b.(*config.LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.LeaderMigrationConfiguration)(nil), (*LeaderMigrationConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration(a.(*config.LeaderMigrationConfiguration), b.(*LeaderMigrationConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +// Convert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration is an autogenerated conversion function. +func Convert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in *ControllerLeaderConfiguration, out *config.ControllerLeaderConfiguration, s conversion.Scope) error { + return autoConvert_v1beta1_ControllerLeaderConfiguration_To_config_ControllerLeaderConfiguration(in, out, s) +} + +func autoConvert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + out.Name = in.Name + out.Component = in.Component + return nil +} + +// Convert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration is an autogenerated conversion function. +func Convert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration(in *config.ControllerLeaderConfiguration, out *ControllerLeaderConfiguration, s conversion.Scope) error { + return autoConvert_config_ControllerLeaderConfiguration_To_v1beta1_ControllerLeaderConfiguration(in, out, s) +} + +func autoConvert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ResourceLock = in.ResourceLock + out.ControllerLeaders = *(*[]config.ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +// Convert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration is an autogenerated conversion function. +func Convert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in *LeaderMigrationConfiguration, out *config.LeaderMigrationConfiguration, s conversion.Scope) error { + return autoConvert_v1beta1_LeaderMigrationConfiguration_To_config_LeaderMigrationConfiguration(in, out, s) +} + +func autoConvert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + out.LeaderName = in.LeaderName + out.ResourceLock = in.ResourceLock + out.ControllerLeaders = *(*[]ControllerLeaderConfiguration)(unsafe.Pointer(&in.ControllerLeaders)) + return nil +} + +// Convert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration is an autogenerated conversion function. +func Convert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration(in *config.LeaderMigrationConfiguration, out *LeaderMigrationConfiguration, s conversion.Scope) error { + return autoConvert_config_LeaderMigrationConfiguration_To_v1beta1_LeaderMigrationConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 000000000..8285edb9f --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,72 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration. +func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration { + if in == nil { + return nil + } + out := new(ControllerLeaderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.ControllerLeaders != nil { + in, out := &in.ControllerLeaders, &out.ControllerLeaders + *out = make([]ControllerLeaderConfiguration, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration. +func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration { + if in == nil { + return nil + } + out := new(LeaderMigrationConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/controller-manager/config/zz_generated.deepcopy.go b/vendor/k8s.io/controller-manager/config/zz_generated.deepcopy.go new file mode 100644 index 000000000..00cd42088 --- /dev/null +++ b/vendor/k8s.io/controller-manager/config/zz_generated.deepcopy.go @@ -0,0 +1,99 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package config + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControllerLeaderConfiguration) DeepCopyInto(out *ControllerLeaderConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerLeaderConfiguration. +func (in *ControllerLeaderConfiguration) DeepCopy() *ControllerLeaderConfiguration { + if in == nil { + return nil + } + out := new(ControllerLeaderConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericControllerManagerConfiguration) DeepCopyInto(out *GenericControllerManagerConfiguration) { + *out = *in + out.MinResyncPeriod = in.MinResyncPeriod + out.ClientConnection = in.ClientConnection + out.ControllerStartInterval = in.ControllerStartInterval + out.LeaderElection = in.LeaderElection + if in.Controllers != nil { + in, out := &in.Controllers, &out.Controllers + *out = make([]string, len(*in)) + copy(*out, *in) + } + out.Debugging = in.Debugging + in.LeaderMigration.DeepCopyInto(&out.LeaderMigration) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericControllerManagerConfiguration. +func (in *GenericControllerManagerConfiguration) DeepCopy() *GenericControllerManagerConfiguration { + if in == nil { + return nil + } + out := new(GenericControllerManagerConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaderMigrationConfiguration) DeepCopyInto(out *LeaderMigrationConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.ControllerLeaders != nil { + in, out := &in.ControllerLeaders, &out.ControllerLeaders + *out = make([]ControllerLeaderConfiguration, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaderMigrationConfiguration. +func (in *LeaderMigrationConfiguration) DeepCopy() *LeaderMigrationConfiguration { + if in == nil { + return nil + } + out := new(LeaderMigrationConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaderMigrationConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/vendor/k8s.io/controller-manager/options/debugging.go b/vendor/k8s.io/controller-manager/options/debugging.go new file mode 100644 index 000000000..eafd78a88 --- /dev/null +++ b/vendor/k8s.io/controller-manager/options/debugging.go @@ -0,0 +1,72 @@ +/* +Copyright 2018 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 options + +import ( + "github.com/spf13/pflag" + + componentbaseconfig "k8s.io/component-base/config" +) + +// DebuggingOptions holds the Debugging options. +type DebuggingOptions struct { + *componentbaseconfig.DebuggingConfiguration +} + +// RecommendedDebuggingOptions returns the currently recommended debugging options. These are subject to change +// between releases as we add options and decide which features should be exposed or not by default. +func RecommendedDebuggingOptions() *DebuggingOptions { + return &DebuggingOptions{ + DebuggingConfiguration: &componentbaseconfig.DebuggingConfiguration{ + EnableProfiling: true, // profile debugging is cheap to have exposed and standard on kube binaries + }, + } +} + +// AddFlags adds flags related to debugging for controller manager to the specified FlagSet. +func (o *DebuggingOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + fs.BoolVar(&o.EnableProfiling, "profiling", o.EnableProfiling, + "Enable profiling via web interface host:port/debug/pprof/") + fs.BoolVar(&o.EnableContentionProfiling, "contention-profiling", o.EnableContentionProfiling, + "Enable lock contention profiling, if profiling is enabled") +} + +// ApplyTo fills up Debugging config with options. +func (o *DebuggingOptions) ApplyTo(cfg *componentbaseconfig.DebuggingConfiguration) error { + if o == nil { + return nil + } + + cfg.EnableProfiling = o.EnableProfiling + cfg.EnableContentionProfiling = o.EnableContentionProfiling + + return nil +} + +// Validate checks validation of DebuggingOptions. +func (o *DebuggingOptions) Validate() []error { + if o == nil { + return nil + } + + errs := []error{} + return errs +} diff --git a/vendor/k8s.io/controller-manager/options/generic.go b/vendor/k8s.io/controller-manager/options/generic.go new file mode 100644 index 000000000..bb7e8c7d4 --- /dev/null +++ b/vendor/k8s.io/controller-manager/options/generic.go @@ -0,0 +1,117 @@ +/* +Copyright 2018 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 options + +import ( + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/util/sets" + cliflag "k8s.io/component-base/cli/flag" + "k8s.io/component-base/config/options" + cmconfig "k8s.io/controller-manager/config" + migration "k8s.io/controller-manager/pkg/leadermigration/options" +) + +// GenericControllerManagerConfigurationOptions holds the options which are generic. +type GenericControllerManagerConfigurationOptions struct { + *cmconfig.GenericControllerManagerConfiguration + Debugging *DebuggingOptions + // LeaderMigration is the options for leader migration, a nil indicates default options should be applied. + LeaderMigration *migration.LeaderMigrationOptions +} + +// NewGenericControllerManagerConfigurationOptions returns generic configuration default values for both +// the kube-controller-manager and the cloud-contoller-manager. Any common changes should +// be made here. Any individual changes should be made in that controller. +func NewGenericControllerManagerConfigurationOptions(cfg *cmconfig.GenericControllerManagerConfiguration) *GenericControllerManagerConfigurationOptions { + o := &GenericControllerManagerConfigurationOptions{ + GenericControllerManagerConfiguration: cfg, + Debugging: RecommendedDebuggingOptions(), + LeaderMigration: &migration.LeaderMigrationOptions{}, + } + + return o +} + +// AddFlags adds flags related to generic for controller manager to the specified FlagSet. +func (o *GenericControllerManagerConfigurationOptions) AddFlags(fss *cliflag.NamedFlagSets, allControllers, disabledByDefaultControllers []string) { + if o == nil { + return + } + + o.Debugging.AddFlags(fss.FlagSet("debugging")) + o.LeaderMigration.AddFlags(fss.FlagSet("leader-migration")) + genericfs := fss.FlagSet("generic") + genericfs.DurationVar(&o.MinResyncPeriod.Duration, "min-resync-period", o.MinResyncPeriod.Duration, "The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod.") + genericfs.StringVar(&o.ClientConnection.ContentType, "kube-api-content-type", o.ClientConnection.ContentType, "Content type of requests sent to apiserver.") + genericfs.Float32Var(&o.ClientConnection.QPS, "kube-api-qps", o.ClientConnection.QPS, "QPS to use while talking with kubernetes apiserver.") + genericfs.Int32Var(&o.ClientConnection.Burst, "kube-api-burst", o.ClientConnection.Burst, "Burst to use while talking with kubernetes apiserver.") + genericfs.DurationVar(&o.ControllerStartInterval.Duration, "controller-start-interval", o.ControllerStartInterval.Duration, "Interval between starting controller managers.") + genericfs.StringSliceVar(&o.Controllers, "controllers", o.Controllers, fmt.Sprintf(""+ + "A list of controllers to enable. '*' enables all on-by-default controllers, 'foo' enables the controller "+ + "named 'foo', '-foo' disables the controller named 'foo'.\nAll controllers: %s\nDisabled-by-default controllers: %s", + strings.Join(allControllers, ", "), strings.Join(disabledByDefaultControllers, ", "))) + + options.BindLeaderElectionFlags(&o.LeaderElection, genericfs) +} + +// ApplyTo fills up generic config with options. +func (o *GenericControllerManagerConfigurationOptions) ApplyTo(cfg *cmconfig.GenericControllerManagerConfiguration) error { + if o == nil { + return nil + } + + if err := o.Debugging.ApplyTo(&cfg.Debugging); err != nil { + return err + } + if err := o.LeaderMigration.ApplyTo(cfg); err != nil { + return err + } + cfg.Port = o.Port + cfg.Address = o.Address + cfg.MinResyncPeriod = o.MinResyncPeriod + cfg.ClientConnection = o.ClientConnection + cfg.ControllerStartInterval = o.ControllerStartInterval + cfg.LeaderElection = o.LeaderElection + cfg.Controllers = o.Controllers + + return nil +} + +// Validate checks validation of GenericOptions. +func (o *GenericControllerManagerConfigurationOptions) Validate(allControllers []string, disabledByDefaultControllers []string) []error { + if o == nil { + return nil + } + + errs := []error{} + errs = append(errs, o.Debugging.Validate()...) + + allControllersSet := sets.NewString(allControllers...) + for _, controller := range o.Controllers { + if controller == "*" { + continue + } + controller = strings.TrimPrefix(controller, "-") + if !allControllersSet.Has(controller) { + errs = append(errs, fmt.Errorf("%q is not in the list of known controllers", controller)) + } + } + + return errs +} diff --git a/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go b/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go new file mode 100644 index 000000000..290847483 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go @@ -0,0 +1,102 @@ +/* +Copyright 2016 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 clientbuilder + +import ( + "k8s.io/client-go/discovery" + clientset "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" + "k8s.io/klog/v2" +) + +// ControllerClientBuilder allows you to get clients and configs for controllers +// Please note a copy also exists in staging/src/k8s.io/cloud-provider/cloud.go +// TODO: Extract this into a separate controller utilities repo (issues/68947) +type ControllerClientBuilder interface { + Config(name string) (*restclient.Config, error) + ConfigOrDie(name string) *restclient.Config + Client(name string) (clientset.Interface, error) + ClientOrDie(name string) clientset.Interface + DiscoveryClient(name string) (discovery.DiscoveryInterface, error) + DiscoveryClientOrDie(name string) discovery.DiscoveryInterface +} + +// SimpleControllerClientBuilder returns a fixed client with different user agents +type SimpleControllerClientBuilder struct { + // ClientConfig is a skeleton config to clone and use as the basis for each controller client + ClientConfig *restclient.Config +} + +// Config returns a client config for a fixed client +func (b SimpleControllerClientBuilder) Config(name string) (*restclient.Config, error) { + clientConfig := *b.ClientConfig + return restclient.AddUserAgent(&clientConfig, name), nil +} + +// ConfigOrDie returns a client config if no error from previous config func. +// If it gets an error getting the client, it will log the error and kill the process it's running in. +func (b SimpleControllerClientBuilder) ConfigOrDie(name string) *restclient.Config { + clientConfig, err := b.Config(name) + if err != nil { + klog.Fatal(err) + } + return clientConfig +} + +// Client returns a clientset.Interface built from the ClientBuilder +func (b SimpleControllerClientBuilder) Client(name string) (clientset.Interface, error) { + clientConfig, err := b.Config(name) + if err != nil { + return nil, err + } + return clientset.NewForConfig(clientConfig) +} + +// ClientOrDie returns a clientset.interface built from the ClientBuilder with no error. +// If it gets an error getting the client, it will log the error and kill the process it's running in. +func (b SimpleControllerClientBuilder) ClientOrDie(name string) clientset.Interface { + client, err := b.Client(name) + if err != nil { + klog.Fatal(err) + } + return client +} + +// DiscoveryClient returns a discovery.DiscoveryInterface built from the ClientBuilder +// Discovery is special because it will artificially pump the burst quite high to handle the many discovery requests. +func (b SimpleControllerClientBuilder) DiscoveryClient(name string) (discovery.DiscoveryInterface, error) { + clientConfig, err := b.Config(name) + if err != nil { + return nil, err + } + // Discovery makes a lot of requests infrequently. This allows the burst to succeed and refill to happen + // in just a few seconds. + clientConfig.Burst = 200 + clientConfig.QPS = 20 + return clientset.NewForConfig(clientConfig) +} + +// DiscoveryClientOrDie returns a discovery.DiscoveryInterface built from the ClientBuilder with no error. +// Discovery is special because it will artificially pump the burst quite high to handle the many discovery requests. +// If it gets an error getting the client, it will log the error and kill the process it's running in. +func (b SimpleControllerClientBuilder) DiscoveryClientOrDie(name string) discovery.DiscoveryInterface { + client, err := b.DiscoveryClient(name) + if err != nil { + klog.Fatal(err) + } + return client +} diff --git a/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go b/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go new file mode 100644 index 000000000..514bb1b83 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go @@ -0,0 +1,271 @@ +/* +Copyright 2018 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 clientbuilder + +import ( + "context" + "fmt" + "net/http" + "sync" + "time" + + "golang.org/x/oauth2" + v1authenticationapi "k8s.io/api/authentication/v1" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/client-go/discovery" + clientset "k8s.io/client-go/kubernetes" + v1core "k8s.io/client-go/kubernetes/typed/core/v1" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/transport" + "k8s.io/klog/v2" + "k8s.io/utils/clock" + utilpointer "k8s.io/utils/pointer" +) + +var ( + // defaultExpirationSeconds defines the duration of a TokenRequest in seconds. + defaultExpirationSeconds = int64(3600) + // defaultLeewayPercent defines the percentage of expiration left before the client trigger a token rotation. + // range[0, 100] + defaultLeewayPercent = 20 +) + +type DynamicControllerClientBuilder struct { + // ClientConfig is a skeleton config to clone and use as the basis for each controller client + ClientConfig *restclient.Config + + // CoreClient is used to provision service accounts if needed and watch for their associated tokens + // to construct a controller client + CoreClient v1core.CoreV1Interface + + // Namespace is the namespace used to host the service accounts that will back the + // controllers. It must be highly privileged namespace which normal users cannot inspect. + Namespace string + + // roundTripperFuncMap is a cache stores the corresponding roundtripper func for each + // service account + roundTripperFuncMap map[string]func(http.RoundTripper) http.RoundTripper + + // expirationSeconds defines the token expiration seconds + expirationSeconds int64 + + // leewayPercent defines the percentage of expiration left before the client trigger a token rotation. + leewayPercent int + + mutex sync.Mutex + + clock clock.Clock +} + +// NewDynamicClientBuilder returns client builder which uses TokenRequest feature and refresh service account token periodically +func NewDynamicClientBuilder(clientConfig *restclient.Config, coreClient v1core.CoreV1Interface, ns string) ControllerClientBuilder { + builder := &DynamicControllerClientBuilder{ + ClientConfig: clientConfig, + CoreClient: coreClient, + Namespace: ns, + roundTripperFuncMap: map[string]func(http.RoundTripper) http.RoundTripper{}, + expirationSeconds: defaultExpirationSeconds, + leewayPercent: defaultLeewayPercent, + clock: clock.RealClock{}, + } + return builder +} + +// this function only for test purpose, don't call it +func NewTestDynamicClientBuilder(clientConfig *restclient.Config, coreClient v1core.CoreV1Interface, ns string, expirationSeconds int64, leewayPercent int) ControllerClientBuilder { + builder := &DynamicControllerClientBuilder{ + ClientConfig: clientConfig, + CoreClient: coreClient, + Namespace: ns, + roundTripperFuncMap: map[string]func(http.RoundTripper) http.RoundTripper{}, + expirationSeconds: expirationSeconds, + leewayPercent: leewayPercent, + clock: clock.RealClock{}, + } + return builder +} + +func (t *DynamicControllerClientBuilder) Config(saName string) (*restclient.Config, error) { + _, err := getOrCreateServiceAccount(t.CoreClient, t.Namespace, saName) + if err != nil { + return nil, err + } + + configCopy := constructClient(t.Namespace, saName, t.ClientConfig) + + t.mutex.Lock() + defer t.mutex.Unlock() + + rt, ok := t.roundTripperFuncMap[saName] + if ok { + configCopy.Wrap(rt) + } else { + cachedTokenSource := transport.NewCachedTokenSource(&tokenSourceImpl{ + namespace: t.Namespace, + serviceAccountName: saName, + coreClient: t.CoreClient, + expirationSeconds: t.expirationSeconds, + leewayPercent: t.leewayPercent, + }) + configCopy.Wrap(transport.ResettableTokenSourceWrapTransport(cachedTokenSource)) + t.roundTripperFuncMap[saName] = configCopy.WrapTransport + } + + return &configCopy, nil +} + +func (t *DynamicControllerClientBuilder) ConfigOrDie(name string) *restclient.Config { + clientConfig, err := t.Config(name) + if err != nil { + klog.Fatal(err) + } + return clientConfig +} + +func (t *DynamicControllerClientBuilder) Client(name string) (clientset.Interface, error) { + clientConfig, err := t.Config(name) + if err != nil { + return nil, err + } + return clientset.NewForConfig(clientConfig) +} + +func (t *DynamicControllerClientBuilder) ClientOrDie(name string) clientset.Interface { + client, err := t.Client(name) + if err != nil { + klog.Fatal(err) + } + return client +} + +func (t *DynamicControllerClientBuilder) DiscoveryClient(name string) (discovery.DiscoveryInterface, error) { + clientConfig, err := t.Config(name) + if err != nil { + return nil, err + } + // Discovery makes a lot of requests infrequently. This allows the burst to succeed and refill to happen + // in just a few seconds. + clientConfig.Burst = 200 + clientConfig.QPS = 20 + return clientset.NewForConfig(clientConfig) +} + +func (t *DynamicControllerClientBuilder) DiscoveryClientOrDie(name string) discovery.DiscoveryInterface { + client, err := t.DiscoveryClient(name) + if err != nil { + klog.Fatal(err) + } + return client +} + +type tokenSourceImpl struct { + namespace string + serviceAccountName string + coreClient v1core.CoreV1Interface + expirationSeconds int64 + leewayPercent int +} + +func (ts *tokenSourceImpl) Token() (*oauth2.Token, error) { + var retTokenRequest *v1authenticationapi.TokenRequest + + backoff := wait.Backoff{ + Duration: 500 * time.Millisecond, + Factor: 2, // double the timeout for every failure + Steps: 4, + } + if err := wait.ExponentialBackoff(backoff, func() (bool, error) { + if _, inErr := getOrCreateServiceAccount(ts.coreClient, ts.namespace, ts.serviceAccountName); inErr != nil { + klog.Warningf("get or create service account failed: %v", inErr) + return false, nil + } + + tr, inErr := ts.coreClient.ServiceAccounts(ts.namespace).CreateToken(context.TODO(), ts.serviceAccountName, &v1authenticationapi.TokenRequest{ + Spec: v1authenticationapi.TokenRequestSpec{ + ExpirationSeconds: utilpointer.Int64Ptr(ts.expirationSeconds), + }, + }, metav1.CreateOptions{}) + if inErr != nil { + klog.Warningf("get token failed: %v", inErr) + return false, nil + } + retTokenRequest = tr + return true, nil + }); err != nil { + return nil, fmt.Errorf("failed to get token for %s/%s: %v", ts.namespace, ts.serviceAccountName, err) + } + + if retTokenRequest.Spec.ExpirationSeconds == nil { + return nil, fmt.Errorf("nil pointer of expiration in token request") + } + + lifetime := retTokenRequest.Status.ExpirationTimestamp.Time.Sub(time.Now()) + if lifetime < time.Minute*10 { + // possible clock skew issue, pin to minimum token lifetime + lifetime = time.Minute * 10 + } + + leeway := time.Duration(int64(lifetime) * int64(ts.leewayPercent) / 100) + expiry := time.Now().Add(lifetime).Add(-1 * leeway) + + return &oauth2.Token{ + AccessToken: retTokenRequest.Status.Token, + TokenType: "Bearer", + Expiry: expiry, + }, nil +} + +func constructClient(saNamespace, saName string, config *restclient.Config) restclient.Config { + username := apiserverserviceaccount.MakeUsername(saNamespace, saName) + // make a shallow copy + // the caller already castrated the config during creation + // this allows for potential extensions in the future + // for example it preserve HTTP wrappers for custom behavior per request + ret := *config + restclient.AddUserAgent(&ret, username) + return ret +} + +func getOrCreateServiceAccount(coreClient v1core.CoreV1Interface, namespace, name string) (*v1.ServiceAccount, error) { + sa, err := coreClient.ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + if err == nil { + return sa, nil + } + if !apierrors.IsNotFound(err) { + return nil, err + } + + // Create the namespace if we can't verify it exists. + // Tolerate errors, since we don't know whether this component has namespace creation permissions. + if _, err := coreClient.Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}); apierrors.IsNotFound(err) { + if _, err = coreClient.Namespaces().Create(context.TODO(), &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) { + klog.Warningf("create non-exist namespace %s failed:%v", namespace, err) + } + } + + // Create the service account + sa, err = coreClient.ServiceAccounts(namespace).Create(context.TODO(), &v1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}}, metav1.CreateOptions{}) + if apierrors.IsAlreadyExists(err) { + // If we're racing to init and someone else already created it, re-fetch + return coreClient.ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + } + return sa, err +} diff --git a/vendor/k8s.io/controller-manager/pkg/features/OWNERS b/vendor/k8s.io/controller-manager/pkg/features/OWNERS new file mode 100644 index 000000000..3e1dd9f08 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/features/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - feature-approvers diff --git a/vendor/k8s.io/controller-manager/pkg/features/kube_features.go b/vendor/k8s.io/controller-manager/pkg/features/kube_features.go new file mode 100644 index 000000000..62d44a09e --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/features/kube_features.go @@ -0,0 +1,62 @@ +/* +Copyright 2020 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 features + +import ( + "k8s.io/component-base/featuregate" +) + +const ( + // Every feature gate should add method here following this template: + // + // // owner: @username + // // alpha: v1.4 + // MyFeature featuregate.Feature = "MyFeature" + // + // Feature gates should be listed in alphabetical, case-sensitive + // (upper before any lower case character) order. This reduces the risk + // of code conflicts because changes are more likely to be scattered + // across the file. + + // owner: @jiahuif + // alpha: v1.21 + // beta: v1.22 + // GA: v1.24 + // + // Enables Leader Migration for kube-controller-manager and cloud-controller-manager + // copied and sync'ed from k8s.io/kubernetes/pkg/features/kube_features.go + ControllerManagerLeaderMigration featuregate.Feature = "ControllerManagerLeaderMigration" + + // owner: @khenidak + // alpha: v1.15 + // + // Enables ipv6 dual stack + // Original copy from k8s.io/kubernetes/pkg/features/kube_features.go + IPv6DualStack featuregate.Feature = "IPv6DualStack" +) + +func SetupCurrentKubernetesSpecificFeatureGates(featuregates featuregate.MutableFeatureGate) error { + return featuregates.Add(cloudPublicFeatureGates) +} + +// cloudPublicFeatureGates consists of cloud-specific feature keys. +// To add a new feature, define a key for it at k8s.io/api/pkg/features and add it here. +var cloudPublicFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ + ControllerManagerLeaderMigration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26 + + IPv6DualStack: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, +} diff --git a/vendor/k8s.io/controller-manager/pkg/features/register/register.go b/vendor/k8s.io/controller-manager/pkg/features/register/register.go new file mode 100644 index 000000000..5672dac00 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/features/register/register.go @@ -0,0 +1,27 @@ +/* +Copyright 2020 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 register + +import ( + "k8s.io/apimachinery/pkg/util/runtime" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/controller-manager/pkg/features" +) + +func init() { + runtime.Must(features.SetupCurrentKubernetesSpecificFeatureGates(utilfeature.DefaultMutableFeatureGate)) +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/config/config.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/config.go new file mode 100644 index 000000000..fc8cf1714 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/config.go @@ -0,0 +1,109 @@ +/* +Copyright 2020 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 config + +import ( + "fmt" + "os" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + util "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/validation/field" + internal "k8s.io/controller-manager/config" + "k8s.io/controller-manager/config/v1" + "k8s.io/controller-manager/config/v1alpha1" + "k8s.io/controller-manager/config/v1beta1" +) + +// ResourceLockLeases is the resourceLock value for 'leases' API +const ResourceLockLeases = "leases" + +// ResourceLockEndpoints is the resourceLock value for 'endpoints' API +const ResourceLockEndpoints = "endpoints" + +var cfgScheme = runtime.NewScheme() + +func init() { + // internal + util.Must(internal.AddToScheme(cfgScheme)) + + // v1alpha1 + util.Must(v1alpha1.AddToScheme(cfgScheme)) + util.Must(cfgScheme.SetVersionPriority(v1alpha1.SchemeGroupVersion)) + + // v1beta1 + util.Must(v1beta1.AddToScheme(cfgScheme)) + util.Must(cfgScheme.SetVersionPriority(v1beta1.SchemeGroupVersion)) + + // v1 + util.Must(v1.AddToScheme(cfgScheme)) + util.Must(cfgScheme.SetVersionPriority(v1.SchemeGroupVersion)) +} + +// ReadLeaderMigrationConfiguration reads LeaderMigrationConfiguration from a YAML file at the given path. +// The parsed LeaderMigrationConfiguration may be invalid. +// It returns an error if the file did not exist. +func ReadLeaderMigrationConfiguration(configFilePath string) (*internal.LeaderMigrationConfiguration, error) { + data, err := os.ReadFile(configFilePath) + if err != nil { + return nil, fmt.Errorf("unable to read leader migration configuration from %q: %w", configFilePath, err) + } + config, gvk, err := serializer.NewCodecFactory(cfgScheme).UniversalDecoder().Decode(data, nil, nil) + if err != nil { + return nil, err + } + internalConfig, ok := config.(*internal.LeaderMigrationConfiguration) + if !ok { + return nil, fmt.Errorf("unexpected config type: %v", gvk) + } + return internalConfig, nil +} + +// ValidateLeaderMigrationConfiguration validates the LeaderMigrationConfiguration against common errors. +// It checks required names and whether resourceLock is either 'leases' or 'endpoints'. +// It will return nil if it does not find anything wrong. +func ValidateLeaderMigrationConfiguration(config *internal.LeaderMigrationConfiguration) (allErrs field.ErrorList) { + if config.LeaderName == "" { + allErrs = append(allErrs, field.Required(field.NewPath("leaderName"), + "leaderName must be set for LeaderMigrationConfiguration")) + } + if config.ResourceLock != ResourceLockLeases && config.ResourceLock != ResourceLockEndpoints { + allErrs = append(allErrs, field.Invalid(field.NewPath("resourceLock"), config.ResourceLock, + "resource Lock must be one of 'leases' or 'endpoints'")) + } + // validate controllerLeaders + fldPath := field.NewPath("controllerLeaders") + for i, controllerLeader := range config.ControllerLeaders { + path := fldPath.Index(i) + allErrs = append(allErrs, validateControllerLeaderConfiguration(path, &controllerLeader)...) + } + return +} + +func validateControllerLeaderConfiguration(path *field.Path, config *internal.ControllerLeaderConfiguration) (allErrs field.ErrorList) { + if config == nil { + return + } + if config.Component == "" { + allErrs = append(allErrs, field.Required(path.Child("component"), "component must be set")) + } + if config.Name == "" { + allErrs = append(allErrs, field.Required(path.Child("name"), "name must be set")) + } + return +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go new file mode 100644 index 000000000..de8a2c9e0 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go @@ -0,0 +1,41 @@ +/* +Copyright 2021 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 config + +import internal "k8s.io/controller-manager/config" + +// DefaultLeaderMigrationConfiguration returns the default LeaderMigrationConfiguration +// +// that is valid for this release of Kubernetes. +func DefaultLeaderMigrationConfiguration() *internal.LeaderMigrationConfiguration { + return &internal.LeaderMigrationConfiguration{ + LeaderName: "cloud-provider-extraction-migration", + ResourceLock: ResourceLockLeases, + ControllerLeaders: []internal.ControllerLeaderConfiguration{ + { + Name: "route", + Component: "*", + }, { + Name: "service", + Component: "*", + }, { + Name: "cloud-node-lifecycle", + Component: "*", + }, + }, + } +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/feature.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/feature.go new file mode 100644 index 000000000..fec07edb1 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/feature.go @@ -0,0 +1,28 @@ +/* +Copyright 2021 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 leadermigration + +import ( + "k8s.io/apiserver/pkg/util/feature" + "k8s.io/controller-manager/pkg/features" + _ "k8s.io/controller-manager/pkg/features/register" +) + +// FeatureEnabled tells if leader migration is enabled through the feature gate. +func FeatureEnabled() bool { + return feature.DefaultMutableFeatureGate.Enabled(features.ControllerManagerLeaderMigration) +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/filter.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/filter.go new file mode 100644 index 000000000..a3e8f2187 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/filter.go @@ -0,0 +1,35 @@ +/* +Copyright 2021 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 leadermigration + +// FilterResult indicates whether and how the controller manager should start the controller. +type FilterResult int32 + +const ( + // ControllerUnowned indicates that the controller is owned by another controller manager + // and thus should NOT be started by this controller manager. + ControllerUnowned = iota + // ControllerMigrated indicates that the controller manager should start this controller + // with the migration lock. + ControllerMigrated + // ControllerNonMigrated indicates that the controller manager should start this controller + // with the main lock. + ControllerNonMigrated +) + +// FilterFunc takes a name of controller, returning a FilterResult indicating how to start controller. +type FilterFunc func(controllerName string) FilterResult diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/migrator.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/migrator.go new file mode 100644 index 000000000..fdd74a46a --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/migrator.go @@ -0,0 +1,62 @@ +/* +Copyright 2021 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 leadermigration + +import ( + internal "k8s.io/controller-manager/config" +) + +// LeaderMigrator holds information required by the leader migration process. +type LeaderMigrator struct { + // MigrationReady is closed after the controller manager finishes preparing for the migration lock. + // After this point, the leader migration process will proceed to acquire the migration lock. + MigrationReady chan struct{} + + // FilterFunc returns a FilterResult telling the controller manager what to do with the controller. + FilterFunc FilterFunc +} + +// NewLeaderMigrator creates a LeaderMigrator with given config for the given component. component +// +// indicates which controller manager is requesting this leader migration, and it should be consistent +// with the component field of ControllerLeaderConfiguration. +func NewLeaderMigrator(config *internal.LeaderMigrationConfiguration, component string) *LeaderMigrator { + migratedControllers := make(map[string]bool) + for _, leader := range config.ControllerLeaders { + migratedControllers[leader.Name] = leader.Component == component || leader.Component == "*" + } + return &LeaderMigrator{ + MigrationReady: make(chan struct{}), + FilterFunc: func(controllerName string) FilterResult { + shouldRun, ok := migratedControllers[controllerName] + if ok { + // The controller is included in the migration + if shouldRun { + // If the controller manager should run the controller, + // start it in the migration lock. + return ControllerMigrated + } + // Otherwise, the controller should be started by + // some other controller manager. + return ControllerUnowned + } + // The controller is not included in the migration, + // and should be started in the main lock. + return ControllerNonMigrated + }, + } +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go new file mode 100644 index 000000000..5bd078ec7 --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go @@ -0,0 +1,89 @@ +/* +Copyright 2021 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 options + +import ( + "fmt" + + "github.com/spf13/pflag" + "k8s.io/controller-manager/config" + "k8s.io/controller-manager/pkg/leadermigration" + migrationconfig "k8s.io/controller-manager/pkg/leadermigration/config" +) + +// LeaderMigrationOptions is the set of options for Leader Migration, +// which is given to the controller manager through flags +type LeaderMigrationOptions struct { + // Enabled indicates whether leader migration is enabled through the --enabled-leader-migration flag. + Enabled bool + + // ControllerMigrationConfig is the path to the file of LeaderMigrationConfiguration type. + // It can be set with --leader-migration-config flag + // If the path is "" (default vaule), the default vaule will be used. + ControllerMigrationConfig string +} + +// DefaultLeaderMigrationOptions returns a LeaderMigrationOptions with default values. +func DefaultLeaderMigrationOptions() *LeaderMigrationOptions { + return &LeaderMigrationOptions{ + Enabled: false, + ControllerMigrationConfig: "", + } +} + +// AddFlags adds all flags related to leader migration to given flag set. +func (o *LeaderMigrationOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + fs.BoolVar(&o.Enabled, "enable-leader-migration", false, "Whether to enable controller leader migration.") + fs.StringVar(&o.ControllerMigrationConfig, "leader-migration-config", "", + "Path to the config file for controller leader migration, "+ + "or empty to use the value that reflects default configuration of the controller manager. "+ + "The config file should be of type LeaderMigrationConfiguration, group controllermanager.config.k8s.io, version v1alpha1.") +} + +// ApplyTo applies the options of leader migration to generic configuration. +func (o *LeaderMigrationOptions) ApplyTo(cfg *config.GenericControllerManagerConfiguration) error { + if o == nil { + // an nil LeaderMigrationOptions indicates that default options should be used + // in which case leader migration will be disabled + cfg.LeaderMigrationEnabled = false + return nil + } + if o.Enabled && !leadermigration.FeatureEnabled() { + return fmt.Errorf("Leader Migration is not enabled through feature gate") + } + cfg.LeaderMigrationEnabled = o.Enabled + if !cfg.LeaderMigrationEnabled { + return nil + } + if o.ControllerMigrationConfig == "" { + cfg.LeaderMigration = *migrationconfig.DefaultLeaderMigrationConfiguration() + return nil + } + leaderMigrationConfig, err := migrationconfig.ReadLeaderMigrationConfiguration(o.ControllerMigrationConfig) + if err != nil { + return err + } + errs := migrationconfig.ValidateLeaderMigrationConfiguration(leaderMigrationConfig) + if len(errs) != 0 { + return fmt.Errorf("failed to parse leader migration configuration: %v", errs) + } + cfg.LeaderMigration = *leaderMigrationConfig + return nil +} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/util.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/util.go new file mode 100644 index 000000000..83eacc0df --- /dev/null +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/util.go @@ -0,0 +1,25 @@ +/* +Copyright 2021 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 leadermigration + +import config "k8s.io/controller-manager/config" + +// Enabled checks whether Leader Migration should be enabled, given the GenericControllerManagerConfiguration. +// It considers the feature gate first, and will always return false if the feature gate is not enabled. +func Enabled(genericConfig *config.GenericControllerManagerConfiguration) bool { + return FeatureEnabled() && genericConfig.LeaderElection.LeaderElect && genericConfig.LeaderMigrationEnabled +} diff --git a/vendor/k8s.io/kms/LICENSE b/vendor/k8s.io/kms/LICENSE new file mode 100644 index 000000000..8dada3eda --- /dev/null +++ b/vendor/k8s.io/kms/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/vendor/k8s.io/kms/apis/v1beta1/api.pb.go b/vendor/k8s.io/kms/apis/v1beta1/api.pb.go new file mode 100644 index 000000000..6210014a2 --- /dev/null +++ b/vendor/k8s.io/kms/apis/v1beta1/api.pb.go @@ -0,0 +1,502 @@ +/* +Copyright 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. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: api.proto + +package v1beta1 + +import ( + context "context" + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type VersionRequest struct { + // Version of the KMS plugin API. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VersionRequest) Reset() { *m = VersionRequest{} } +func (m *VersionRequest) String() string { return proto.CompactTextString(m) } +func (*VersionRequest) ProtoMessage() {} +func (*VersionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{0} +} +func (m *VersionRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VersionRequest.Unmarshal(m, b) +} +func (m *VersionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VersionRequest.Marshal(b, m, deterministic) +} +func (m *VersionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VersionRequest.Merge(m, src) +} +func (m *VersionRequest) XXX_Size() int { + return xxx_messageInfo_VersionRequest.Size(m) +} +func (m *VersionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_VersionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_VersionRequest proto.InternalMessageInfo + +func (m *VersionRequest) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +type VersionResponse struct { + // Version of the KMS plugin API. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // Name of the KMS provider. + RuntimeName string `protobuf:"bytes,2,opt,name=runtime_name,json=runtimeName,proto3" json:"runtime_name,omitempty"` + // Version of the KMS provider. The string must be semver-compatible. + RuntimeVersion string `protobuf:"bytes,3,opt,name=runtime_version,json=runtimeVersion,proto3" json:"runtime_version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VersionResponse) Reset() { *m = VersionResponse{} } +func (m *VersionResponse) String() string { return proto.CompactTextString(m) } +func (*VersionResponse) ProtoMessage() {} +func (*VersionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{1} +} +func (m *VersionResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VersionResponse.Unmarshal(m, b) +} +func (m *VersionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VersionResponse.Marshal(b, m, deterministic) +} +func (m *VersionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VersionResponse.Merge(m, src) +} +func (m *VersionResponse) XXX_Size() int { + return xxx_messageInfo_VersionResponse.Size(m) +} +func (m *VersionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_VersionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_VersionResponse proto.InternalMessageInfo + +func (m *VersionResponse) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *VersionResponse) GetRuntimeName() string { + if m != nil { + return m.RuntimeName + } + return "" +} + +func (m *VersionResponse) GetRuntimeVersion() string { + if m != nil { + return m.RuntimeVersion + } + return "" +} + +type DecryptRequest struct { + // Version of the KMS plugin API. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // The data to be decrypted. + Cipher []byte `protobuf:"bytes,2,opt,name=cipher,proto3" json:"cipher,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DecryptRequest) Reset() { *m = DecryptRequest{} } +func (m *DecryptRequest) String() string { return proto.CompactTextString(m) } +func (*DecryptRequest) ProtoMessage() {} +func (*DecryptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{2} +} +func (m *DecryptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DecryptRequest.Unmarshal(m, b) +} +func (m *DecryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DecryptRequest.Marshal(b, m, deterministic) +} +func (m *DecryptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecryptRequest.Merge(m, src) +} +func (m *DecryptRequest) XXX_Size() int { + return xxx_messageInfo_DecryptRequest.Size(m) +} +func (m *DecryptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DecryptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DecryptRequest proto.InternalMessageInfo + +func (m *DecryptRequest) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *DecryptRequest) GetCipher() []byte { + if m != nil { + return m.Cipher + } + return nil +} + +type DecryptResponse struct { + // The decrypted data. + Plain []byte `protobuf:"bytes,1,opt,name=plain,proto3" json:"plain,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DecryptResponse) Reset() { *m = DecryptResponse{} } +func (m *DecryptResponse) String() string { return proto.CompactTextString(m) } +func (*DecryptResponse) ProtoMessage() {} +func (*DecryptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{3} +} +func (m *DecryptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DecryptResponse.Unmarshal(m, b) +} +func (m *DecryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DecryptResponse.Marshal(b, m, deterministic) +} +func (m *DecryptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecryptResponse.Merge(m, src) +} +func (m *DecryptResponse) XXX_Size() int { + return xxx_messageInfo_DecryptResponse.Size(m) +} +func (m *DecryptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DecryptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DecryptResponse proto.InternalMessageInfo + +func (m *DecryptResponse) GetPlain() []byte { + if m != nil { + return m.Plain + } + return nil +} + +type EncryptRequest struct { + // Version of the KMS plugin API. + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // The data to be encrypted. + Plain []byte `protobuf:"bytes,2,opt,name=plain,proto3" json:"plain,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptRequest) Reset() { *m = EncryptRequest{} } +func (m *EncryptRequest) String() string { return proto.CompactTextString(m) } +func (*EncryptRequest) ProtoMessage() {} +func (*EncryptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{4} +} +func (m *EncryptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptRequest.Unmarshal(m, b) +} +func (m *EncryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptRequest.Marshal(b, m, deterministic) +} +func (m *EncryptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptRequest.Merge(m, src) +} +func (m *EncryptRequest) XXX_Size() int { + return xxx_messageInfo_EncryptRequest.Size(m) +} +func (m *EncryptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptRequest proto.InternalMessageInfo + +func (m *EncryptRequest) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *EncryptRequest) GetPlain() []byte { + if m != nil { + return m.Plain + } + return nil +} + +type EncryptResponse struct { + // The encrypted data. + Cipher []byte `protobuf:"bytes,1,opt,name=cipher,proto3" json:"cipher,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptResponse) Reset() { *m = EncryptResponse{} } +func (m *EncryptResponse) String() string { return proto.CompactTextString(m) } +func (*EncryptResponse) ProtoMessage() {} +func (*EncryptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{5} +} +func (m *EncryptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptResponse.Unmarshal(m, b) +} +func (m *EncryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptResponse.Marshal(b, m, deterministic) +} +func (m *EncryptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptResponse.Merge(m, src) +} +func (m *EncryptResponse) XXX_Size() int { + return xxx_messageInfo_EncryptResponse.Size(m) +} +func (m *EncryptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptResponse proto.InternalMessageInfo + +func (m *EncryptResponse) GetCipher() []byte { + if m != nil { + return m.Cipher + } + return nil +} + +func init() { + proto.RegisterType((*VersionRequest)(nil), "v1beta1.VersionRequest") + proto.RegisterType((*VersionResponse)(nil), "v1beta1.VersionResponse") + proto.RegisterType((*DecryptRequest)(nil), "v1beta1.DecryptRequest") + proto.RegisterType((*DecryptResponse)(nil), "v1beta1.DecryptResponse") + proto.RegisterType((*EncryptRequest)(nil), "v1beta1.EncryptRequest") + proto.RegisterType((*EncryptResponse)(nil), "v1beta1.EncryptResponse") +} + +func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } + +var fileDescriptor_00212fb1f9d3bf1c = []byte{ + // 286 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4f, 0x4b, 0xc3, 0x30, + 0x14, 0x5f, 0x27, 0xae, 0xec, 0x59, 0x5a, 0x08, 0x43, 0x8b, 0x27, 0xcd, 0x65, 0xea, 0xa1, 0x30, + 0xbd, 0x8b, 0x88, 0x9e, 0x44, 0x0f, 0x15, 0xbc, 0x4a, 0x56, 0x1e, 0x1a, 0xb0, 0x69, 0x4c, 0xb3, + 0xca, 0xbe, 0xa8, 0x9f, 0x47, 0x6c, 0x5e, 0x6b, 0x3a, 0x11, 0x77, 0x7c, 0x2f, 0xef, 0xf7, 0xef, + 0xbd, 0xc0, 0x54, 0x68, 0x99, 0x69, 0x53, 0xd9, 0x8a, 0x85, 0xcd, 0x62, 0x89, 0x56, 0x2c, 0xf8, + 0x19, 0xc4, 0x4f, 0x68, 0x6a, 0x59, 0xa9, 0x1c, 0xdf, 0x57, 0x58, 0x5b, 0x96, 0x42, 0xd8, 0xb8, + 0x4e, 0x1a, 0x1c, 0x05, 0x27, 0xd3, 0xbc, 0x2b, 0xf9, 0x07, 0x24, 0xfd, 0x6c, 0xad, 0x2b, 0x55, + 0xe3, 0xdf, 0xc3, 0xec, 0x18, 0x22, 0xb3, 0x52, 0x56, 0x96, 0xf8, 0xac, 0x44, 0x89, 0xe9, 0xb8, + 0x7d, 0xde, 0xa3, 0xde, 0x83, 0x28, 0x91, 0xcd, 0x21, 0xe9, 0x46, 0x3a, 0x92, 0x9d, 0x76, 0x2a, + 0xa6, 0x36, 0xa9, 0xf1, 0x6b, 0x88, 0x6f, 0xb0, 0x30, 0x6b, 0x6d, 0xff, 0x35, 0xc9, 0xf6, 0x61, + 0x52, 0x48, 0xfd, 0x8a, 0xa6, 0x55, 0x8c, 0x72, 0xaa, 0xf8, 0x1c, 0x92, 0x9e, 0x83, 0xcc, 0xcf, + 0x60, 0x57, 0xbf, 0x09, 0xe9, 0x28, 0xa2, 0xdc, 0x15, 0xfc, 0x0a, 0xe2, 0x5b, 0xb5, 0xa5, 0x58, + 0xcf, 0x30, 0xf6, 0x19, 0x4e, 0x21, 0xe9, 0x19, 0x48, 0xea, 0xc7, 0x55, 0xe0, 0xbb, 0x3a, 0xff, + 0x0c, 0x60, 0x76, 0x87, 0xeb, 0x7b, 0xa1, 0xc4, 0x0b, 0x96, 0xa8, 0xec, 0x23, 0x9a, 0x46, 0x16, + 0xc8, 0x2e, 0x21, 0xa4, 0xf4, 0xec, 0x20, 0xa3, 0x63, 0x65, 0xc3, 0x4b, 0x1d, 0xa6, 0xbf, 0x1f, + 0x9c, 0x1c, 0x1f, 0x7d, 0xe3, 0x29, 0xae, 0x87, 0x1f, 0x2e, 0xd1, 0xc3, 0x6f, 0x6c, 0xc6, 0xe1, + 0x29, 0x83, 0x87, 0x1f, 0xee, 0xc5, 0xc3, 0x6f, 0xc4, 0xe5, 0xa3, 0xe5, 0xa4, 0xfd, 0x67, 0x17, + 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x57, 0xc8, 0x65, 0x5a, 0x74, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// KeyManagementServiceClient is the client API for KeyManagementService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type KeyManagementServiceClient interface { + // Version returns the runtime name and runtime version of the KMS provider. + Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) + // Execute decryption operation in KMS provider. + Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) + // Execute encryption operation in KMS provider. + Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) +} + +type keyManagementServiceClient struct { + cc *grpc.ClientConn +} + +func NewKeyManagementServiceClient(cc *grpc.ClientConn) KeyManagementServiceClient { + return &keyManagementServiceClient{cc} +} + +func (c *keyManagementServiceClient) Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) { + out := new(VersionResponse) + err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Version", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) { + out := new(DecryptResponse) + err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Decrypt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keyManagementServiceClient) Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) { + out := new(EncryptResponse) + err := c.cc.Invoke(ctx, "/v1beta1.KeyManagementService/Encrypt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// KeyManagementServiceServer is the server API for KeyManagementService service. +type KeyManagementServiceServer interface { + // Version returns the runtime name and runtime version of the KMS provider. + Version(context.Context, *VersionRequest) (*VersionResponse, error) + // Execute decryption operation in KMS provider. + Decrypt(context.Context, *DecryptRequest) (*DecryptResponse, error) + // Execute encryption operation in KMS provider. + Encrypt(context.Context, *EncryptRequest) (*EncryptResponse, error) +} + +// UnimplementedKeyManagementServiceServer can be embedded to have forward compatible implementations. +type UnimplementedKeyManagementServiceServer struct { +} + +func (*UnimplementedKeyManagementServiceServer) Version(ctx context.Context, req *VersionRequest) (*VersionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") +} +func (*UnimplementedKeyManagementServiceServer) Decrypt(ctx context.Context, req *DecryptRequest) (*DecryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Decrypt not implemented") +} +func (*UnimplementedKeyManagementServiceServer) Encrypt(ctx context.Context, req *EncryptRequest) (*EncryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Encrypt not implemented") +} + +func RegisterKeyManagementServiceServer(s *grpc.Server, srv KeyManagementServiceServer) { + s.RegisterService(&_KeyManagementService_serviceDesc, srv) +} + +func _KeyManagementService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VersionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Version(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1beta1.KeyManagementService/Version", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Version(ctx, req.(*VersionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _KeyManagementService_Decrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DecryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Decrypt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1beta1.KeyManagementService/Decrypt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Decrypt(ctx, req.(*DecryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EncryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Encrypt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v1beta1.KeyManagementService/Encrypt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Encrypt(ctx, req.(*EncryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _KeyManagementService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "v1beta1.KeyManagementService", + HandlerType: (*KeyManagementServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Version", + Handler: _KeyManagementService_Version_Handler, + }, + { + MethodName: "Decrypt", + Handler: _KeyManagementService_Decrypt_Handler, + }, + { + MethodName: "Encrypt", + Handler: _KeyManagementService_Encrypt_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api.proto", +} diff --git a/vendor/k8s.io/kms/apis/v1beta1/api.proto b/vendor/k8s.io/kms/apis/v1beta1/api.proto new file mode 100644 index 000000000..a9b44bf5f --- /dev/null +++ b/vendor/k8s.io/kms/apis/v1beta1/api.proto @@ -0,0 +1,70 @@ +/* +Copyright 2018 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. +*/ + +// To regenerate api.pb.go run hack/update-generated-kms.sh +syntax = "proto3"; + +package v1beta1; + +// This service defines the public APIs for remote KMS provider. +service KeyManagementService { + // Version returns the runtime name and runtime version of the KMS provider. + rpc Version(VersionRequest) returns (VersionResponse) {} + + // Execute decryption operation in KMS provider. + rpc Decrypt(DecryptRequest) returns (DecryptResponse) {} + // Execute encryption operation in KMS provider. + rpc Encrypt(EncryptRequest) returns (EncryptResponse) {} +} + +message VersionRequest { + // Version of the KMS plugin API. + string version = 1; +} + +message VersionResponse { + // Version of the KMS plugin API. + string version = 1; + // Name of the KMS provider. + string runtime_name = 2; + // Version of the KMS provider. The string must be semver-compatible. + string runtime_version = 3; +} + +message DecryptRequest { + // Version of the KMS plugin API. + string version = 1; + // The data to be decrypted. + bytes cipher = 2; +} + +message DecryptResponse { + // The decrypted data. + bytes plain = 1; +} + +message EncryptRequest { + // Version of the KMS plugin API. + string version = 1; + // The data to be encrypted. + bytes plain = 2; +} + +message EncryptResponse { + // The encrypted data. + bytes cipher = 1; +} + diff --git a/vendor/k8s.io/kms/apis/v1beta1/v1beta1.go b/vendor/k8s.io/kms/apis/v1beta1/v1beta1.go new file mode 100644 index 000000000..842d0a2fd --- /dev/null +++ b/vendor/k8s.io/kms/apis/v1beta1/v1beta1.go @@ -0,0 +1,23 @@ +/* +Copyright 2019 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 v1beta1 contains definition of kms-plugin's gRPC service. +package v1beta1 + +// IsVersionCheckMethod determines whether the supplied method is a version check against kms-plugin. +func IsVersionCheckMethod(method string) bool { + return method == "/v1beta1.KeyManagementService/Version" +} diff --git a/vendor/k8s.io/kms/apis/v2alpha1/api.pb.go b/vendor/k8s.io/kms/apis/v2alpha1/api.pb.go new file mode 100644 index 000000000..ab55bd1b3 --- /dev/null +++ b/vendor/k8s.io/kms/apis/v2alpha1/api.pb.go @@ -0,0 +1,542 @@ +/* +Copyright 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. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: api.proto + +package v2alpha1 + +import ( + context "context" + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type StatusRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StatusRequest) Reset() { *m = StatusRequest{} } +func (m *StatusRequest) String() string { return proto.CompactTextString(m) } +func (*StatusRequest) ProtoMessage() {} +func (*StatusRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{0} +} +func (m *StatusRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StatusRequest.Unmarshal(m, b) +} +func (m *StatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StatusRequest.Marshal(b, m, deterministic) +} +func (m *StatusRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatusRequest.Merge(m, src) +} +func (m *StatusRequest) XXX_Size() int { + return xxx_messageInfo_StatusRequest.Size(m) +} +func (m *StatusRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StatusRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StatusRequest proto.InternalMessageInfo + +type StatusResponse struct { + // Version of the KMS plugin API. Must match the configured .resources[].providers[].kms.apiVersion + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // Any value other than "ok" is failing healthz. On failure, the associated API server healthz endpoint will contain this value as part of the error message. + Healthz string `protobuf:"bytes,2,opt,name=healthz,proto3" json:"healthz,omitempty"` + // the current write key, used to determine staleness of data updated via value.Transformer.TransformFromStorage. + KeyId string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StatusResponse) Reset() { *m = StatusResponse{} } +func (m *StatusResponse) String() string { return proto.CompactTextString(m) } +func (*StatusResponse) ProtoMessage() {} +func (*StatusResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{1} +} +func (m *StatusResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StatusResponse.Unmarshal(m, b) +} +func (m *StatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StatusResponse.Marshal(b, m, deterministic) +} +func (m *StatusResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatusResponse.Merge(m, src) +} +func (m *StatusResponse) XXX_Size() int { + return xxx_messageInfo_StatusResponse.Size(m) +} +func (m *StatusResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StatusResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StatusResponse proto.InternalMessageInfo + +func (m *StatusResponse) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *StatusResponse) GetHealthz() string { + if m != nil { + return m.Healthz + } + return "" +} + +func (m *StatusResponse) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +type DecryptRequest struct { + // The data to be decrypted. + Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"` + // UID is a unique identifier for the request. + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + // The keyID that was provided to the apiserver during encryption. + // This represents the KMS KEK that was used to encrypt the data. + KeyId string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + // Additional metadata that was sent by the KMS plugin during encryption. + Annotations map[string][]byte `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DecryptRequest) Reset() { *m = DecryptRequest{} } +func (m *DecryptRequest) String() string { return proto.CompactTextString(m) } +func (*DecryptRequest) ProtoMessage() {} +func (*DecryptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{2} +} +func (m *DecryptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DecryptRequest.Unmarshal(m, b) +} +func (m *DecryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DecryptRequest.Marshal(b, m, deterministic) +} +func (m *DecryptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecryptRequest.Merge(m, src) +} +func (m *DecryptRequest) XXX_Size() int { + return xxx_messageInfo_DecryptRequest.Size(m) +} +func (m *DecryptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DecryptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DecryptRequest proto.InternalMessageInfo + +func (m *DecryptRequest) GetCiphertext() []byte { + if m != nil { + return m.Ciphertext + } + return nil +} + +func (m *DecryptRequest) GetUid() string { + if m != nil { + return m.Uid + } + return "" +} + +func (m *DecryptRequest) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +func (m *DecryptRequest) GetAnnotations() map[string][]byte { + if m != nil { + return m.Annotations + } + return nil +} + +type DecryptResponse struct { + // The decrypted data. + Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DecryptResponse) Reset() { *m = DecryptResponse{} } +func (m *DecryptResponse) String() string { return proto.CompactTextString(m) } +func (*DecryptResponse) ProtoMessage() {} +func (*DecryptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{3} +} +func (m *DecryptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DecryptResponse.Unmarshal(m, b) +} +func (m *DecryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DecryptResponse.Marshal(b, m, deterministic) +} +func (m *DecryptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DecryptResponse.Merge(m, src) +} +func (m *DecryptResponse) XXX_Size() int { + return xxx_messageInfo_DecryptResponse.Size(m) +} +func (m *DecryptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DecryptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DecryptResponse proto.InternalMessageInfo + +func (m *DecryptResponse) GetPlaintext() []byte { + if m != nil { + return m.Plaintext + } + return nil +} + +type EncryptRequest struct { + // The data to be encrypted. + Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"` + // UID is a unique identifier for the request. + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptRequest) Reset() { *m = EncryptRequest{} } +func (m *EncryptRequest) String() string { return proto.CompactTextString(m) } +func (*EncryptRequest) ProtoMessage() {} +func (*EncryptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{4} +} +func (m *EncryptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptRequest.Unmarshal(m, b) +} +func (m *EncryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptRequest.Marshal(b, m, deterministic) +} +func (m *EncryptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptRequest.Merge(m, src) +} +func (m *EncryptRequest) XXX_Size() int { + return xxx_messageInfo_EncryptRequest.Size(m) +} +func (m *EncryptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptRequest proto.InternalMessageInfo + +func (m *EncryptRequest) GetPlaintext() []byte { + if m != nil { + return m.Plaintext + } + return nil +} + +func (m *EncryptRequest) GetUid() string { + if m != nil { + return m.Uid + } + return "" +} + +type EncryptResponse struct { + // The encrypted data. + Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"` + // The KMS key ID used to encrypt the data. This must always refer to the KMS KEK and not any local KEKs that may be in use. + // This can be used to inform staleness of data updated via value.Transformer.TransformFromStorage. + KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` + // Additional metadata to be stored with the encrypted data. + // This metadata can contain the encrypted local KEK that was used to encrypt the DEK. + // This data is stored in plaintext in etcd. KMS plugin implementations are responsible for pre-encrypting any sensitive data. + Annotations map[string][]byte `protobuf:"bytes,3,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptResponse) Reset() { *m = EncryptResponse{} } +func (m *EncryptResponse) String() string { return proto.CompactTextString(m) } +func (*EncryptResponse) ProtoMessage() {} +func (*EncryptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00212fb1f9d3bf1c, []int{5} +} +func (m *EncryptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EncryptResponse.Unmarshal(m, b) +} +func (m *EncryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EncryptResponse.Marshal(b, m, deterministic) +} +func (m *EncryptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptResponse.Merge(m, src) +} +func (m *EncryptResponse) XXX_Size() int { + return xxx_messageInfo_EncryptResponse.Size(m) +} +func (m *EncryptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptResponse proto.InternalMessageInfo + +func (m *EncryptResponse) GetCiphertext() []byte { + if m != nil { + return m.Ciphertext + } + return nil +} + +func (m *EncryptResponse) GetKeyId() string { + if m != nil { + return m.KeyId + } + return "" +} + +func (m *EncryptResponse) GetAnnotations() map[string][]byte { + if m != nil { + return m.Annotations + } + return nil +} + +func init() { + proto.RegisterType((*StatusRequest)(nil), "v2alpha1.StatusRequest") + proto.RegisterType((*StatusResponse)(nil), "v2alpha1.StatusResponse") + proto.RegisterType((*DecryptRequest)(nil), "v2alpha1.DecryptRequest") + proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.DecryptRequest.AnnotationsEntry") + proto.RegisterType((*DecryptResponse)(nil), "v2alpha1.DecryptResponse") + proto.RegisterType((*EncryptRequest)(nil), "v2alpha1.EncryptRequest") + proto.RegisterType((*EncryptResponse)(nil), "v2alpha1.EncryptResponse") + proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.EncryptResponse.AnnotationsEntry") +} + +func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } + +var fileDescriptor_00212fb1f9d3bf1c = []byte{ + // 391 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xcf, 0x4f, 0xe2, 0x40, + 0x14, 0xc7, 0x29, 0x5d, 0x60, 0x79, 0xb0, 0x40, 0x26, 0x6c, 0xb6, 0x4b, 0x36, 0x1b, 0x32, 0x27, + 0x76, 0x0f, 0xdd, 0x2c, 0x5e, 0x8c, 0x89, 0x06, 0x13, 0x39, 0x18, 0xf4, 0x52, 0x8e, 0x1e, 0xcc, + 0x08, 0x2f, 0x76, 0x42, 0x9d, 0xd6, 0x76, 0xda, 0x58, 0xff, 0x50, 0x13, 0xff, 0x01, 0xff, 0x0e, + 0xd3, 0x76, 0xa0, 0x2d, 0x88, 0x9e, 0xbc, 0xcd, 0xfb, 0xd1, 0xef, 0xf7, 0xcd, 0x67, 0x5e, 0xa1, + 0xc9, 0x3c, 0x6e, 0x7a, 0xbe, 0x2b, 0x5d, 0xf2, 0x35, 0x1a, 0x33, 0xc7, 0xb3, 0xd9, 0x7f, 0xda, + 0x85, 0x6f, 0x73, 0xc9, 0x64, 0x18, 0x58, 0x78, 0x1f, 0x62, 0x20, 0xe9, 0x15, 0x74, 0xd6, 0x89, + 0xc0, 0x73, 0x45, 0x80, 0xc4, 0x80, 0x46, 0x84, 0x7e, 0xc0, 0x5d, 0x61, 0x68, 0x43, 0x6d, 0xd4, + 0xb4, 0xd6, 0x61, 0x52, 0xb1, 0x91, 0x39, 0xd2, 0x7e, 0x34, 0xaa, 0x59, 0x45, 0x85, 0xe4, 0x3b, + 0xd4, 0x57, 0x18, 0x5f, 0xf3, 0xa5, 0xa1, 0xa7, 0x85, 0xda, 0x0a, 0xe3, 0xf3, 0x25, 0x7d, 0xd1, + 0xa0, 0x73, 0x86, 0x0b, 0x3f, 0xf6, 0xa4, 0xf2, 0x23, 0xbf, 0x01, 0x16, 0xdc, 0xb3, 0xd1, 0x97, + 0xf8, 0x20, 0x53, 0x83, 0xb6, 0x55, 0xc8, 0x90, 0x1e, 0xe8, 0x21, 0x5f, 0x2a, 0xfd, 0xe4, 0xb8, + 0x47, 0x9b, 0xcc, 0xa0, 0xc5, 0x84, 0x70, 0x25, 0x93, 0xdc, 0x15, 0x81, 0xf1, 0x65, 0xa8, 0x8f, + 0x5a, 0xe3, 0x3f, 0xe6, 0xfa, 0xa6, 0x66, 0xd9, 0xd7, 0x3c, 0xcd, 0x7b, 0xa7, 0x42, 0xfa, 0xb1, + 0x55, 0xfc, 0x7a, 0x70, 0x02, 0xbd, 0xed, 0x86, 0x64, 0x92, 0x15, 0xc6, 0x8a, 0x41, 0x72, 0x24, + 0x7d, 0xa8, 0x45, 0xcc, 0x09, 0x31, 0x9d, 0xae, 0x6d, 0x65, 0xc1, 0x51, 0xf5, 0x50, 0xa3, 0xff, + 0xa0, 0xbb, 0xf1, 0x53, 0x18, 0x7f, 0x41, 0xd3, 0x73, 0x18, 0x17, 0x85, 0x7b, 0xe6, 0x09, 0x3a, + 0x81, 0xce, 0x54, 0x94, 0xc0, 0xbc, 0xdb, 0xbf, 0x8b, 0x85, 0x3e, 0x69, 0xd0, 0xdd, 0x48, 0x28, + 0xcf, 0x8f, 0xe0, 0xe6, 0x28, 0xab, 0x45, 0x94, 0x17, 0x65, 0x94, 0x7a, 0x8a, 0xf2, 0x6f, 0x8e, + 0x72, 0xcb, 0xe6, 0x73, 0x59, 0x8e, 0x9f, 0x35, 0xe8, 0xcf, 0x30, 0xbe, 0x64, 0x82, 0xdd, 0xe2, + 0x1d, 0x0a, 0x39, 0x47, 0x3f, 0xe2, 0x0b, 0x24, 0xc7, 0x50, 0xcf, 0x56, 0x95, 0xfc, 0xc8, 0x67, + 0x2b, 0x6d, 0xf3, 0xc0, 0xd8, 0x2d, 0x64, 0x33, 0xd3, 0x0a, 0x99, 0x40, 0x43, 0xbd, 0x11, 0x31, + 0xf6, 0xad, 0xc9, 0xe0, 0xe7, 0x1b, 0x95, 0xa2, 0x82, 0x42, 0x51, 0x54, 0x28, 0xbf, 0x63, 0x51, + 0x61, 0x8b, 0x1b, 0xad, 0xdc, 0xd4, 0xd3, 0xff, 0xf1, 0xe0, 0x35, 0x00, 0x00, 0xff, 0xff, 0xa7, + 0xdd, 0xa1, 0x79, 0x9c, 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// KeyManagementServiceClient is the client API for KeyManagementService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type KeyManagementServiceClient interface { + // this API is meant to be polled + Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) + // Execute decryption operation in KMS provider. + Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) + // Execute encryption operation in KMS provider. + Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) +} + +type keyManagementServiceClient struct { + cc *grpc.ClientConn +} + +func NewKeyManagementServiceClient(cc *grpc.ClientConn) KeyManagementServiceClient { + return &keyManagementServiceClient{cc} +} + +func (c *keyManagementServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { + out := new(StatusResponse) + err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Status", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) { + out := new(DecryptResponse) + err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Decrypt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keyManagementServiceClient) Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) { + out := new(EncryptResponse) + err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Encrypt", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// KeyManagementServiceServer is the server API for KeyManagementService service. +type KeyManagementServiceServer interface { + // this API is meant to be polled + Status(context.Context, *StatusRequest) (*StatusResponse, error) + // Execute decryption operation in KMS provider. + Decrypt(context.Context, *DecryptRequest) (*DecryptResponse, error) + // Execute encryption operation in KMS provider. + Encrypt(context.Context, *EncryptRequest) (*EncryptResponse, error) +} + +// UnimplementedKeyManagementServiceServer can be embedded to have forward compatible implementations. +type UnimplementedKeyManagementServiceServer struct { +} + +func (*UnimplementedKeyManagementServiceServer) Status(ctx context.Context, req *StatusRequest) (*StatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Status not implemented") +} +func (*UnimplementedKeyManagementServiceServer) Decrypt(ctx context.Context, req *DecryptRequest) (*DecryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Decrypt not implemented") +} +func (*UnimplementedKeyManagementServiceServer) Encrypt(ctx context.Context, req *EncryptRequest) (*EncryptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Encrypt not implemented") +} + +func RegisterKeyManagementServiceServer(s *grpc.Server, srv KeyManagementServiceServer) { + s.RegisterService(&_KeyManagementService_serviceDesc, srv) +} + +func _KeyManagementService_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Status(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v2alpha1.KeyManagementService/Status", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Status(ctx, req.(*StatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _KeyManagementService_Decrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DecryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Decrypt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v2alpha1.KeyManagementService/Decrypt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Decrypt(ctx, req.(*DecryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EncryptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeyManagementServiceServer).Encrypt(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/v2alpha1.KeyManagementService/Encrypt", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeyManagementServiceServer).Encrypt(ctx, req.(*EncryptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _KeyManagementService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "v2alpha1.KeyManagementService", + HandlerType: (*KeyManagementServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Status", + Handler: _KeyManagementService_Status_Handler, + }, + { + MethodName: "Decrypt", + Handler: _KeyManagementService_Decrypt_Handler, + }, + { + MethodName: "Encrypt", + Handler: _KeyManagementService_Encrypt_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api.proto", +} diff --git a/vendor/k8s.io/kms/apis/v2alpha1/api.proto b/vendor/k8s.io/kms/apis/v2alpha1/api.proto new file mode 100644 index 000000000..9b960b2ac --- /dev/null +++ b/vendor/k8s.io/kms/apis/v2alpha1/api.proto @@ -0,0 +1,78 @@ +/* +Copyright 2022 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. +*/ + +// To regenerate api.pb.go run hack/update-generated-kms.sh +syntax = "proto3"; + +package v2alpha1; + +// This service defines the public APIs for remote KMS provider. +service KeyManagementService { + // this API is meant to be polled + rpc Status(StatusRequest) returns (StatusResponse) {} + + // Execute decryption operation in KMS provider. + rpc Decrypt(DecryptRequest) returns (DecryptResponse) {} + // Execute encryption operation in KMS provider. + rpc Encrypt(EncryptRequest) returns (EncryptResponse) {} +} + +message StatusRequest {} + +message StatusResponse { + // Version of the KMS plugin API. Must match the configured .resources[].providers[].kms.apiVersion + string version = 1; + // Any value other than "ok" is failing healthz. On failure, the associated API server healthz endpoint will contain this value as part of the error message. + string healthz = 2; + // the current write key, used to determine staleness of data updated via value.Transformer.TransformFromStorage. + string key_id = 3; +} + +message DecryptRequest { + // The data to be decrypted. + bytes ciphertext = 1; + // UID is a unique identifier for the request. + string uid = 2; + // The keyID that was provided to the apiserver during encryption. + // This represents the KMS KEK that was used to encrypt the data. + string key_id = 3; + // Additional metadata that was sent by the KMS plugin during encryption. + map annotations = 4; +} + +message DecryptResponse { + // The decrypted data. + bytes plaintext = 1; +} + +message EncryptRequest { + // The data to be encrypted. + bytes plaintext = 1; + // UID is a unique identifier for the request. + string uid = 2; +} + +message EncryptResponse { + // The encrypted data. + bytes ciphertext = 1; + // The KMS key ID used to encrypt the data. This must always refer to the KMS KEK and not any local KEKs that may be in use. + // This can be used to inform staleness of data updated via value.Transformer.TransformFromStorage. + string key_id = 2; + // Additional metadata to be stored with the encrypted data. + // This metadata can contain the encrypted local KEK that was used to encrypt the DEK. + // This data is stored in plaintext in etcd. KMS plugin implementations are responsible for pre-encrypting any sensitive data. + map annotations = 3; +} diff --git a/vendor/k8s.io/kms/apis/v2alpha1/v2alpha1.go b/vendor/k8s.io/kms/apis/v2alpha1/v2alpha1.go new file mode 100644 index 000000000..546c4074e --- /dev/null +++ b/vendor/k8s.io/kms/apis/v2alpha1/v2alpha1.go @@ -0,0 +1,18 @@ +/* +Copyright 2022 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 v2alpha1 contains definition of kms-plugin's gRPC service. +package v2alpha1 diff --git a/vendor/k8s.io/kube-openapi/pkg/builder/doc.go b/vendor/k8s.io/kube-openapi/pkg/builder/doc.go new file mode 100644 index 000000000..c3109067f --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2016 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 builder contains code to generate OpenAPI discovery spec (which +// initial version of it also known as Swagger 2.0). +// For more details: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md +package builder diff --git a/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go b/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go new file mode 100644 index 000000000..98be932cb --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go @@ -0,0 +1,468 @@ +/* +Copyright 2016 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 builder + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + restful "github.com/emicklei/go-restful/v3" + + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/common/restfuladapter" + "k8s.io/kube-openapi/pkg/util" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +const ( + OpenAPIVersion = "2.0" +) + +type openAPI struct { + config *common.Config + swagger *spec.Swagger + protocolList []string + definitions map[string]common.OpenAPIDefinition +} + +// BuildOpenAPISpec builds OpenAPI spec given a list of route containers and common.Config to customize it. +// +// Deprecated: BuildOpenAPISpecFromRoutes should be used instead. +func BuildOpenAPISpec(routeContainers []*restful.WebService, config *common.Config) (*spec.Swagger, error) { + return BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(routeContainers), config) +} + +// BuildOpenAPISpecFromRoutes builds OpenAPI spec given a list of route containers and common.Config to customize it. +func BuildOpenAPISpecFromRoutes(routeContainers []common.RouteContainer, config *common.Config) (*spec.Swagger, error) { + o := newOpenAPI(config) + err := o.buildPaths(routeContainers) + if err != nil { + return nil, err + } + return o.finalizeSwagger() +} + +// BuildOpenAPIDefinitionsForResource builds a partial OpenAPI spec given a sample object and common.Config to customize it. +func BuildOpenAPIDefinitionsForResource(model interface{}, config *common.Config) (*spec.Definitions, error) { + o := newOpenAPI(config) + // We can discard the return value of toSchema because all we care about is the side effect of calling it. + // All the models created for this resource get added to o.swagger.Definitions + _, err := o.toSchema(util.GetCanonicalTypeName(model)) + if err != nil { + return nil, err + } + swagger, err := o.finalizeSwagger() + if err != nil { + return nil, err + } + return &swagger.Definitions, nil +} + +// BuildOpenAPIDefinitionsForResources returns the OpenAPI spec which includes the definitions for the +// passed type names. +func BuildOpenAPIDefinitionsForResources(config *common.Config, names ...string) (*spec.Swagger, error) { + o := newOpenAPI(config) + // We can discard the return value of toSchema because all we care about is the side effect of calling it. + // All the models created for this resource get added to o.swagger.Definitions + for _, name := range names { + _, err := o.toSchema(name) + if err != nil { + return nil, err + } + } + return o.finalizeSwagger() +} + +// newOpenAPI sets up the openAPI object so we can build the spec. +func newOpenAPI(config *common.Config) openAPI { + o := openAPI{ + config: config, + swagger: &spec.Swagger{ + SwaggerProps: spec.SwaggerProps{ + Swagger: OpenAPIVersion, + Definitions: spec.Definitions{}, + Responses: config.ResponseDefinitions, + Paths: &spec.Paths{Paths: map[string]spec.PathItem{}}, + Info: config.Info, + }, + }, + } + + if o.config.GetOperationIDAndTagsFromRoute == nil { + // Map the deprecated handler to the common interface, if provided. + if o.config.GetOperationIDAndTags != nil { + o.config.GetOperationIDAndTagsFromRoute = func(r common.Route) (string, []string, error) { + restfulRouteAdapter, ok := r.(*restfuladapter.RouteAdapter) + if !ok { + return "", nil, fmt.Errorf("config.GetOperationIDAndTags specified but route is not a restful v1 Route") + } + + return o.config.GetOperationIDAndTags(restfulRouteAdapter.Route) + } + } else { + o.config.GetOperationIDAndTagsFromRoute = func(r common.Route) (string, []string, error) { + return r.OperationName(), nil, nil + } + } + } + + if o.config.GetDefinitionName == nil { + o.config.GetDefinitionName = func(name string) (string, spec.Extensions) { + return name[strings.LastIndex(name, "/")+1:], nil + } + } + o.definitions = o.config.GetDefinitions(func(name string) spec.Ref { + defName, _ := o.config.GetDefinitionName(name) + return spec.MustCreateRef("#/definitions/" + common.EscapeJsonPointer(defName)) + }) + if o.config.CommonResponses == nil { + o.config.CommonResponses = map[int]spec.Response{} + } + return o +} + +// finalizeSwagger is called after the spec is built and returns the final spec. +// NOTE: finalizeSwagger also make changes to the final spec, as specified in the config. +func (o *openAPI) finalizeSwagger() (*spec.Swagger, error) { + if o.config.SecurityDefinitions != nil { + o.swagger.SecurityDefinitions = *o.config.SecurityDefinitions + o.swagger.Security = o.config.DefaultSecurity + } + if o.config.PostProcessSpec != nil { + var err error + o.swagger, err = o.config.PostProcessSpec(o.swagger) + if err != nil { + return nil, err + } + } + + return o.swagger, nil +} + +func (o *openAPI) buildDefinitionRecursively(name string) error { + uniqueName, extensions := o.config.GetDefinitionName(name) + if _, ok := o.swagger.Definitions[uniqueName]; ok { + return nil + } + if item, ok := o.definitions[name]; ok { + schema := spec.Schema{ + VendorExtensible: item.Schema.VendorExtensible, + SchemaProps: item.Schema.SchemaProps, + SwaggerSchemaProps: item.Schema.SwaggerSchemaProps, + } + if extensions != nil { + if schema.Extensions == nil { + schema.Extensions = spec.Extensions{} + } + for k, v := range extensions { + schema.Extensions[k] = v + } + } + if v, ok := item.Schema.Extensions[common.ExtensionV2Schema]; ok { + if v2Schema, isOpenAPISchema := v.(spec.Schema); isOpenAPISchema { + schema = v2Schema + } + } + o.swagger.Definitions[uniqueName] = schema + for _, v := range item.Dependencies { + if err := o.buildDefinitionRecursively(v); err != nil { + return err + } + } + } else { + return fmt.Errorf("cannot find model definition for %v. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again", name) + } + return nil +} + +// buildDefinitionForType build a definition for a given type and return a referable name to its definition. +// This is the main function that keep track of definitions used in this spec and is depend on code generated +// by k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen. +func (o *openAPI) buildDefinitionForType(name string) (string, error) { + if err := o.buildDefinitionRecursively(name); err != nil { + return "", err + } + defName, _ := o.config.GetDefinitionName(name) + return "#/definitions/" + common.EscapeJsonPointer(defName), nil +} + +// buildPaths builds OpenAPI paths using go-restful's web services. +func (o *openAPI) buildPaths(routeContainers []common.RouteContainer) error { + pathsToIgnore := util.NewTrie(o.config.IgnorePrefixes) + duplicateOpId := make(map[string]string) + for _, w := range routeContainers { + rootPath := w.RootPath() + if pathsToIgnore.HasPrefix(rootPath) { + continue + } + commonParams, err := o.buildParameters(w.PathParameters()) + if err != nil { + return err + } + for path, routes := range groupRoutesByPath(w.Routes()) { + // go-swagger has special variable definition {$NAME:*} that can only be + // used at the end of the path and it is not recognized by OpenAPI. + if strings.HasSuffix(path, ":*}") { + path = path[:len(path)-3] + "}" + } + if pathsToIgnore.HasPrefix(path) { + continue + } + // Aggregating common parameters make API spec (and generated clients) simpler + inPathCommonParamsMap, err := o.findCommonParameters(routes) + if err != nil { + return err + } + pathItem, exists := o.swagger.Paths.Paths[path] + if exists { + return fmt.Errorf("duplicate webservice route has been found for path: %v", path) + } + pathItem = spec.PathItem{ + PathItemProps: spec.PathItemProps{ + Parameters: make([]spec.Parameter, 0), + }, + } + // add web services's parameters as well as any parameters appears in all ops, as common parameters + pathItem.Parameters = append(pathItem.Parameters, commonParams...) + for _, p := range inPathCommonParamsMap { + pathItem.Parameters = append(pathItem.Parameters, p) + } + sortParameters(pathItem.Parameters) + for _, route := range routes { + op, err := o.buildOperations(route, inPathCommonParamsMap) + sortParameters(op.Parameters) + if err != nil { + return err + } + dpath, exists := duplicateOpId[op.ID] + if exists { + return fmt.Errorf("duplicate Operation ID %v for path %v and %v", op.ID, dpath, path) + } else { + duplicateOpId[op.ID] = path + } + switch strings.ToUpper(route.Method()) { + case "GET": + pathItem.Get = op + case "POST": + pathItem.Post = op + case "HEAD": + pathItem.Head = op + case "PUT": + pathItem.Put = op + case "DELETE": + pathItem.Delete = op + case "OPTIONS": + pathItem.Options = op + case "PATCH": + pathItem.Patch = op + } + } + o.swagger.Paths.Paths[path] = pathItem + } + } + return nil +} + +// buildOperations builds operations for each webservice path +func (o *openAPI) buildOperations(route common.Route, inPathCommonParamsMap map[interface{}]spec.Parameter) (ret *spec.Operation, err error) { + ret = &spec.Operation{ + OperationProps: spec.OperationProps{ + Description: route.Description(), + Consumes: route.Consumes(), + Produces: route.Produces(), + Schemes: o.config.ProtocolList, + Responses: &spec.Responses{ + ResponsesProps: spec.ResponsesProps{ + StatusCodeResponses: make(map[int]spec.Response), + }, + }, + }, + } + for k, v := range route.Metadata() { + if strings.HasPrefix(k, common.ExtensionPrefix) { + if ret.Extensions == nil { + ret.Extensions = spec.Extensions{} + } + ret.Extensions.Add(k, v) + } + } + if ret.ID, ret.Tags, err = o.config.GetOperationIDAndTagsFromRoute(route); err != nil { + return ret, err + } + + // Build responses + for _, resp := range route.StatusCodeResponses() { + ret.Responses.StatusCodeResponses[resp.Code()], err = o.buildResponse(resp.Model(), resp.Message()) + if err != nil { + return ret, err + } + } + // If there is no response but a write sample, assume that write sample is an http.StatusOK response. + if len(ret.Responses.StatusCodeResponses) == 0 && route.ResponsePayloadSample() != nil { + ret.Responses.StatusCodeResponses[http.StatusOK], err = o.buildResponse(route.ResponsePayloadSample(), "OK") + if err != nil { + return ret, err + } + } + for code, resp := range o.config.CommonResponses { + if _, exists := ret.Responses.StatusCodeResponses[code]; !exists { + ret.Responses.StatusCodeResponses[code] = resp + } + } + // If there is still no response, use default response provided. + if len(ret.Responses.StatusCodeResponses) == 0 { + ret.Responses.Default = o.config.DefaultResponse + } + + // Build non-common Parameters + ret.Parameters = make([]spec.Parameter, 0) + for _, param := range route.Parameters() { + if _, isCommon := inPathCommonParamsMap[mapKeyFromParam(param)]; !isCommon { + openAPIParam, err := o.buildParameter(param, route.RequestPayloadSample()) + if err != nil { + return ret, err + } + ret.Parameters = append(ret.Parameters, openAPIParam) + } + } + return ret, nil +} + +func (o *openAPI) buildResponse(model interface{}, description string) (spec.Response, error) { + schema, err := o.toSchema(util.GetCanonicalTypeName(model)) + if err != nil { + return spec.Response{}, err + } + return spec.Response{ + ResponseProps: spec.ResponseProps{ + Description: description, + Schema: schema, + }, + }, nil +} + +func (o *openAPI) findCommonParameters(routes []common.Route) (map[interface{}]spec.Parameter, error) { + commonParamsMap := make(map[interface{}]spec.Parameter, 0) + paramOpsCountByName := make(map[interface{}]int, 0) + paramNameKindToDataMap := make(map[interface{}]common.Parameter, 0) + for _, route := range routes { + routeParamDuplicateMap := make(map[interface{}]bool) + s := "" + params := route.Parameters() + for _, param := range params { + m, _ := json.Marshal(param) + s += string(m) + "\n" + key := mapKeyFromParam(param) + if routeParamDuplicateMap[key] { + msg, _ := json.Marshal(params) + return commonParamsMap, fmt.Errorf("duplicate parameter %v for route %v, %v", param.Name(), string(msg), s) + } + routeParamDuplicateMap[key] = true + paramOpsCountByName[key]++ + paramNameKindToDataMap[key] = param + } + } + for key, count := range paramOpsCountByName { + paramData := paramNameKindToDataMap[key] + if count == len(routes) && paramData.Kind() != common.BodyParameterKind { + openAPIParam, err := o.buildParameter(paramData, nil) + if err != nil { + return commonParamsMap, err + } + commonParamsMap[key] = openAPIParam + } + } + return commonParamsMap, nil +} + +func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) { + if openAPIType, openAPIFormat := common.OpenAPITypeFormat(name); openAPIType != "" { + return &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{openAPIType}, + Format: openAPIFormat, + }, + }, nil + } else { + ref, err := o.buildDefinitionForType(name) + if err != nil { + return nil, err + } + return &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: spec.MustCreateRef(ref), + }, + }, nil + } +} + +func (o *openAPI) buildParameter(restParam common.Parameter, bodySample interface{}) (ret spec.Parameter, err error) { + ret = spec.Parameter{ + ParamProps: spec.ParamProps{ + Name: restParam.Name(), + Description: restParam.Description(), + Required: restParam.Required(), + }, + } + switch restParam.Kind() { + case common.BodyParameterKind: + if bodySample != nil { + ret.In = "body" + ret.Schema, err = o.toSchema(util.GetCanonicalTypeName(bodySample)) + return ret, err + } else { + // There is not enough information in the body parameter to build the definition. + // Body parameter has a data type that is a short name but we need full package name + // of the type to create a definition. + return ret, fmt.Errorf("restful body parameters are not supported: %v", restParam.DataType()) + } + case common.PathParameterKind: + ret.In = "path" + if !restParam.Required() { + return ret, fmt.Errorf("path parameters should be marked at required for parameter %v", restParam) + } + case common.QueryParameterKind: + ret.In = "query" + case common.HeaderParameterKind: + ret.In = "header" + case common.FormParameterKind: + ret.In = "formData" + default: + return ret, fmt.Errorf("unknown restful operation kind : %v", restParam.Kind()) + } + openAPIType, openAPIFormat := common.OpenAPITypeFormat(restParam.DataType()) + if openAPIType == "" { + return ret, fmt.Errorf("non-body Restful parameter type should be a simple type, but got : %v", restParam.DataType()) + } + ret.Type = openAPIType + ret.Format = openAPIFormat + ret.UniqueItems = !restParam.AllowMultiple() + return ret, nil +} + +func (o *openAPI) buildParameters(restParam []common.Parameter) (ret []spec.Parameter, err error) { + ret = make([]spec.Parameter, len(restParam)) + for i, v := range restParam { + ret[i], err = o.buildParameter(v, nil) + if err != nil { + return ret, err + } + } + return ret, nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/builder/util.go b/vendor/k8s.io/kube-openapi/pkg/builder/util.go new file mode 100644 index 000000000..3621a4de1 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder/util.go @@ -0,0 +1,61 @@ +/* +Copyright 2016 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 builder + +import ( + "sort" + + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +type parameters []spec.Parameter + +func (s parameters) Len() int { return len(s) } +func (s parameters) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// byNameIn used in sorting parameters by Name and In fields. +type byNameIn struct { + parameters +} + +func (s byNameIn) Less(i, j int) bool { + return s.parameters[i].Name < s.parameters[j].Name || (s.parameters[i].Name == s.parameters[j].Name && s.parameters[i].In < s.parameters[j].In) +} + +// SortParameters sorts parameters by Name and In fields. +func sortParameters(p []spec.Parameter) { + sort.Sort(byNameIn{p}) +} + +func groupRoutesByPath(routes []common.Route) map[string][]common.Route { + pathToRoutes := make(map[string][]common.Route) + for _, r := range routes { + pathToRoutes[r.Path()] = append(pathToRoutes[r.Path()], r) + } + return pathToRoutes +} + +func mapKeyFromParam(param common.Parameter) interface{} { + return struct { + Name string + Kind common.ParameterKind + }{ + Name: param.Name(), + Kind: param.Kind(), + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/builder3/openapi.go b/vendor/k8s.io/kube-openapi/pkg/builder3/openapi.go new file mode 100644 index 000000000..3a8d765f1 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder3/openapi.go @@ -0,0 +1,490 @@ +/* +Copyright 2021 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 builder3 + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + restful "github.com/emicklei/go-restful/v3" + + builderutil "k8s.io/kube-openapi/pkg/builder3/util" + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/common/restfuladapter" + "k8s.io/kube-openapi/pkg/spec3" + "k8s.io/kube-openapi/pkg/util" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +const ( + OpenAPIVersion = "3.0" +) + +type openAPI struct { + config *common.OpenAPIV3Config + spec *spec3.OpenAPI + definitions map[string]common.OpenAPIDefinition +} + +func groupRoutesByPath(routes []common.Route) map[string][]common.Route { + pathToRoutes := make(map[string][]common.Route) + for _, r := range routes { + pathToRoutes[r.Path()] = append(pathToRoutes[r.Path()], r) + } + return pathToRoutes +} + +func (o *openAPI) buildResponse(model interface{}, description string, content []string) (*spec3.Response, error) { + response := &spec3.Response{ + ResponseProps: spec3.ResponseProps{ + Description: description, + Content: make(map[string]*spec3.MediaType), + }, + } + + s, err := o.toSchema(util.GetCanonicalTypeName(model)) + if err != nil { + return nil, err + } + + for _, contentType := range content { + response.ResponseProps.Content[contentType] = &spec3.MediaType{ + MediaTypeProps: spec3.MediaTypeProps{ + Schema: s, + }, + } + } + return response, nil +} + +func (o *openAPI) buildOperations(route common.Route, inPathCommonParamsMap map[interface{}]*spec3.Parameter) (*spec3.Operation, error) { + ret := &spec3.Operation{ + OperationProps: spec3.OperationProps{ + Description: route.Description(), + Responses: &spec3.Responses{ + ResponsesProps: spec3.ResponsesProps{ + StatusCodeResponses: make(map[int]*spec3.Response), + }, + }, + }, + } + for k, v := range route.Metadata() { + if strings.HasPrefix(k, common.ExtensionPrefix) { + if ret.Extensions == nil { + ret.Extensions = spec.Extensions{} + } + ret.Extensions.Add(k, v) + } + } + + var err error + if ret.OperationId, ret.Tags, err = o.config.GetOperationIDAndTagsFromRoute(route); err != nil { + return ret, err + } + + // Build responses + for _, resp := range route.StatusCodeResponses() { + ret.Responses.StatusCodeResponses[resp.Code()], err = o.buildResponse(resp.Model(), resp.Message(), route.Produces()) + if err != nil { + return ret, err + } + } + + // If there is no response but a write sample, assume that write sample is an http.StatusOK response. + if len(ret.Responses.StatusCodeResponses) == 0 && route.ResponsePayloadSample() != nil { + ret.Responses.StatusCodeResponses[http.StatusOK], err = o.buildResponse(route.ResponsePayloadSample(), "OK", route.Produces()) + if err != nil { + return ret, err + } + } + + for code, resp := range o.config.CommonResponses { + if _, exists := ret.Responses.StatusCodeResponses[code]; !exists { + ret.Responses.StatusCodeResponses[code] = resp + } + } + + if len(ret.Responses.StatusCodeResponses) == 0 { + ret.Responses.Default = o.config.DefaultResponse + } + + params := route.Parameters() + for _, param := range params { + _, isCommon := inPathCommonParamsMap[mapKeyFromParam(param)] + if !isCommon && param.Kind() != common.BodyParameterKind { + openAPIParam, err := o.buildParameter(param) + if err != nil { + return ret, err + } + ret.Parameters = append(ret.Parameters, openAPIParam) + } + } + + body, err := o.buildRequestBody(params, route.Consumes(), route.RequestPayloadSample()) + if err != nil { + return nil, err + } + + if body != nil { + ret.RequestBody = body + } + return ret, nil +} + +func (o *openAPI) buildRequestBody(parameters []common.Parameter, consumes []string, bodySample interface{}) (*spec3.RequestBody, error) { + for _, param := range parameters { + if param.Kind() == common.BodyParameterKind && bodySample != nil { + schema, err := o.toSchema(util.GetCanonicalTypeName(bodySample)) + if err != nil { + return nil, err + } + r := &spec3.RequestBody{ + RequestBodyProps: spec3.RequestBodyProps{ + Content: map[string]*spec3.MediaType{}, + }, + } + for _, consume := range consumes { + r.Content[consume] = &spec3.MediaType{ + MediaTypeProps: spec3.MediaTypeProps{ + Schema: schema, + }, + } + } + return r, nil + } + } + return nil, nil +} + +func newOpenAPI(config *common.Config) openAPI { + o := openAPI{ + config: common.ConvertConfigToV3(config), + spec: &spec3.OpenAPI{ + Version: "3.0.0", + Info: config.Info, + Paths: &spec3.Paths{ + Paths: map[string]*spec3.Path{}, + }, + Components: &spec3.Components{ + Schemas: map[string]*spec.Schema{}, + }, + }, + } + if len(o.config.ResponseDefinitions) > 0 { + o.spec.Components.Responses = make(map[string]*spec3.Response) + + } + for k, response := range o.config.ResponseDefinitions { + o.spec.Components.Responses[k] = response + } + + if len(o.config.SecuritySchemes) > 0 { + o.spec.Components.SecuritySchemes = make(spec3.SecuritySchemes) + + } + for k, securityScheme := range o.config.SecuritySchemes { + o.spec.Components.SecuritySchemes[k] = securityScheme + } + + if o.config.GetOperationIDAndTagsFromRoute == nil { + // Map the deprecated handler to the common interface, if provided. + if o.config.GetOperationIDAndTags != nil { + o.config.GetOperationIDAndTagsFromRoute = func(r common.Route) (string, []string, error) { + restfulRouteAdapter, ok := r.(*restfuladapter.RouteAdapter) + if !ok { + return "", nil, fmt.Errorf("config.GetOperationIDAndTags specified but route is not a restful v1 Route") + } + + return o.config.GetOperationIDAndTags(restfulRouteAdapter.Route) + } + } else { + o.config.GetOperationIDAndTagsFromRoute = func(r common.Route) (string, []string, error) { + return r.OperationName(), nil, nil + } + } + } + + if o.config.GetDefinitionName == nil { + o.config.GetDefinitionName = func(name string) (string, spec.Extensions) { + return name[strings.LastIndex(name, "/")+1:], nil + } + } + + if o.config.Definitions != nil { + o.definitions = o.config.Definitions + } else { + o.definitions = o.config.GetDefinitions(func(name string) spec.Ref { + defName, _ := o.config.GetDefinitionName(name) + return spec.MustCreateRef("#/components/schemas/" + common.EscapeJsonPointer(defName)) + }) + } + + return o +} + +func (o *openAPI) buildOpenAPISpec(webServices []common.RouteContainer) error { + pathsToIgnore := util.NewTrie(o.config.IgnorePrefixes) + for _, w := range webServices { + rootPath := w.RootPath() + if pathsToIgnore.HasPrefix(rootPath) { + continue + } + + commonParams, err := o.buildParameters(w.PathParameters()) + if err != nil { + return err + } + + for path, routes := range groupRoutesByPath(w.Routes()) { + // go-swagger has special variable definition {$NAME:*} that can only be + // used at the end of the path and it is not recognized by OpenAPI. + if strings.HasSuffix(path, ":*}") { + path = path[:len(path)-3] + "}" + } + if pathsToIgnore.HasPrefix(path) { + continue + } + + // Aggregating common parameters make API spec (and generated clients) simpler + inPathCommonParamsMap, err := o.findCommonParameters(routes) + if err != nil { + return err + } + pathItem, exists := o.spec.Paths.Paths[path] + if exists { + return fmt.Errorf("duplicate webservice route has been found for path: %v", path) + } + + pathItem = &spec3.Path{ + PathProps: spec3.PathProps{}, + } + + // add web services's parameters as well as any parameters appears in all ops, as common parameters + pathItem.Parameters = append(pathItem.Parameters, commonParams...) + for _, p := range inPathCommonParamsMap { + pathItem.Parameters = append(pathItem.Parameters, p) + } + sortParameters(pathItem.Parameters) + + for _, route := range routes { + op, _ := o.buildOperations(route, inPathCommonParamsMap) + sortParameters(op.Parameters) + + switch strings.ToUpper(route.Method()) { + case "GET": + pathItem.Get = op + case "POST": + pathItem.Post = op + case "HEAD": + pathItem.Head = op + case "PUT": + pathItem.Put = op + case "DELETE": + pathItem.Delete = op + case "OPTIONS": + pathItem.Options = op + case "PATCH": + pathItem.Patch = op + } + + } + o.spec.Paths.Paths[path] = pathItem + } + } + return nil +} + +// BuildOpenAPISpec builds OpenAPI v3 spec given a list of route containers and common.Config to customize it. +// +// Deprecated: BuildOpenAPISpecFromRoutes should be used instead. +func BuildOpenAPISpec(webServices []*restful.WebService, config *common.Config) (*spec3.OpenAPI, error) { + return BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(webServices), config) +} + +// BuildOpenAPISpecFromRoutes builds OpenAPI v3 spec given a list of route containers and common.Config to customize it. +func BuildOpenAPISpecFromRoutes(webServices []common.RouteContainer, config *common.Config) (*spec3.OpenAPI, error) { + a := newOpenAPI(config) + err := a.buildOpenAPISpec(webServices) + if err != nil { + return nil, err + } + return a.spec, nil +} + +// BuildOpenAPIDefinitionsForResource builds a partial OpenAPI spec given a sample object and common.Config to customize it. +// BuildOpenAPIDefinitionsForResources returns the OpenAPI spec which includes the definitions for the +// passed type names. +func BuildOpenAPIDefinitionsForResources(config *common.Config, names ...string) (map[string]*spec.Schema, error) { + o := newOpenAPI(config) + // We can discard the return value of toSchema because all we care about is the side effect of calling it. + // All the models created for this resource get added to o.swagger.Definitions + for _, name := range names { + _, err := o.toSchema(name) + if err != nil { + return nil, err + } + } + return o.spec.Components.Schemas, nil +} +func (o *openAPI) findCommonParameters(routes []common.Route) (map[interface{}]*spec3.Parameter, error) { + commonParamsMap := make(map[interface{}]*spec3.Parameter, 0) + paramOpsCountByName := make(map[interface{}]int, 0) + paramNameKindToDataMap := make(map[interface{}]common.Parameter, 0) + for _, route := range routes { + routeParamDuplicateMap := make(map[interface{}]bool) + s := "" + params := route.Parameters() + for _, param := range params { + m, _ := json.Marshal(param) + s += string(m) + "\n" + key := mapKeyFromParam(param) + if routeParamDuplicateMap[key] { + msg, _ := json.Marshal(params) + return commonParamsMap, fmt.Errorf("duplicate parameter %v for route %v, %v", param.Name(), string(msg), s) + } + routeParamDuplicateMap[key] = true + paramOpsCountByName[key]++ + paramNameKindToDataMap[key] = param + } + } + for key, count := range paramOpsCountByName { + paramData := paramNameKindToDataMap[key] + if count == len(routes) && paramData.Kind() != common.BodyParameterKind { + openAPIParam, err := o.buildParameter(paramData) + if err != nil { + return commonParamsMap, err + } + commonParamsMap[key] = openAPIParam + } + } + return commonParamsMap, nil +} + +func (o *openAPI) buildParameters(restParam []common.Parameter) (ret []*spec3.Parameter, err error) { + ret = make([]*spec3.Parameter, len(restParam)) + for i, v := range restParam { + ret[i], err = o.buildParameter(v) + if err != nil { + return ret, err + } + } + return ret, nil +} + +func (o *openAPI) buildParameter(restParam common.Parameter) (ret *spec3.Parameter, err error) { + ret = &spec3.Parameter{ + ParameterProps: spec3.ParameterProps{ + Name: restParam.Name(), + Description: restParam.Description(), + Required: restParam.Required(), + }, + } + switch restParam.Kind() { + case common.BodyParameterKind: + return nil, nil + case common.PathParameterKind: + ret.In = "path" + if !restParam.Required() { + return ret, fmt.Errorf("path parameters should be marked as required for parameter %v", restParam) + } + case common.QueryParameterKind: + ret.In = "query" + case common.HeaderParameterKind: + ret.In = "header" + /* TODO: add support for the cookie param */ + default: + return ret, fmt.Errorf("unsupported restful parameter kind : %v", restParam.Kind()) + } + openAPIType, openAPIFormat := common.OpenAPITypeFormat(restParam.DataType()) + if openAPIType == "" { + return ret, fmt.Errorf("non-body Restful parameter type should be a simple type, but got : %v", restParam.DataType()) + } + + ret.Schema = &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{openAPIType}, + Format: openAPIFormat, + UniqueItems: !restParam.AllowMultiple(), + }, + } + return ret, nil +} + +func (o *openAPI) buildDefinitionRecursively(name string) error { + uniqueName, extensions := o.config.GetDefinitionName(name) + if _, ok := o.spec.Components.Schemas[uniqueName]; ok { + return nil + } + if item, ok := o.definitions[name]; ok { + schema := &spec.Schema{ + VendorExtensible: item.Schema.VendorExtensible, + SchemaProps: item.Schema.SchemaProps, + SwaggerSchemaProps: item.Schema.SwaggerSchemaProps, + } + if extensions != nil { + if schema.Extensions == nil { + schema.Extensions = spec.Extensions{} + } + for k, v := range extensions { + schema.Extensions[k] = v + } + } + // delete the embedded v2 schema if exists, otherwise no-op + delete(schema.VendorExtensible.Extensions, common.ExtensionV2Schema) + schema = builderutil.WrapRefs(schema) + o.spec.Components.Schemas[uniqueName] = schema + for _, v := range item.Dependencies { + if err := o.buildDefinitionRecursively(v); err != nil { + return err + } + } + } else { + return fmt.Errorf("cannot find model definition for %v. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again", name) + } + return nil +} + +func (o *openAPI) buildDefinitionForType(name string) (string, error) { + if err := o.buildDefinitionRecursively(name); err != nil { + return "", err + } + defName, _ := o.config.GetDefinitionName(name) + return "#/components/schemas/" + common.EscapeJsonPointer(defName), nil +} + +func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) { + if openAPIType, openAPIFormat := common.OpenAPITypeFormat(name); openAPIType != "" { + return &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{openAPIType}, + Format: openAPIFormat, + }, + }, nil + } else { + ref, err := o.buildDefinitionForType(name) + if err != nil { + return nil, err + } + return &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: spec.MustCreateRef(ref), + }, + }, nil + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/builder3/util.go b/vendor/k8s.io/kube-openapi/pkg/builder3/util.go new file mode 100644 index 000000000..a8a90fa15 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/builder3/util.go @@ -0,0 +1,52 @@ +/* +Copyright 2021 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 builder3 + +import ( + "sort" + + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/spec3" +) + +func mapKeyFromParam(param common.Parameter) interface{} { + return struct { + Name string + Kind common.ParameterKind + }{ + Name: param.Name(), + Kind: param.Kind(), + } +} + +func (s parameters) Len() int { return len(s) } +func (s parameters) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +type parameters []*spec3.Parameter + +type byNameIn struct { + parameters +} + +func (s byNameIn) Less(i, j int) bool { + return s.parameters[i].Name < s.parameters[j].Name || (s.parameters[i].Name == s.parameters[j].Name && s.parameters[i].In < s.parameters[j].In) +} + +// SortParameters sorts parameters by Name and In fields. +func sortParameters(p []*spec3.Parameter) { + sort.Sort(byNameIn{p}) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/cached/cache.go b/vendor/k8s.io/kube-openapi/pkg/cached/cache.go new file mode 100644 index 000000000..16e34853a --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/cached/cache.go @@ -0,0 +1,264 @@ +/* +Copyright 2022 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 cache provides a cache mechanism based on etags to lazily +// build, and/or cache results from expensive operation such that those +// operations are not repeated unnecessarily. The operations can be +// created as a tree, and replaced dynamically as needed. +// +// # Dependencies and types of caches +// +// This package uses a source/transform/sink model of caches to build +// the dependency tree, and can be used as follows: +// - [NewSource]: A source cache that recomputes the content every time. +// - [NewStaticSource]: A source cache that always produces the +// same content, it is only called once. +// - [NewTransformer]: A cache that transforms data from one format to +// another. It's only refreshed when the source changes. +// - [NewMerger]: A cache that aggregates multiple caches into one. +// It's only refreshed when the source changes. +// - [Replaceable]: A cache adapter that can be atomically +// replaced with a new one, and saves the previous results in case an +// error pops-up. +// +// # Atomicity +// +// Most of the operations are not atomic/thread-safe, except for +// [Replaceable.Replace] which can be performed while the objects +// are being read. +// +// # Etags +// +// Etags in this library is a cache version identifier. It doesn't +// necessarily strictly match to the semantics of http `etags`, but are +// somewhat inspired from it and function with the same principles. +// Hashing the content is a good way to guarantee that your function is +// never going to be called spuriously. In Kubernetes world, this could +// be a `resourceVersion`, this can be an actual etag, a hash, a UUID +// (if the cache always changes), or even a made-up string when the +// content of the cache never changes. +package cached + +import ( + "fmt" + "sync/atomic" +) + +// Result is the content returned from a call to a cache. It can either +// be created with [NewResultOK] if the call was a success, or +// [NewResultErr] if the call resulted in an error. +type Result[T any] struct { + Data T + Etag string + Err error +} + +// NewResultOK creates a new [Result] for a successful operation. +func NewResultOK[T any](data T, etag string) Result[T] { + return Result[T]{ + Data: data, + Etag: etag, + } +} + +// NewResultErr creates a new [Result] when an error has happened. +func NewResultErr[T any](err error) Result[T] { + return Result[T]{ + Err: err, + } +} + +// Result can be treated as a [Data] if necessary. +func (r Result[T]) Get() Result[T] { + return r +} + +// Data is a cache that performs an action whose result data will be +// cached. It also returns an "etag" identifier to version the cache, so +// that the caller can know if they have the most recent version of the +// cache (and can decide to cache some operation based on that). +// +// The [NewMerger] and [NewTransformer] automatically handle +// that for you by checking if the etag is updated before calling the +// merging or transforming function. +type Data[T any] interface { + // Returns the cached data, as well as an "etag" to identify the + // version of the cache, or an error if something happened. + Get() Result[T] +} + +// T is the source type, V is the destination type. +type merger[K comparable, T, V any] struct { + mergeFn func(map[K]Result[T]) Result[V] + caches map[K]Data[T] + cacheResults map[K]Result[T] + result Result[V] +} + +// NewMerger creates a new merge cache, a cache that merges the result +// of other caches. The function only gets called if any of the +// dependency has changed. +// +// If any of the dependency returned an error before, or any of the +// dependency returned an error this time, or if the mergeFn failed +// before, then the function is reran. +// +// The caches and results are mapped by K so that associated data can be +// retrieved. The map of dependencies can not be modified after +// creation, and a new merger should be created (and probably replaced +// using a [Replaceable]). +// +// Note that this assumes there is no "partial" merge, the merge +// function will remerge all the dependencies together everytime. Since +// the list of dependencies is constant, there is no way to save some +// partial merge information either. +func NewMerger[K comparable, T, V any](mergeFn func(results map[K]Result[T]) Result[V], caches map[K]Data[T]) Data[V] { + return &merger[K, T, V]{ + mergeFn: mergeFn, + caches: caches, + } +} + +func (c *merger[K, T, V]) prepareResults() map[K]Result[T] { + cacheResults := make(map[K]Result[T], len(c.caches)) + for key, cache := range c.caches { + cacheResults[key] = cache.Get() + } + return cacheResults +} + +// Rerun if: +// - The last run resulted in an error +// - Any of the dependency previously returned an error +// - Any of the dependency just returned an error +// - Any of the dependency's etag changed +func (c *merger[K, T, V]) needsRunning(results map[K]Result[T]) bool { + if c.cacheResults == nil { + return true + } + if c.result.Err != nil { + return true + } + if len(results) != len(c.cacheResults) { + panic(fmt.Errorf("invalid number of results: %v (expected %v)", len(results), len(c.cacheResults))) + } + for key, oldResult := range c.cacheResults { + newResult, ok := results[key] + if !ok { + panic(fmt.Errorf("unknown cache entry: %v", key)) + } + + if newResult.Etag != oldResult.Etag || newResult.Err != nil || oldResult.Err != nil { + return true + } + } + return false +} + +func (c *merger[K, T, V]) Get() Result[V] { + cacheResults := c.prepareResults() + if c.needsRunning(cacheResults) { + c.cacheResults = cacheResults + c.result = c.mergeFn(c.cacheResults) + } + return c.result +} + +type transformerCacheKeyType struct{} + +// NewTransformer creates a new cache that transforms the result of +// another cache. The transformFn will only be called if the source +// cache has updated the output, otherwise, the cached result will be +// returned. +// +// If the dependency returned an error before, or it returns an error +// this time, or if the transformerFn failed before, the function is +// reran. +func NewTransformer[T, V any](transformerFn func(Result[T]) Result[V], source Data[T]) Data[V] { + return NewMerger(func(caches map[transformerCacheKeyType]Result[T]) Result[V] { + cache, ok := caches[transformerCacheKeyType{}] + if len(caches) != 1 || !ok { + panic(fmt.Errorf("invalid cache for transformer cache: %v", caches)) + } + return transformerFn(cache) + }, map[transformerCacheKeyType]Data[T]{ + {}: source, + }) +} + +// NewSource creates a new cache that generates some data. This +// will always be called since we don't know the origin of the data and +// if it needs to be updated or not. +func NewSource[T any](sourceFn func() Result[T]) Data[T] { + c := source[T](sourceFn) + return &c +} + +type source[T any] func() Result[T] + +func (c *source[T]) Get() Result[T] { + return (*c)() +} + +// NewStaticSource creates a new cache that always generates the +// same data. This will only be called once (lazily). +func NewStaticSource[T any](staticFn func() Result[T]) Data[T] { + return &static[T]{ + fn: staticFn, + } +} + +type static[T any] struct { + fn func() Result[T] + result *Result[T] +} + +func (c *static[T]) Get() Result[T] { + if c.result == nil { + result := c.fn() + c.result = &result + } + return *c.result +} + +// Replaceable is a cache that carries the result even when the +// cache is replaced. The cache can be replaced atomically (without any +// lock held). This is the type that should typically be stored in +// structs. +type Replaceable[T any] struct { + cache atomic.Pointer[Data[T]] + result *Result[T] +} + +// Get retrieves the data from the underlying source. [Replaceable] +// implements the [Data] interface itself. This is a pass-through +// that calls the most recent underlying cache. If the cache fails but +// previously had returned a success, that success will be returned +// instead. If the cache fails but we never returned a success, that +// failure is returned. +func (c *Replaceable[T]) Get() Result[T] { + result := (*c.cache.Load()).Get() + if result.Err != nil && c.result != nil && c.result.Err == nil { + return *c.result + } + c.result = &result + return *c.result +} + +// Replace changes the cache in a thread-safe way. +func (c *Replaceable[T]) Replace(cache Data[T]) { + c.cache.Swap(&cache) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/common.go b/vendor/k8s.io/kube-openapi/pkg/common/common.go index 24f2b0e88..1a6c12e17 100644 --- a/vendor/k8s.io/kube-openapi/pkg/common/common.go +++ b/vendor/k8s.io/kube-openapi/pkg/common/common.go @@ -246,38 +246,42 @@ var schemaTypeFormatMap = map[string]typeInfo{ // the spec does not need to be simple type,format) or can even return a simple type,format (e.g. IntOrString). For simple // type formats, the benefit of adding OpenAPIDefinitionGetter interface is to keep both type and property documentation. // Example: -// type Sample struct { -// ... -// // port of the server -// port IntOrString -// ... -// } +// +// type Sample struct { +// ... +// // port of the server +// port IntOrString +// ... +// } +// // // IntOrString documentation... // type IntOrString { ... } // // Adding IntOrString to this function: -// "port" : { -// format: "string", -// type: "int-or-string", -// Description: "port of the server" -// } +// +// "port" : { +// format: "string", +// type: "int-or-string", +// Description: "port of the server" +// } // // Implement OpenAPIDefinitionGetter for IntOrString: // -// "port" : { -// $Ref: "#/definitions/IntOrString" -// Description: "port of the server" -// } +// "port" : { +// $Ref: "#/definitions/IntOrString" +// Description: "port of the server" +// } +// // ... // definitions: -// { -// "IntOrString": { -// format: "string", -// type: "int-or-string", -// Description: "IntOrString documentation..." // new -// } -// } // +// { +// "IntOrString": { +// format: "string", +// type: "int-or-string", +// Description: "IntOrString documentation..." // new +// } +// } func OpenAPITypeFormat(typeName string) (string, string) { mapped, ok := schemaTypeFormatMap[typeName] if !ok { diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/adapter.go new file mode 100644 index 000000000..932b84a01 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/adapter.go @@ -0,0 +1,15 @@ +package restfuladapter + +import ( + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +// AdaptWebServices adapts a slice of restful.WebService into the common interfaces. +func AdaptWebServices(webServices []*restful.WebService) []common.RouteContainer { + var containers []common.RouteContainer + for _, ws := range webServices { + containers = append(containers, &WebServiceAdapter{ws}) + } + return containers +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/param_adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/param_adapter.go new file mode 100644 index 000000000..6805dd6c7 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/param_adapter.go @@ -0,0 +1,54 @@ +package restfuladapter + +import ( + "encoding/json" + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +var _ common.Parameter = &ParamAdapter{} + +type ParamAdapter struct { + Param *restful.Parameter +} + +func (r *ParamAdapter) MarshalJSON() ([]byte, error) { + return json.Marshal(r.Param) +} + +func (r *ParamAdapter) Name() string { + return r.Param.Data().Name +} + +func (r *ParamAdapter) Description() string { + return r.Param.Data().Description +} + +func (r *ParamAdapter) Required() bool { + return r.Param.Data().Required +} + +func (r *ParamAdapter) Kind() common.ParameterKind { + switch r.Param.Kind() { + case restful.PathParameterKind: + return common.PathParameterKind + case restful.QueryParameterKind: + return common.QueryParameterKind + case restful.BodyParameterKind: + return common.BodyParameterKind + case restful.HeaderParameterKind: + return common.HeaderParameterKind + case restful.FormParameterKind: + return common.FormParameterKind + default: + return common.UnknownParameterKind + } +} + +func (r *ParamAdapter) DataType() string { + return r.Param.Data().DataType +} + +func (r *ParamAdapter) AllowMultiple() bool { + return r.Param.Data().AllowMultiple +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/response_error_adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/response_error_adapter.go new file mode 100644 index 000000000..92556398e --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/response_error_adapter.go @@ -0,0 +1,25 @@ +package restfuladapter + +import ( + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +var _ common.StatusCodeResponse = &ResponseErrorAdapter{} + +// ResponseErrorAdapter adapts a restful.ResponseError to common.StatusCodeResponse. +type ResponseErrorAdapter struct { + Err *restful.ResponseError +} + +func (r *ResponseErrorAdapter) Message() string { + return r.Err.Message +} + +func (r *ResponseErrorAdapter) Model() interface{} { + return r.Err.Model +} + +func (r *ResponseErrorAdapter) Code() int { + return r.Err.Code +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/route_adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/route_adapter.go new file mode 100644 index 000000000..c7ba3a564 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/route_adapter.go @@ -0,0 +1,68 @@ +package restfuladapter + +import ( + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +var _ common.Route = &RouteAdapter{} + +// RouteAdapter adapts a restful.Route to common.Route. +type RouteAdapter struct { + Route *restful.Route +} + +func (r *RouteAdapter) StatusCodeResponses() []common.StatusCodeResponse { + // go-restful uses the ResponseErrors field to contain both error and regular responses. + var responses []common.StatusCodeResponse + for _, res := range r.Route.ResponseErrors { + localRes := res + responses = append(responses, &ResponseErrorAdapter{&localRes}) + } + + return responses +} + +func (r *RouteAdapter) OperationName() string { + return r.Route.Operation +} + +func (r *RouteAdapter) Method() string { + return r.Route.Method +} + +func (r *RouteAdapter) Path() string { + return r.Route.Path +} + +func (r *RouteAdapter) Parameters() []common.Parameter { + var params []common.Parameter + for _, rParam := range r.Route.ParameterDocs { + params = append(params, &ParamAdapter{rParam}) + } + return params +} + +func (r *RouteAdapter) Description() string { + return r.Route.Doc +} + +func (r *RouteAdapter) Consumes() []string { + return r.Route.Consumes +} + +func (r *RouteAdapter) Produces() []string { + return r.Route.Produces +} + +func (r *RouteAdapter) Metadata() map[string]interface{} { + return r.Route.Metadata +} + +func (r *RouteAdapter) RequestPayloadSample() interface{} { + return r.Route.ReadSample +} + +func (r *RouteAdapter) ResponsePayloadSample() interface{} { + return r.Route.WriteSample +} diff --git a/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/webservice_adapter.go b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/webservice_adapter.go new file mode 100644 index 000000000..995586538 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/common/restfuladapter/webservice_adapter.go @@ -0,0 +1,34 @@ +package restfuladapter + +import ( + "github.com/emicklei/go-restful/v3" + "k8s.io/kube-openapi/pkg/common" +) + +var _ common.RouteContainer = &WebServiceAdapter{} + +// WebServiceAdapter adapts a restful.WebService to common.RouteContainer. +type WebServiceAdapter struct { + WebService *restful.WebService +} + +func (r *WebServiceAdapter) RootPath() string { + return r.WebService.RootPath() +} + +func (r *WebServiceAdapter) PathParameters() []common.Parameter { + var params []common.Parameter + for _, rParam := range r.WebService.PathParameters() { + params = append(params, &ParamAdapter{rParam}) + } + return params +} + +func (r *WebServiceAdapter) Routes() []common.Route { + var routes []common.Route + for _, rRoute := range r.WebService.Routes() { + localRoute := rRoute + routes = append(routes, &RouteAdapter{&localRoute}) + } + return routes +} diff --git a/vendor/k8s.io/kube-openapi/pkg/handler/default_pruning.go b/vendor/k8s.io/kube-openapi/pkg/handler/default_pruning.go new file mode 100644 index 000000000..53bd9a640 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/handler/default_pruning.go @@ -0,0 +1,208 @@ +/* +Copyright 2020 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 handler + +import "k8s.io/kube-openapi/pkg/validation/spec" + +// PruneDefaults remove all the defaults recursively from all the +// schemas in the definitions, and does not modify the definitions in +// place. +func PruneDefaults(definitions spec.Definitions) spec.Definitions { + definitionsCloned := false + for k, v := range definitions { + if s := PruneDefaultsSchema(&v); s != &v { + if !definitionsCloned { + definitionsCloned = true + orig := definitions + definitions = make(spec.Definitions, len(orig)) + for k2, v2 := range orig { + definitions[k2] = v2 + } + } + definitions[k] = *s + } + } + return definitions +} + +// PruneDefaultsSchema remove all the defaults recursively from the +// schema in place. +func PruneDefaultsSchema(schema *spec.Schema) *spec.Schema { + if schema == nil { + return nil + } + + orig := schema + clone := func() { + if orig == schema { + schema = &spec.Schema{} + *schema = *orig + } + } + + if schema.Default != nil { + clone() + schema.Default = nil + } + + definitionsCloned := false + for k, v := range schema.Definitions { + if s := PruneDefaultsSchema(&v); s != &v { + if !definitionsCloned { + definitionsCloned = true + clone() + schema.Definitions = make(spec.Definitions, len(orig.Definitions)) + for k2, v2 := range orig.Definitions { + schema.Definitions[k2] = v2 + } + } + schema.Definitions[k] = *s + } + } + + propertiesCloned := false + for k, v := range schema.Properties { + if s := PruneDefaultsSchema(&v); s != &v { + if !propertiesCloned { + propertiesCloned = true + clone() + schema.Properties = make(map[string]spec.Schema, len(orig.Properties)) + for k2, v2 := range orig.Properties { + schema.Properties[k2] = v2 + } + } + schema.Properties[k] = *s + } + } + + patternPropertiesCloned := false + for k, v := range schema.PatternProperties { + if s := PruneDefaultsSchema(&v); s != &v { + if !patternPropertiesCloned { + patternPropertiesCloned = true + clone() + schema.PatternProperties = make(map[string]spec.Schema, len(orig.PatternProperties)) + for k2, v2 := range orig.PatternProperties { + schema.PatternProperties[k2] = v2 + } + } + schema.PatternProperties[k] = *s + } + } + + dependenciesCloned := false + for k, v := range schema.Dependencies { + if s := PruneDefaultsSchema(v.Schema); s != v.Schema { + if !dependenciesCloned { + dependenciesCloned = true + clone() + schema.Dependencies = make(spec.Dependencies, len(orig.Dependencies)) + for k2, v2 := range orig.Dependencies { + schema.Dependencies[k2] = v2 + } + } + v.Schema = s + schema.Dependencies[k] = v + } + } + + allOfCloned := false + for i := range schema.AllOf { + if s := PruneDefaultsSchema(&schema.AllOf[i]); s != &schema.AllOf[i] { + if !allOfCloned { + allOfCloned = true + clone() + schema.AllOf = make([]spec.Schema, len(orig.AllOf)) + copy(schema.AllOf, orig.AllOf) + } + schema.AllOf[i] = *s + } + } + + anyOfCloned := false + for i := range schema.AnyOf { + if s := PruneDefaultsSchema(&schema.AnyOf[i]); s != &schema.AnyOf[i] { + if !anyOfCloned { + anyOfCloned = true + clone() + schema.AnyOf = make([]spec.Schema, len(orig.AnyOf)) + copy(schema.AnyOf, orig.AnyOf) + } + schema.AnyOf[i] = *s + } + } + + oneOfCloned := false + for i := range schema.OneOf { + if s := PruneDefaultsSchema(&schema.OneOf[i]); s != &schema.OneOf[i] { + if !oneOfCloned { + oneOfCloned = true + clone() + schema.OneOf = make([]spec.Schema, len(orig.OneOf)) + copy(schema.OneOf, orig.OneOf) + } + schema.OneOf[i] = *s + } + } + + if schema.Not != nil { + if s := PruneDefaultsSchema(schema.Not); s != schema.Not { + clone() + schema.Not = s + } + } + + if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil { + if s := PruneDefaultsSchema(schema.AdditionalProperties.Schema); s != schema.AdditionalProperties.Schema { + clone() + schema.AdditionalProperties = &spec.SchemaOrBool{Schema: s, Allows: schema.AdditionalProperties.Allows} + } + } + + if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil { + if s := PruneDefaultsSchema(schema.AdditionalItems.Schema); s != schema.AdditionalItems.Schema { + clone() + schema.AdditionalItems = &spec.SchemaOrBool{Schema: s, Allows: schema.AdditionalItems.Allows} + } + } + + if schema.Items != nil { + if schema.Items.Schema != nil { + if s := PruneDefaultsSchema(schema.Items.Schema); s != schema.Items.Schema { + clone() + schema.Items = &spec.SchemaOrArray{Schema: s} + } + } else { + itemsCloned := false + for i := range schema.Items.Schemas { + if s := PruneDefaultsSchema(&schema.Items.Schemas[i]); s != &schema.Items.Schemas[i] { + if !itemsCloned { + clone() + schema.Items = &spec.SchemaOrArray{ + Schemas: make([]spec.Schema, len(orig.Items.Schemas)), + } + itemsCloned = true + copy(schema.Items.Schemas, orig.Items.Schemas) + } + schema.Items.Schemas[i] = *s + } + } + } + } + + return schema +} diff --git a/vendor/k8s.io/kube-openapi/pkg/handler/handler.go b/vendor/k8s.io/kube-openapi/pkg/handler/handler.go new file mode 100644 index 000000000..37cb96f1b --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/handler/handler.go @@ -0,0 +1,207 @@ +/* +Copyright 2017 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 handler + +import ( + "bytes" + "crypto/sha512" + "fmt" + "net/http" + "strconv" + "sync" + "time" + + "github.com/NYTimes/gziphandler" + "github.com/emicklei/go-restful/v3" + "github.com/golang/protobuf/proto" + openapi_v2 "github.com/google/gnostic/openapiv2" + "github.com/google/uuid" + "github.com/munnerz/goautoneg" + klog "k8s.io/klog/v2" + "k8s.io/kube-openapi/pkg/builder" + "k8s.io/kube-openapi/pkg/cached" + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/common/restfuladapter" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +const ( + subTypeProtobufDeprecated = "com.github.proto-openapi.spec.v2@v1.0+protobuf" + subTypeProtobuf = "com.github.proto-openapi.spec.v2.v1.0+protobuf" + subTypeJSON = "json" +) + +func computeETag(data []byte) string { + if data == nil { + return "" + } + return fmt.Sprintf("%X", sha512.Sum512(data)) +} + +type timedSpec struct { + spec []byte + lastModified time.Time +} + +// OpenAPIService is the service responsible for serving OpenAPI spec. It has +// the ability to safely change the spec while serving it. +type OpenAPIService struct { + specCache cached.Replaceable[*spec.Swagger] + jsonCache cached.Data[timedSpec] + protoCache cached.Data[timedSpec] +} + +// NewOpenAPIService builds an OpenAPIService starting with the given spec. +func NewOpenAPIService(swagger *spec.Swagger) *OpenAPIService { + return NewOpenAPIServiceLazy(cached.NewResultOK(swagger, uuid.New().String())) +} + +// NewOpenAPIServiceLazy builds an OpenAPIService from lazy spec. +func NewOpenAPIServiceLazy(swagger cached.Data[*spec.Swagger]) *OpenAPIService { + o := &OpenAPIService{} + o.UpdateSpecLazy(swagger) + + o.jsonCache = cached.NewTransformer[*spec.Swagger](func(result cached.Result[*spec.Swagger]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + json, err := result.Data.MarshalJSON() + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + return cached.NewResultOK(timedSpec{spec: json, lastModified: time.Now()}, computeETag(json)) + }, &o.specCache) + o.protoCache = cached.NewTransformer(func(result cached.Result[timedSpec]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + proto, err := ToProtoBinary(result.Data.spec) + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + // We can re-use the same etag as json because of the Vary header. + return cached.NewResultOK(timedSpec{spec: proto, lastModified: result.Data.lastModified}, result.Etag) + }, o.jsonCache) + return o +} + +func (o *OpenAPIService) UpdateSpec(swagger *spec.Swagger) error { + o.UpdateSpecLazy(cached.NewResultOK(swagger, uuid.New().String())) + return nil +} + +func (o *OpenAPIService) UpdateSpecLazy(swagger cached.Data[*spec.Swagger]) { + o.specCache.Replace(swagger) +} + +func ToProtoBinary(json []byte) ([]byte, error) { + document, err := openapi_v2.ParseDocument(json) + if err != nil { + return nil, err + } + return proto.Marshal(document) +} + +// RegisterOpenAPIVersionedService registers a handler to provide access to provided swagger spec. +// +// Deprecated: use OpenAPIService.RegisterOpenAPIVersionedService instead. +func RegisterOpenAPIVersionedService(spec *spec.Swagger, servePath string, handler common.PathHandler) (*OpenAPIService, error) { + o := NewOpenAPIService(spec) + return o, o.RegisterOpenAPIVersionedService(servePath, handler) +} + +// RegisterOpenAPIVersionedService registers a handler to provide access to provided swagger spec. +func (o *OpenAPIService) RegisterOpenAPIVersionedService(servePath string, handler common.PathHandler) error { + // Mutex protects the cache chain + var mutex sync.Mutex + + accepted := []struct { + Type string + SubType string + ReturnedContentType string + GetDataAndEtag cached.Data[timedSpec] + }{ + {"application", subTypeJSON, "application/" + subTypeJSON, o.jsonCache}, + {"application", subTypeProtobufDeprecated, "application/" + subTypeProtobuf, o.protoCache}, + {"application", subTypeProtobuf, "application/" + subTypeProtobuf, o.protoCache}, + } + + handler.Handle(servePath, gziphandler.GzipHandler(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + decipherableFormats := r.Header.Get("Accept") + if decipherableFormats == "" { + decipherableFormats = "*/*" + } + clauses := goautoneg.ParseAccept(decipherableFormats) + w.Header().Add("Vary", "Accept") + for _, clause := range clauses { + for _, accepts := range accepted { + if clause.Type != accepts.Type && clause.Type != "*" { + continue + } + if clause.SubType != accepts.SubType && clause.SubType != "*" { + continue + } + // serve the first matching media type in the sorted clause list + mutex.Lock() + result := accepts.GetDataAndEtag.Get() + mutex.Unlock() + if result.Err != nil { + klog.Errorf("Error in OpenAPI handler: %s", result.Err) + // only return a 503 if we have no older cache data to serve + if result.Data.spec == nil { + w.WriteHeader(http.StatusServiceUnavailable) + return + } + } + // Set Content-Type header in the reponse + w.Header().Set("Content-Type", accepts.ReturnedContentType) + + // ETag must be enclosed in double quotes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag + w.Header().Set("Etag", strconv.Quote(result.Etag)) + // ServeContent will take care of caching using eTag. + http.ServeContent(w, r, servePath, result.Data.lastModified, bytes.NewReader(result.Data.spec)) + return + } + } + // Return 406 for not acceptable format + w.WriteHeader(406) + return + }), + )) + + return nil +} + +// BuildAndRegisterOpenAPIVersionedService builds the spec and registers a handler to provide access to it. +// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIVersionedService. +// +// Deprecated: BuildAndRegisterOpenAPIVersionedServiceFromRoutes should be used instead. +func BuildAndRegisterOpenAPIVersionedService(servePath string, webServices []*restful.WebService, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) { + return BuildAndRegisterOpenAPIVersionedServiceFromRoutes(servePath, restfuladapter.AdaptWebServices(webServices), config, handler) +} + +// BuildAndRegisterOpenAPIVersionedServiceFromRoutes builds the spec and registers a handler to provide access to it. +// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIVersionedService. +func BuildAndRegisterOpenAPIVersionedServiceFromRoutes(servePath string, routeContainers []common.RouteContainer, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) { + spec, err := builder.BuildOpenAPISpecFromRoutes(routeContainers, config) + if err != nil { + return nil, err + } + o := NewOpenAPIService(spec) + return o, o.RegisterOpenAPIVersionedService(servePath, handler) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go b/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go index ec4adcdec..66b7a68da 100644 --- a/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go +++ b/vendor/k8s.io/kube-openapi/pkg/handler3/handler.go @@ -21,11 +21,9 @@ import ( "crypto/sha512" "encoding/json" "fmt" - "mime" "net/http" "net/url" "path" - "sort" "strconv" "strings" "sync" @@ -33,23 +31,18 @@ import ( "github.com/golang/protobuf/proto" openapi_v3 "github.com/google/gnostic/openapiv3" + "github.com/google/uuid" "github.com/munnerz/goautoneg" + "k8s.io/klog/v2" + "k8s.io/kube-openapi/pkg/cached" "k8s.io/kube-openapi/pkg/common" - "k8s.io/kube-openapi/pkg/internal/handler" "k8s.io/kube-openapi/pkg/spec3" - "k8s.io/kube-openapi/pkg/validation/spec" ) const ( - jsonExt = ".json" - - mimeJson = "application/json" - // TODO(mehdy): change @68f4ded to a version tag when gnostic add version tags. - mimePb = "application/com.github.googleapis.gnostic.OpenAPIv3@68f4ded+protobuf" - mimePbGz = "application/x-gzip" - - subTypeProtobuf = "com.github.proto-openapi.spec.v3@v1.0+protobuf" - subTypeJSON = "json" + subTypeProtobufDeprecated = "com.github.proto-openapi.spec.v3@v1.0+protobuf" + subTypeProtobuf = "com.github.proto-openapi.spec.v3.v1.0+protobuf" + subTypeJSON = "json" ) // OpenAPIV3Discovery is the format of the Discovery document for OpenAPI V3 @@ -65,29 +58,63 @@ type OpenAPIV3DiscoveryGroupVersion struct { ServerRelativeURL string `json:"serverRelativeURL"` } +func ToV3ProtoBinary(json []byte) ([]byte, error) { + document, err := openapi_v3.ParseDocument(json) + if err != nil { + return nil, err + } + return proto.Marshal(document) +} + +type timedSpec struct { + spec []byte + lastModified time.Time +} + +// This type is protected by the lock on OpenAPIService. +type openAPIV3Group struct { + specCache cached.Replaceable[*spec3.OpenAPI] + pbCache cached.Data[timedSpec] + jsonCache cached.Data[timedSpec] +} + +func newOpenAPIV3Group() *openAPIV3Group { + o := &openAPIV3Group{} + o.jsonCache = cached.NewTransformer[*spec3.OpenAPI](func(result cached.Result[*spec3.OpenAPI]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + json, err := json.Marshal(result.Data) + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + return cached.NewResultOK(timedSpec{spec: json, lastModified: time.Now()}, computeETag(json)) + }, &o.specCache) + o.pbCache = cached.NewTransformer(func(result cached.Result[timedSpec]) cached.Result[timedSpec] { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + proto, err := ToV3ProtoBinary(result.Data.spec) + if err != nil { + return cached.NewResultErr[timedSpec](err) + } + return cached.NewResultOK(timedSpec{spec: proto, lastModified: result.Data.lastModified}, result.Etag) + }, o.jsonCache) + return o +} + +func (o *openAPIV3Group) UpdateSpec(openapi cached.Data[*spec3.OpenAPI]) { + o.specCache.Replace(openapi) +} + // OpenAPIService is the service responsible for serving OpenAPI spec. It has // the ability to safely change the spec while serving it. type OpenAPIService struct { - // rwMutex protects All members of this service. - rwMutex sync.RWMutex - lastModified time.Time - v3Schema map[string]*OpenAPIV3Group -} + // Mutex protects the schema map. + mutex sync.Mutex + v3Schema map[string]*openAPIV3Group -type OpenAPIV3Group struct { - rwMutex sync.RWMutex - - lastModified time.Time - - pbCache handler.HandlerCache - jsonCache handler.HandlerCache - etagCache handler.HandlerCache -} - -func init() { - mime.AddExtensionType(".json", mimeJson) - mime.AddExtensionType(".pb-v1", mimePb) - mime.AddExtensionType(".gz", mimePbGz) + discoveryCache cached.Replaceable[timedSpec] } func computeETag(data []byte) string { @@ -106,92 +133,90 @@ func constructServerRelativeURL(gvString, etag string) string { } // NewOpenAPIService builds an OpenAPIService starting with the given spec. -func NewOpenAPIService(spec *spec.Swagger) (*OpenAPIService, error) { +func NewOpenAPIService() *OpenAPIService { o := &OpenAPIService{} - o.v3Schema = make(map[string]*OpenAPIV3Group) - return o, nil + o.v3Schema = make(map[string]*openAPIV3Group) + // We're not locked because we haven't shared the structure yet. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) + return o } -func (o *OpenAPIService) getGroupBytes() ([]byte, error) { - o.rwMutex.RLock() - defer o.rwMutex.RUnlock() - keys := make([]string, len(o.v3Schema)) - i := 0 - for k := range o.v3Schema { - keys[i] = k - i++ +func (o *OpenAPIService) buildDiscoveryCacheLocked() cached.Data[timedSpec] { + caches := make(map[string]cached.Data[timedSpec], len(o.v3Schema)) + for gvName, group := range o.v3Schema { + caches[gvName] = group.jsonCache } - - sort.Strings(keys) - discovery := &OpenAPIV3Discovery{Paths: make(map[string]OpenAPIV3DiscoveryGroupVersion)} - for gvString, groupVersion := range o.v3Schema { - etagBytes, err := groupVersion.etagCache.Get() + return cached.NewMerger(func(results map[string]cached.Result[timedSpec]) cached.Result[timedSpec] { + discovery := &OpenAPIV3Discovery{Paths: make(map[string]OpenAPIV3DiscoveryGroupVersion)} + for gvName, result := range results { + if result.Err != nil { + return cached.NewResultErr[timedSpec](result.Err) + } + discovery.Paths[gvName] = OpenAPIV3DiscoveryGroupVersion{ + ServerRelativeURL: constructServerRelativeURL(gvName, result.Etag), + } + } + j, err := json.Marshal(discovery) if err != nil { - return nil, err + return cached.NewResultErr[timedSpec](err) } - discovery.Paths[gvString] = OpenAPIV3DiscoveryGroupVersion{ - ServerRelativeURL: constructServerRelativeURL(gvString, string(etagBytes)), - } - } - j, err := json.Marshal(discovery) - if err != nil { - return nil, err - } - return j, nil + return cached.NewResultOK(timedSpec{spec: j, lastModified: time.Now()}, computeETag(j)) + }, caches) } func (o *OpenAPIService) getSingleGroupBytes(getType string, group string) ([]byte, string, time.Time, error) { - o.rwMutex.RLock() - defer o.rwMutex.RUnlock() + o.mutex.Lock() + defer o.mutex.Unlock() v, ok := o.v3Schema[group] if !ok { return nil, "", time.Now(), fmt.Errorf("Cannot find CRD group %s", group) } - if getType == subTypeJSON { - specBytes, err := v.jsonCache.Get() - if err != nil { - return nil, "", v.lastModified, err - } - etagBytes, err := v.etagCache.Get() - return specBytes, string(etagBytes), v.lastModified, err - } else if getType == subTypeProtobuf { - specPb, err := v.pbCache.Get() - if err != nil { - return nil, "", v.lastModified, err - } - etagBytes, err := v.etagCache.Get() - return specPb, string(etagBytes), v.lastModified, err + result := cached.Result[timedSpec]{} + switch getType { + case subTypeJSON: + result = v.jsonCache.Get() + case subTypeProtobuf, subTypeProtobufDeprecated: + result = v.pbCache.Get() + default: + return nil, "", time.Now(), fmt.Errorf("Invalid accept clause %s", getType) } - return nil, "", time.Now(), fmt.Errorf("Invalid accept clause %s", getType) + return result.Data.spec, result.Etag, result.Data.lastModified, result.Err } -func (o *OpenAPIService) UpdateGroupVersion(group string, openapi *spec3.OpenAPI) (err error) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() - +// UpdateGroupVersionLazy adds or updates an existing group with the new cached. +func (o *OpenAPIService) UpdateGroupVersionLazy(group string, openapi cached.Data[*spec3.OpenAPI]) { + o.mutex.Lock() + defer o.mutex.Unlock() if _, ok := o.v3Schema[group]; !ok { - o.v3Schema[group] = &OpenAPIV3Group{} + o.v3Schema[group] = newOpenAPIV3Group() + // Since there is a new item, we need to re-build the cache map. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) } - return o.v3Schema[group].UpdateSpec(openapi) + o.v3Schema[group].UpdateSpec(openapi) +} + +func (o *OpenAPIService) UpdateGroupVersion(group string, openapi *spec3.OpenAPI) { + o.UpdateGroupVersionLazy(group, cached.NewResultOK(openapi, uuid.New().String())) } func (o *OpenAPIService) DeleteGroupVersion(group string) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() + o.mutex.Lock() + defer o.mutex.Unlock() delete(o.v3Schema, group) -} - -func ToV3ProtoBinary(json []byte) ([]byte, error) { - document, err := openapi_v3.ParseDocument(json) - if err != nil { - return nil, err - } - return proto.Marshal(document) + // Rebuild the merge cache map since the items have changed. + o.discoveryCache.Replace(o.buildDiscoveryCacheLocked()) } func (o *OpenAPIService) HandleDiscovery(w http.ResponseWriter, r *http.Request) { - data, _ := o.getGroupBytes() - http.ServeContent(w, r, "/openapi/v3", time.Now(), bytes.NewReader(data)) + result := o.discoveryCache.Get() + if result.Err != nil { + klog.Errorf("Error serving discovery: %s", result.Err) + w.WriteHeader(http.StatusInternalServerError) + return + } + w.Header().Set("Etag", strconv.Quote(result.Etag)) + w.Header().Set("Content-Type", "application/json") + http.ServeContent(w, r, "/openapi/v3", result.Data.lastModified, bytes.NewReader(result.Data.spec)) } func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Request) { @@ -210,11 +235,13 @@ func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Reque } accepted := []struct { - Type string - SubType string + Type string + SubType string + ReturnedContentType string }{ - {"application", subTypeJSON}, - {"application", subTypeProtobuf}, + {"application", subTypeJSON, "application/" + subTypeJSON}, + {"application", subTypeProtobuf, "application/" + subTypeProtobuf}, + {"application", subTypeProtobufDeprecated, "application/" + subTypeProtobuf}, } for _, clause := range clauses { @@ -229,6 +256,9 @@ func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Reque if err != nil { return } + // Set Content-Type header in the reponse + w.Header().Set("Content-Type", accepts.ReturnedContentType) + // ETag must be enclosed in double quotes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag w.Header().Set("Etag", strconv.Quote(etag)) @@ -262,30 +292,3 @@ func (o *OpenAPIService) RegisterOpenAPIV3VersionedService(servePath string, han handler.HandlePrefix(servePath+"/", http.HandlerFunc(o.HandleGroupVersion)) return nil } - -func (o *OpenAPIV3Group) UpdateSpec(openapi *spec3.OpenAPI) (err error) { - o.rwMutex.Lock() - defer o.rwMutex.Unlock() - - o.jsonCache = o.jsonCache.New(func() ([]byte, error) { - return json.Marshal(openapi) - }) - o.pbCache = o.pbCache.New(func() ([]byte, error) { - json, err := o.jsonCache.Get() - if err != nil { - return nil, err - } - return ToV3ProtoBinary(json) - }) - // TODO: This forces a json marshal of corresponding group-versions. - // We should look to replace this with a faster hashing mechanism. - o.etagCache = o.etagCache.New(func() ([]byte, error) { - json, err := o.jsonCache.Get() - if err != nil { - return nil, err - } - return []byte(computeETag(json)), nil - }) - o.lastModified = time.Now() - return nil -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/flags.go b/vendor/k8s.io/kube-openapi/pkg/internal/flags.go index 3ff3c8d89..bef603782 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/flags.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/flags.go @@ -18,3 +18,7 @@ package internal // Used by tests to selectively disable experimental JSON unmarshaler var UseOptimizedJSONUnmarshaling bool = true +var UseOptimizedJSONUnmarshalingV3 bool = true + +// Used by tests to selectively disable experimental JSON marshaler +var UseOptimizedJSONMarshaling bool = true diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go b/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go deleted file mode 100644 index e128c26eb..000000000 --- a/vendor/k8s.io/kube-openapi/pkg/internal/handler/handler_cache.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2021 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 handler - -import ( - "sync" -) - -// HandlerCache represents a lazy cache for generating a byte array -// It is used to lazily marshal OpenAPI v2/v3 and lazily generate the ETag -type HandlerCache struct { - BuildCache func() ([]byte, error) - once sync.Once - bytes []byte - err error -} - -// Get either returns the cached value or calls BuildCache() once before caching and returning -// its results. If BuildCache returns an error, the last valid value for the cache (from prior -// calls to New()) is used instead if possible. -func (c *HandlerCache) Get() ([]byte, error) { - c.once.Do(func() { - bytes, err := c.BuildCache() - // if there is an error updating the cache, there can be situations where - // c.bytes contains a valid value (carried over from the previous update) - // but c.err is also not nil; the cache user is expected to check for this - c.err = err - if c.err == nil { - // don't override previous spec if we had an error - c.bytes = bytes - } - }) - return c.bytes, c.err -} - -// New creates a new HandlerCache for situations where a cache refresh is needed. -// This function is not thread-safe and should not be called at the same time as Get(). -func (c *HandlerCache) New(cacheBuilder func() ([]byte, error)) HandlerCache { - return HandlerCache{ - bytes: c.bytes, - BuildCache: cacheBuilder, - } -} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go b/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go new file mode 100644 index 000000000..7393bacf7 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/internal/serialization.go @@ -0,0 +1,65 @@ +/* +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 internal + +import ( + "github.com/go-openapi/jsonreference" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" +) + +// DeterministicMarshal calls the jsonv2 library with the deterministic +// flag in order to have stable marshaling. +func DeterministicMarshal(in any) ([]byte, error) { + return jsonv2.MarshalOptions{Deterministic: true}.Marshal(jsonv2.EncodeOptions{}, in) +} + +// JSONRefFromMap populates a json reference object if the map v contains a $ref key. +func JSONRefFromMap(jsonRef *jsonreference.Ref, v map[string]interface{}) error { + if v == nil { + return nil + } + if vv, ok := v["$ref"]; ok { + if str, ok := vv.(string); ok { + ref, err := jsonreference.New(str) + if err != nil { + return err + } + *jsonRef = ref + } + } + return nil +} + +// SanitizeExtensions sanitizes the input map such that non extension +// keys (non x-*, X-*) keys are dropped from the map. Returns the new +// modified map, or nil if the map is now empty. +func SanitizeExtensions(e map[string]interface{}) map[string]interface{} { + for k := range e { + if !IsExtensionKey(k) { + delete(e, k) + } + } + if len(e) == 0 { + e = nil + } + return e +} + +// IsExtensionKey returns true if the input string is of format x-* or X-* +func IsExtensionKey(k string) bool { + return len(k) > 1 && (k[0] == 'x' || k[0] == 'X') && k[1] == '-' +} diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go index febde20f9..e6c6216ff 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal.go @@ -34,6 +34,13 @@ type MarshalOptions struct { // unknown JSON object members. DiscardUnknownMembers bool + // Deterministic specifies that the same input value will be serialized + // as the exact same output bytes. Different processes of + // the same program will serialize equal values to the same bytes, + // but different versions of the same program are not guaranteed + // to produce the exact same sequence of bytes. + Deterministic bool + // formatDepth is the depth at which we respect the format flag. formatDepth int // format is custom formatting for the value at the specified depth. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go index 204d0648d..c62b1f320 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_any.go @@ -62,7 +62,7 @@ func unmarshalValueAny(uo UnmarshalOptions, dec *Decoder) (any, error) { } return dec.stringCache.make(val), nil case '0': - fv, _ := parseFloat(val, 64) // ignore error since readValue gaurantees val is valid + fv, _ := parseFloat(val, 64) // ignore error since readValue guarantees val is valid return fv, nil default: panic("BUG: invalid kind: " + k.String()) @@ -99,13 +99,32 @@ func marshalObjectAny(mo MarshalOptions, enc *Encoder, obj map[string]any) error if !enc.options.AllowInvalidUTF8 { enc.tokens.last.disableNamespace() } - for name, val := range obj { - if err := enc.WriteToken(String(name)); err != nil { - return err + if !mo.Deterministic || len(obj) <= 1 { + for name, val := range obj { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + if err := marshalValueAny(mo, enc, val); err != nil { + return err + } } - if err := marshalValueAny(mo, enc, val); err != nil { - return err + } else { + names := getStrings(len(obj)) + var i int + for name := range obj { + (*names)[i] = name + i++ } + names.Sort() + for _, name := range *names { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + if err := marshalValueAny(mo, enc, obj[name]); err != nil { + return err + } + } + putStrings(names) } if err := enc.WriteToken(ObjectEnd); err != nil { return err diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go index fcf3d5000..fd26eba35 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_default.go @@ -5,6 +5,7 @@ package json import ( + "bytes" "encoding/base32" "encoding/base64" "encoding/hex" @@ -12,6 +13,7 @@ import ( "fmt" "math" "reflect" + "sort" "strconv" "sync" ) @@ -228,13 +230,7 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { } } val := enc.UnusedBuffer() - var b []byte - if va.Kind() == reflect.Array { - // TODO(https://go.dev/issue/47066): Avoid reflect.Value.Slice. - b = va.Slice(0, va.Len()).Bytes() - } else { - b = va.Bytes() - } + b := va.Bytes() n := len(`"`) + encodedLen(len(b)) + len(`"`) if cap(val) < n { val = make([]byte, n) @@ -248,19 +244,19 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { } unmarshalDefault := fncs.unmarshal fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - decode, decodedLen := decodeBase64, decodedLenBase64 + decode, decodedLen, encodedLen := decodeBase64, decodedLenBase64, encodedLenBase64 if uo.format != "" && uo.formatDepth == dec.tokens.depth() { switch uo.format { case "base64": - decode, decodedLen = decodeBase64, decodedLenBase64 + decode, decodedLen, encodedLen = decodeBase64, decodedLenBase64, encodedLenBase64 case "base64url": - decode, decodedLen = decodeBase64URL, decodedLenBase64URL + decode, decodedLen, encodedLen = decodeBase64URL, decodedLenBase64URL, encodedLenBase64URL case "base32": - decode, decodedLen = decodeBase32, decodedLenBase32 + decode, decodedLen, encodedLen = decodeBase32, decodedLenBase32, encodedLenBase32 case "base32hex": - decode, decodedLen = decodeBase32Hex, decodedLenBase32Hex + decode, decodedLen, encodedLen = decodeBase32Hex, decodedLenBase32Hex, encodedLenBase32Hex case "base16", "hex": - decode, decodedLen = decodeBase16, decodedLenBase16 + decode, decodedLen, encodedLen = decodeBase16, decodedLenBase16, encodedLenBase16 case "array": uo.format = "" return unmarshalDefault(uo, dec, va) @@ -290,23 +286,28 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { n-- } n = decodedLen(n) - var b []byte + b := va.Bytes() if va.Kind() == reflect.Array { - // TODO(https://go.dev/issue/47066): Avoid reflect.Value.Slice. - b = va.Slice(0, va.Len()).Bytes() if n != len(b) { err := fmt.Errorf("decoded base64 length of %d mismatches array length of %d", n, len(b)) return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} } } else { - b = va.Bytes() if b == nil || cap(b) < n { b = make([]byte, n) } else { b = b[:n] } } - if _, err := decode(b, val); err != nil { + n2, err := decode(b, val) + if err == nil && len(val) != encodedLen(n2) { + // TODO(https://go.dev/issue/53845): RFC 4648, section 3.3, + // specifies that non-alphabet characters must be rejected. + // Unfortunately, the "base32" and "base64" packages allow + // '\r' and '\n' characters by default. + err = errors.New("illegal data at input byte " + strconv.Itoa(bytes.IndexAny(val, "\r\n"))) + } + if err != nil { return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} } if va.Kind() == reflect.Slice { @@ -412,7 +413,7 @@ func makeUintArshaler(t reflect.Type) *arshaler { return nil } - x := math.Float64frombits(uint64(va.Uint())) + x := math.Float64frombits(va.Uint()) return enc.writeNumber(x, rawUintNumber, mo.StringifyNumbers) } fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { @@ -450,7 +451,7 @@ func makeUintArshaler(t reflect.Type) *arshaler { err := fmt.Errorf("cannot parse %q as unsigned integer: %w", val, strconv.ErrRange) return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} } - va.SetUint(uint64(n)) + va.SetUint(n) return nil } return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t} @@ -549,23 +550,9 @@ func makeFloatArshaler(t reflect.Type) *arshaler { return &fncs } -var mapIterPool = sync.Pool{ - New: func() any { return new(reflect.MapIter) }, -} - -func getMapIter(mv reflect.Value) *reflect.MapIter { - iter := mapIterPool.Get().(*reflect.MapIter) - iter.Reset(mv) - return iter -} -func putMapIter(iter *reflect.MapIter) { - iter.Reset(reflect.Value{}) // allow underlying map to be garbage collected - mapIterPool.Put(iter) -} - func makeMapArshaler(t reflect.Type) *arshaler { // NOTE: The logic below disables namespaces for tracking duplicate names - // when handling map keys with a unique represention. + // when handling map keys with a unique representation. // NOTE: Values retrieved from a map are not addressable, // so we shallow copy the values to make them addressable and @@ -641,24 +628,76 @@ func makeMapArshaler(t reflect.Type) *arshaler { enc.tokens.last.disableNamespace() } - // NOTE: Map entries are serialized in a non-deterministic order. - // Users that need stable output should call RawValue.Canonicalize. - // TODO(go1.19): Remove use of a sync.Pool with reflect.MapIter. - // Calling reflect.Value.MapRange no longer allocates. - // See https://go.dev/cl/400675. - iter := getMapIter(va.Value) - defer putMapIter(iter) - for iter.Next() { - k.SetIterKey(iter) - if err := marshalKey(mko, enc, k); err != nil { - // TODO: If err is errMissingName, then wrap it as a - // SemanticError since this key type cannot be serialized - // as a JSON string. - return err + switch { + case !mo.Deterministic || n <= 1: + for iter := va.Value.MapRange(); iter.Next(); { + k.SetIterKey(iter) + if err := marshalKey(mko, enc, k); err != nil { + // TODO: If err is errMissingName, then wrap it as a + // SemanticError since this key type cannot be serialized + // as a JSON string. + return err + } + v.SetIterValue(iter) + if err := marshalVal(mo, enc, v); err != nil { + return err + } } - v.SetIterValue(iter) - if err := marshalVal(mo, enc, v); err != nil { - return err + case !nonDefaultKey && t.Key().Kind() == reflect.String: + names := getStrings(n) + for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ { + k.SetIterKey(iter) + (*names)[i] = k.String() + } + names.Sort() + for _, name := range *names { + if err := enc.WriteToken(String(name)); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf. + k.SetString(name) + v.Set(va.MapIndex(k.Value)) + if err := marshalVal(mo, enc, v); err != nil { + return err + } + } + putStrings(names) + default: + type member struct { + name string // unquoted name + key addressableValue + } + members := make([]member, n) + keys := reflect.MakeSlice(reflect.SliceOf(t.Key()), n, n) + for i, iter := 0, va.Value.MapRange(); i < n && iter.Next(); i++ { + // Marshal the member name. + k := addressableValue{keys.Index(i)} // indexed slice element is always addressable + k.SetIterKey(iter) + if err := marshalKey(mko, enc, k); err != nil { + // TODO: If err is errMissingName, then wrap it as a + // SemanticError since this key type cannot be serialized + // as a JSON string. + return err + } + name := enc.unwriteOnlyObjectMemberName() + members[i] = member{name, k} + } + // TODO: If AllowDuplicateNames is enabled, then sort according + // to reflect.Value as well if the names are equal. + // See internal/fmtsort. + // TODO(https://go.dev/issue/47619): Use slices.SortFunc instead. + sort.Slice(members, func(i, j int) bool { + return lessUTF16(members[i].name, members[j].name) + }) + for _, member := range members { + if err := enc.WriteToken(String(member.name)); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use v.SetMapIndexOf. + v.Set(va.MapIndex(member.key.Value)) + if err := marshalVal(mo, enc, v); err != nil { + return err + } } } } @@ -856,7 +895,7 @@ func makeStructArshaler(t reflect.Type) *arshaler { // 2. The object namespace is guaranteed to be disabled. // 3. The object name is guaranteed to be valid and pre-escaped. // 4. There is no need to flush the buffer (for unwrite purposes). - // 5. There is no possibility of an error occuring. + // 5. There is no possibility of an error occurring. if optimizeCommon { // Append any delimiters or optional whitespace. if enc.tokens.last.length() > 0 { @@ -996,7 +1035,7 @@ func makeStructArshaler(t reflect.Type) *arshaler { if fields.inlinedFallback == nil { // Skip unknown value since we have no place to store it. - if err := dec.skipValue(); err != nil { + if err := dec.SkipValue(); err != nil { return err } } else { diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go index 7476eda30..258a98247 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_inlined.go @@ -5,6 +5,7 @@ package json import ( + "bytes" "errors" "reflect" ) @@ -89,35 +90,61 @@ func marshalInlinedFallbackAll(mo MarshalOptions, enc *Encoder, va addressableVa } return nil } else { - if v.Len() == 0 { + m := v // must be a map[string]V + n := m.Len() + if n == 0 { return nil } - m := v + mk := newAddressableValue(stringType) mv := newAddressableValue(m.Type().Elem()) - for iter := m.MapRange(); iter.Next(); { - b, err := appendString(enc.UnusedBuffer(), iter.Key().String(), !enc.options.AllowInvalidUTF8, nil) + marshalKey := func(mk addressableValue) error { + b, err := appendString(enc.UnusedBuffer(), mk.String(), !enc.options.AllowInvalidUTF8, nil) if err != nil { return err } if insertUnquotedName != nil { - isVerbatim := consumeSimpleString(b) == len(b) + isVerbatim := bytes.IndexByte(b, '\\') < 0 name := unescapeStringMayCopy(b, isVerbatim) if !insertUnquotedName(name) { return &SyntacticError{str: "duplicate name " + string(b) + " in object"} } } - if err := enc.WriteValue(b); err != nil { - return err + return enc.WriteValue(b) + } + marshalVal := f.fncs.marshal + if mo.Marshalers != nil { + marshalVal, _ = mo.Marshalers.lookup(marshalVal, mv.Type()) + } + if !mo.Deterministic || n <= 1 { + for iter := m.MapRange(); iter.Next(); { + mk.SetIterKey(iter) + if err := marshalKey(mk); err != nil { + return err + } + mv.Set(iter.Value()) + if err := marshalVal(mo, enc, mv); err != nil { + return err + } } - - mv.Set(iter.Value()) - marshal := f.fncs.marshal - if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.lookup(marshal, mv.Type()) + } else { + names := getStrings(n) + for i, iter := 0, m.Value.MapRange(); i < n && iter.Next(); i++ { + mk.SetIterKey(iter) + (*names)[i] = mk.String() } - if err := marshal(mo, enc, mv); err != nil { - return err + names.Sort() + for _, name := range *names { + mk.SetString(name) + if err := marshalKey(mk); err != nil { + return err + } + // TODO(https://go.dev/issue/57061): Use mv.SetMapIndexOf. + mv.Set(m.MapIndex(mk.Value)) + if err := marshalVal(mo, enc, mv); err != nil { + return err + } } + putStrings(names) } return nil } @@ -162,7 +189,7 @@ func unmarshalInlinedFallbackNext(uo UnmarshalOptions, dec *Decoder, va addressa } else { name := string(unquotedName) // TODO: Intern this? - m := v + m := v // must be a map[string]V if m.IsNil() { m.Set(reflect.MakeMap(m.Type())) } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go index ef4e1f5e3..20899c868 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_methods.go @@ -21,8 +21,8 @@ var ( ) // MarshalerV1 is implemented by types that can marshal themselves. -// It is recommended that types implement MarshalerV2 unless -// the implementation is trying to avoid a hard dependency on this package. +// It is recommended that types implement MarshalerV2 unless the implementation +// is trying to avoid a hard dependency on the "jsontext" package. // // It is recommended that implementations return a buffer that is safe // for the caller to retain and potentially mutate. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go index 22e802221..fc8d5b007 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/arshal_time.go @@ -5,6 +5,7 @@ package json import ( + "errors" "fmt" "reflect" "strings" @@ -85,25 +86,39 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { fncs.nonDefault = true fncs.marshal = func(mo MarshalOptions, enc *Encoder, va addressableValue) error { format := time.RFC3339Nano + isRFC3339 := true if mo.format != "" && mo.formatDepth == enc.tokens.depth() { var err error - format, err = checkTimeFormat(mo.format) + format, isRFC3339, err = checkTimeFormat(mo.format) if err != nil { return &SemanticError{action: "marshal", GoType: t, Err: err} } } tt := va.Interface().(time.Time) - if y := tt.Year(); y < 0 || y >= 10000 { - // RFC 3339 is clear that years are 4 digits exactly. - // See https://go.dev/issue/4556#c15 for more discussion. - err := fmt.Errorf("year %d outside of range [0,9999]", y) - return &SemanticError{action: "marshal", GoType: t, Err: err} - } b := enc.UnusedBuffer() b = append(b, '"') b = tt.AppendFormat(b, format) b = append(b, '"') + if isRFC3339 { + // Not all Go timestamps can be represented as valid RFC 3339. + // Explicitly check for these edge cases. + // See https://go.dev/issue/4556 and https://go.dev/issue/54580. + var err error + switch b := b[len(`"`) : len(b)-len(`"`)]; { + case b[len("9999")] != '-': // year must be exactly 4 digits wide + err = errors.New("year outside of range [0,9999]") + case b[len(b)-1] != 'Z': + c := b[len(b)-len("Z07:00")] + if ('0' <= c && c <= '9') || parseDec2(b[len(b)-len("07:00"):]) >= 24 { + err = errors.New("timezone hour outside of range [0,23]") + } + } + if err != nil { + return &SemanticError{action: "marshal", GoType: t, Err: err} + } + return enc.WriteValue(b) // RFC 3339 never needs JSON escaping + } // The format may contain special characters that need escaping. // Verify that the result is a valid JSON string (common case), // otherwise escape the string correctly (slower case). @@ -113,10 +128,11 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { return enc.WriteValue(b) } fncs.unmarshal = func(uo UnmarshalOptions, dec *Decoder, va addressableValue) error { - format := time.RFC3339Nano + format := time.RFC3339 + isRFC3339 := true if uo.format != "" && uo.formatDepth == dec.tokens.depth() { var err error - format, err = checkTimeFormat(uo.format) + format, isRFC3339, err = checkTimeFormat(uo.format) if err != nil { return &SemanticError{action: "unmarshal", GoType: t, Err: err} } @@ -136,6 +152,29 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { case '"': val = unescapeStringMayCopy(val, flags.isVerbatim()) tt2, err := time.Parse(format, string(val)) + if isRFC3339 && err == nil { + // TODO(https://go.dev/issue/54580): RFC 3339 specifies + // the exact grammar of a valid timestamp. However, + // the parsing functionality in "time" is too loose and + // incorrectly accepts invalid timestamps as valid. + // Remove these manual checks when "time" checks it for us. + newParseError := func(layout, value, layoutElem, valueElem, message string) error { + return &time.ParseError{Layout: layout, Value: value, LayoutElem: layoutElem, ValueElem: valueElem, Message: message} + } + switch { + case val[len("2006-01-02T")+1] == ':': // hour must be two digits + err = newParseError(format, string(val), "15", string(val[len("2006-01-02T"):][:1]), "") + case val[len("2006-01-02T15:04:05")] == ',': // sub-second separator must be a period + err = newParseError(format, string(val), ".", ",", "") + case val[len(val)-1] != 'Z': + switch { + case parseDec2(val[len(val)-len("07:00"):]) >= 24: // timezone hour must be in range + err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone hour out of range") + case parseDec2(val[len(val)-len("00"):]) >= 60: // timezone minute must be in range + err = newParseError(format, string(val), "Z07:00", string(val[len(val)-len("Z07:00"):]), ": timezone minute out of range") + } + } + } if err != nil { return &SemanticError{action: "unmarshal", JSONKind: k, GoType: t, Err: err} } @@ -149,48 +188,54 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { return fncs } -func checkTimeFormat(format string) (string, error) { +func checkTimeFormat(format string) (string, bool, error) { // We assume that an exported constant in the time package will // always start with an uppercase ASCII letter. if len(format) > 0 && 'A' <= format[0] && format[0] <= 'Z' { switch format { case "ANSIC": - return time.ANSIC, nil + return time.ANSIC, false, nil case "UnixDate": - return time.UnixDate, nil + return time.UnixDate, false, nil case "RubyDate": - return time.RubyDate, nil + return time.RubyDate, false, nil case "RFC822": - return time.RFC822, nil + return time.RFC822, false, nil case "RFC822Z": - return time.RFC822Z, nil + return time.RFC822Z, false, nil case "RFC850": - return time.RFC850, nil + return time.RFC850, false, nil case "RFC1123": - return time.RFC1123, nil + return time.RFC1123, false, nil case "RFC1123Z": - return time.RFC1123Z, nil + return time.RFC1123Z, false, nil case "RFC3339": - return time.RFC3339, nil + return time.RFC3339, true, nil case "RFC3339Nano": - return time.RFC3339Nano, nil + return time.RFC3339Nano, true, nil case "Kitchen": - return time.Kitchen, nil + return time.Kitchen, false, nil case "Stamp": - return time.Stamp, nil + return time.Stamp, false, nil case "StampMilli": - return time.StampMilli, nil + return time.StampMilli, false, nil case "StampMicro": - return time.StampMicro, nil + return time.StampMicro, false, nil case "StampNano": - return time.StampNano, nil + return time.StampNano, false, nil default: // Reject any format that is an exported Go identifier in case // new format constants are added to the time package. if strings.TrimFunc(format, isLetterOrDigit) == "" { - return "", fmt.Errorf("undefined format layout: %v", format) + return "", false, fmt.Errorf("undefined format layout: %v", format) } } } - return format, nil + return format, false, nil +} + +// parseDec2 parses b as an unsigned, base-10, 2-digit number. +// It panics if len(b) < 2. The result is undefined if digits are not base-10. +func parseDec2(b []byte) byte { + return 10*(b[0]-'0') + (b[1] - '0') } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go index 998ad68fc..0d68b3233 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/decode.go @@ -347,9 +347,9 @@ func (d *Decoder) PeekKind() Kind { return next } -// skipValue is semantically equivalent to calling ReadValue and discarding +// SkipValue is semantically equivalent to calling ReadValue and discarding // the result except that memory is not wasted trying to hold the entire result. -func (d *Decoder) skipValue() error { +func (d *Decoder) SkipValue() error { switch d.PeekKind() { case '{', '[': // For JSON objects and arrays, keep skipping all tokens @@ -374,7 +374,7 @@ func (d *Decoder) skipValue() error { } // ReadToken reads the next Token, advancing the read offset. -// The returned token is only valid until the next Peek or Read call. +// The returned token is only valid until the next Peek, Read, or Skip call. // It returns io.EOF if there are no more tokens. func (d *Decoder) ReadToken() (Token, error) { // Determine the next kind. @@ -585,7 +585,7 @@ func (f valueFlags) isCanonical() bool { return f&stringNonCanonical == 0 } // ReadValue returns the next raw JSON value, advancing the read offset. // The value is stripped of any leading or trailing whitespace. -// The returned value is only valid until the next Peek or Read call and +// The returned value is only valid until the next Peek, Read, or Skip call and // may not be mutated while the Decoder remains in use. // If the decoder is currently at the end token for an object or array, // then it reports a SyntacticError and the internal state remains unchanged. @@ -1013,7 +1013,7 @@ func (d *Decoder) InputOffset() int64 { // UnreadBuffer returns the data remaining in the unread buffer, // which may contain zero or more bytes. // The returned buffer must not be mutated while Decoder continues to be used. -// The buffer contents are valid until the next Peek or Read call. +// The buffer contents are valid until the next Peek, Read, or Skip call. func (d *Decoder) UnreadBuffer() []byte { return d.unreadBuffer() } @@ -1213,7 +1213,7 @@ func consumeStringResumable(flags *valueFlags, b []byte, resumeOffset int, valid return n, &SyntacticError{str: "invalid escape sequence " + strconv.Quote(string(b[n:n+6])) + " within string"} } // Only certain control characters can use the \uFFFF notation - // for canonical formating (per RFC 8785, section 3.2.2.2.). + // for canonical formatting (per RFC 8785, section 3.2.2.2.). switch v1 { // \uFFFF notation not permitted for these characters. case '\b', '\f', '\n', '\r', '\t': diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go index ba4af4b7b..e4eefa3de 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/doc.go @@ -8,8 +8,7 @@ // primitive data types such as booleans, strings, and numbers, // in addition to structured data types such as objects and arrays. // -// -// Terminology +// # Terminology // // This package uses the terms "encode" and "decode" for syntactic functionality // that is concerned with processing JSON based on its grammar, and @@ -32,8 +31,7 @@ // // See RFC 8259 for more information. // -// -// Specifications +// # Specifications // // Relevant specifications include RFC 4627, RFC 7159, RFC 7493, RFC 8259, // and RFC 8785. Each RFC is generally a stricter subset of another RFC. @@ -60,8 +58,7 @@ // In particular, it makes specific choices about behavior that RFC 8259 // leaves as undefined in order to ensure greater interoperability. // -// -// JSON Representation of Go structs +// # JSON Representation of Go structs // // A Go struct is naturally represented as a JSON object, // where each Go struct field corresponds with a JSON object member. diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go index 5f98a8409..5b81ca15a 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/encode.go @@ -347,6 +347,30 @@ func (e *Encoder) unwriteEmptyObjectMember(prevName *string) bool { return true } +// unwriteOnlyObjectMemberName unwrites the only object member name +// and returns the unquoted name. +func (e *Encoder) unwriteOnlyObjectMemberName() string { + if last := e.tokens.last; !last.isObject() || last.length() != 1 { + panic("BUG: must be called on an object after writing first name") + } + + // Unwrite the name and whitespace. + b := trimSuffixString(e.buf) + isVerbatim := bytes.IndexByte(e.buf[len(b):], '\\') < 0 + name := string(unescapeStringMayCopy(e.buf[len(b):], isVerbatim)) + e.buf = trimSuffixWhitespace(b) + + // Undo state changes. + e.tokens.last.decrement() + if !e.options.AllowDuplicateNames { + if e.tokens.last.isActiveNamespace() { + e.namespaces.last().removeLast() + } + e.names.clearLast() + } + return name +} + func trimSuffixWhitespace(b []byte) []byte { // NOTE: The arguments and logic are kept simple to keep this inlineable. n := len(b) - 1 diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go index f72282211..60e93270f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/pools.go @@ -8,6 +8,7 @@ import ( "bytes" "io" "math/bits" + "sort" "sync" ) @@ -148,3 +149,34 @@ func putStreamingDecoder(d *Decoder) { streamingDecoderPool.Put(d) } } + +var stringsPools = &sync.Pool{New: func() any { return new(stringSlice) }} + +type stringSlice []string + +// getStrings returns a non-nil pointer to a slice with length n. +func getStrings(n int) *stringSlice { + s := stringsPools.Get().(*stringSlice) + if cap(*s) < n { + *s = make([]string, n) + } + *s = (*s)[:n] + return s +} + +func putStrings(s *stringSlice) { + if cap(*s) > 1<<10 { + *s = nil // avoid pinning arbitrarily large amounts of memory + } + stringsPools.Put(s) +} + +// Sort sorts the string slice according to RFC 8785, section 3.2.3. +func (ss *stringSlice) Sort() { + // TODO(https://go.dev/issue/47619): Use slices.SortFunc instead. + sort.Sort(ss) +} + +func (ss *stringSlice) Len() int { return len(*ss) } +func (ss *stringSlice) Less(i, j int) bool { return lessUTF16((*ss)[i], (*ss)[j]) } +func (ss *stringSlice) Swap(i, j int) { (*ss)[i], (*ss)[j] = (*ss)[j], (*ss)[i] } diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go index d9c33f2b4..ee14c753f 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/state.go @@ -721,7 +721,7 @@ func (s *uintSet) has(i uint) bool { return s.lo.has(i) } else { i -= 64 - iHi, iLo := int(i/64), uint(i%64) + iHi, iLo := int(i/64), i%64 return iHi < len(s.hi) && s.hi[iHi].has(iLo) } } @@ -735,7 +735,7 @@ func (s *uintSet) insert(i uint) bool { return !has } else { i -= 64 - iHi, iLo := int(i/64), uint(i%64) + iHi, iLo := int(i/64), i%64 if iHi >= len(s.hi) { s.hi = append(s.hi, make([]uintSet64, iHi+1-len(s.hi))...) s.hi = s.hi[:cap(s.hi)] diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go index 08509c296..9acba7dad 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/token.go @@ -112,7 +112,7 @@ func Bool(b bool) Token { return False } -// String construct a Token representing a JSON string. +// String constructs a Token representing a JSON string. // The provided string should contain valid UTF-8, otherwise invalid characters // may be mangled as the Unicode replacement character. func String(s string) Token { @@ -225,7 +225,7 @@ func (t Token) appendString(dst []byte, validateUTF8, preserveRaw bool, escapeRu } // String returns the unescaped string value for a JSON string. -// For other JSON kinds, this returns the raw JSON represention. +// For other JSON kinds, this returns the raw JSON representation. func (t Token) String() string { // This is inlinable to take advantage of "function outlining". // This avoids an allocation for the string(b) conversion @@ -373,10 +373,10 @@ func (t Token) Int() int64 { case 'i': return int64(t.num) case 'u': - if uint64(t.num) > maxInt64 { + if t.num > maxInt64 { return maxInt64 } - return int64(uint64(t.num)) + return int64(t.num) } } @@ -425,7 +425,7 @@ func (t Token) Uint() uint64 { // Handle exact integer value. switch t.str[0] { case 'u': - return uint64(t.num) + return t.num case 'i': if int64(t.num) < minUint64 { return minUint64 diff --git a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go index fe88e4fb5..e0bd1b31d 100644 --- a/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go +++ b/vendor/k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json/value.go @@ -263,7 +263,7 @@ func reorderObjects(d *Decoder, scratch *[]byte) { afterValue := d.InputOffset() if isSorted && len(*members) > 0 { - isSorted = lessUTF16(prevName, name) + isSorted = lessUTF16(prevName, []byte(name)) } *members = append(*members, memberName{name, beforeName, afterValue}) prevName = name @@ -317,7 +317,7 @@ func reorderObjects(d *Decoder, scratch *[]byte) { // to the UTF-16 codepoints of the UTF-8 encoded input strings. // This implements the ordering specified in RFC 8785, section 3.2.3. // The inputs must be valid UTF-8, otherwise this may panic. -func lessUTF16(x, y []byte) bool { +func lessUTF16[Bytes []byte | string](x, y Bytes) bool { // NOTE: This is an optimized, allocation-free implementation // of lessUTF16Simple in fuzz_test.go. FuzzLessUTF16 verifies that the // two implementations agree on the result of comparing any two strings. @@ -326,8 +326,13 @@ func lessUTF16(x, y []byte) bool { return ('\u0000' <= r && r <= '\uD7FF') || ('\uE000' <= r && r <= '\uFFFF') } + var invalidUTF8 bool + x0, y0 := x, y for { if len(x) == 0 || len(y) == 0 { + if len(x) == len(y) && invalidUTF8 { + return string(x0) < string(y0) + } return len(x) < len(y) } @@ -341,35 +346,36 @@ func lessUTF16(x, y []byte) bool { } // Decode next pair of runes as UTF-8. - rx, nx := utf8.DecodeRune(x) - ry, ny := utf8.DecodeRune(y) + // TODO(https://go.dev/issue/56948): Use a generic implementation + // of utf8.DecodeRune, or rely on a compiler optimization to statically + // hide the cost of a type switch (https://go.dev/issue/57072). + var rx, ry rune + var nx, ny int + switch any(x).(type) { + case string: + rx, nx = utf8.DecodeRuneInString(string(x)) + ry, ny = utf8.DecodeRuneInString(string(y)) + case []byte: + rx, nx = utf8.DecodeRune([]byte(x)) + ry, ny = utf8.DecodeRune([]byte(y)) + } + + selfx := isUTF16Self(rx) + selfy := isUTF16Self(ry) switch { - - // Both runes encode as either a single or surrogate pair - // of UTF-16 codepoints. - case isUTF16Self(rx) == isUTF16Self(ry): - if rx != ry { - return rx < ry - } - // The x rune is a single UTF-16 codepoint, while // the y rune is a surrogate pair of UTF-16 codepoints. - case isUTF16Self(rx): - ry, _ := utf16.EncodeRune(ry) - if rx != ry { - return rx < ry - } - panic("BUG: invalid UTF-8") // implies rx is an unpaired surrogate half - + case selfx && !selfy: + ry, _ = utf16.EncodeRune(ry) // The y rune is a single UTF-16 codepoint, while // the x rune is a surrogate pair of UTF-16 codepoints. - case isUTF16Self(ry): - rx, _ := utf16.EncodeRune(rx) - if rx != ry { - return rx < ry - } - panic("BUG: invalid UTF-8") // implies ry is an unpaired surrogate half + case selfy && !selfx: + rx, _ = utf16.EncodeRune(rx) } + if rx != ry { + return rx < ry + } + invalidUTF8 = invalidUTF8 || (rx == utf8.RuneError && nx == 1) || (ry == utf8.RuneError && ny == 1) x, y = x[nx:], y[ny:] } } diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go new file mode 100644 index 000000000..61141a500 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/openapi.go @@ -0,0 +1,260 @@ +/* +Copyright 2022 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 schemaconv + +import ( + "errors" + "path" + "strings" + + "k8s.io/kube-openapi/pkg/validation/spec" + "sigs.k8s.io/structured-merge-diff/v4/schema" +) + +// ToSchemaFromOpenAPI converts a directory of OpenAPI schemas to an smd Schema. +// - models: a map from definition name to OpenAPI V3 structural schema for each definition. +// Key in map is used to resolve references in the schema. +// - preserveUnknownFields: flag indicating whether unknown fields in all schemas should be preserved. +// - returns: nil and an error if there is a parse error, or if schema does not satisfy a +// required structural schema invariant for conversion. If no error, returns +// a new smd schema. +// +// Schema should be validated as structural before using with this function, or +// there may be information lost. +func ToSchemaFromOpenAPI(models map[string]*spec.Schema, preserveUnknownFields bool) (*schema.Schema, error) { + c := convert{ + preserveUnknownFields: preserveUnknownFields, + output: &schema.Schema{}, + } + + for name, spec := range models { + // Skip/Ignore top-level references + if len(spec.Ref.String()) > 0 { + continue + } + + var a schema.Atom + + // Hard-coded schemas for now as proto_models implementation functions. + // https://github.com/kubernetes/kube-openapi/issues/364 + if name == quantityResource { + a = schema.Atom{ + Scalar: untypedDef.Atom.Scalar, + } + } else if name == rawExtensionResource { + a = untypedDef.Atom + } else { + c2 := c.push(name, &a) + c2.visitSpec(spec) + c.pop(c2) + } + + c.insertTypeDef(name, a) + } + + if len(c.errorMessages) > 0 { + return nil, errors.New(strings.Join(c.errorMessages, "\n")) + } + + c.addCommonTypes() + return c.output, nil +} + +func (c *convert) visitSpec(m *spec.Schema) { + // Check if this schema opts its descendants into preserve-unknown-fields + if p, ok := m.Extensions["x-kubernetes-preserve-unknown-fields"]; ok && p == true { + c.preserveUnknownFields = true + } + a := c.top() + *a = c.parseSchema(m) +} + +func (c *convert) parseSchema(m *spec.Schema) schema.Atom { + // k8s-generated OpenAPI specs have historically used only one value for + // type and starting with OpenAPIV3 it is only allowed to be + // a single string. + typ := "" + if len(m.Type) > 0 { + typ = m.Type[0] + } + + // Structural Schemas produced by kubernetes follow very specific rules which + // we can use to infer the SMD type: + switch typ { + case "": + // According to Swagger docs: + // https://swagger.io/docs/specification/data-models/data-types/#any + // + // If no type is specified, it is equivalent to accepting any type. + return schema.Atom{ + Scalar: ptr(schema.Scalar("untyped")), + List: c.parseList(m), + Map: c.parseObject(m), + } + + case "object": + return schema.Atom{ + Map: c.parseObject(m), + } + case "array": + return schema.Atom{ + List: c.parseList(m), + } + case "integer", "boolean", "number", "string": + return convertPrimitive(typ, m.Format) + default: + c.reportError("unrecognized type: '%v'", typ) + return schema.Atom{ + Scalar: ptr(schema.Scalar("untyped")), + } + } +} + +func (c *convert) makeOpenAPIRef(specSchema *spec.Schema) schema.TypeRef { + refString := specSchema.Ref.String() + + // Special-case handling for $ref stored inside a single-element allOf + if len(refString) == 0 && len(specSchema.AllOf) == 1 && len(specSchema.AllOf[0].Ref.String()) > 0 { + refString = specSchema.AllOf[0].Ref.String() + } + + if _, n := path.Split(refString); len(n) > 0 { + //!TODO: Refactor the field ElementRelationship override + // we can generate the types with overrides ahead of time rather than + // requiring the hacky runtime support + // (could just create a normalized key struct containing all customizations + // to deduplicate) + mapRelationship, err := getMapElementRelationship(specSchema.Extensions) + if err != nil { + c.reportError(err.Error()) + } + + if len(mapRelationship) > 0 { + return schema.TypeRef{ + NamedType: &n, + ElementRelationship: &mapRelationship, + } + } + + return schema.TypeRef{ + NamedType: &n, + } + + } + var inlined schema.Atom + + // compute the type inline + c2 := c.push("inlined in "+c.currentName, &inlined) + c2.preserveUnknownFields = c.preserveUnknownFields + c2.visitSpec(specSchema) + c.pop(c2) + + return schema.TypeRef{ + Inlined: inlined, + } +} + +func (c *convert) parseObject(s *spec.Schema) *schema.Map { + var fields []schema.StructField + for name, member := range s.Properties { + fields = append(fields, schema.StructField{ + Name: name, + Type: c.makeOpenAPIRef(&member), + Default: member.Default, + }) + } + + // AdditionalProperties informs the schema of any "unknown" keys + // Unknown keys are enforced by the ElementType field. + elementType := func() schema.TypeRef { + if s.AdditionalProperties == nil { + // According to openAPI spec, an object without properties and without + // additionalProperties is assumed to be a free-form object. + if c.preserveUnknownFields || len(s.Properties) == 0 { + return schema.TypeRef{ + NamedType: &deducedName, + } + } + + // If properties are specified, do not implicitly allow unknown + // fields + return schema.TypeRef{} + } else if s.AdditionalProperties.Schema != nil { + // Unknown fields use the referred schema + return c.makeOpenAPIRef(s.AdditionalProperties.Schema) + + } else if s.AdditionalProperties.Allows { + // A boolean instead of a schema was provided. Deduce the + // type from the value provided at runtime. + return schema.TypeRef{ + NamedType: &deducedName, + } + } else { + // Additional Properties are explicitly disallowed by the user. + // Ensure element type is empty. + return schema.TypeRef{} + } + }() + + relationship, err := getMapElementRelationship(s.Extensions) + if err != nil { + c.reportError(err.Error()) + } + + return &schema.Map{ + Fields: fields, + ElementRelationship: relationship, + ElementType: elementType, + } +} + +func (c *convert) parseList(s *spec.Schema) *schema.List { + relationship, mapKeys, err := getListElementRelationship(s.Extensions) + if err != nil { + c.reportError(err.Error()) + } + elementType := func() schema.TypeRef { + if s.Items != nil { + if s.Items.Schema == nil || s.Items.Len() != 1 { + c.reportError("structural schema arrays must have exactly one member subtype") + return schema.TypeRef{ + NamedType: &deducedName, + } + } + + subSchema := s.Items.Schema + if subSchema == nil { + subSchema = &s.Items.Schemas[0] + } + return c.makeOpenAPIRef(subSchema) + } else if len(s.Type) > 0 && len(s.Type[0]) > 0 { + c.reportError("`items` must be specified on arrays") + } + + // A list with no items specified is treated as "untyped". + return schema.TypeRef{ + NamedType: &untypedName, + } + + }() + + return &schema.List{ + ElementRelationship: relationship, + Keys: mapKeys, + ElementType: elementType, + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go new file mode 100644 index 000000000..2c6fd76a9 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/proto_models.go @@ -0,0 +1,178 @@ +/* +Copyright 2022 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 schemaconv + +import ( + "errors" + "path" + "strings" + + "k8s.io/kube-openapi/pkg/util/proto" + "sigs.k8s.io/structured-merge-diff/v4/schema" +) + +// ToSchema converts openapi definitions into a schema suitable for structured +// merge (i.e. kubectl apply v2). +func ToSchema(models proto.Models) (*schema.Schema, error) { + return ToSchemaWithPreserveUnknownFields(models, false) +} + +// ToSchemaWithPreserveUnknownFields converts openapi definitions into a schema suitable for structured +// merge (i.e. kubectl apply v2), it will preserve unknown fields if specified. +func ToSchemaWithPreserveUnknownFields(models proto.Models, preserveUnknownFields bool) (*schema.Schema, error) { + c := convert{ + preserveUnknownFields: preserveUnknownFields, + output: &schema.Schema{}, + } + for _, name := range models.ListModels() { + model := models.LookupModel(name) + + var a schema.Atom + c2 := c.push(name, &a) + model.Accept(c2) + c.pop(c2) + + c.insertTypeDef(name, a) + } + + if len(c.errorMessages) > 0 { + return nil, errors.New(strings.Join(c.errorMessages, "\n")) + } + + c.addCommonTypes() + return c.output, nil +} + +func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema.TypeRef { + var tr schema.TypeRef + if r, ok := model.(*proto.Ref); ok { + if r.Reference() == "io.k8s.apimachinery.pkg.runtime.RawExtension" { + return schema.TypeRef{ + NamedType: &untypedName, + } + } + // reference a named type + _, n := path.Split(r.Reference()) + tr.NamedType = &n + + mapRelationship, err := getMapElementRelationship(model.GetExtensions()) + + if err != nil { + c.reportError(err.Error()) + } + + // empty string means unset. + if len(mapRelationship) > 0 { + tr.ElementRelationship = &mapRelationship + } + } else { + // compute the type inline + c2 := c.push("inlined in "+c.currentName, &tr.Inlined) + c2.preserveUnknownFields = preserveUnknownFields + model.Accept(c2) + c.pop(c2) + + if tr == (schema.TypeRef{}) { + // emit warning? + tr.NamedType = &untypedName + } + } + return tr +} + +func (c *convert) VisitKind(k *proto.Kind) { + preserveUnknownFields := c.preserveUnknownFields + if p, ok := k.GetExtensions()["x-kubernetes-preserve-unknown-fields"]; ok && p == true { + preserveUnknownFields = true + } + + a := c.top() + a.Map = &schema.Map{} + for _, name := range k.FieldOrder { + member := k.Fields[name] + tr := c.makeRef(member, preserveUnknownFields) + a.Map.Fields = append(a.Map.Fields, schema.StructField{ + Name: name, + Type: tr, + Default: member.GetDefault(), + }) + } + + unions, err := makeUnions(k.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + return + } + // TODO: We should check that the fields and discriminator + // specified in the union are actual fields in the struct. + a.Map.Unions = unions + + if preserveUnknownFields { + a.Map.ElementType = schema.TypeRef{ + NamedType: &deducedName, + } + } + + a.Map.ElementRelationship, err = getMapElementRelationship(k.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } +} + +func (c *convert) VisitArray(a *proto.Array) { + relationship, mapKeys, err := getListElementRelationship(a.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } + + atom := c.top() + atom.List = &schema.List{ + ElementType: c.makeRef(a.SubType, c.preserveUnknownFields), + ElementRelationship: relationship, + Keys: mapKeys, + } +} + +func (c *convert) VisitMap(m *proto.Map) { + relationship, err := getMapElementRelationship(m.GetExtensions()) + if err != nil { + c.reportError(err.Error()) + } + + a := c.top() + a.Map = &schema.Map{ + ElementType: c.makeRef(m.SubType, c.preserveUnknownFields), + ElementRelationship: relationship, + } +} + +func (c *convert) VisitPrimitive(p *proto.Primitive) { + a := c.top() + if c.currentName == quantityResource { + a.Scalar = ptr(schema.Scalar("untyped")) + } else { + *a = convertPrimitive(p.Type, p.Format) + } +} + +func (c *convert) VisitArbitrary(a *proto.Arbitrary) { + *c.top() = deducedDef.Atom +} + +func (c *convert) VisitReference(proto.Reference) { + // Do nothing, we handle references specially +} diff --git a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go index bec0e7809..799d866d5 100644 --- a/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go +++ b/vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go @@ -17,43 +17,18 @@ limitations under the License. package schemaconv import ( - "errors" "fmt" - "path" "sort" - "strings" - "k8s.io/kube-openapi/pkg/util/proto" "sigs.k8s.io/structured-merge-diff/v4/schema" ) const ( - quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity" + quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity" + rawExtensionResource = "io.k8s.apimachinery.pkg.runtime.RawExtension" ) -// ToSchema converts openapi definitions into a schema suitable for structured -// merge (i.e. kubectl apply v2). -func ToSchema(models proto.Models) (*schema.Schema, error) { - return ToSchemaWithPreserveUnknownFields(models, false) -} - -// ToSchemaWithPreserveUnknownFields converts openapi definitions into a schema suitable for structured -// merge (i.e. kubectl apply v2), it will preserve unknown fields if specified. -func ToSchemaWithPreserveUnknownFields(models proto.Models, preserveUnknownFields bool) (*schema.Schema, error) { - c := convert{ - input: models, - preserveUnknownFields: preserveUnknownFields, - output: &schema.Schema{}, - } - if err := c.convertAll(); err != nil { - return nil, err - } - c.addCommonTypes() - return c.output, nil -} - type convert struct { - input proto.Models preserveUnknownFields bool output *schema.Schema @@ -64,7 +39,6 @@ type convert struct { func (c *convert) push(name string, a *schema.Atom) *convert { return &convert{ - input: c.input, preserveUnknownFields: c.preserveUnknownFields, output: c.output, currentName: name, @@ -78,30 +52,17 @@ func (c *convert) pop(c2 *convert) { c.errorMessages = append(c.errorMessages, c2.errorMessages...) } -func (c *convert) convertAll() error { - for _, name := range c.input.ListModels() { - model := c.input.LookupModel(name) - c.insertTypeDef(name, model) - } - if len(c.errorMessages) > 0 { - return errors.New(strings.Join(c.errorMessages, "\n")) - } - return nil -} - func (c *convert) reportError(format string, args ...interface{}) { c.errorMessages = append(c.errorMessages, c.currentName+": "+fmt.Sprintf(format, args...), ) } -func (c *convert) insertTypeDef(name string, model proto.Schema) { +func (c *convert) insertTypeDef(name string, atom schema.Atom) { def := schema.TypeDef{ Name: name, + Atom: atom, } - c2 := c.push(name, &def.Atom) - model.Accept(c2) - c.pop(c2) if def.Atom == (schema.Atom{}) { // This could happen if there were a top-level reference. return @@ -156,46 +117,6 @@ var deducedDef schema.TypeDef = schema.TypeDef{ }, } -func (c *convert) makeRef(model proto.Schema, preserveUnknownFields bool) schema.TypeRef { - var tr schema.TypeRef - if r, ok := model.(*proto.Ref); ok { - if r.Reference() == "io.k8s.apimachinery.pkg.runtime.RawExtension" { - return schema.TypeRef{ - NamedType: &untypedName, - } - } - // reference a named type - _, n := path.Split(r.Reference()) - tr.NamedType = &n - - ext := model.GetExtensions() - if val, ok := ext["x-kubernetes-map-type"]; ok { - switch val { - case "atomic": - relationship := schema.Atomic - tr.ElementRelationship = &relationship - case "granular": - relationship := schema.Separable - tr.ElementRelationship = &relationship - default: - c.reportError("unknown map type %v", val) - } - } - } else { - // compute the type inline - c2 := c.push("inlined in "+c.currentName, &tr.Inlined) - c2.preserveUnknownFields = preserveUnknownFields - model.Accept(c2) - c.pop(c2) - - if tr == (schema.TypeRef{}) { - // emit warning? - tr.NamedType = &untypedName - } - } - return tr -} - func makeUnions(extensions map[string]interface{}) ([]schema.Union, error) { schemaUnions := []schema.Union{} if iunions, ok := extensions["x-kubernetes-unions"]; ok { @@ -299,52 +220,6 @@ func makeUnion(extensions map[string]interface{}) (schema.Union, error) { return union, nil } -func (c *convert) VisitKind(k *proto.Kind) { - preserveUnknownFields := c.preserveUnknownFields - if p, ok := k.GetExtensions()["x-kubernetes-preserve-unknown-fields"]; ok && p == true { - preserveUnknownFields = true - } - - a := c.top() - a.Map = &schema.Map{} - for _, name := range k.FieldOrder { - member := k.Fields[name] - tr := c.makeRef(member, preserveUnknownFields) - a.Map.Fields = append(a.Map.Fields, schema.StructField{ - Name: name, - Type: tr, - Default: member.GetDefault(), - }) - } - - unions, err := makeUnions(k.GetExtensions()) - if err != nil { - c.reportError(err.Error()) - return - } - // TODO: We should check that the fields and discriminator - // specified in the union are actual fields in the struct. - a.Map.Unions = unions - - if preserveUnknownFields { - a.Map.ElementType = schema.TypeRef{ - NamedType: &deducedName, - } - } - - ext := k.GetExtensions() - if val, ok := ext["x-kubernetes-map-type"]; ok { - switch val { - case "atomic": - a.Map.ElementRelationship = schema.Atomic - case "granular": - a.Map.ElementRelationship = schema.Separable - default: - c.reportError("unknown map type %v", val) - } - } -} - func toStringSlice(o interface{}) (out []string, ok bool) { switch t := o.(type) { case []interface{}: @@ -355,117 +230,108 @@ func toStringSlice(o interface{}) (out []string, ok bool) { } } return out, true + case []string: + return t, true } return nil, false } -func (c *convert) VisitArray(a *proto.Array) { - atom := c.top() - atom.List = &schema.List{ - ElementRelationship: schema.Atomic, - } - l := atom.List - l.ElementType = c.makeRef(a.SubType, c.preserveUnknownFields) - - ext := a.GetExtensions() - - if val, ok := ext["x-kubernetes-list-type"]; ok { - if val == "atomic" { - l.ElementRelationship = schema.Atomic - } else if val == "set" { - l.ElementRelationship = schema.Associative - } else if val == "map" { - l.ElementRelationship = schema.Associative - if keys, ok := ext["x-kubernetes-list-map-keys"]; ok { - if keyNames, ok := toStringSlice(keys); ok { - l.Keys = keyNames - } else { - c.reportError("uninterpreted map keys: %#v", keys) - } - } else { - c.reportError("missing map keys") - } - } else { - c.reportError("unknown list type %v", val) - l.ElementRelationship = schema.Atomic - } - } else if val, ok := ext["x-kubernetes-patch-strategy"]; ok { - if val == "merge" || val == "merge,retainKeys" { - l.ElementRelationship = schema.Associative - if key, ok := ext["x-kubernetes-patch-merge-key"]; ok { - if keyName, ok := key.(string); ok { - l.Keys = []string{keyName} - } else { - c.reportError("uninterpreted merge key: %#v", key) - } - } else { - // It's not an error for this to be absent, it - // means it's a set. - } - } else if val == "retainKeys" { - } else { - c.reportError("unknown patch strategy %v", val) - l.ElementRelationship = schema.Atomic - } - } -} - -func (c *convert) VisitMap(m *proto.Map) { - a := c.top() - a.Map = &schema.Map{} - a.Map.ElementType = c.makeRef(m.SubType, c.preserveUnknownFields) - - ext := m.GetExtensions() - if val, ok := ext["x-kubernetes-map-type"]; ok { - switch val { - case "atomic": - a.Map.ElementRelationship = schema.Atomic - case "granular": - a.Map.ElementRelationship = schema.Separable - default: - c.reportError("unknown map type %v", val) - } - } -} - func ptr(s schema.Scalar) *schema.Scalar { return &s } -func (c *convert) VisitPrimitive(p *proto.Primitive) { - a := c.top() - if c.currentName == quantityResource { - a.Scalar = ptr(schema.Scalar("untyped")) - } else { - switch p.Type { - case proto.Integer: - a.Scalar = ptr(schema.Numeric) - case proto.Number: - a.Scalar = ptr(schema.Numeric) - case proto.String: - switch p.Format { - case "": - a.Scalar = ptr(schema.String) - case "byte": - // byte really means []byte and is encoded as a string. - a.Scalar = ptr(schema.String) - case "int-or-string": - a.Scalar = ptr(schema.Scalar("untyped")) - case "date-time": - a.Scalar = ptr(schema.Scalar("untyped")) - default: - a.Scalar = ptr(schema.Scalar("untyped")) - } - case proto.Boolean: - a.Scalar = ptr(schema.Boolean) +// Basic conversion functions to convert OpenAPI schema definitions to +// SMD Schema atoms +func convertPrimitive(typ string, format string) (a schema.Atom) { + switch typ { + case "integer": + a.Scalar = ptr(schema.Numeric) + case "number": + a.Scalar = ptr(schema.Numeric) + case "string": + switch format { + case "": + a.Scalar = ptr(schema.String) + case "byte": + // byte really means []byte and is encoded as a string. + a.Scalar = ptr(schema.String) + case "int-or-string": + a.Scalar = ptr(schema.Scalar("untyped")) + case "date-time": + a.Scalar = ptr(schema.Scalar("untyped")) default: a.Scalar = ptr(schema.Scalar("untyped")) } + case "boolean": + a.Scalar = ptr(schema.Boolean) + default: + a.Scalar = ptr(schema.Scalar("untyped")) + } + + return a +} + +func getListElementRelationship(ext map[string]any) (schema.ElementRelationship, []string, error) { + if val, ok := ext["x-kubernetes-list-type"]; ok { + switch val { + case "atomic": + return schema.Atomic, nil, nil + case "set": + return schema.Associative, nil, nil + case "map": + keys, ok := ext["x-kubernetes-list-map-keys"] + + if !ok { + return schema.Associative, nil, fmt.Errorf("missing map keys") + } + + keyNames, ok := toStringSlice(keys) + if !ok { + return schema.Associative, nil, fmt.Errorf("uninterpreted map keys: %#v", keys) + } + + return schema.Associative, keyNames, nil + default: + return schema.Atomic, nil, fmt.Errorf("unknown list type %v", val) + } + } else if val, ok := ext["x-kubernetes-patch-strategy"]; ok { + switch val { + case "merge", "merge,retainKeys": + if key, ok := ext["x-kubernetes-patch-merge-key"]; ok { + keyName, ok := key.(string) + + if !ok { + return schema.Associative, nil, fmt.Errorf("uninterpreted merge key: %#v", key) + } + + return schema.Associative, []string{keyName}, nil + } + // It's not an error for x-kubernetes-patch-merge-key to be absent, + // it means it's a set + return schema.Associative, nil, nil + case "retainKeys": + return schema.Atomic, nil, nil + default: + return schema.Atomic, nil, fmt.Errorf("unknown patch strategy %v", val) + } + } + + // Treat as atomic by default + return schema.Atomic, nil, nil +} + +// Returns map element relationship if specified, or empty string if unspecified +func getMapElementRelationship(ext map[string]any) (schema.ElementRelationship, error) { + val, ok := ext["x-kubernetes-map-type"] + if !ok { + // unset Map element relationship + return "", nil + } + + switch val { + case "atomic": + return schema.Atomic, nil + case "granular": + return schema.Separable, nil + default: + return "", fmt.Errorf("unknown map type %v", val) } } - -func (c *convert) VisitArbitrary(a *proto.Arbitrary) { - *c.top() = deducedDef.Atom -} - -func (c *convert) VisitReference(proto.Reference) { - // Do nothing, we handle references specially -} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go b/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go index 51dac4bdf..699291f1d 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go @@ -18,7 +18,10 @@ package spec3 import ( "encoding/json" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -41,6 +44,9 @@ func (e *Encoding) MarshalJSON() ([]byte, error) { } func (e *Encoding) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.EncodingProps); err != nil { return err } @@ -50,6 +56,20 @@ func (e *Encoding) UnmarshalJSON(data []byte) error { return nil } +func (e *Encoding) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + EncodingProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.EncodingProps = x.EncodingProps + return nil +} + type EncodingProps struct { // Content Type for encoding a specific property ContentType string `json:"contentType,omitempty"` @@ -58,7 +78,7 @@ type EncodingProps struct { // Describes how a specific property value will be serialized depending on its type Style string `json:"style,omitempty"` // When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. For other types of properties this property has no effect - Explode string `json:"explode,omitempty"` + Explode bool `json:"explode,omitempty"` // AllowReserved determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 AllowReserved bool `json:"allowReserved,omitempty"` } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/example.go b/vendor/k8s.io/kube-openapi/pkg/spec3/example.go index 0f5ab983c..03b872717 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/example.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/example.go @@ -19,8 +19,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + + "k8s.io/kube-openapi/pkg/validation/spec" ) // Example https://swagger.io/specification/#example-object @@ -49,6 +52,9 @@ func (e *Example) MarshalJSON() ([]byte, error) { } func (e *Example) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.Refable); err != nil { return err } @@ -61,6 +67,23 @@ func (e *Example) UnmarshalJSON(data []byte) error { return nil } +func (e *Example) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ExampleProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&e.Ref.Ref, x.Extensions); err != nil { + return err + } + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.ExampleProps = x.ExampleProps + + return nil +} + type ExampleProps struct { // Summary holds a short description of the example Summary string `json:"summary,omitempty"` diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go b/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go index 117113e7a..e79956721 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go @@ -18,8 +18,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) type ExternalDocumentation struct { @@ -48,6 +51,9 @@ func (e *ExternalDocumentation) MarshalJSON() ([]byte, error) { } func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, e) + } if err := json.Unmarshal(data, &e.ExternalDocumentationProps); err != nil { return err } @@ -56,3 +62,16 @@ func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error { } return nil } + +func (e *ExternalDocumentation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ExternalDocumentationProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + e.Extensions = internal.SanitizeExtensions(x.Extensions) + e.ExternalDocumentationProps = x.ExternalDocumentationProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go b/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go new file mode 100644 index 000000000..bc19dd48e --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/fuzz.go @@ -0,0 +1,254 @@ +package spec3 + +import ( + "math/rand" + "strings" + + fuzz "github.com/google/gofuzz" + + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// refChance is the chance that a particular component will use a $ref +// instead of fuzzed. Expressed as a fraction 1/n, currently there is +// a 1/3 chance that a ref will be used. +const refChance = 3 + +const alphaNumChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +func randAlphanumString() string { + arr := make([]string, rand.Intn(10)+5) + for i := 0; i < len(arr); i++ { + arr[i] = string(alphaNumChars[rand.Intn(len(alphaNumChars))]) + } + return strings.Join(arr, "") +} + +var OpenAPIV3FuzzFuncs []interface{} = []interface{}{ + func(s *string, c fuzz.Continue) { + // All OpenAPI V3 map keys must follow the corresponding + // regex. Note that this restricts the range for all other + // string values as well. + str := randAlphanumString() + *s = str + }, + func(o *OpenAPI, c fuzz.Continue) { + c.FuzzNoCustom(o) + o.Version = "3.0.0" + }, + func(r *interface{}, c fuzz.Continue) { + switch c.Intn(3) { + case 0: + *r = nil + case 1: + n := c.RandString() + "x" + *r = n + case 2: + n := c.Float64() + *r = n + } + }, + func(v **spec.Info, c fuzz.Continue) { + // Info is never nil + *v = &spec.Info{} + c.FuzzNoCustom(*v) + (*v).Title = c.RandString() + "x" + }, + func(v *Paths, c fuzz.Continue) { + c.Fuzz(&v.VendorExtensible) + num := c.Intn(5) + if num > 0 { + v.Paths = make(map[string]*Path) + } + for i := 0; i < num; i++ { + val := Path{} + c.Fuzz(&val) + v.Paths["/"+c.RandString()] = &val + } + }, + func(v *SecurityScheme, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + switch c.Intn(4) { + case 0: + v.Type = "apiKey" + v.Name = c.RandString() + "x" + switch c.Intn(3) { + case 0: + v.In = "query" + case 1: + v.In = "header" + case 2: + v.In = "cookie" + } + case 1: + v.Type = "http" + case 2: + v.Type = "oauth2" + v.Flows = make(map[string]*OAuthFlow) + flow := OAuthFlow{} + flow.AuthorizationUrl = c.RandString() + "x" + v.Flows["implicit"] = &flow + flow.Scopes = make(map[string]string) + flow.Scopes["foo"] = "bar" + case 3: + v.Type = "openIdConnect" + v.OpenIdConnectUrl = "https://" + c.RandString() + } + v.Scheme = "basic" + }, + func(v *spec.Ref, c fuzz.Continue) { + switch c.Intn(7) { + case 0: + *v = spec.MustCreateRef("#/components/schemas/" + randAlphanumString()) + case 1: + *v = spec.MustCreateRef("#/components/responses/" + randAlphanumString()) + case 2: + *v = spec.MustCreateRef("#/components/headers/" + randAlphanumString()) + case 3: + *v = spec.MustCreateRef("#/components/securitySchemes/" + randAlphanumString()) + case 5: + *v = spec.MustCreateRef("#/components/parameters/" + randAlphanumString()) + case 6: + *v = spec.MustCreateRef("#/components/requestBodies/" + randAlphanumString()) + } + }, + func(v *Parameter, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.ParameterProps) + c.Fuzz(&v.VendorExtensible) + + switch c.Intn(3) { + case 0: + // Header param + v.In = "query" + case 1: + v.In = "header" + case 2: + v.In = "cookie" + } + }, + func(v *RequestBody, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.RequestBodyProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *Header, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.HeaderProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *ResponsesProps, c fuzz.Continue) { + c.Fuzz(&v.Default) + n := c.Intn(5) + for i := 0; i < n; i++ { + r2 := Response{} + c.Fuzz(&r2) + // HTTP Status code in 100-599 Range + code := c.Intn(500) + 100 + v.StatusCodeResponses = make(map[int]*Response) + v.StatusCodeResponses[code] = &r2 + } + }, + func(v *Response, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Refable) + return + } + c.Fuzz(&v.ResponseProps) + c.Fuzz(&v.VendorExtensible) + }, + func(v *spec.Extensions, c fuzz.Continue) { + numChildren := c.Intn(5) + for i := 0; i < numChildren; i++ { + if *v == nil { + *v = spec.Extensions{} + } + (*v)["x-"+c.RandString()] = c.RandString() + } + }, + func(v *spec.ExternalDocumentation, c fuzz.Continue) { + c.Fuzz(&v.Description) + v.URL = "https://" + randAlphanumString() + }, + func(v *spec.SchemaURL, c fuzz.Continue) { + *v = spec.SchemaURL("https://" + randAlphanumString()) + }, + func(v *spec.SchemaOrBool, c fuzz.Continue) { + *v = spec.SchemaOrBool{} + + if c.RandBool() { + v.Allows = c.RandBool() + } else { + v.Schema = &spec.Schema{} + v.Allows = true + c.Fuzz(&v.Schema) + } + }, + func(v *spec.SchemaOrArray, c fuzz.Continue) { + *v = spec.SchemaOrArray{} + if c.RandBool() { + schema := spec.Schema{} + c.Fuzz(&schema) + v.Schema = &schema + } else { + v.Schemas = []spec.Schema{} + numChildren := c.Intn(5) + for i := 0; i < numChildren; i++ { + schema := spec.Schema{} + c.Fuzz(&schema) + v.Schemas = append(v.Schemas, schema) + } + + } + + }, + func(v *spec.SchemaOrStringArray, c fuzz.Continue) { + if c.RandBool() { + *v = spec.SchemaOrStringArray{} + if c.RandBool() { + c.Fuzz(&v.Property) + } else { + c.Fuzz(&v.Schema) + } + } + }, + func(v *spec.Schema, c fuzz.Continue) { + if c.Intn(refChance) == 0 { + c.Fuzz(&v.Ref) + return + } + if c.RandBool() { + // file schema + c.Fuzz(&v.Default) + c.Fuzz(&v.Description) + c.Fuzz(&v.Example) + c.Fuzz(&v.ExternalDocs) + + c.Fuzz(&v.Format) + c.Fuzz(&v.ReadOnly) + c.Fuzz(&v.Required) + c.Fuzz(&v.Title) + v.Type = spec.StringOrArray{"file"} + + } else { + // normal schema + c.Fuzz(&v.SchemaProps) + c.Fuzz(&v.SwaggerSchemaProps) + c.Fuzz(&v.VendorExtensible) + c.Fuzz(&v.ExtraProps) + } + + }, +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/header.go b/vendor/k8s.io/kube-openapi/pkg/spec3/header.go index cead4b15d..ee5a30f79 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/header.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/header.go @@ -20,6 +20,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -50,6 +52,9 @@ func (h *Header) MarshalJSON() ([]byte, error) { } func (h *Header) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, h) + } if err := json.Unmarshal(data, &h.Refable); err != nil { return err } @@ -63,6 +68,22 @@ func (h *Header) UnmarshalJSON(data []byte) error { return nil } +func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + HeaderProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&h.Ref.Ref, x.Extensions); err != nil { + return err + } + h.Extensions = internal.SanitizeExtensions(x.Extensions) + h.HeaderProps = x.HeaderProps + return nil +} + // HeaderProps a struct that describes a header object type HeaderProps struct { // Description holds a brief description of the parameter diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go b/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go index 828fd8dc5..d390e69bc 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go @@ -18,7 +18,10 @@ package spec3 import ( "encoding/json" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -44,6 +47,9 @@ func (m *MediaType) MarshalJSON() ([]byte, error) { } func (m *MediaType) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, m) + } if err := json.Unmarshal(data, &m.MediaTypeProps); err != nil { return err } @@ -53,10 +59,24 @@ func (m *MediaType) UnmarshalJSON(data []byte) error { return nil } +func (m *MediaType) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + MediaTypeProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + m.Extensions = internal.SanitizeExtensions(x.Extensions) + m.MediaTypeProps = x.MediaTypeProps + + return nil +} + // MediaTypeProps a struct that allows you to specify content format, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#mediaTypeObject type MediaTypeProps struct { // Schema holds the schema defining the type used for the media type - Schema *spec.Schema `json:"schema,omitempty"` + Schema *spec.Schema `json:"schema,omitempty"` // Example of the media type Example interface{} `json:"example,omitempty"` // Examples of the media type. Each example object should match the media type and specific schema if present diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go b/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go index de8aa4602..28230610b 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/operation.go @@ -19,8 +19,10 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Operation describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject @@ -46,12 +48,28 @@ func (o *Operation) MarshalJSON() ([]byte, error) { // UnmarshalJSON hydrates this items instance with the data from JSON func (o *Operation) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, o) + } if err := json.Unmarshal(data, &o.OperationProps); err != nil { return err } return json.Unmarshal(data, &o.VendorExtensible) } +func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + OperationProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + o.Extensions = internal.SanitizeExtensions(x.Extensions) + o.OperationProps = x.OperationProps + return nil +} + // OperationProps describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject type OperationProps struct { // Tags holds a list of tags for API documentation control @@ -73,7 +91,7 @@ type OperationProps struct { // Deprecated declares this operation to be deprecated Deprecated bool `json:"deprecated,omitempty"` // SecurityRequirement holds a declaration of which security mechanisms can be used for this operation - SecurityRequirement []*SecurityRequirement `json:"security,omitempty"` + SecurityRequirement []map[string][]string `json:"security,omitempty"` // Servers contains an alternative server array to service this operation Servers []*Server `json:"servers,omitempty"` } diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go b/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go index 0d7180e50..613da71a6 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go @@ -20,6 +20,8 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -50,6 +52,10 @@ func (p *Parameter) MarshalJSON() ([]byte, error) { } func (p *Parameter) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } + if err := json.Unmarshal(data, &p.Refable); err != nil { return err } @@ -63,6 +69,22 @@ func (p *Parameter) UnmarshalJSON(data []byte) error { return nil } +func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ParameterProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&p.Ref.Ref, x.Extensions); err != nil { + return err + } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.ParameterProps = x.ParameterProps + return nil +} + // ParameterProps a struct that describes a single operation parameter, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject type ParameterProps struct { // Name holds the name of the parameter diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/path.go b/vendor/k8s.io/kube-openapi/pkg/spec3/path.go index bc48c504d..40d9061ac 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/path.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/path.go @@ -18,10 +18,13 @@ package spec3 import ( "encoding/json" + "fmt" "strings" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Paths describes the available paths and operations for the API, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathsObject @@ -45,6 +48,9 @@ func (p *Paths) MarshalJSON() ([]byte, error) { // UnmarshalJSON hydrates this items instance with the data from JSON func (p *Paths) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { return err @@ -74,6 +80,59 @@ func (p *Paths) UnmarshalJSON(data []byte) error { return nil } +func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + tok, err := dec.ReadToken() + if err != nil { + return err + } + switch k := tok.Kind(); k { + case 'n': + *p = Paths{} + return nil + case '{': + for { + tok, err := dec.ReadToken() + if err != nil { + return err + } + + if tok.Kind() == '}' { + return nil + } + + switch k := tok.String(); { + case internal.IsExtensionKey(k): + var ext any + if err := opts.UnmarshalNext(dec, &ext); err != nil { + return err + } + + if p.Extensions == nil { + p.Extensions = make(map[string]any) + } + p.Extensions[k] = ext + case len(k) > 0 && k[0] == '/': + pi := Path{} + if err := opts.UnmarshalNext(dec, &pi); err != nil { + return err + } + + if p.Paths == nil { + p.Paths = make(map[string]*Path) + } + p.Paths[k] = &pi + default: + _, err := dec.ReadValue() // skip value + if err != nil { + return err + } + } + } + default: + return fmt.Errorf("unknown JSON kind: %v", k) + } +} + // Path describes the operations available on a single path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject // // Note that this struct is actually a thin wrapper around PathProps to make it referable and extensible @@ -101,6 +160,9 @@ func (p *Path) MarshalJSON() ([]byte, error) { } func (p *Path) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, p) + } if err := json.Unmarshal(data, &p.Refable); err != nil { return err } @@ -113,6 +175,24 @@ func (p *Path) UnmarshalJSON(data []byte) error { return nil } +func (p *Path) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + PathProps + } + + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&p.Ref.Ref, x.Extensions); err != nil { + return err + } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.PathProps = x.PathProps + + return nil +} + // PathProps describes the operations available on a single path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject type PathProps struct { // Summary holds a summary for all operations in this path diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go b/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go index 0adc62826..33267ce67 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go @@ -19,8 +19,10 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // RequestBody describes a single request body, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#requestBodyObject @@ -50,6 +52,9 @@ func (r *RequestBody) MarshalJSON() ([]byte, error) { } func (r *RequestBody) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -71,3 +76,19 @@ type RequestBodyProps struct { // Required determines if the request body is required in the request Required bool `json:"required,omitempty"` } + +func (r *RequestBody) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + RequestBodyProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&r.Ref.Ref, x.Extensions); err != nil { + return err + } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.RequestBodyProps = x.RequestBodyProps + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/response.go b/vendor/k8s.io/kube-openapi/pkg/spec3/response.go index ccd73369f..95b388e6c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/response.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/response.go @@ -18,10 +18,13 @@ package spec3 import ( "encoding/json" + "fmt" "strconv" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) // Responses holds the list of possible responses as they are returned from executing this operation @@ -46,13 +49,15 @@ func (r *Responses) MarshalJSON() ([]byte, error) { } func (r *Responses) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.ResponsesProps); err != nil { return err } if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { return err } - return nil } @@ -78,25 +83,91 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals responses from JSON func (r *ResponsesProps) UnmarshalJSON(data []byte) error { - var res map[string]*Response + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } + var res map[string]json.RawMessage if err := json.Unmarshal(data, &res); err != nil { - return nil + return err } if v, ok := res["default"]; ok { - r.Default = v + value := Response{} + if err := json.Unmarshal(v, &value); err != nil { + return err + } + r.Default = &value delete(res, "default") } for k, v := range res { + // Take all integral keys if nk, err := strconv.Atoi(k); err == nil { if r.StatusCodeResponses == nil { r.StatusCodeResponses = map[int]*Response{} } - r.StatusCodeResponses[nk] = v + value := Response{} + if err := json.Unmarshal(v, &value); err != nil { + return err + } + r.StatusCodeResponses[nk] = &value } } return nil } +func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) (err error) { + tok, err := dec.ReadToken() + if err != nil { + return err + } + switch k := tok.Kind(); k { + case 'n': + *r = Responses{} + return nil + case '{': + for { + tok, err := dec.ReadToken() + if err != nil { + return err + } + if tok.Kind() == '}' { + return nil + } + switch k := tok.String(); { + case internal.IsExtensionKey(k): + var ext any + if err := opts.UnmarshalNext(dec, &ext); err != nil { + return err + } + + if r.Extensions == nil { + r.Extensions = make(map[string]any) + } + r.Extensions[k] = ext + case k == "default": + resp := Response{} + if err := opts.UnmarshalNext(dec, &resp); err != nil { + return err + } + r.ResponsesProps.Default = &resp + default: + if nk, err := strconv.Atoi(k); err == nil { + resp := Response{} + if err := opts.UnmarshalNext(dec, &resp); err != nil { + return err + } + + if r.StatusCodeResponses == nil { + r.StatusCodeResponses = map[int]*Response{} + } + r.StatusCodeResponses[nk] = &resp + } + } + } + default: + return fmt.Errorf("unknown JSON kind: %v", k) + } +} + // Response describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject // // Note that this struct is actually a thin wrapper around ResponseProps to make it referable and extensible @@ -124,6 +195,9 @@ func (r *Response) MarshalJSON() ([]byte, error) { } func (r *Response) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -133,7 +207,22 @@ func (r *Response) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &r.VendorExtensible); err != nil { return err } + return nil +} +func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ResponseProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&r.Ref.Ref, x.Extensions); err != nil { + return err + } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.ResponseProps = x.ResponseProps return nil } @@ -149,7 +238,6 @@ type ResponseProps struct { Links map[string]*Link `json:"links,omitempty"` } - // Link represents a possible design-time link for a response, more at https://swagger.io/specification/#link-object type Link struct { spec.Refable @@ -175,6 +263,9 @@ func (r *Link) MarshalJSON() ([]byte, error) { } func (r *Link) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, r) + } if err := json.Unmarshal(data, &r.Refable); err != nil { return err } @@ -188,6 +279,22 @@ func (r *Link) UnmarshalJSON(data []byte) error { return nil } +func (l *Link) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + LinkProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + if err := internal.JSONRefFromMap(&l.Ref.Ref, x.Extensions); err != nil { + return err + } + l.Extensions = internal.SanitizeExtensions(x.Extensions) + l.LinkProps = x.LinkProps + return nil +} + // LinkProps describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject type LinkProps struct { // OperationId is the name of an existing, resolvable OAS operation diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go b/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go deleted file mode 100644 index 0ce8924ef..000000000 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2021 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 spec3 - -import ( - "encoding/json" - - "k8s.io/kube-openapi/pkg/validation/spec" - "github.com/go-openapi/swag" -) - -// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object -// -// Note that this struct is actually a thin wrapper around SecurityRequirementProps to make it referable and extensible -type SecurityRequirement struct { - SecurityRequirementProps - spec.VendorExtensible -} - -// MarshalJSON is a custom marshal function that knows how to encode SecurityRequirement as JSON -func (s *SecurityRequirement) MarshalJSON() ([]byte, error) { - b1, err := json.Marshal(s.SecurityRequirementProps) - if err != nil { - return nil, err - } - b2, err := json.Marshal(s.VendorExtensible) - if err != nil { - return nil, err - } - return swag.ConcatJSON(b1, b2), nil -} - -// UnmarshalJSON hydrates this items instance with the data from JSON -func (s *SecurityRequirement) UnmarshalJSON(data []byte) error { - if err := json.Unmarshal(data, &s.SecurityRequirementProps); err != nil { - return err - } - return json.Unmarshal(data, &s.VendorExtensible) -} - -// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object -type SecurityRequirementProps map[string][]string diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go b/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go index 9b1352f4e..edf7e6de3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go @@ -19,8 +19,8 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/validation/spec" ) // SecurityScheme defines reusable Security Scheme Object, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/server.go b/vendor/k8s.io/kube-openapi/pkg/spec3/server.go index a505fb221..d5df0a781 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/server.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/server.go @@ -18,9 +18,11 @@ package spec3 import ( "encoding/json" - "k8s.io/kube-openapi/pkg/validation/spec" - "github.com/go-openapi/swag" + "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" + "k8s.io/kube-openapi/pkg/validation/spec" ) type Server struct { @@ -51,6 +53,10 @@ func (s *Server) MarshalJSON() ([]byte, error) { } func (s *Server) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, s) + } + if err := json.Unmarshal(data, &s.ServerProps); err != nil { return err } @@ -60,6 +66,20 @@ func (s *Server) UnmarshalJSON(data []byte) error { return nil } +func (s *Server) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ServerProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.ServerProps = x.ServerProps + + return nil +} + type ServerVariable struct { ServerVariableProps spec.VendorExtensible @@ -88,6 +108,9 @@ func (s *ServerVariable) MarshalJSON() ([]byte, error) { } func (s *ServerVariable) UnmarshalJSON(data []byte) error { + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, s) + } if err := json.Unmarshal(data, &s.ServerVariableProps); err != nil { return err } @@ -96,3 +119,17 @@ func (s *ServerVariable) UnmarshalJSON(data []byte) error { } return nil } + +func (s *ServerVariable) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decoder) error { + var x struct { + spec.Extensions + ServerVariableProps + } + if err := opts.UnmarshalNext(dec, &x); err != nil { + return err + } + s.Extensions = internal.SanitizeExtensions(x.Extensions) + s.ServerVariableProps = x.ServerVariableProps + + return nil +} diff --git a/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go b/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go index 3ff48a3c3..bed096fb7 100644 --- a/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go +++ b/vendor/k8s.io/kube-openapi/pkg/spec3/spec.go @@ -17,6 +17,10 @@ limitations under the License. package spec3 import ( + "encoding/json" + + "k8s.io/kube-openapi/pkg/internal" + jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" "k8s.io/kube-openapi/pkg/validation/spec" ) @@ -35,3 +39,12 @@ type OpenAPI struct { // ExternalDocs holds additional external documentation ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"` } + +func (o *OpenAPI) UnmarshalJSON(data []byte) error { + type OpenAPIWithNoFunctions OpenAPI + p := (*OpenAPIWithNoFunctions)(o) + if internal.UseOptimizedJSONUnmarshalingV3 { + return jsonv2.Unmarshal(data, &p) + } + return json.Unmarshal(data, &p) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go b/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go index a3f476d5d..519dcf2eb 100644 --- a/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go +++ b/vendor/k8s.io/kube-openapi/pkg/util/proto/document_v3.go @@ -120,7 +120,7 @@ func (d *Definitions) ParseSchemaV3(s *openapi_v3.Schema, path *Path) (Schema, e switch s.GetType() { case object: for _, extension := range s.GetSpecificationExtension() { - if extension.Name == "x-kuberentes-group-version-kind" { + if extension.Name == "x-kubernetes-group-version-kind" { // Objects with x-kubernetes-group-version-kind are always top // level types. return d.parseV3Kind(s, path) @@ -285,7 +285,7 @@ func parseV3Interface(def *yaml.Node) (interface{}, error) { func (d *Definitions) parseV3BaseSchema(s *openapi_v3.Schema, path *Path) (*BaseSchema, error) { if s == nil { - return nil, fmt.Errorf("cannot initializae BaseSchema from nil") + return nil, fmt.Errorf("cannot initialize BaseSchema from nil") } def, err := parseV3Interface(s.GetDefault().ToRawInfo()) diff --git a/vendor/k8s.io/kube-openapi/pkg/util/trie.go b/vendor/k8s.io/kube-openapi/pkg/util/trie.go new file mode 100644 index 000000000..a9a76c179 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/util/trie.go @@ -0,0 +1,79 @@ +/* +Copyright 2016 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 util + +// A simple trie implementation with Add and HasPrefix methods only. +type Trie struct { + children map[byte]*Trie + wordTail bool + word string +} + +// NewTrie creates a Trie and add all strings in the provided list to it. +func NewTrie(list []string) Trie { + ret := Trie{ + children: make(map[byte]*Trie), + wordTail: false, + } + for _, v := range list { + ret.Add(v) + } + return ret +} + +// Add adds a word to this trie +func (t *Trie) Add(v string) { + root := t + for _, b := range []byte(v) { + child, exists := root.children[b] + if !exists { + child = &Trie{ + children: make(map[byte]*Trie), + wordTail: false, + } + root.children[b] = child + } + root = child + } + root.wordTail = true + root.word = v +} + +// HasPrefix returns true of v has any of the prefixes stored in this trie. +func (t *Trie) HasPrefix(v string) bool { + _, has := t.GetPrefix(v) + return has +} + +// GetPrefix is like HasPrefix but return the prefix in case of match or empty string otherwise. +func (t *Trie) GetPrefix(v string) (string, bool) { + root := t + if root.wordTail { + return root.word, true + } + for _, b := range []byte(v) { + child, exists := root.children[b] + if !exists { + return "", false + } + if child.wordTail { + return child.word, true + } + root = child + } + return "", false +} diff --git a/vendor/k8s.io/kube-openapi/pkg/util/util.go b/vendor/k8s.io/kube-openapi/pkg/util/util.go new file mode 100644 index 000000000..6eee935b2 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/util/util.go @@ -0,0 +1,115 @@ +/* +Copyright 2017 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 util + +import ( + "reflect" + "strings" +) + +// [DEPRECATED] ToCanonicalName converts Golang package/type canonical name into REST friendly OpenAPI name. +// This method is deprecated because it has a misleading name. Please use ToRESTFriendlyName +// instead +// +// NOTE: actually the "canonical name" in this method should be named "REST friendly OpenAPI name", +// which is different from "canonical name" defined in GetCanonicalTypeName. The "canonical name" defined +// in GetCanonicalTypeName means Go type names with full package path. +// +// Examples of REST friendly OpenAPI name: +// +// Input: k8s.io/api/core/v1.Pod +// Output: io.k8s.api.core.v1.Pod +// +// Input: k8s.io/api/core/v1 +// Output: io.k8s.api.core.v1 +// +// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo +func ToCanonicalName(name string) string { + return ToRESTFriendlyName(name) +} + +// ToRESTFriendlyName converts Golang package/type canonical name into REST friendly OpenAPI name. +// +// Examples of REST friendly OpenAPI name: +// +// Input: k8s.io/api/core/v1.Pod +// Output: io.k8s.api.core.v1.Pod +// +// Input: k8s.io/api/core/v1 +// Output: io.k8s.api.core.v1 +// +// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo +func ToRESTFriendlyName(name string) string { + nameParts := strings.Split(name, "/") + // Reverse first part. e.g., io.k8s... instead of k8s.io... + if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") { + parts := strings.Split(nameParts[0], ".") + for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 { + parts[i], parts[j] = parts[j], parts[i] + } + nameParts[0] = strings.Join(parts, ".") + } + return strings.Join(nameParts, ".") +} + +// OpenAPICanonicalTypeNamer is an interface for models without Go type to seed model name. +// +// OpenAPI canonical names are Go type names with full package path, for uniquely indentifying +// a model / Go type. If a Go type is vendored from another package, only the path after "/vendor/" +// should be used. For custom resource definition (CRD), the canonical name is expected to be +// +// group/version.kind +// +// Examples of canonical name: +// +// Go type: k8s.io/kubernetes/pkg/apis/core.Pod +// CRD: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// +// Example for vendored Go type: +// +// Original full path: k8s.io/kubernetes/vendor/k8s.io/api/core/v1.Pod +// Canonical name: k8s.io/api/core/v1.Pod +// +// Original full path: vendor/k8s.io/api/core/v1.Pod +// Canonical name: k8s.io/api/core/v1.Pod +type OpenAPICanonicalTypeNamer interface { + OpenAPICanonicalTypeName() string +} + +// GetCanonicalTypeName will find the canonical type name of a sample object, removing +// the "vendor" part of the path +func GetCanonicalTypeName(model interface{}) string { + if namer, ok := model.(OpenAPICanonicalTypeNamer); ok { + return namer.OpenAPICanonicalTypeName() + } + t := reflect.TypeOf(model) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.PkgPath() == "" { + return t.Name() + } + path := t.PkgPath() + if strings.Contains(path, "/vendor/") { + path = path[strings.Index(path, "/vendor/")+len("/vendor/"):] + } else if strings.HasPrefix(path, "vendor/") { + path = strings.TrimPrefix(path, "vendor/") + } + return path + "." + t.Name() +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go index 9a2556306..05310c46b 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/header.go @@ -43,6 +43,9 @@ type Header struct { // MarshalJSON marshal this to JSON func (h Header) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(h) + } b1, err := json.Marshal(h.CommonValidations) if err != nil { return nil, err @@ -62,6 +65,20 @@ func (h Header) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3, b4), nil } +func (h Header) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + Extensions + HeaderProps + } + x.CommonValidations = commonValidationsOmitZero(h.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(h.SimpleSchema) + x.Extensions = internal.SanitizeExtensions(h.Extensions) + x.HeaderProps = h.HeaderProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON unmarshals this header from JSON func (h *Header) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -94,12 +111,8 @@ func (h *Header) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Dec h.CommonValidations = x.CommonValidations h.SimpleSchema = x.SimpleSchema - h.Extensions = x.Extensions + h.Extensions = internal.SanitizeExtensions(x.Extensions) h.HeaderProps = x.HeaderProps - h.Extensions.sanitize() - if len(h.Extensions) == 0 { - h.Extensions = nil - } return nil } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go index 395ececae..d667b705b 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/info.go @@ -89,17 +89,9 @@ func (e Extensions) GetObject(key string, out interface{}) error { return nil } -func (e Extensions) sanitize() { - for k := range e { - if !isExtensionKey(k) { - delete(e, k) - } - } -} - func (e Extensions) sanitizeWithExtra() (extra map[string]any) { for k, v := range e { - if !isExtensionKey(k) { + if !internal.IsExtensionKey(k) { if extra == nil { extra = make(map[string]any) } @@ -110,10 +102,6 @@ func (e Extensions) sanitizeWithExtra() (extra map[string]any) { return extra } -func isExtensionKey(k string) bool { - return len(k) > 1 && (k[0] == 'x' || k[0] == 'X') && k[1] == '-' -} - // VendorExtensible composition block. type VendorExtensible struct { Extensions Extensions @@ -181,6 +169,9 @@ type Info struct { // MarshalJSON marshal this to JSON func (i Info) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(i) + } b1, err := json.Marshal(i.InfoProps) if err != nil { return nil, err @@ -192,6 +183,16 @@ func (i Info) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (i Info) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + InfoProps + } + x.Extensions = i.Extensions + x.InfoProps = i.InfoProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (i *Info) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -212,11 +213,7 @@ func (i *Info) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decod if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } - i.VendorExtensible.Extensions = x.Extensions + i.Extensions = internal.SanitizeExtensions(x.Extensions) i.InfoProps = x.InfoProps return nil } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go index 374f90d28..4132467d2 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/items.go @@ -37,6 +37,18 @@ type SimpleSchema struct { Example interface{} `json:"example,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type simpleSchemaOmitZero struct { + Type string `json:"type,omitempty"` + Nullable bool `json:"nullable,omitzero"` + Format string `json:"format,omitempty"` + Items *Items `json:"items,omitzero"` + CollectionFormat string `json:"collectionFormat,omitempty"` + Default interface{} `json:"default,omitempty"` + Example interface{} `json:"example,omitempty"` +} + // CommonValidations describe common JSON-schema validations type CommonValidations struct { Maximum *float64 `json:"maximum,omitempty"` @@ -53,6 +65,23 @@ type CommonValidations struct { Enum []interface{} `json:"enum,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type commonValidationsOmitZero struct { + Maximum *float64 `json:"maximum,omitempty"` + ExclusiveMaximum bool `json:"exclusiveMaximum,omitzero"` + Minimum *float64 `json:"minimum,omitempty"` + ExclusiveMinimum bool `json:"exclusiveMinimum,omitzero"` + MaxLength *int64 `json:"maxLength,omitempty"` + MinLength *int64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *int64 `json:"maxItems,omitempty"` + MinItems *int64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitzero"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Enum []interface{} `json:"enum,omitempty"` +} + // Items a limited subset of JSON-Schema's items object. // It is used by parameter definitions that are not located in "body". // @@ -105,18 +134,18 @@ func (i *Items) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco if err := i.Refable.Ref.fromMap(x.Extensions); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } + i.CommonValidations = x.CommonValidations i.SimpleSchema = x.SimpleSchema - i.VendorExtensible.Extensions = x.Extensions + i.Extensions = internal.SanitizeExtensions(x.Extensions) return nil } // MarshalJSON converts this items object to JSON func (i Items) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(i) + } b1, err := json.Marshal(i.CommonValidations) if err != nil { return nil, err @@ -135,3 +164,17 @@ func (i Items) MarshalJSON() ([]byte, error) { } return swag.ConcatJSON(b4, b3, b1, b2), nil } + +func (i Items) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + Ref string `json:"$ref,omitempty"` + Extensions + } + x.CommonValidations = commonValidationsOmitZero(i.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(i.SimpleSchema) + x.Ref = i.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(i.Extensions) + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go index 923769ae0..63eed3460 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/operation.go @@ -42,6 +42,23 @@ type OperationProps struct { Responses *Responses `json:"responses,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type operationPropsOmitZero struct { + Description string `json:"description,omitempty"` + Consumes []string `json:"consumes,omitempty"` + Produces []string `json:"produces,omitempty"` + Schemes []string `json:"schemes,omitempty"` + Tags []string `json:"tags,omitempty"` + Summary string `json:"summary,omitempty"` + ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"` + ID string `json:"operationId,omitempty"` + Deprecated bool `json:"deprecated,omitempty,omitzero"` + Security []map[string][]string `json:"security,omitempty"` + Parameters []Parameter `json:"parameters,omitempty"` + Responses *Responses `json:"responses,omitzero"` +} + // MarshalJSON takes care of serializing operation properties to JSON // // We use a custom marhaller here to handle a special cases related to @@ -96,17 +113,16 @@ func (o *Operation) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } - o.VendorExtensible.Extensions = x.Extensions + o.Extensions = internal.SanitizeExtensions(x.Extensions) o.OperationProps = OperationProps(x.OperationPropsNoMethods) return nil } // MarshalJSON converts this items object to JSON func (o Operation) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(o) + } b1, err := json.Marshal(o.OperationProps) if err != nil { return nil, err @@ -118,3 +134,13 @@ func (o Operation) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b1, b2) return concated, nil } + +func (o Operation) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + OperationProps operationPropsOmitZero `json:",inline"` + } + x.Extensions = internal.SanitizeExtensions(o.Extensions) + x.OperationProps = operationPropsOmitZero(o.OperationProps) + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go index 7cb229ac1..53d1e0aa9 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/parameter.go @@ -36,6 +36,17 @@ type ParamProps struct { AllowEmptyValue bool `json:"allowEmptyValue,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type paramPropsOmitZero struct { + Description string `json:"description,omitempty"` + Name string `json:"name,omitempty"` + In string `json:"in,omitempty"` + Required bool `json:"required,omitzero"` + Schema *Schema `json:"schema,omitzero"` + AllowEmptyValue bool `json:"allowEmptyValue,omitzero"` +} + // Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn). // // There are five possible parameter types. @@ -109,19 +120,18 @@ func (p *Parameter) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. if err := p.Refable.Ref.fromMap(x.Extensions); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } p.CommonValidations = x.CommonValidations p.SimpleSchema = x.SimpleSchema - p.VendorExtensible.Extensions = x.Extensions + p.Extensions = internal.SanitizeExtensions(x.Extensions) p.ParamProps = x.ParamProps return nil } // MarshalJSON converts this items object to JSON func (p Parameter) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b1, err := json.Marshal(p.CommonValidations) if err != nil { return nil, err @@ -144,3 +154,19 @@ func (p Parameter) MarshalJSON() ([]byte, error) { } return swag.ConcatJSON(b3, b1, b2, b4, b5), nil } + +func (p Parameter) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + CommonValidations commonValidationsOmitZero `json:",inline"` + SimpleSchema simpleSchemaOmitZero `json:",inline"` + ParamProps paramPropsOmitZero `json:",inline"` + Ref string `json:"$ref,omitempty"` + Extensions + } + x.CommonValidations = commonValidationsOmitZero(p.CommonValidations) + x.SimpleSchema = simpleSchemaOmitZero(p.SimpleSchema) + x.Extensions = internal.SanitizeExtensions(p.Extensions) + x.ParamProps = paramPropsOmitZero(p.ParamProps) + x.Ref = p.Refable.Ref.String() + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go index 03741fcfb..1d1588cb9 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/path_item.go @@ -70,24 +70,20 @@ func (p *PathItem) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.D if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - - p.Extensions = x.Extensions - p.PathItemProps = x.PathItemProps - - if err := p.Refable.Ref.fromMap(p.Extensions); err != nil { + if err := p.Refable.Ref.fromMap(x.Extensions); err != nil { return err } - - p.Extensions.sanitize() - if len(p.Extensions) == 0 { - p.Extensions = nil - } + p.Extensions = internal.SanitizeExtensions(x.Extensions) + p.PathItemProps = x.PathItemProps return nil } // MarshalJSON converts this items object to JSON func (p PathItem) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b3, err := json.Marshal(p.Refable) if err != nil { return nil, err @@ -103,3 +99,15 @@ func (p PathItem) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b3, b4, b5) return concated, nil } + +func (p PathItem) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Ref string `json:"$ref,omitempty"` + Extensions + PathItemProps + } + x.Ref = p.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(p.Extensions) + x.PathItemProps = p.PathItemProps + return opts.MarshalNext(enc, x) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go index 7c63d440a..18f6a9f42 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/paths.go @@ -92,7 +92,7 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco } switch k := tok.String(); { - case isExtensionKey(k): + case internal.IsExtensionKey(k): ext = nil if err := opts.UnmarshalNext(dec, &ext); err != nil { return err @@ -114,7 +114,9 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco p.Paths[k] = pi default: _, err := dec.ReadValue() // skip value - return err + if err != nil { + return err + } } } default: @@ -124,6 +126,9 @@ func (p *Paths) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Deco // MarshalJSON converts this items object to JSON func (p Paths) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(p) + } b1, err := json.Marshal(p.VendorExtensible) if err != nil { return nil, err @@ -142,3 +147,18 @@ func (p Paths) MarshalJSON() ([]byte, error) { concated := swag.ConcatJSON(b1, b2) return concated, nil } + +func (p Paths) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + m := make(map[string]any, len(p.Extensions)+len(p.Paths)) + for k, v := range p.Extensions { + if internal.IsExtensionKey(k) { + m[k] = v + } + } + for k, v := range p.Paths { + if strings.HasPrefix(k, "/") { + m[k] = v + } + } + return opts.MarshalNext(enc, m) +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go index 1405bfd8e..775b3b0c3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/ref.go @@ -21,6 +21,8 @@ import ( "path/filepath" "github.com/go-openapi/jsonreference" + + "k8s.io/kube-openapi/pkg/internal" ) // Refable is a struct for things that accept a $ref property @@ -149,19 +151,5 @@ func (r *Ref) UnmarshalJSON(d []byte) error { } func (r *Ref) fromMap(v map[string]interface{}) error { - if v == nil { - return nil - } - - if vv, ok := v["$ref"]; ok { - if str, ok := vv.(string); ok { - ref, err := jsonreference.New(str) - if err != nil { - return err - } - *r = Ref{Ref: ref} - } - } - - return nil + return internal.JSONRefFromMap(&r.Ref, v) } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go index f01364b75..3ff1fe132 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/response.go @@ -30,6 +30,15 @@ type ResponseProps struct { Examples map[string]interface{} `json:"examples,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type responsePropsOmitZero struct { + Description string `json:"description,omitempty"` + Schema *Schema `json:"schema,omitzero"` + Headers map[string]Header `json:"headers,omitempty"` + Examples map[string]interface{} `json:"examples,omitempty"` +} + // Response describes a single response from an API Operation. // // For more information: http://goo.gl/8us55a#responseObject @@ -68,23 +77,20 @@ func (r *Response) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.D return err } - r.Extensions = x.Extensions - r.ResponseProps = x.ResponseProps - - if err := r.Refable.Ref.fromMap(r.Extensions); err != nil { + if err := r.Refable.Ref.fromMap(x.Extensions); err != nil { return err } - - r.Extensions.sanitize() - if len(r.Extensions) == 0 { - r.Extensions = nil - } + r.Extensions = internal.SanitizeExtensions(x.Extensions) + r.ResponseProps = x.ResponseProps return nil } // MarshalJSON converts this items object to JSON func (r Response) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(r) + } b1, err := json.Marshal(r.ResponseProps) if err != nil { return nil, err @@ -100,6 +106,18 @@ func (r Response) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3), nil } +func (r Response) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Ref string `json:"$ref,omitempty"` + Extensions + ResponseProps responsePropsOmitZero `json:",inline"` + } + x.Ref = r.Refable.Ref.String() + x.Extensions = internal.SanitizeExtensions(r.Extensions) + x.ResponseProps = responsePropsOmitZero(r.ResponseProps) + return opts.MarshalNext(enc, x) +} + // NewResponse creates a new response instance func NewResponse() *Response { return new(Response) diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go index c3fa68191..d9ad760a4 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/responses.go @@ -63,6 +63,9 @@ func (r *Responses) UnmarshalJSON(data []byte) error { // MarshalJSON converts this items object to JSON func (r Responses) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(r) + } b1, err := json.Marshal(r.ResponsesProps) if err != nil { return nil, err @@ -75,6 +78,25 @@ func (r Responses) MarshalJSON() ([]byte, error) { return concated, nil } +func (r Responses) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + type ArbitraryKeys map[string]interface{} + var x struct { + ArbitraryKeys + Default *Response `json:"default,omitempty"` + } + x.ArbitraryKeys = make(map[string]any, len(r.Extensions)+len(r.StatusCodeResponses)) + for k, v := range r.Extensions { + if internal.IsExtensionKey(k) { + x.ArbitraryKeys[k] = v + } + } + for k, v := range r.StatusCodeResponses { + x.ArbitraryKeys[strconv.Itoa(k)] = v + } + x.Default = r.Default + return opts.MarshalNext(enc, x) +} + // ResponsesProps describes all responses for an operation. // It tells what is the default response and maps all responses with a // HTTP status code. @@ -148,7 +170,7 @@ func (r *Responses) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2. return nil } switch k := tok.String(); { - case isExtensionKey(k): + case internal.IsExtensionKey(k): ext = nil if err := opts.UnmarshalNext(dec, &ext); err != nil { return err diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go index 9add0c163..dfbb2e05c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/schema.go @@ -196,6 +196,46 @@ type SchemaProps struct { Definitions Definitions `json:"definitions,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type schemaPropsOmitZero struct { + ID string `json:"id,omitempty"` + Ref Ref `json:"-"` + Schema SchemaURL `json:"-"` + Description string `json:"description,omitempty"` + Type StringOrArray `json:"type,omitzero"` + Nullable bool `json:"nullable,omitzero"` + Format string `json:"format,omitempty"` + Title string `json:"title,omitempty"` + Default interface{} `json:"default,omitzero"` + Maximum *float64 `json:"maximum,omitempty"` + ExclusiveMaximum bool `json:"exclusiveMaximum,omitzero"` + Minimum *float64 `json:"minimum,omitempty"` + ExclusiveMinimum bool `json:"exclusiveMinimum,omitzero"` + MaxLength *int64 `json:"maxLength,omitempty"` + MinLength *int64 `json:"minLength,omitempty"` + Pattern string `json:"pattern,omitempty"` + MaxItems *int64 `json:"maxItems,omitempty"` + MinItems *int64 `json:"minItems,omitempty"` + UniqueItems bool `json:"uniqueItems,omitzero"` + MultipleOf *float64 `json:"multipleOf,omitempty"` + Enum []interface{} `json:"enum,omitempty"` + MaxProperties *int64 `json:"maxProperties,omitempty"` + MinProperties *int64 `json:"minProperties,omitempty"` + Required []string `json:"required,omitempty"` + Items *SchemaOrArray `json:"items,omitzero"` + AllOf []Schema `json:"allOf,omitempty"` + OneOf []Schema `json:"oneOf,omitempty"` + AnyOf []Schema `json:"anyOf,omitempty"` + Not *Schema `json:"not,omitzero"` + Properties map[string]Schema `json:"properties,omitempty"` + AdditionalProperties *SchemaOrBool `json:"additionalProperties,omitzero"` + PatternProperties map[string]Schema `json:"patternProperties,omitempty"` + Dependencies Dependencies `json:"dependencies,omitempty"` + AdditionalItems *SchemaOrBool `json:"additionalItems,omitzero"` + Definitions Definitions `json:"definitions,omitempty"` +} + // SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4) type SwaggerSchemaProps struct { Discriminator string `json:"discriminator,omitempty"` @@ -204,6 +244,15 @@ type SwaggerSchemaProps struct { Example interface{} `json:"example,omitempty"` } +// Marshaling structure only, always edit along with corresponding +// struct (or compilation will fail). +type swaggerSchemaPropsOmitZero struct { + Discriminator string `json:"discriminator,omitempty"` + ReadOnly bool `json:"readOnly,omitzero"` + ExternalDocs *ExternalDocumentation `json:"externalDocs,omitzero"` + Example interface{} `json:"example,omitempty"` +} + // Schema the schema object allows the definition of input and output data types. // These types can be objects, but also primitives and arrays. // This object is based on the [JSON Schema Specification Draft 4](http://json-schema.org/) @@ -434,6 +483,9 @@ func (s *Schema) WithExternalDocs(description, url string) *Schema { // MarshalJSON marshal this to JSON func (s Schema) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SchemaProps) if err != nil { return nil, fmt.Errorf("schema props %v", err) @@ -465,6 +517,31 @@ func (s Schema) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil } +func (s Schema) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + type ArbitraryKeys map[string]interface{} + var x struct { + ArbitraryKeys + SchemaProps schemaPropsOmitZero `json:",inline"` + SwaggerSchemaProps swaggerSchemaPropsOmitZero `json:",inline"` + Schema string `json:"$schema,omitempty"` + Ref string `json:"$ref,omitempty"` + } + x.ArbitraryKeys = make(map[string]any, len(s.Extensions)+len(s.ExtraProps)) + for k, v := range s.Extensions { + if internal.IsExtensionKey(k) { + x.ArbitraryKeys[k] = v + } + } + for k, v := range s.ExtraProps { + x.ArbitraryKeys[k] = v + } + x.SchemaProps = schemaPropsOmitZero(s.SchemaProps) + x.SwaggerSchemaProps = swaggerSchemaPropsOmitZero(s.SwaggerSchemaProps) + x.Ref = s.Ref.String() + x.Schema = string(s.Schema) + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (s *Schema) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -547,7 +624,7 @@ func (s *Schema) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Dec } s.ExtraProps = x.Extensions.sanitizeWithExtra() - s.VendorExtensible.Extensions = x.Extensions + s.Extensions = internal.SanitizeExtensions(x.Extensions) s.SchemaProps = x.SchemaProps s.SwaggerSchemaProps = x.SwaggerSchemaProps return nil diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go index 34723fb71..e2b7da14c 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/security_scheme.go @@ -18,6 +18,7 @@ import ( "encoding/json" "github.com/go-openapi/swag" + "k8s.io/kube-openapi/pkg/internal" jsonv2 "k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json" ) @@ -45,6 +46,9 @@ type SecurityScheme struct { // MarshalJSON marshal this to JSON func (s SecurityScheme) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SecuritySchemeProps) if err != nil { return nil, err @@ -56,6 +60,16 @@ func (s SecurityScheme) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (s SecurityScheme) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + SecuritySchemeProps + } + x.Extensions = internal.SanitizeExtensions(s.Extensions) + x.SecuritySchemeProps = s.SecuritySchemeProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (s *SecurityScheme) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &s.SecuritySchemeProps); err != nil { @@ -72,11 +86,7 @@ func (s *SecurityScheme) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *js if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } - s.VendorExtensible.Extensions = x.Extensions + s.Extensions = internal.SanitizeExtensions(x.Extensions) s.SecuritySchemeProps = x.SecuritySchemeProps return nil } diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go index f6cb7da3f..c8f3beaa3 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/swagger.go @@ -35,6 +35,9 @@ type Swagger struct { // MarshalJSON marshals this swagger structure to json func (s Swagger) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } b1, err := json.Marshal(s.SwaggerProps) if err != nil { return nil, err @@ -46,12 +49,22 @@ func (s Swagger) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +// MarshalJSON marshals this swagger structure to json +func (s Swagger) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + SwaggerProps + } + x.Extensions = internal.SanitizeExtensions(s.Extensions) + x.SwaggerProps = s.SwaggerProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON unmarshals a swagger spec from json func (s *Swagger) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { return jsonv2.Unmarshal(data, s) } - var sw Swagger if err := json.Unmarshal(data, &sw.SwaggerProps); err != nil { return err @@ -75,15 +88,8 @@ func (s *Swagger) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.De if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - - s.Extensions = x.Extensions + s.Extensions = internal.SanitizeExtensions(x.Extensions) s.SwaggerProps = x.SwaggerProps - - s.Extensions.sanitize() - if len(s.Extensions) == 0 { - s.Extensions = nil - } - return nil } @@ -126,6 +132,9 @@ var jsFalse = []byte("false") // MarshalJSON convert this object to JSON func (s SchemaOrBool) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } if s.Schema != nil { return json.Marshal(s.Schema) } @@ -136,6 +145,18 @@ func (s SchemaOrBool) MarshalJSON() ([]byte, error) { return jsTrue, nil } +// MarshalJSON convert this object to JSON +func (s SchemaOrBool) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if s.Schema != nil { + return opts.MarshalNext(enc, s.Schema) + } + + if s.Schema == nil && !s.Allows { + return enc.WriteToken(jsonv2.False) + } + return enc.WriteToken(jsonv2.True) +} + // UnmarshalJSON converts this bool or schema object from a JSON structure func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -143,15 +164,15 @@ func (s *SchemaOrBool) UnmarshalJSON(data []byte) error { } var nw SchemaOrBool - if len(data) >= 4 { - if data[0] == '{' { - var sch Schema - if err := json.Unmarshal(data, &sch); err != nil { - return err - } - nw.Schema = &sch + if len(data) > 0 && data[0] == '{' { + var sch Schema + if err := json.Unmarshal(data, &sch); err != nil { + return err } - nw.Allows = !(data[0] == 'f' && data[1] == 'a' && data[2] == 'l' && data[3] == 's' && data[4] == 'e') + nw.Schema = &sch + nw.Allows = true + } else { + json.Unmarshal(data, &nw.Allows) } *s = nw return nil @@ -185,6 +206,9 @@ type SchemaOrStringArray struct { // MarshalJSON converts this schema object or array into JSON structure func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } if len(s.Property) > 0 { return json.Marshal(s.Property) } @@ -194,6 +218,17 @@ func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) { return []byte("null"), nil } +// MarshalJSON converts this schema object or array into JSON structure +func (s SchemaOrStringArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if len(s.Property) > 0 { + return opts.MarshalNext(enc, s.Property) + } + if s.Schema != nil { + return opts.MarshalNext(enc, s.Schema) + } + return enc.WriteToken(jsonv2.Null) +} + // UnmarshalJSON converts this schema object or array from a JSON structure func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -347,12 +382,23 @@ func (s *SchemaOrArray) ContainsType(name string) bool { // MarshalJSON converts this schema object or array into JSON structure func (s SchemaOrArray) MarshalJSON() ([]byte, error) { - if len(s.Schemas) > 0 { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(s) + } + if s.Schemas != nil { return json.Marshal(s.Schemas) } return json.Marshal(s.Schema) } +// MarshalJSON converts this schema object or array into JSON structure +func (s SchemaOrArray) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + if s.Schemas != nil { + return opts.MarshalNext(enc, s.Schemas) + } + return opts.MarshalNext(enc, s.Schema) +} + // UnmarshalJSON converts this schema object or array from a JSON structure func (s *SchemaOrArray) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go b/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go index 69e93b60b..d105d52ca 100644 --- a/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go +++ b/vendor/k8s.io/kube-openapi/pkg/validation/spec/tag.go @@ -41,6 +41,9 @@ type Tag struct { // MarshalJSON marshal this to JSON func (t Tag) MarshalJSON() ([]byte, error) { + if internal.UseOptimizedJSONMarshaling { + return internal.DeterministicMarshal(t) + } b1, err := json.Marshal(t.TagProps) if err != nil { return nil, err @@ -52,6 +55,16 @@ func (t Tag) MarshalJSON() ([]byte, error) { return swag.ConcatJSON(b1, b2), nil } +func (t Tag) MarshalNextJSON(opts jsonv2.MarshalOptions, enc *jsonv2.Encoder) error { + var x struct { + Extensions + TagProps + } + x.Extensions = internal.SanitizeExtensions(t.Extensions) + x.TagProps = t.TagProps + return opts.MarshalNext(enc, x) +} + // UnmarshalJSON marshal this from JSON func (t *Tag) UnmarshalJSON(data []byte) error { if internal.UseOptimizedJSONUnmarshaling { @@ -72,11 +85,7 @@ func (t *Tag) UnmarshalNextJSON(opts jsonv2.UnmarshalOptions, dec *jsonv2.Decode if err := opts.UnmarshalNext(dec, &x); err != nil { return err } - x.Extensions.sanitize() - if len(x.Extensions) == 0 { - x.Extensions = nil - } - t.VendorExtensible.Extensions = x.Extensions + t.Extensions = internal.SanitizeExtensions(x.Extensions) t.TagProps = x.TagProps return nil } diff --git a/vendor/k8s.io/kubelet/pkg/apis/well_known_labels.go b/vendor/k8s.io/kubelet/pkg/apis/well_known_labels.go new file mode 100644 index 000000000..96890b553 --- /dev/null +++ b/vendor/k8s.io/kubelet/pkg/apis/well_known_labels.go @@ -0,0 +1,87 @@ +/* +Copyright 2015 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 apis + +import ( + "strings" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/sets" +) + +const ( + // LabelOS is a label to indicate the operating system of the node. + // The OS labels are promoted to GA in 1.14. kubelet applies GA labels and stop applying the beta OS labels in Kubernetes 1.19. + LabelOS = "beta.kubernetes.io/os" + // LabelArch is a label to indicate the architecture of the node. + // The Arch labels are promoted to GA in 1.14. kubelet applies GA labels and stop applying the beta Arch labels in Kubernetes 1.19. + LabelArch = "beta.kubernetes.io/arch" +) + +var kubeletLabels = sets.NewString( + v1.LabelHostname, + v1.LabelTopologyZone, + v1.LabelTopologyRegion, + v1.LabelFailureDomainBetaZone, + v1.LabelFailureDomainBetaRegion, + v1.LabelInstanceType, + v1.LabelInstanceTypeStable, + v1.LabelOSStable, + v1.LabelArchStable, + + LabelOS, + LabelArch, +) + +var kubeletLabelNamespaces = sets.NewString( + v1.LabelNamespaceSuffixKubelet, + v1.LabelNamespaceSuffixNode, +) + +// KubeletLabels returns the list of label keys kubelets are allowed to set on their own Node objects +func KubeletLabels() []string { + return kubeletLabels.List() +} + +// KubeletLabelNamespaces returns the list of label key namespaces kubelets are allowed to set on their own Node objects +func KubeletLabelNamespaces() []string { + return kubeletLabelNamespaces.List() +} + +// IsKubeletLabel returns true if the label key is one that kubelets are allowed to set on their own Node object. +// This checks if the key is in the KubeletLabels() list, or has a namespace in the KubeletLabelNamespaces() list. +func IsKubeletLabel(key string) bool { + if kubeletLabels.Has(key) { + return true + } + + namespace := getLabelNamespace(key) + for allowedNamespace := range kubeletLabelNamespaces { + if namespace == allowedNamespace || strings.HasSuffix(namespace, "."+allowedNamespace) { + return true + } + } + + return false +} + +func getLabelNamespace(key string) string { + if parts := strings.SplitN(key, "/", 2); len(parts) == 2 { + return parts[0] + } + return "" +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/service/util.go b/vendor/k8s.io/kubernetes/pkg/api/service/util.go index a4262edad..c73d96a6c 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/service/util.go +++ b/vendor/k8s.io/kubernetes/pkg/api/service/util.go @@ -74,7 +74,7 @@ func RequestsOnlyLocalTraffic(service *api.Service) bool { return false } - return service.Spec.ExternalTrafficPolicy == api.ServiceExternalTrafficPolicyTypeLocal + return service.Spec.ExternalTrafficPolicy == api.ServiceExternalTrafficPolicyLocal } // NeedsHealthCheck checks if service needs health check. diff --git a/vendor/k8s.io/kubernetes/pkg/api/service/warnings.go b/vendor/k8s.io/kubernetes/pkg/api/service/warnings.go new file mode 100644 index 000000000..c99553367 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/api/service/warnings.go @@ -0,0 +1,99 @@ +/* +Copyright 2022 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 service + +import ( + "fmt" + "net/netip" + + "k8s.io/apimachinery/pkg/util/validation/field" + api "k8s.io/kubernetes/pkg/apis/core" + "k8s.io/kubernetes/pkg/apis/core/helper" +) + +func GetWarningsForService(service, oldService *api.Service) []string { + if service == nil { + return nil + } + var warnings []string + + if _, ok := service.Annotations[api.DeprecatedAnnotationTopologyAwareHints]; ok { + warnings = append(warnings, fmt.Sprintf("annotation %s is deprecated, please use %s instead", api.DeprecatedAnnotationTopologyAwareHints, api.AnnotationTopologyMode)) + } + + if helper.IsServiceIPSet(service) { + for i, clusterIP := range service.Spec.ClusterIPs { + warnings = append(warnings, getWarningsForIP(field.NewPath("spec").Child("clusterIPs").Index(i), clusterIP)...) + } + } + + for i, externalIP := range service.Spec.ExternalIPs { + warnings = append(warnings, getWarningsForIP(field.NewPath("spec").Child("externalIPs").Index(i), externalIP)...) + } + + if len(service.Spec.LoadBalancerIP) > 0 { + warnings = append(warnings, getWarningsForIP(field.NewPath("spec").Child("loadBalancerIP"), service.Spec.LoadBalancerIP)...) + } + + for i, cidr := range service.Spec.LoadBalancerSourceRanges { + warnings = append(warnings, getWarningsForCIDR(field.NewPath("spec").Child("loadBalancerSourceRanges").Index(i), cidr)...) + } + + return warnings +} + +func getWarningsForIP(fieldPath *field.Path, address string) []string { + // IPv4 addresses with leading zeros CVE-2021-29923 are not valid in golang since 1.17 + // This will also warn about possible future changes on the golang std library + // xref: https://issues.k8s.io/108074 + ip, err := netip.ParseAddr(address) + if err != nil { + return []string{fmt.Sprintf("%s: IP address was accepted, but will be invalid in a future Kubernetes release: %v", fieldPath, err)} + } + // A Recommendation for IPv6 Address Text Representation + // + // "All of the above examples represent the same IPv6 address. This + // flexibility has caused many problems for operators, systems + // engineers, and customers. + // ..." + // https://datatracker.ietf.org/doc/rfc5952/ + if ip.Is6() && ip.String() != address { + return []string{fmt.Sprintf("%s: IPv6 address %q is not in RFC 5952 canonical format (%q), which may cause controller apply-loops", fieldPath, address, ip.String())} + } + return []string{} +} + +func getWarningsForCIDR(fieldPath *field.Path, cidr string) []string { + // IPv4 addresses with leading zeros CVE-2021-29923 are not valid in golang since 1.17 + // This will also warn about possible future changes on the golang std library + // xref: https://issues.k8s.io/108074 + prefix, err := netip.ParsePrefix(cidr) + if err != nil { + return []string{fmt.Sprintf("%s: IP prefix was accepted, but will be invalid in a future Kubernetes release: %v", fieldPath, err)} + } + // A Recommendation for IPv6 Address Text Representation + // + // "All of the above examples represent the same IPv6 address. This + // flexibility has caused many problems for operators, systems + // engineers, and customers. + // ..." + // https://datatracker.ietf.org/doc/rfc5952/ + if prefix.Addr().Is6() && prefix.String() != cidr { + return []string{fmt.Sprintf("%s: IPv6 prefix %q is not in RFC 5952 canonical format (%q), which may cause controller apply-loops", fieldPath, cidr, prefix.String())} + } + return []string{} +} diff --git a/vendor/k8s.io/kubernetes/pkg/api/v1/pod/util.go b/vendor/k8s.io/kubernetes/pkg/api/v1/pod/util.go index dc526b62e..2bd37c5b5 100644 --- a/vendor/k8s.io/kubernetes/pkg/api/v1/pod/util.go +++ b/vendor/k8s.io/kubernetes/pkg/api/v1/pod/util.go @@ -257,7 +257,7 @@ func visitContainerConfigmapNames(container *v1.Container, visitor Visitor) bool } // GetContainerStatus extracts the status of container "name" from "statuses". -// It also returns if "name" exists. +// It returns true if "name" exists, else returns false. func GetContainerStatus(statuses []v1.ContainerStatus, name string) (v1.ContainerStatus, bool) { for i := range statuses { if statuses[i].Name == name { @@ -274,6 +274,17 @@ func GetExistingContainerStatus(statuses []v1.ContainerStatus, name string) v1.C return status } +// GetIndexOfContainerStatus gets the index of status of container "name" from "statuses", +// It returns (index, true) if "name" exists, else returns (0, false). +func GetIndexOfContainerStatus(statuses []v1.ContainerStatus, name string) (int, bool) { + for i := range statuses { + if statuses[i].Name == name { + return i, true + } + } + return 0, false +} + // IsPodAvailable returns true if a pod is available; false otherwise. // Precondition for an available pod is that it must be ready. On top // of that, there are two cases when a pod can be considered available: diff --git a/vendor/k8s.io/kubernetes/pkg/apis/apps/types.go b/vendor/k8s.io/kubernetes/pkg/apis/apps/types.go index 624deca9b..90d71cd16 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/apps/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/apps/types.go @@ -180,6 +180,7 @@ type StatefulSetSpec struct { // of the StatefulSet. Each pod will be named with the format // -. For example, a pod in a StatefulSet named // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". Template api.PodTemplateSpec // VolumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -229,7 +230,7 @@ type StatefulSetSpec struct { // PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from // the StatefulSet VolumeClaimTemplates. This requires the - // StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. + // StatefulSetAutoDeletePVC feature gate to be enabled, which is beta and default on from 1.27. // +optional PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy @@ -237,7 +238,7 @@ type StatefulSetSpec struct { // default ordinals behavior assigns a "0" index to the first replica and // increments the index by one for each additional replica requested. Using // the ordinals field requires the StatefulSetStartOrdinal feature gate to be - // enabled, which is alpha. + // enabled, which is beta. // +optional Ordinals *StatefulSetOrdinals } @@ -376,6 +377,7 @@ type DeploymentSpec struct { Selector *metav1.LabelSelector // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". Template api.PodTemplateSpec // The deployment strategy to use to replace existing pods with new ones. @@ -666,6 +668,7 @@ type DaemonSetSpec struct { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template Template api.PodTemplateSpec @@ -857,6 +860,7 @@ type ReplicaSetSpec struct { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. + // The only allowed template.spec.restartPolicy value is "Always". // +optional Template api.PodTemplateSpec } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go index e0ed0dad1..7f254442b 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go @@ -31,25 +31,25 @@ type Scale struct { // +optional metav1.ObjectMeta - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional Spec ScaleSpec - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status represents the current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional Status ScaleStatus } // ScaleSpec describes the attributes of a scale subresource. type ScaleSpec struct { - // desired number of instances for the scaled object. + // replicas is the desired number of instances for the scaled object. // +optional Replicas int32 } // ScaleStatus represents the current status of a scale subresource. type ScaleStatus struct { - // actual number of observed instances of the scaled object. + // replicas is the actual number of observed instances of the scaled object. Replicas int32 // label query over pods that should match the replicas count. This is same @@ -62,20 +62,23 @@ type ScaleStatus struct { // CrossVersionObjectReference contains enough information to let you identify the referred resource. type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" Kind string - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string - // API version of the referent + + // apiVersion is the API version of the referent // +optional APIVersion string } // HorizontalPodAutoscalerSpec describes the desired functionality of the HorizontalPodAutoscaler. type HorizontalPodAutoscalerSpec struct { - // ScaleTargetRef points to the target resource to scale, and is used to the pods for which metrics + // scaleTargetRef points to the target resource to scale, and is used to the pods for which metrics // should be collected, as well as to actually change the replica count. ScaleTargetRef CrossVersionObjectReference + // minReplicas is the lower limit for the number of replicas to which the autoscaler // can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the // alpha feature gate HPAScaleToZero is enabled and at least one Object or External @@ -83,10 +86,12 @@ type HorizontalPodAutoscalerSpec struct { // available. // +optional MinReplicas *int32 - // MaxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. + + // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. // It cannot be less that minReplicas. MaxReplicas int32 - // Metrics contains the specifications for which to use to calculate the + + // metrics contains the specifications for which to use to calculate the // desired replica count (the maximum replica count across all metrics will // be used). The desired replica count is calculated multiplying the // ratio between the target value and the current value by the current @@ -487,7 +492,7 @@ type PodsMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name api.ResourceName Current MetricValueStatus } @@ -498,7 +503,7 @@ type ResourceMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ContainerResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name api.ResourceName Container string Current MetricValueStatus @@ -530,12 +535,12 @@ type HorizontalPodAutoscaler struct { // +optional metav1.ObjectMeta - // Spec is the specification for the behaviour of the autoscaler. + // spec is the specification for the behaviour of the autoscaler. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional Spec HorizontalPodAutoscalerSpec - // Status is the current information about the autoscaler. + // status is the current information about the autoscaler. // +optional Status HorizontalPodAutoscalerStatus } @@ -549,6 +554,6 @@ type HorizontalPodAutoscalerList struct { // +optional metav1.ListMeta - // Items is the list of horizontal pod autoscaler objects. + // items is the list of horizontal pod autoscaler objects. Items []HorizontalPodAutoscaler } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/register.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/register.go index 3b1558ab4..f496b994c 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/register.go @@ -49,7 +49,6 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &Job{}, &JobList{}, - &JobTemplate{}, &CronJob{}, &CronJobList{}, ) diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/types.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/types.go index cd3dd9656..dbddde490 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/types.go @@ -22,16 +22,29 @@ import ( api "k8s.io/kubernetes/pkg/apis/core" ) -// JobTrackingFinalizer is a finalizer for Job's pods. It prevents them from -// being deleted before being accounted in the Job status. -// -// Additionally, the apiserver and job controller use this string as a Job -// annotation, to mark Jobs that are being tracked using pod finalizers. -// However, this behavior is deprecated in kubernetes 1.26. This means that, in -// 1.27+, one release after JobTrackingWithFinalizers graduates to GA, the -// apiserver and job controller will ignore this annotation and they will -// always track jobs using finalizers. -const JobTrackingFinalizer = "batch.kubernetes.io/job-tracking" +const ( + // Unprefixed labels are reserved for end-users + // so we will add a batch.kubernetes.io to designate these labels as official Kubernetes labels. + // See https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#label-selector-and-annotation-conventions + labelPrefix = "batch.kubernetes.io/" + // JobTrackingFinalizer is a finalizer for Job's pods. It prevents them from + // being deleted before being accounted in the Job status. + // + // Additionally, the apiserver and job controller use this string as a Job + // annotation, to mark Jobs that are being tracked using pod finalizers. + // However, this behavior is deprecated in kubernetes 1.26. This means that, in + // 1.27+, one release after JobTrackingWithFinalizers graduates to GA, the + // apiserver and job controller will ignore this annotation and they will + // always track jobs using finalizers. + JobTrackingFinalizer = labelPrefix + "job-tracking" + // LegacyJobName and LegacyControllerUid are legacy labels that were set using unprefixed labels. + LegacyJobNameLabel = "job-name" + LegacyControllerUidLabel = "controller-uid" + // JobName is a user friendly way to refer to jobs and is set in the labels for jobs. + JobNameLabel = labelPrefix + LegacyJobNameLabel + // Controller UID is used for selectors and labels for jobs + ControllerUidLabel = labelPrefix + LegacyControllerUidLabel +) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -68,22 +81,6 @@ type JobList struct { Items []Job } -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// JobTemplate describes a template for creating copies of a predefined pod. -type JobTemplate struct { - metav1.TypeMeta - // Standard object's metadata. - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta - - // Defines jobs that will be created from this template. - // https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional - Template JobTemplateSpec -} - // JobTemplateSpec describes the data a Job should have when created from a template type JobTemplateSpec struct { // Standard object's metadata of the jobs created from this template. @@ -158,6 +155,7 @@ type PodFailurePolicyOnExitCodesRequirement struct { // Represents the relationship between the container exit code(s) and the // specified values. Containers completed with success (exit code 0) are // excluded from the requirement check. Possible values are: + // // - In: the requirement is satisfied if at least one container exit code // (might be multiple if there are multiple containers not restricted // by the 'containerName' field) is in the set of specified values. @@ -194,6 +192,7 @@ type PodFailurePolicyOnPodConditionsPattern struct { type PodFailurePolicyRule struct { // Specifies the action taken on a pod failure when the requirements are satisfied. // Possible values are: + // // - FailJob: indicates that the pod's job is marked as Failed and all // running pods are terminated. // - Ignore: indicates that the counter towards the .backoffLimit is not @@ -237,7 +236,7 @@ type JobSpec struct { Parallelism *int32 // Specifies the desired number of successfully finished pods the - // job should be run with. Setting to nil means that the success of any + // 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. @@ -293,6 +292,7 @@ type JobSpec struct { ManualSelector *bool // Describes the pod that will be created when executing a job. + // The only allowed template.spec.restartPolicy values are "Never" or "OnFailure". Template api.PodTemplateSpec // ttlSecondsAfterFinished limits the lifetime of a Job that has finished @@ -305,7 +305,7 @@ type JobSpec struct { // +optional TTLSecondsAfterFinished *int32 - // CompletionMode specifies how Pod completions are tracked. It can be + // completionMode specifies how Pod completions are tracked. It can be // `NonIndexed` (default) or `Indexed`. // // `NonIndexed` means that the Job is considered complete when there have @@ -330,7 +330,7 @@ type JobSpec struct { // +optional CompletionMode *CompletionMode - // Suspend specifies whether the Job controller should create Pods or not. If + // suspend specifies whether the Job controller should create Pods or not. If // a Job is created with suspend set to true, no Pods are created by the Job // controller. If a Job is suspended after creation (i.e. the flag goes from // false to true), the Job controller will delete all active Pods associated @@ -387,7 +387,7 @@ type JobStatus struct { // +optional Failed int32 - // CompletedIndexes holds the completed indexes when .spec.completionMode = + // 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 @@ -397,15 +397,16 @@ type JobStatus struct { // +optional CompletedIndexes string - // UncountedTerminatedPods holds the UIDs of Pods that have terminated but + // uncountedTerminatedPods holds the UIDs of Pods that have terminated but // the job controller hasn't yet accounted for in the status counters. // // The 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: - // (1) Add the pod UID to the corresponding array in this field. - // (2) Remove the pod finalizer. - // (3) Remove the pod UID from the array while increasing the corresponding + // + // 1. Add the pod UID to the corresponding array in this field. + // 2. Remove the pod finalizer. + // 3. Remove the pod UID from the array while increasing the corresponding // counter. // // Old jobs might not be tracked using this field, in which case the field @@ -417,12 +418,12 @@ type JobStatus struct { // UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't // been accounted in Job status counters. type UncountedTerminatedPods struct { - // Succeeded holds UIDs of succeeded Pods. + // succeeded holds UIDs of succeeded Pods. // +listType=set // +optional Succeeded []types.UID - // Failed holds UIDs of failed Pods. + // failed holds UIDs of failed Pods. // +listType=set // +optional Failed []types.UID @@ -513,7 +514,6 @@ type CronJobSpec struct { // configuration, the controller will stop creating new new Jobs and will create a system event with the // reason UnknownTimeZone. // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones - // This is beta field and must be enabled via the `CronJobTimeZone` feature gate. // +optional TimeZone *string @@ -524,6 +524,7 @@ type CronJobSpec struct { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one diff --git a/vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go index 98b86bfcc..015128250 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/batch/zz_generated.deepcopy.go @@ -347,33 +347,6 @@ func (in *JobStatus) DeepCopy() *JobStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JobTemplate) DeepCopyInto(out *JobTemplate) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Template.DeepCopyInto(&out.Template) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobTemplate. -func (in *JobTemplate) DeepCopy() *JobTemplate { - if in == nil { - return nil - } - out := new(JobTemplate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *JobTemplate) 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 *JobTemplateSpec) DeepCopyInto(out *JobTemplateSpec) { *out = *in diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/annotation_key_constants.go b/vendor/k8s.io/kubernetes/pkg/apis/core/annotation_key_constants.go index 3053200a2..60cff22b9 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/annotation_key_constants.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/annotation_key_constants.go @@ -122,8 +122,24 @@ const ( // This annotation is beta-level and is only honored when PodDeletionCost feature is enabled. PodDeletionCost = "controller.kubernetes.io/pod-deletion-cost" - // AnnotationTopologyAwareHints can be used to enable or disable Topology - // Aware Hints for a Service. This may be set to "Auto" or "Disabled". Any - // other value is treated as "Disabled". - AnnotationTopologyAwareHints = "service.kubernetes.io/topology-aware-hints" + // DeprecatedAnnotationTopologyAwareHints can be used to enable or disable + // Topology Aware Hints for a Service. This may be set to "Auto" or + // "Disabled". Any other value is treated as "Disabled". This annotation has + // been deprecated in favor of the `service.kubernetes.io/topology-mode` + // annotation which also allows "Auto" and "Disabled", but is not limited to + // those (it's open ended to provide room for experimentation while we + // pursue configuration for topology via specification). When both + // `service.kubernetes.io/topology-aware-hints` and + // `service.kubernetes.io/topology-mode` annotations are set, the value of + // `service.kubernetes.io/topology-aware-hints` has precedence. + DeprecatedAnnotationTopologyAwareHints = "service.kubernetes.io/topology-aware-hints" + + // AnnotationTopologyMode can be used to enable or disable Topology Aware + // Routing for a Service. Well known values are "Auto" and "Disabled". + // Implementations may choose to develop new topology approaches, exposing + // them with domain-prefixed values. For example, "example.com/lowest-rtt" + // could be a valid implementation-specific value for this annotation. These + // heuristics will often populate topology hints on EndpointSlices, but that + // is not a requirement. + AnnotationTopologyMode = "service.kubernetes.io/topology-mode" ) diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/helper/qos/qos.go b/vendor/k8s.io/kubernetes/pkg/apis/core/helper/qos/qos.go new file mode 100644 index 000000000..8401cb6c3 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/helper/qos/qos.go @@ -0,0 +1,102 @@ +/* +Copyright 2017 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. +*/ + +// NOTE: DO NOT use those helper functions through client-go, the +// package path will be changed in the future. +package qos + +import ( + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/kubernetes/pkg/apis/core" +) + +var supportedQoSComputeResources = sets.NewString(string(core.ResourceCPU), string(core.ResourceMemory)) + +func isSupportedQoSComputeResource(name core.ResourceName) bool { + return supportedQoSComputeResources.Has(string(name)) +} + +// GetPodQOS returns the QoS class of a pod. +// A pod is besteffort if none of its containers have specified any requests or limits. +// A pod is guaranteed only when requests and limits are specified for all the containers and they are equal. +// A pod is burstable if limits and requests do not match across all containers. +// When this function is updated please also update staging/src/k8s.io/kubectl/pkg/util/qos/qos.go +func GetPodQOS(pod *core.Pod) core.PodQOSClass { + requests := core.ResourceList{} + limits := core.ResourceList{} + zeroQuantity := resource.MustParse("0") + isGuaranteed := true + // note, ephemeral containers are not considered for QoS as they cannot define resources + allContainers := []core.Container{} + allContainers = append(allContainers, pod.Spec.Containers...) + allContainers = append(allContainers, pod.Spec.InitContainers...) + for _, container := range allContainers { + // process requests + for name, quantity := range container.Resources.Requests { + if !isSupportedQoSComputeResource(name) { + continue + } + if quantity.Cmp(zeroQuantity) == 1 { + delta := quantity.DeepCopy() + if _, exists := requests[name]; !exists { + requests[name] = delta + } else { + delta.Add(requests[name]) + requests[name] = delta + } + } + } + // process limits + qosLimitsFound := sets.NewString() + for name, quantity := range container.Resources.Limits { + if !isSupportedQoSComputeResource(name) { + continue + } + if quantity.Cmp(zeroQuantity) == 1 { + qosLimitsFound.Insert(string(name)) + delta := quantity.DeepCopy() + if _, exists := limits[name]; !exists { + limits[name] = delta + } else { + delta.Add(limits[name]) + limits[name] = delta + } + } + } + + if !qosLimitsFound.HasAll(string(core.ResourceMemory), string(core.ResourceCPU)) { + isGuaranteed = false + } + } + if len(requests) == 0 && len(limits) == 0 { + return core.PodQOSBestEffort + } + // Check is requests match limits for all resources. + if isGuaranteed { + for name, req := range requests { + if lim, exists := limits[name]; !exists || lim.Cmp(req) != 0 { + isGuaranteed = false + break + } + } + } + if isGuaranteed && + len(requests) == len(limits) { + return core.PodQOSGuaranteed + } + return core.PodQOSBurstable +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/types.go b/vendor/k8s.io/kubernetes/pkg/apis/core/types.go index fbbecb00d..5d5b51b1b 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/types.go @@ -682,7 +682,7 @@ type EmptyDirVolumeSource struct { // The maximum usage on memory medium EmptyDir would be the minimum value between // the SizeLimit specified here and the sum of memory limits of all containers in a pod. // The default is nil which means that the limit is undefined. - // More info: http://kubernetes.io/docs/user-guide/volumes#emptydir + // More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir // +optional SizeLimit *resource.Quantity } @@ -1741,7 +1741,6 @@ type CSIPersistentVolumeSource struct { // ControllerExpandSecretRef is a reference to the secret object containing // sensitive information to pass to the CSI driver to complete the CSI // ControllerExpandVolume call. - // This is an beta field and requires enabling ExpandCSIVolumes feature gate. // This field is optional, and may be empty if no secret is required. If the // secret object contains more than one secret, all secrets are passed. // +optional @@ -1750,9 +1749,10 @@ type CSIPersistentVolumeSource struct { // NodeExpandSecretRef is a reference to the secret object containing // sensitive information to pass to the CSI driver to complete the CSI // NodeExpandVolume call. - // This is an alpha field and requires enabling CSINodeExpandSecret feature gate. + // This is a beta field which is enabled default by CSINodeExpandSecret feature gate. // This field is optional, may be omitted if no secret is required. If the // secret object contains more than one secret, all secrets are passed. + // +featureGate=CSINodeExpandSecret // +optional NodeExpandSecretRef *SecretReference } @@ -2037,7 +2037,8 @@ type SecretEnvSource struct { // HTTPHeader describes a custom header to be used in HTTP probes type HTTPHeader struct { - // The header field name + // The header field name. + // This will be canonicalized upon output, so case-variant names will be understood as the same header. Name string // The header field value Value string @@ -2139,6 +2140,33 @@ const ( PullIfNotPresent PullPolicy = "IfNotPresent" ) +// ResourceResizeRestartPolicy specifies how to handle container resource resize. +type ResourceResizeRestartPolicy string + +// These are the valid resource resize restart policy values: +const ( + // 'NotRequired' means Kubernetes will try to resize the container + // without restarting it, if possible. Kubernetes may however choose to + // restart the container if it is unable to actuate resize without a + // restart. For e.g. the runtime doesn't support restart-free resizing. + NotRequired ResourceResizeRestartPolicy = "NotRequired" + // 'RestartContainer' means Kubernetes will resize the container in-place + // by stopping and starting the container when new resources are applied. + // This is needed for legacy applications. For e.g. java apps using the + // -xmxN flag which are unable to use resized memory without restarting. + RestartContainer ResourceResizeRestartPolicy = "RestartContainer" +) + +// ContainerResizePolicy represents resource resize policy for the container. +type ContainerResizePolicy struct { + // Name of the resource to which this resource resize policy applies. + // Supported values: cpu, memory. + ResourceName ResourceName + // Restart policy to apply when specified resource is resized. + // If not specified, it defaults to NotRequired. + RestartPolicy ResourceResizeRestartPolicy +} + // PreemptionPolicy describes a policy for if/when to preempt a pod. type PreemptionPolicy string @@ -2191,7 +2219,7 @@ type ResourceRequirements struct { // This is an alpha field and requires enabling the // DynamicResourceAllocation feature gate. // - // This field is immutable. + // This field is immutable. It can only be set for containers. // // +featureGate=DynamicResourceAllocation // +optional @@ -2247,6 +2275,10 @@ type Container struct { // Compute resource requirements. // +optional Resources ResourceRequirements + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + ResizePolicy []ContainerResizePolicy // +optional VolumeMounts []VolumeMount // volumeDevices is the list of block devices to be used by the container. @@ -2296,8 +2328,6 @@ type ProbeHandler struct { TCPSocket *TCPSocketAction // GRPC specifies an action involving a GRPC port. - // This is a beta field and requires enabling GRPCContainerProbe feature gate. - // +featureGate=GRPCContainerProbe // +optional GRPC *GRPCAction } @@ -2413,24 +2443,68 @@ type ContainerState struct { Terminated *ContainerStateTerminated } -// ContainerStatus represents the status of a container +// ContainerStatus contains details for the current status of this container. type ContainerStatus struct { - // Each container in a pod must have a unique name. + // Name is a DNS_LABEL representing the unique name of the container. + // Each container in a pod must have a unique name across all container types. + // Cannot be updated. Name string + // State holds details about the container's current condition. // +optional State ContainerState + // LastTerminationState holds the last termination state of the container to + // help debug container crashes and restarts. This field is not + // populated if the container is still running and RestartCount is 0. // +optional LastTerminationState ContainerState - // Ready specifies whether the container has passed its readiness check. + // Ready specifies whether the container is currently passing its readiness check. + // The value will change as readiness probes keep executing. If no readiness + // probes are specified, this field defaults to true once the container is + // fully started (see Started field). + // + // The value is typically used to determine whether a container is ready to + // accept traffic. Ready bool - // Note that this is calculated from dead containers. But those containers are subject to - // garbage collection. This value will get capped at 5 by GC. + // RestartCount holds the number of times the container has been restarted. + // Kubelet makes an effort to always increment the value, but there + // are cases when the state may be lost due to node restarts and then the value + // may be reset to 0. The value is never negative. RestartCount int32 - Image string - ImageID string + // Image is the name of container image that the container is running. + // The container image may not match the image used in the PodSpec, + // as it may have been resolved by the runtime. + // More info: https://kubernetes.io/docs/concepts/containers/images. + Image string + // ImageID is the image ID of the container's image. The image ID may not + // match the image ID of the image used in the PodSpec, as it may have been + // resolved by the runtime. + ImageID string + // ContainerID is the ID of the container in the format '://'. + // Where type is a container runtime identifier, returned from Version call of CRI API + // (for example "containerd"). // +optional ContainerID string - Started *bool + // Started indicates whether the container has finished its postStart lifecycle hook + // and passed its startup probe. + // Initialized as false, becomes true after startupProbe is considered + // successful. Resets to false when the container is restarted, or if kubelet + // loses state temporarily. In both cases, startup probes will run again. + // Is always true when no startupProbe is defined and container is running and + // has passed the postStart lifecycle hook. The null value must be treated the + // same as false. + // +optional + Started *bool + // AllocatedResources represents the compute resources allocated for this container by the + // node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission + // and after successfully admitting desired pod resize. + // +featureGate=InPlacePodVerticalScaling + // +optional + AllocatedResources ResourceList + // Resources represents the compute resource requests and limits that have been successfully + // enacted on the running container after it has been started or has been successfully resized. + // +featureGate=InPlacePodVerticalScaling + // +optional + Resources *ResourceRequirements } // PodPhase is a label for the condition of a pod at the current time. @@ -2496,6 +2570,20 @@ type PodCondition struct { Message string } +// 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. + PodResizeStatusDeferred PodResizeStatus = "Deferred" + // Requested pod resize is not feasible and will not be re-evaluated. + PodResizeStatusInfeasible PodResizeStatus = "Infeasible" +) + // RestartPolicy describes how the container should be restarted. // Only one of the following restart policies may be specified. // If none of the following policies is specified, the default one @@ -3045,9 +3133,14 @@ type PodSpec struct { OS *PodOS // SchedulingGates is an opaque list of values that if specified will block scheduling the pod. - // More info: https://git.k8s.io/enhancements/keps/sig-scheduling/3521-pod-scheduling-readiness. + // If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + // scheduler will not attempt to schedule the pod. // - // This is an alpha-level feature enabled by PodSchedulingReadiness feature gate. + // SchedulingGates can only be set at pod creation time, and be removed only afterwards. + // + // This is a beta feature enabled by the PodSchedulingReadiness feature gate. + // + // +featureGate=PodSchedulingReadiness // +optional SchedulingGates []PodSchedulingGate // ResourceClaims defines which ResourceClaims must be allocated @@ -3408,6 +3501,10 @@ type EphemeralContainerCommon struct { // already allocated to the pod. // +optional Resources ResourceRequirements + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + ResizePolicy []ContainerResizePolicy // Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. // +optional VolumeMounts []VolumeMount @@ -3524,6 +3621,13 @@ type PodStatus struct { // Status for any ephemeral containers that have run in this pod. // +optional EphemeralContainerStatuses []ContainerStatus + + // 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" + // +featureGate=InPlacePodVerticalScaling + // +optional + Resize PodResizeStatus } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -3617,6 +3721,7 @@ type ReplicationControllerSpec struct { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. Internally, this takes precedence over a // TemplateRef. + // The only allowed template.spec.restartPolicy value is "Always". // +optional Template *PodTemplateSpec } @@ -3781,33 +3886,33 @@ const ( ServiceTypeExternalName ServiceType = "ExternalName" ) -// ServiceInternalTrafficPolicyType describes the endpoint-selection policy for +// ServiceInternalTrafficPolicy describes the endpoint-selection policy for // traffic sent to the ClusterIP. -type ServiceInternalTrafficPolicyType string +type ServiceInternalTrafficPolicy string const ( // ServiceInternalTrafficPolicyCluster routes traffic to all endpoints. - ServiceInternalTrafficPolicyCluster ServiceInternalTrafficPolicyType = "Cluster" + ServiceInternalTrafficPolicyCluster ServiceInternalTrafficPolicy = "Cluster" // ServiceInternalTrafficPolicyLocal routes traffic only to endpoints on the same // node as the traffic was received on (dropping the traffic if there are no // local endpoints). - ServiceInternalTrafficPolicyLocal ServiceInternalTrafficPolicyType = "Local" + ServiceInternalTrafficPolicyLocal ServiceInternalTrafficPolicy = "Local" ) -// ServiceExternalTrafficPolicyType describes the endpoint-selection policy for +// ServiceExternalTrafficPolicy describes the endpoint-selection policy for // traffic to external service entrypoints (NodePorts, ExternalIPs, and // LoadBalancer IPs). -type ServiceExternalTrafficPolicyType string +type ServiceExternalTrafficPolicy string const ( - // ServiceExternalTrafficPolicyTypeCluster routes traffic to all endpoints. - ServiceExternalTrafficPolicyTypeCluster ServiceExternalTrafficPolicyType = "Cluster" + // ServiceExternalTrafficPolicyCluster routes traffic to all endpoints. + ServiceExternalTrafficPolicyCluster ServiceExternalTrafficPolicy = "Cluster" - // ServiceExternalTrafficPolicyTypeLocal preserves the source IP of the traffic by + // ServiceExternalTrafficPolicyLocal preserves the source IP of the traffic by // routing only to endpoints on the same node as the traffic was received on // (dropping the traffic if there are no local endpoints). - ServiceExternalTrafficPolicyTypeLocal ServiceExternalTrafficPolicyType = "Local" + ServiceExternalTrafficPolicyLocal ServiceExternalTrafficPolicy = "Local" ) // These are the valid conditions of a service. @@ -4013,7 +4118,7 @@ type ServiceSpec struct { // a NodePort from within the cluster may need to take traffic policy into account // when picking a node. // +optional - ExternalTrafficPolicy ServiceExternalTrafficPolicyType + ExternalTrafficPolicy ServiceExternalTrafficPolicy // healthCheckNodePort specifies the healthcheck nodePort for the service. // If not specified, HealthCheckNodePort is created by the service api @@ -4064,7 +4169,7 @@ type ServiceSpec struct { // "Cluster", uses the standard behavior of routing to all endpoints evenly // (possibly modified by topology and other features). // +optional - InternalTrafficPolicy *ServiceInternalTrafficPolicyType + InternalTrafficPolicy *ServiceInternalTrafficPolicy } // ServicePort represents the port on which the service is exposed @@ -4079,10 +4184,17 @@ type ServicePort struct { Protocol Protocol // 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. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional AppProtocol *string @@ -4208,9 +4320,8 @@ type EndpointSubset struct { // EndpointAddress is a tuple that describes single IP address. type EndpointAddress struct { // The IP of this endpoint. - // IPv6 is also accepted but not fully supported on all platforms. Also, certain - // kubernetes components, like kube-proxy, are not IPv6 ready. - // TODO: This should allow hostname or IP, see #4447. + // 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). IP string // Optional: Hostname of this endpoint // Meant to be used by DNS servers etc. @@ -5870,8 +5981,12 @@ type TopologySpreadConstraint struct { // 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. Keys that don't exist in the incoming pod labels will + // 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. + // + // This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). // +listType=atomic // +optional MatchLabelKeys []string diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go index 7869f0389..dd92428cd 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/core" + utilpointer "k8s.io/utils/pointer" ) func addConversionFuncs(scheme *runtime.Scheme) error { @@ -372,6 +373,11 @@ func Convert_v1_Pod_To_core_Pod(in *v1.Pod, out *core.Pod, s conversion.Scope) e // drop init container annotations so they don't show up as differences when receiving requests from old clients out.Annotations = dropInitContainerAnnotations(out.Annotations) + // Forcing the value of TerminationGracePeriodSeconds to 1 if it is negative. + // Just for Pod, not for PodSpec, because we don't want to change the behavior of the PodTemplate. + if in.Spec.TerminationGracePeriodSeconds != nil && *in.Spec.TerminationGracePeriodSeconds < 0 { + out.Spec.TerminationGracePeriodSeconds = utilpointer.Int64(1) + } return nil } @@ -384,6 +390,11 @@ func Convert_core_Pod_To_v1_Pod(in *core.Pod, out *v1.Pod, s conversion.Scope) e // remove this once the oldest supported kubelet no longer honors the annotations over the field. out.Annotations = dropInitContainerAnnotations(out.Annotations) + // Forcing the value of TerminationGracePeriodSeconds to 1 if it is negative. + // Just for Pod, not for PodSpec, because we don't want to change the behavior of the PodTemplate. + if in.Spec.TerminationGracePeriodSeconds != nil && *in.Spec.TerminationGracePeriodSeconds < 0 { + out.Spec.TerminationGracePeriodSeconds = utilpointer.Int64(1) + } return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/defaults.go b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/defaults.go index b42221691..433ae39b5 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/defaults.go @@ -22,6 +22,8 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/util/parsers" "k8s.io/utils/pointer" ) @@ -125,7 +127,7 @@ func SetDefaults_Service(obj *v1.Service) { if (obj.Spec.Type == v1.ServiceTypeNodePort || obj.Spec.Type == v1.ServiceTypeLoadBalancer) && obj.Spec.ExternalTrafficPolicy == "" { - obj.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeCluster + obj.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyCluster } if obj.Spec.InternalTrafficPolicy == nil { @@ -137,7 +139,7 @@ func SetDefaults_Service(obj *v1.Service) { if obj.Spec.Type == v1.ServiceTypeLoadBalancer { if obj.Spec.AllocateLoadBalancerNodePorts == nil { - obj.Spec.AllocateLoadBalancerNodePorts = pointer.BoolPtr(true) + obj.Spec.AllocateLoadBalancerNodePorts = pointer.Bool(true) } } } @@ -157,6 +159,29 @@ func SetDefaults_Pod(obj *v1.Pod) { } } } + if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) && + obj.Spec.Containers[i].Resources.Requests != nil { + // For normal containers, set resize restart policy to default value (NotRequired), if not specified. + resizePolicySpecified := make(map[v1.ResourceName]bool) + for _, p := range obj.Spec.Containers[i].ResizePolicy { + resizePolicySpecified[p.ResourceName] = true + } + setDefaultResizePolicy := func(resourceName v1.ResourceName) { + if _, found := resizePolicySpecified[resourceName]; !found { + obj.Spec.Containers[i].ResizePolicy = append(obj.Spec.Containers[i].ResizePolicy, + v1.ContainerResizePolicy{ + ResourceName: resourceName, + RestartPolicy: v1.NotRequired, + }) + } + } + if _, exists := obj.Spec.Containers[i].Resources.Requests[v1.ResourceCPU]; exists { + setDefaultResizePolicy(v1.ResourceCPU) + } + if _, exists := obj.Spec.Containers[i].Resources.Requests[v1.ResourceMemory]; exists { + setDefaultResizePolicy(v1.ResourceMemory) + } + } } for i := range obj.Spec.InitContainers { if obj.Spec.InitContainers[i].Resources.Limits != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go index be33b1f94..34aca4f2c 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go @@ -370,62 +370,3 @@ func ScopedResourceSelectorRequirementsAsSelector(ssr v1.ScopedResourceSelectorR selector = selector.Add(*r) return selector, nil } - -// nodeSelectorRequirementsAsLabelRequirements converts the NodeSelectorRequirement -// type to a labels.Requirement type. -func nodeSelectorRequirementsAsLabelRequirements(nsr v1.NodeSelectorRequirement) (*labels.Requirement, error) { - var op selection.Operator - switch nsr.Operator { - case v1.NodeSelectorOpIn: - op = selection.In - case v1.NodeSelectorOpNotIn: - op = selection.NotIn - case v1.NodeSelectorOpExists: - op = selection.Exists - case v1.NodeSelectorOpDoesNotExist: - op = selection.DoesNotExist - case v1.NodeSelectorOpGt: - op = selection.GreaterThan - case v1.NodeSelectorOpLt: - op = selection.LessThan - default: - return nil, fmt.Errorf("%q is not a valid node selector operator", nsr.Operator) - } - return labels.NewRequirement(nsr.Key, op, nsr.Values) -} - -// NodeSelectorAsSelector converts the NodeSelector api type into a struct that -// implements labels.Selector -// Note: This function should be kept in sync with the selector methods in -// pkg/labels/selector.go -func NodeSelectorAsSelector(ns *v1.NodeSelector) (labels.Selector, error) { - if ns == nil { - return labels.Nothing(), nil - } - if len(ns.NodeSelectorTerms) == 0 { - return labels.Everything(), nil - } - var requirements []labels.Requirement - - for _, nsTerm := range ns.NodeSelectorTerms { - for _, expr := range nsTerm.MatchExpressions { - req, err := nodeSelectorRequirementsAsLabelRequirements(expr) - if err != nil { - return nil, err - } - requirements = append(requirements, *req) - } - - for _, field := range nsTerm.MatchFields { - req, err := nodeSelectorRequirementsAsLabelRequirements(field) - if err != nil { - return nil, err - } - requirements = append(requirements, *req) - } - } - - selector := labels.NewSelector() - selector = selector.Add(requirements...) - return selector, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go index c27a86783..685f1dac9 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go @@ -342,6 +342,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*v1.ContainerResizePolicy)(nil), (*core.ContainerResizePolicy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_ContainerResizePolicy_To_core_ContainerResizePolicy(a.(*v1.ContainerResizePolicy), b.(*core.ContainerResizePolicy), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*core.ContainerResizePolicy)(nil), (*v1.ContainerResizePolicy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_core_ContainerResizePolicy_To_v1_ContainerResizePolicy(a.(*core.ContainerResizePolicy), b.(*v1.ContainerResizePolicy), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1.ContainerState)(nil), (*core.ContainerState)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1_ContainerState_To_core_ContainerState(a.(*v1.ContainerState), b.(*core.ContainerState), scope) }); err != nil { @@ -2975,6 +2985,7 @@ func autoConvert_v1_Container_To_core_Container(in *v1.Container, out *core.Cont if err := Convert_v1_ResourceRequirements_To_core_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { return err } + out.ResizePolicy = *(*[]core.ContainerResizePolicy)(unsafe.Pointer(&in.ResizePolicy)) out.VolumeMounts = *(*[]core.VolumeMount)(unsafe.Pointer(&in.VolumeMounts)) out.VolumeDevices = *(*[]core.VolumeDevice)(unsafe.Pointer(&in.VolumeDevices)) out.LivenessProbe = (*core.Probe)(unsafe.Pointer(in.LivenessProbe)) @@ -3008,6 +3019,7 @@ func autoConvert_core_Container_To_v1_Container(in *core.Container, out *v1.Cont if err := Convert_core_ResourceRequirements_To_v1_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { return err } + out.ResizePolicy = *(*[]v1.ContainerResizePolicy)(unsafe.Pointer(&in.ResizePolicy)) out.VolumeMounts = *(*[]v1.VolumeMount)(unsafe.Pointer(&in.VolumeMounts)) out.VolumeDevices = *(*[]v1.VolumeDevice)(unsafe.Pointer(&in.VolumeDevices)) out.LivenessProbe = (*v1.Probe)(unsafe.Pointer(in.LivenessProbe)) @@ -3079,6 +3091,28 @@ func Convert_core_ContainerPort_To_v1_ContainerPort(in *core.ContainerPort, out return autoConvert_core_ContainerPort_To_v1_ContainerPort(in, out, s) } +func autoConvert_v1_ContainerResizePolicy_To_core_ContainerResizePolicy(in *v1.ContainerResizePolicy, out *core.ContainerResizePolicy, s conversion.Scope) error { + out.ResourceName = core.ResourceName(in.ResourceName) + out.RestartPolicy = core.ResourceResizeRestartPolicy(in.RestartPolicy) + return nil +} + +// Convert_v1_ContainerResizePolicy_To_core_ContainerResizePolicy is an autogenerated conversion function. +func Convert_v1_ContainerResizePolicy_To_core_ContainerResizePolicy(in *v1.ContainerResizePolicy, out *core.ContainerResizePolicy, s conversion.Scope) error { + return autoConvert_v1_ContainerResizePolicy_To_core_ContainerResizePolicy(in, out, s) +} + +func autoConvert_core_ContainerResizePolicy_To_v1_ContainerResizePolicy(in *core.ContainerResizePolicy, out *v1.ContainerResizePolicy, s conversion.Scope) error { + out.ResourceName = v1.ResourceName(in.ResourceName) + out.RestartPolicy = v1.ResourceResizeRestartPolicy(in.RestartPolicy) + return nil +} + +// Convert_core_ContainerResizePolicy_To_v1_ContainerResizePolicy is an autogenerated conversion function. +func Convert_core_ContainerResizePolicy_To_v1_ContainerResizePolicy(in *core.ContainerResizePolicy, out *v1.ContainerResizePolicy, s conversion.Scope) error { + return autoConvert_core_ContainerResizePolicy_To_v1_ContainerResizePolicy(in, out, s) +} + func autoConvert_v1_ContainerState_To_core_ContainerState(in *v1.ContainerState, out *core.ContainerState, s conversion.Scope) error { out.Waiting = (*core.ContainerStateWaiting)(unsafe.Pointer(in.Waiting)) out.Running = (*core.ContainerStateRunning)(unsafe.Pointer(in.Running)) @@ -3191,6 +3225,8 @@ func autoConvert_v1_ContainerStatus_To_core_ContainerStatus(in *v1.ContainerStat out.ImageID = in.ImageID out.ContainerID = in.ContainerID out.Started = (*bool)(unsafe.Pointer(in.Started)) + out.AllocatedResources = *(*core.ResourceList)(unsafe.Pointer(&in.AllocatedResources)) + out.Resources = (*core.ResourceRequirements)(unsafe.Pointer(in.Resources)) return nil } @@ -3213,6 +3249,8 @@ func autoConvert_core_ContainerStatus_To_v1_ContainerStatus(in *core.ContainerSt out.ImageID = in.ImageID out.ContainerID = in.ContainerID out.Started = (*bool)(unsafe.Pointer(in.Started)) + out.AllocatedResources = *(*v1.ResourceList)(unsafe.Pointer(&in.AllocatedResources)) + out.Resources = (*v1.ResourceRequirements)(unsafe.Pointer(in.Resources)) return nil } @@ -3563,6 +3601,7 @@ func autoConvert_v1_EphemeralContainerCommon_To_core_EphemeralContainerCommon(in if err := Convert_v1_ResourceRequirements_To_core_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { return err } + out.ResizePolicy = *(*[]core.ContainerResizePolicy)(unsafe.Pointer(&in.ResizePolicy)) out.VolumeMounts = *(*[]core.VolumeMount)(unsafe.Pointer(&in.VolumeMounts)) out.VolumeDevices = *(*[]core.VolumeDevice)(unsafe.Pointer(&in.VolumeDevices)) out.LivenessProbe = (*core.Probe)(unsafe.Pointer(in.LivenessProbe)) @@ -3596,6 +3635,7 @@ func autoConvert_core_EphemeralContainerCommon_To_v1_EphemeralContainerCommon(in if err := Convert_core_ResourceRequirements_To_v1_ResourceRequirements(&in.Resources, &out.Resources, s); err != nil { return err } + out.ResizePolicy = *(*[]v1.ContainerResizePolicy)(unsafe.Pointer(&in.ResizePolicy)) out.VolumeMounts = *(*[]v1.VolumeMount)(unsafe.Pointer(&in.VolumeMounts)) out.VolumeDevices = *(*[]v1.VolumeDevice)(unsafe.Pointer(&in.VolumeDevices)) out.LivenessProbe = (*v1.Probe)(unsafe.Pointer(in.LivenessProbe)) @@ -6380,6 +6420,7 @@ func autoConvert_v1_PodStatus_To_core_PodStatus(in *v1.PodStatus, out *core.PodS out.ContainerStatuses = *(*[]core.ContainerStatus)(unsafe.Pointer(&in.ContainerStatuses)) out.QOSClass = core.PodQOSClass(in.QOSClass) out.EphemeralContainerStatuses = *(*[]core.ContainerStatus)(unsafe.Pointer(&in.EphemeralContainerStatuses)) + out.Resize = core.PodResizeStatus(in.Resize) return nil } @@ -6396,6 +6437,7 @@ func autoConvert_core_PodStatus_To_v1_PodStatus(in *core.PodStatus, out *v1.PodS out.InitContainerStatuses = *(*[]v1.ContainerStatus)(unsafe.Pointer(&in.InitContainerStatuses)) out.ContainerStatuses = *(*[]v1.ContainerStatus)(unsafe.Pointer(&in.ContainerStatuses)) out.EphemeralContainerStatuses = *(*[]v1.ContainerStatus)(unsafe.Pointer(&in.EphemeralContainerStatuses)) + out.Resize = v1.PodResizeStatus(in.Resize) return nil } @@ -7850,7 +7892,7 @@ func autoConvert_v1_ServiceSpec_To_core_ServiceSpec(in *v1.ServiceSpec, out *cor out.LoadBalancerIP = in.LoadBalancerIP out.LoadBalancerSourceRanges = *(*[]string)(unsafe.Pointer(&in.LoadBalancerSourceRanges)) out.ExternalName = in.ExternalName - out.ExternalTrafficPolicy = core.ServiceExternalTrafficPolicyType(in.ExternalTrafficPolicy) + out.ExternalTrafficPolicy = core.ServiceExternalTrafficPolicy(in.ExternalTrafficPolicy) out.HealthCheckNodePort = in.HealthCheckNodePort out.PublishNotReadyAddresses = in.PublishNotReadyAddresses out.SessionAffinityConfig = (*core.SessionAffinityConfig)(unsafe.Pointer(in.SessionAffinityConfig)) @@ -7858,7 +7900,7 @@ func autoConvert_v1_ServiceSpec_To_core_ServiceSpec(in *v1.ServiceSpec, out *cor out.IPFamilyPolicy = (*core.IPFamilyPolicy)(unsafe.Pointer(in.IPFamilyPolicy)) out.AllocateLoadBalancerNodePorts = (*bool)(unsafe.Pointer(in.AllocateLoadBalancerNodePorts)) out.LoadBalancerClass = (*string)(unsafe.Pointer(in.LoadBalancerClass)) - out.InternalTrafficPolicy = (*core.ServiceInternalTrafficPolicyType)(unsafe.Pointer(in.InternalTrafficPolicy)) + out.InternalTrafficPolicy = (*core.ServiceInternalTrafficPolicy)(unsafe.Pointer(in.InternalTrafficPolicy)) return nil } @@ -7881,12 +7923,12 @@ func autoConvert_core_ServiceSpec_To_v1_ServiceSpec(in *core.ServiceSpec, out *v out.SessionAffinity = v1.ServiceAffinity(in.SessionAffinity) out.SessionAffinityConfig = (*v1.SessionAffinityConfig)(unsafe.Pointer(in.SessionAffinityConfig)) out.LoadBalancerSourceRanges = *(*[]string)(unsafe.Pointer(&in.LoadBalancerSourceRanges)) - out.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyType(in.ExternalTrafficPolicy) + out.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicy(in.ExternalTrafficPolicy) out.HealthCheckNodePort = in.HealthCheckNodePort out.PublishNotReadyAddresses = in.PublishNotReadyAddresses out.AllocateLoadBalancerNodePorts = (*bool)(unsafe.Pointer(in.AllocateLoadBalancerNodePorts)) out.LoadBalancerClass = (*string)(unsafe.Pointer(in.LoadBalancerClass)) - out.InternalTrafficPolicy = (*v1.ServiceInternalTrafficPolicyType)(unsafe.Pointer(in.InternalTrafficPolicy)) + out.InternalTrafficPolicy = (*v1.ServiceInternalTrafficPolicy)(unsafe.Pointer(in.InternalTrafficPolicy)) return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.defaults.go b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.defaults.go index 7706bbf9a..a99a0be89 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.defaults.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.defaults.go @@ -48,6 +48,7 @@ func RegisterDefaults(scheme *runtime.Scheme) error { scheme.AddTypeDefaultingFunc(&v1.PersistentVolumeList{}, func(obj interface{}) { SetObjectDefaults_PersistentVolumeList(obj.(*v1.PersistentVolumeList)) }) scheme.AddTypeDefaultingFunc(&v1.Pod{}, func(obj interface{}) { SetObjectDefaults_Pod(obj.(*v1.Pod)) }) scheme.AddTypeDefaultingFunc(&v1.PodList{}, func(obj interface{}) { SetObjectDefaults_PodList(obj.(*v1.PodList)) }) + scheme.AddTypeDefaultingFunc(&v1.PodStatusResult{}, func(obj interface{}) { SetObjectDefaults_PodStatusResult(obj.(*v1.PodStatusResult)) }) scheme.AddTypeDefaultingFunc(&v1.PodTemplate{}, func(obj interface{}) { SetObjectDefaults_PodTemplate(obj.(*v1.PodTemplate)) }) scheme.AddTypeDefaultingFunc(&v1.PodTemplateList{}, func(obj interface{}) { SetObjectDefaults_PodTemplateList(obj.(*v1.PodTemplateList)) }) scheme.AddTypeDefaultingFunc(&v1.ReplicationController{}, func(obj interface{}) { SetObjectDefaults_ReplicationController(obj.(*v1.ReplicationController)) }) @@ -438,6 +439,30 @@ func SetObjectDefaults_Pod(in *v1.Pod) { } } SetDefaults_ResourceList(&in.Spec.Overhead) + for i := range in.Status.InitContainerStatuses { + a := &in.Status.InitContainerStatuses[i] + SetDefaults_ResourceList(&a.AllocatedResources) + if a.Resources != nil { + SetDefaults_ResourceList(&a.Resources.Limits) + SetDefaults_ResourceList(&a.Resources.Requests) + } + } + for i := range in.Status.ContainerStatuses { + a := &in.Status.ContainerStatuses[i] + SetDefaults_ResourceList(&a.AllocatedResources) + if a.Resources != nil { + SetDefaults_ResourceList(&a.Resources.Limits) + SetDefaults_ResourceList(&a.Resources.Requests) + } + } + for i := range in.Status.EphemeralContainerStatuses { + a := &in.Status.EphemeralContainerStatuses[i] + SetDefaults_ResourceList(&a.AllocatedResources) + if a.Resources != nil { + SetDefaults_ResourceList(&a.Resources.Limits) + SetDefaults_ResourceList(&a.Resources.Requests) + } + } } func SetObjectDefaults_PodList(in *v1.PodList) { @@ -447,6 +472,33 @@ func SetObjectDefaults_PodList(in *v1.PodList) { } } +func SetObjectDefaults_PodStatusResult(in *v1.PodStatusResult) { + for i := range in.Status.InitContainerStatuses { + a := &in.Status.InitContainerStatuses[i] + SetDefaults_ResourceList(&a.AllocatedResources) + if a.Resources != nil { + SetDefaults_ResourceList(&a.Resources.Limits) + SetDefaults_ResourceList(&a.Resources.Requests) + } + } + for i := range in.Status.ContainerStatuses { + a := &in.Status.ContainerStatuses[i] + SetDefaults_ResourceList(&a.AllocatedResources) + if a.Resources != nil { + SetDefaults_ResourceList(&a.Resources.Limits) + SetDefaults_ResourceList(&a.Resources.Requests) + } + } + for i := range in.Status.EphemeralContainerStatuses { + a := &in.Status.EphemeralContainerStatuses[i] + SetDefaults_ResourceList(&a.AllocatedResources) + if a.Resources != nil { + SetDefaults_ResourceList(&a.Resources.Limits) + SetDefaults_ResourceList(&a.Resources.Requests) + } + } +} + func SetObjectDefaults_PodTemplate(in *v1.PodTemplate) { SetDefaults_PodSpec(&in.Template.Spec) for i := range in.Template.Spec.Volumes { diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go index 1668db832..465c92380 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go @@ -26,6 +26,7 @@ import ( "reflect" "regexp" "strings" + "sync" "unicode" "unicode/utf8" @@ -36,6 +37,7 @@ import ( apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" unversionedvalidation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" + "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" @@ -43,9 +45,11 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" utilfeature "k8s.io/apiserver/pkg/util/feature" schedulinghelper "k8s.io/component-helpers/scheduling/corev1" + kubeletapis "k8s.io/kubelet/pkg/apis" apiservice "k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core/helper" + "k8s.io/kubernetes/pkg/apis/core/helper/qos" podshelper "k8s.io/kubernetes/pkg/apis/core/pods" corev1 "k8s.io/kubernetes/pkg/apis/core/v1" "k8s.io/kubernetes/pkg/capabilities" @@ -295,6 +299,14 @@ var ValidateClassName = apimachineryvalidation.NameIsDNSSubdomain // class name is valid. var ValidatePriorityClassName = apimachineryvalidation.NameIsDNSSubdomain +// ValidateResourceClaimName can be used to check whether the given +// name for a ResourceClaim is valid. +var ValidateResourceClaimName = apimachineryvalidation.NameIsDNSSubdomain + +// ValidateResourceClaimTemplateName can be used to check whether the given +// name for a ResourceClaimTemplate is valid. +var ValidateResourceClaimTemplateName = apimachineryvalidation.NameIsDNSSubdomain + // ValidateRuntimeClassName can be used to check whether the given RuntimeClass name is valid. // Prefix indicates this name will be used as part of generation, in which case // trailing dashes are allowed. @@ -1044,10 +1056,7 @@ func validateDownwardAPIVolumeFile(file *core.DownwardAPIVolumeFile, fldPath *fi allErrs = append(allErrs, field.Invalid(fldPath, "resource", "fieldRef and resourceFieldRef can not be specified simultaneously")) } } else if file.ResourceFieldRef != nil { - localValidContainerResourceFieldPathPrefixes := validContainerResourceFieldPathPrefixes - if opts.AllowDownwardAPIHugePages { - localValidContainerResourceFieldPathPrefixes = validContainerResourceFieldPathPrefixesWithDownwardAPIHugePages - } + localValidContainerResourceFieldPathPrefixes := validContainerResourceFieldPathPrefixesWithDownwardAPIHugePages allErrs = append(allErrs, validateContainerResourceFieldSelector(file.ResourceFieldRef, &validContainerResourceFieldPathExpressions, &localValidContainerResourceFieldPathPrefixes, fldPath.Child("resourceFieldRef"), true)...) } else { allErrs = append(allErrs, field.Required(fldPath, "one of fieldRef and resourceFieldRef is required")) @@ -1531,14 +1540,12 @@ func validateStorageOSPersistentVolumeSource(storageos *core.StorageOSPersistent // validatePVSecretReference check whether provided SecretReference object is valid in terms of secret name and namespace. -func validatePVSecretReference(secretRef *core.SecretReference, allowDNSSubDomainSecretName bool, fldPath *field.Path) field.ErrorList { +func validatePVSecretReference(secretRef *core.SecretReference, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList if len(secretRef.Name) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) - } else if allowDNSSubDomainSecretName { - allErrs = append(allErrs, ValidateDNS1123Subdomain(secretRef.Name, fldPath.Child("name"))...) } else { - allErrs = append(allErrs, ValidateDNS1123Label(secretRef.Name, fldPath.Child("name"))...) + allErrs = append(allErrs, ValidateDNS1123Subdomain(secretRef.Name, fldPath.Child("name"))...) } if len(secretRef.Namespace) == 0 { @@ -1567,7 +1574,7 @@ func ValidateCSIDriverName(driverName string, fldPath *field.Path) field.ErrorLi return allErrs } -func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, allowDNSSubDomainSecretName bool, fldPath *field.Path) field.ErrorList { +func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, ValidateCSIDriverName(csi.Driver, fldPath.Child("driver"))...) @@ -1576,16 +1583,16 @@ func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, allo allErrs = append(allErrs, field.Required(fldPath.Child("volumeHandle"), "")) } if csi.ControllerPublishSecretRef != nil { - allErrs = append(allErrs, validatePVSecretReference(csi.ControllerPublishSecretRef, allowDNSSubDomainSecretName, fldPath.Child("controllerPublishSecretRef"))...) + allErrs = append(allErrs, validatePVSecretReference(csi.ControllerPublishSecretRef, fldPath.Child("controllerPublishSecretRef"))...) } if csi.ControllerExpandSecretRef != nil { - allErrs = append(allErrs, validatePVSecretReference(csi.ControllerExpandSecretRef, allowDNSSubDomainSecretName, fldPath.Child("controllerExpandSecretRef"))...) + allErrs = append(allErrs, validatePVSecretReference(csi.ControllerExpandSecretRef, fldPath.Child("controllerExpandSecretRef"))...) } if csi.NodePublishSecretRef != nil { - allErrs = append(allErrs, validatePVSecretReference(csi.NodePublishSecretRef, allowDNSSubDomainSecretName, fldPath.Child("nodePublishSecretRef"))...) + allErrs = append(allErrs, validatePVSecretReference(csi.NodePublishSecretRef, fldPath.Child("nodePublishSecretRef"))...) } if csi.NodeExpandSecretRef != nil { - allErrs = append(allErrs, validatePVSecretReference(csi.NodeExpandSecretRef, allowDNSSubDomainSecretName, fldPath.Child("nodeExpandSecretRef"))...) + allErrs = append(allErrs, validatePVSecretReference(csi.NodeExpandSecretRef, fldPath.Child("nodeExpandSecretRef"))...) } return allErrs } @@ -1647,8 +1654,6 @@ var allowedTemplateObjectMetaFields = map[string]bool{ type PersistentVolumeSpecValidationOptions struct { // Allow spec to contain the "ReadWiteOncePod" access mode AllowReadWriteOncePod bool - // Allow the secretRef Name field to be of DNSSubDomain Format - AllowDNSSubDomainSecretName bool } // ValidatePersistentVolumeName checks that a name is appropriate for a @@ -1663,8 +1668,7 @@ var supportedVolumeModes = sets.NewString(string(core.PersistentVolumeBlock), st func ValidationOptionsForPersistentVolume(pv, oldPv *core.PersistentVolume) PersistentVolumeSpecValidationOptions { opts := PersistentVolumeSpecValidationOptions{ - AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod), - AllowDNSSubDomainSecretName: false, + AllowReadWriteOncePod: utilfeature.DefaultFeatureGate.Enabled(features.ReadWriteOncePod), } if oldPv == nil { // If there's no old PV, use the options based solely on feature enablement @@ -1674,21 +1678,9 @@ func ValidationOptionsForPersistentVolume(pv, oldPv *core.PersistentVolume) Pers // If the old object allowed "ReadWriteOncePod", continue to allow it in the new object opts.AllowReadWriteOncePod = true } - if oldCSI := oldPv.Spec.CSI; oldCSI != nil { - opts.AllowDNSSubDomainSecretName = - secretRefRequiresSubdomainSecretName(oldCSI.ControllerExpandSecretRef) || - secretRefRequiresSubdomainSecretName(oldCSI.ControllerPublishSecretRef) || - secretRefRequiresSubdomainSecretName(oldCSI.NodeStageSecretRef) || - secretRefRequiresSubdomainSecretName(oldCSI.NodePublishSecretRef) - } return opts } -func secretRefRequiresSubdomainSecretName(secretRef *core.SecretReference) bool { - // ref and name were specified and name didn't fit within label validation - return secretRef != nil && len(secretRef.Name) > 0 && len(validation.IsDNS1123Label(secretRef.Name)) > 0 -} - func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName string, validateInlinePersistentVolumeSpec bool, fldPath *field.Path, opts PersistentVolumeSpecValidationOptions) field.ErrorList { allErrs := field.ErrorList{} @@ -1943,7 +1935,7 @@ func ValidatePersistentVolumeSpec(pvSpec *core.PersistentVolumeSpec, pvName stri allErrs = append(allErrs, field.Forbidden(fldPath.Child("csi"), "may not specify more than 1 volume type")) } else { numVolumes++ - allErrs = append(allErrs, validateCSIPersistentVolumeSource(pvSpec.CSI, opts.AllowDNSSubDomainSecretName, fldPath.Child("csi"))...) + allErrs = append(allErrs, validateCSIPersistentVolumeSource(pvSpec.CSI, fldPath.Child("csi"))...) } } @@ -2007,7 +1999,7 @@ func ValidatePersistentVolumeUpdate(newPv, oldPv *core.PersistentVolume, opts Pe // Allow setting NodeAffinity if oldPv NodeAffinity was not set if oldPv.Spec.NodeAffinity != nil { - allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.NodeAffinity, oldPv.Spec.NodeAffinity, field.NewPath("nodeAffinity"))...) + allErrs = append(allErrs, validatePvNodeAffinity(newPv.Spec.NodeAffinity, oldPv.Spec.NodeAffinity, field.NewPath("nodeAffinity"))...) } return allErrs @@ -2421,8 +2413,6 @@ var validEnvDownwardAPIFieldPathExpressions = sets.NewString( var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "limits.ephemeral-storage", "requests.cpu", "requests.memory", "requests.ephemeral-storage") -// NOTE: this is only valid with DownwardAPIHugePages enabled -var validContainerResourceFieldPathPrefixes = sets.NewString() var validContainerResourceFieldPathPrefixesWithDownwardAPIHugePages = sets.NewString(hugepagesRequestsPrefixDownwardAPI, hugepagesLimitsPrefixDownwardAPI) const hugepagesRequestsPrefixDownwardAPI string = `requests.hugepages-` @@ -2443,10 +2433,7 @@ func validateEnvVarValueFrom(ev core.EnvVar, fldPath *field.Path, opts PodValida } if ev.ValueFrom.ResourceFieldRef != nil { numSources++ - localValidContainerResourceFieldPathPrefixes := validContainerResourceFieldPathPrefixes - if opts.AllowDownwardAPIHugePages { - localValidContainerResourceFieldPathPrefixes = validContainerResourceFieldPathPrefixesWithDownwardAPIHugePages - } + localValidContainerResourceFieldPathPrefixes := validContainerResourceFieldPathPrefixesWithDownwardAPIHugePages allErrs = append(allErrs, validateContainerResourceFieldSelector(ev.ValueFrom.ResourceFieldRef, &validContainerResourceFieldPathExpressions, &localValidContainerResourceFieldPathPrefixes, fldPath.Child("resourceFieldRef"), false)...) } if ev.ValueFrom.ConfigMapKeyRef != nil { @@ -2768,11 +2755,11 @@ func ValidateVolumeDevices(devices []core.VolumeDevice, volmounts map[string]str return allErrs } -func validatePodResourceClaims(claims []core.PodResourceClaim, fldPath *field.Path) field.ErrorList { +func validatePodResourceClaims(podMeta *metav1.ObjectMeta, claims []core.PodResourceClaim, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList podClaimNames := sets.NewString() for i, claim := range claims { - allErrs = append(allErrs, validatePodResourceClaim(claim, &podClaimNames, fldPath.Index(i))...) + allErrs = append(allErrs, validatePodResourceClaim(podMeta, claim, &podClaimNames, fldPath.Index(i))...) } return allErrs } @@ -2790,14 +2777,22 @@ func gatherPodResourceClaimNames(claims []core.PodResourceClaim) sets.String { return podClaimNames } -func validatePodResourceClaim(claim core.PodResourceClaim, podClaimNames *sets.String, fldPath *field.Path) field.ErrorList { +func validatePodResourceClaim(podMeta *metav1.ObjectMeta, claim core.PodResourceClaim, podClaimNames *sets.String, fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList if claim.Name == "" { allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) } else if podClaimNames.Has(claim.Name) { allErrs = append(allErrs, field.Duplicate(fldPath.Child("name"), claim.Name)) } else { - allErrs = append(allErrs, ValidateDNS1123Label(claim.Name, fldPath.Child("name"))...) + nameErrs := ValidateDNS1123Label(claim.Name, fldPath.Child("name")) + if len(nameErrs) > 0 { + allErrs = append(allErrs, nameErrs...) + } else if podMeta != nil && claim.Source.ResourceClaimTemplateName != nil { + claimName := podMeta.Name + "-" + claim.Name + for _, detail := range ValidateResourceClaimName(claimName, false) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), claimName, "final ResourceClaim name: "+detail)) + } + } podClaimNames.Insert(claim.Name) } allErrs = append(allErrs, validatePodResourceClaimSource(claim.Source, fldPath.Child("source"))...) @@ -2813,6 +2808,16 @@ func validatePodResourceClaimSource(claimSource core.ClaimSource, fldPath *field if claimSource.ResourceClaimName == nil && claimSource.ResourceClaimTemplateName == nil { allErrs = append(allErrs, field.Invalid(fldPath, claimSource, "must specify one of: `resourceClaimName`, `resourceClaimTemplateName`")) } + if claimSource.ResourceClaimName != nil { + for _, detail := range ValidateResourceClaimName(*claimSource.ResourceClaimName, false) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceClaimName"), *claimSource.ResourceClaimName, detail)) + } + } + if claimSource.ResourceClaimTemplateName != nil { + for _, detail := range ValidateResourceClaimTemplateName(*claimSource.ResourceClaimTemplateName, false) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceClaimTemplateName"), *claimSource.ResourceClaimTemplateName, detail)) + } + } return allErrs } @@ -3036,6 +3041,37 @@ func validatePullPolicy(policy core.PullPolicy, fldPath *field.Path) field.Error return allErrors } +var supportedResizeResources = sets.NewString(string(core.ResourceCPU), string(core.ResourceMemory)) +var supportedResizePolicies = sets.NewString(string(core.NotRequired), string(core.RestartContainer)) + +func validateResizePolicy(policyList []core.ContainerResizePolicy, fldPath *field.Path) field.ErrorList { + allErrors := field.ErrorList{} + + // validate that resource name is not repeated, supported resource names and policy values are specified + resources := make(map[core.ResourceName]bool) + for i, p := range policyList { + if _, found := resources[p.ResourceName]; found { + allErrors = append(allErrors, field.Duplicate(fldPath.Index(i), p.ResourceName)) + } + resources[p.ResourceName] = true + switch p.ResourceName { + case core.ResourceCPU, core.ResourceMemory: + case "": + allErrors = append(allErrors, field.Required(fldPath, "")) + default: + allErrors = append(allErrors, field.NotSupported(fldPath, p.ResourceName, supportedResizeResources.List())) + } + switch p.RestartPolicy { + case core.NotRequired, core.RestartContainer: + case "": + allErrors = append(allErrors, field.Required(fldPath, "")) + default: + allErrors = append(allErrors, field.NotSupported(fldPath, p.RestartPolicy, supportedResizePolicies.List())) + } + } + return allErrors +} + // validateEphemeralContainers is called by pod spec and template validation to validate the list of ephemeral containers. // Note that this is called for pod template even though ephemeral containers aren't allowed in pod templates. func validateEphemeralContainers(ephemeralContainers []core.EphemeralContainer, containers, initContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.String, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { @@ -3158,6 +3194,9 @@ func validateInitContainers(containers []core.Container, regularContainers []cor if ctr.StartupProbe != nil { allErrs = append(allErrs, field.Forbidden(idxPath.Child("startupProbe"), "may not be set for init containers")) } + if len(ctr.ResizePolicy) > 0 { + allErrs = append(allErrs, field.Invalid(idxPath.Child("resizePolicy"), ctr.ResizePolicy, "must not be set for init containers")) + } } return allErrs @@ -3203,6 +3242,7 @@ func validateContainerCommon(ctr *core.Container, volumes map[string]core.Volume allErrs = append(allErrs, ValidateVolumeDevices(ctr.VolumeDevices, volMounts, volumes, path.Child("volumeDevices"))...) allErrs = append(allErrs, validatePullPolicy(ctr.ImagePullPolicy, path.Child("imagePullPolicy"))...) allErrs = append(allErrs, ValidateResourceRequirements(&ctr.Resources, podClaimNames, path.Child("resources"), opts)...) + allErrs = append(allErrs, validateResizePolicy(ctr.ResizePolicy, path.Child("resizePolicy"))...) allErrs = append(allErrs, ValidateSecurityContext(ctr.SecurityContext, path.Child("securityContext"))...) return allErrs } @@ -3382,9 +3422,7 @@ func validateSchedulingGates(schedulingGates []core.PodSchedulingGate, fldPath * // There should be no duplicates in the list of scheduling gates. seen := sets.String{} for i, schedulingGate := range schedulingGates { - if schedulingGate.Name == "" { - allErrs = append(allErrs, field.Required(fldPath.Index(i), "must not be empty")) - } + allErrs = append(allErrs, ValidateQualifiedName(schedulingGate.Name, fldPath.Index(i))...) if seen.Has(schedulingGate.Name) { allErrs = append(allErrs, field.Duplicate(fldPath.Index(i), schedulingGate.Name)) } @@ -3644,8 +3682,6 @@ func validateContainerOnlyForPod(ctr *core.Container, path *field.Path) field.Er // PodValidationOptions contains the different settings for pod validation type PodValidationOptions struct { - // Allow pod spec to use hugepages in downward API - AllowDownwardAPIHugePages bool // Allow invalid pod-deletion-cost annotation value for backward compatibility. AllowInvalidPodDeletionCost bool // Allow invalid label-value in LabelSelector @@ -3654,6 +3690,10 @@ type PodValidationOptions struct { AllowIndivisibleHugePagesValues bool // Allow more DNSSearchPaths and longer DNSSearchListChars AllowExpandedDNSConfig bool + // Allow invalid topologySpreadConstraint labelSelector for backward compatibility + AllowInvalidTopologySpreadConstraintLabelSelector bool + // Allow node selector additions for gated pods. + AllowMutableNodeSelectorAndNodeAffinity bool } // validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set, @@ -3746,7 +3786,7 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi vols, vErrs := ValidateVolumes(spec.Volumes, podMeta, fldPath.Child("volumes"), opts) allErrs = append(allErrs, vErrs...) podClaimNames := gatherPodResourceClaimNames(spec.ResourceClaims) - allErrs = append(allErrs, validatePodResourceClaims(spec.ResourceClaims, fldPath.Child("resourceClaims"))...) + allErrs = append(allErrs, validatePodResourceClaims(podMeta, spec.ResourceClaims, fldPath.Child("resourceClaims"))...) allErrs = append(allErrs, validateContainers(spec.Containers, vols, podClaimNames, fldPath.Child("containers"), opts)...) allErrs = append(allErrs, validateInitContainers(spec.InitContainers, spec.Containers, vols, podClaimNames, fldPath.Child("initContainers"), opts)...) allErrs = append(allErrs, validateEphemeralContainers(spec.EphemeralContainers, spec.Containers, spec.InitContainers, vols, podClaimNames, fldPath.Child("ephemeralContainers"), opts)...) @@ -3759,7 +3799,7 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi allErrs = append(allErrs, validatePodDNSConfig(spec.DNSConfig, &spec.DNSPolicy, fldPath.Child("dnsConfig"), opts)...) allErrs = append(allErrs, validateReadinessGates(spec.ReadinessGates, fldPath.Child("readinessGates"))...) allErrs = append(allErrs, validateSchedulingGates(spec.SchedulingGates, fldPath.Child("schedulingGates"))...) - allErrs = append(allErrs, validateTopologySpreadConstraints(spec.TopologySpreadConstraints, fldPath.Child("topologySpreadConstraints"))...) + allErrs = append(allErrs, validateTopologySpreadConstraints(spec.TopologySpreadConstraints, fldPath.Child("topologySpreadConstraints"), opts)...) allErrs = append(allErrs, validateWindowsHostProcessPod(spec, fldPath)...) allErrs = append(allErrs, validateHostUsers(spec, fldPath)...) if len(spec.ServiceAccountName) > 0 { @@ -4506,6 +4546,24 @@ func validateSeccompAnnotationsAndFieldsMatch(annotationValue string, seccompFie return nil } +var updatablePodSpecFields = []string{ + "`spec.containers[*].image`", + "`spec.initContainers[*].image`", + "`spec.activeDeadlineSeconds`", + "`spec.tolerations` (only additions to existing tolerations)", + "`spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)", + "`spec.containers[*].resources` (for CPU/memory only)", +} + +// TODO(vinaykul,InPlacePodVerticalScaling): Drop this var once InPlacePodVerticalScaling goes GA and featuregate is gone. +var updatablePodSpecFieldsNoResources = []string{ + "`spec.containers[*].image`", + "`spec.initContainers[*].image`", + "`spec.activeDeadlineSeconds`", + "`spec.tolerations` (only additions to existing tolerations)", + "`spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)", +} + // ValidatePodUpdate tests to see if the update is legal for an end user to make. newPod is updated with fields // that cannot be changed. func ValidatePodUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) field.ErrorList { @@ -4565,12 +4623,56 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel return allErrs } + //TODO(vinaykul,InPlacePodVerticalScaling): With KEP 2527, we can rely on persistence of PodStatus.QOSClass + // We can use PodStatus.QOSClass instead of GetPodQOS here, in kubelet, and elsewhere, as PodStatus.QOSClass + // does not change once it is bootstrapped in podCreate. This needs to be addressed before beta as a + // separate PR covering all uses of GetPodQOS. With that change, we can drop the below block. + // Ref: https://github.com/kubernetes/kubernetes/pull/102884#discussion_r1093790446 + // Ref: https://github.com/kubernetes/kubernetes/pull/102884/#discussion_r663280487 + if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { + // reject attempts to change pod qos + oldQoS := qos.GetPodQOS(oldPod) + newQoS := qos.GetPodQOS(newPod) + if newQoS != oldQoS { + allErrs = append(allErrs, field.Invalid(fldPath, newQoS, "Pod QoS is immutable")) + } + } + // handle updateable fields by munging those fields prior to deep equal comparison. mungedPodSpec := *newPod.Spec.DeepCopy() // munge spec.containers[*].image var newContainers []core.Container for ix, container := range mungedPodSpec.Containers { container.Image = oldPod.Spec.Containers[ix].Image // +k8s:verify-mutation:reason=clone + // When the feature-gate is turned off, any new requests attempting to update CPU or memory + // resource values will result in validation failure. + if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { + // Resources are mutable for CPU & memory only + // - user can now modify Resources to express new desired Resources + mungeCpuMemResources := func(resourceList, oldResourceList core.ResourceList) core.ResourceList { + if oldResourceList == nil { + return nil + } + var mungedResourceList core.ResourceList + if resourceList == nil { + mungedResourceList = make(core.ResourceList) + } else { + mungedResourceList = resourceList.DeepCopy() + } + delete(mungedResourceList, core.ResourceCPU) + delete(mungedResourceList, core.ResourceMemory) + if cpu, found := oldResourceList[core.ResourceCPU]; found { + mungedResourceList[core.ResourceCPU] = cpu + } + if mem, found := oldResourceList[core.ResourceMemory]; found { + mungedResourceList[core.ResourceMemory] = mem + } + return mungedResourceList + } + lim := mungeCpuMemResources(container.Resources.Limits, oldPod.Spec.Containers[ix].Resources.Limits) + req := mungeCpuMemResources(container.Resources.Requests, oldPod.Spec.Containers[ix].Resources.Requests) + container.Resources = core.ResourceRequirements{Limits: lim, Requests: req} + } newContainers = append(newContainers, container) } mungedPodSpec.Containers = newContainers @@ -4598,13 +4700,49 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel mungedPodSpec.TerminationGracePeriodSeconds = oldPod.Spec.TerminationGracePeriodSeconds // +k8s:verify-mutation:reason=clone } + // Handle validations specific to gated pods. + podIsGated := len(oldPod.Spec.SchedulingGates) > 0 + if opts.AllowMutableNodeSelectorAndNodeAffinity && podIsGated { + // Additions to spec.nodeSelector are allowed (no deletions or mutations) for gated pods. + if !apiequality.Semantic.DeepEqual(mungedPodSpec.NodeSelector, oldPod.Spec.NodeSelector) { + allErrs = append(allErrs, validateNodeSelectorMutation(specPath.Child("nodeSelector"), mungedPodSpec.NodeSelector, oldPod.Spec.NodeSelector)...) + mungedPodSpec.NodeSelector = oldPod.Spec.NodeSelector // +k8s:verify-mutation:reason=clone + } + + // Validate node affinity mutations. + var oldNodeAffinity *core.NodeAffinity + if oldPod.Spec.Affinity != nil { + oldNodeAffinity = oldPod.Spec.Affinity.NodeAffinity // +k8s:verify-mutation:reason=clone + } + + var mungedNodeAffinity *core.NodeAffinity + if mungedPodSpec.Affinity != nil { + mungedNodeAffinity = mungedPodSpec.Affinity.NodeAffinity // +k8s:verify-mutation:reason=clone + } + + if !apiequality.Semantic.DeepEqual(oldNodeAffinity, mungedNodeAffinity) { + allErrs = append(allErrs, validateNodeAffinityMutation(specPath.Child("affinity").Child("nodeAffinity"), mungedNodeAffinity, oldNodeAffinity)...) + switch { + case mungedPodSpec.Affinity == nil && oldNodeAffinity == nil: + // already effectively nil, no change needed + case mungedPodSpec.Affinity == nil && oldNodeAffinity != nil: + mungedPodSpec.Affinity = &core.Affinity{NodeAffinity: oldNodeAffinity} // +k8s:verify-mutation:reason=clone + default: + mungedPodSpec.Affinity.NodeAffinity = oldNodeAffinity // +k8s:verify-mutation:reason=clone + } + } + } + if !apiequality.Semantic.DeepEqual(mungedPodSpec, oldPod.Spec) { // This diff isn't perfect, but it's a helluva lot better an "I'm not going to tell you what the difference is". // TODO: Pinpoint the specific field that causes the invalid error after we have strategic merge diff specDiff := cmp.Diff(oldPod.Spec, mungedPodSpec) - allErrs = append(allErrs, field.Forbidden(specPath, fmt.Sprintf("pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds`, `spec.tolerations` (only additions to existing tolerations) or `spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)\n%v", specDiff))) + errs := field.Forbidden(specPath, fmt.Sprintf("pod updates may not change fields other than %s\n%v", strings.Join(updatablePodSpecFieldsNoResources, ","), specDiff)) + if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { + errs = field.Forbidden(specPath, fmt.Sprintf("pod updates may not change fields other than %s\n%v", strings.Join(updatablePodSpecFields, ","), specDiff)) + } + allErrs = append(allErrs, errs) } - return allErrs } @@ -4687,6 +4825,11 @@ func ValidatePodEphemeralContainersUpdate(newPod, oldPod *core.Pod, opts PodVali allErrs = append(allErrs, validatePodMetadataAndSpec(newPod, opts)...) allErrs = append(allErrs, ValidatePodSpecificAnnotationUpdates(newPod, oldPod, fldPath.Child("annotations"), opts)...) + // static pods don't support ephemeral containers #113935 + if _, ok := oldPod.Annotations[core.MirrorPodAnnotationKey]; ok { + return field.ErrorList{field.Forbidden(field.NewPath(""), "static pods do not support ephemeral containers")} + } + // Part 2: Validate that the changes between oldPod.Spec.EphemeralContainers and // newPod.Spec.EphemeralContainers are allowed. // @@ -4743,14 +4886,23 @@ var supportedSessionAffinityType = sets.NewString(string(core.ServiceAffinityCli var supportedServiceType = sets.NewString(string(core.ServiceTypeClusterIP), string(core.ServiceTypeNodePort), string(core.ServiceTypeLoadBalancer), string(core.ServiceTypeExternalName)) -var supportedServiceInternalTrafficPolicy = sets.NewString(string(core.ServiceInternalTrafficPolicyCluster), string(core.ServiceExternalTrafficPolicyTypeLocal)) +var supportedServiceInternalTrafficPolicy = sets.NewString(string(core.ServiceInternalTrafficPolicyCluster), string(core.ServiceExternalTrafficPolicyLocal)) var supportedServiceIPFamily = sets.NewString(string(core.IPv4Protocol), string(core.IPv6Protocol)) var supportedServiceIPFamilyPolicy = sets.NewString(string(core.IPFamilyPolicySingleStack), string(core.IPFamilyPolicyPreferDualStack), string(core.IPFamilyPolicyRequireDualStack)) // ValidateService tests if required fields/annotations of a Service are valid. func ValidateService(service *core.Service) field.ErrorList { - allErrs := ValidateObjectMeta(&service.ObjectMeta, true, ValidateServiceName, field.NewPath("metadata")) + metaPath := field.NewPath("metadata") + allErrs := ValidateObjectMeta(&service.ObjectMeta, true, ValidateServiceName, metaPath) + + topologyHintsVal, topologyHintsSet := service.Annotations[core.DeprecatedAnnotationTopologyAwareHints] + topologyModeVal, topologyModeSet := service.Annotations[core.AnnotationTopologyMode] + + if topologyModeSet && topologyHintsSet && topologyModeVal != topologyHintsVal { + message := fmt.Sprintf("must match annotations[%s] when both are specified", core.DeprecatedAnnotationTopologyAwareHints) + allErrs = append(allErrs, field.Invalid(metaPath.Child("annotations").Key(core.AnnotationTopologyMode), topologyModeVal, message)) + } specPath := field.NewPath("spec") @@ -4975,8 +5127,8 @@ func needsExternalTrafficPolicy(svc *core.Service) bool { } var validExternalTrafficPolicies = sets.NewString( - string(core.ServiceExternalTrafficPolicyTypeCluster), - string(core.ServiceExternalTrafficPolicyTypeLocal)) + string(core.ServiceExternalTrafficPolicyCluster), + string(core.ServiceExternalTrafficPolicyLocal)) func validateServiceExternalTrafficPolicy(service *core.Service) field.ErrorList { allErrs := field.ErrorList{} @@ -5811,7 +5963,6 @@ func ValidateSecret(secret *core.Secret) field.ErrorList { if _, exists := secret.Data[core.TLSPrivateKeyKey]; !exists { allErrs = append(allErrs, field.Required(dataPath.Key(core.TLSPrivateKeyKey), "")) } - // TODO: Verify that the key matches the cert. default: // no-op } @@ -5946,9 +6097,9 @@ func ValidateResourceRequirements(requirements *core.ResourceRequirements, podCl if exists { // For non overcommitable resources, not only requests can't exceed limits, they also can't be lower, i.e. must be equal. if quantity.Cmp(limitQuantity) != 0 && !helper.IsOvercommitAllowed(resourceName) { - allErrs = append(allErrs, field.Invalid(reqPath, quantity.String(), fmt.Sprintf("must be equal to %s limit", resourceName))) + allErrs = append(allErrs, field.Invalid(reqPath, quantity.String(), fmt.Sprintf("must be equal to %s limit of %s", resourceName, limitQuantity.String()))) } else if quantity.Cmp(limitQuantity) > 0 { - allErrs = append(allErrs, field.Invalid(reqPath, quantity.String(), fmt.Sprintf("must be less than or equal to %s limit", resourceName))) + allErrs = append(allErrs, field.Invalid(reqPath, quantity.String(), fmt.Sprintf("must be less than or equal to %s limit of %s", resourceName, limitQuantity.String()))) } } else if !helper.IsOvercommitAllowed(resourceName) { allErrs = append(allErrs, field.Required(limPath, "Limit must be set for non overcommitable resources")) @@ -6741,7 +6892,7 @@ var ( ) // validateTopologySpreadConstraints validates given TopologySpreadConstraints. -func validateTopologySpreadConstraints(constraints []core.TopologySpreadConstraint, fldPath *field.Path) field.ErrorList { +func validateTopologySpreadConstraints(constraints []core.TopologySpreadConstraint, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { allErrs := field.ErrorList{} for i, constraint := range constraints { @@ -6767,6 +6918,9 @@ func validateTopologySpreadConstraints(constraints []core.TopologySpreadConstrai allErrs = append(allErrs, err) } allErrs = append(allErrs, validateMatchLabelKeys(subFldPath.Child("matchLabelKeys"), constraint.MatchLabelKeys, constraint.LabelSelector)...) + if !opts.AllowInvalidTopologySpreadConstraintLabelSelector { + allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(constraint.LabelSelector, unversionedvalidation.LabelSelectorValidationOptions{AllowInvalidLabelValueInSelector: false}, subFldPath.Child("labelSelector"))...) + } } return allErrs @@ -6846,7 +7000,9 @@ func validateMatchLabelKeys(fldPath *field.Path, matchLabelKeys []string, labelS return nil } + var allErrs field.ErrorList labelSelectorKeys := sets.String{} + if labelSelector != nil { for key := range labelSelector.MatchLabels { labelSelectorKeys.Insert(key) @@ -6854,9 +7010,10 @@ func validateMatchLabelKeys(fldPath *field.Path, matchLabelKeys []string, labelS for _, matchExpression := range labelSelector.MatchExpressions { labelSelectorKeys.Insert(matchExpression.Key) } + } else { + allErrs = append(allErrs, field.Forbidden(fldPath, "must not be specified when labelSelector is not set")) } - allErrs := field.ErrorList{} for i, key := range matchLabelKeys { allErrs = append(allErrs, unversionedvalidation.ValidateLabelName(key, fldPath.Index(i))...) if labelSelectorKeys.Has(key) { @@ -7172,3 +7329,115 @@ func ValidatePodAffinityTermSelector(podAffinityTerm core.PodAffinityTerm, allow allErrs = append(allErrs, unversionedvalidation.ValidateLabelSelector(podAffinityTerm.NamespaceSelector, labelSelectorValidationOptions, fldPath.Child("namespaceSelector"))...) return allErrs } + +var betaToGALabel = map[string]string{ + v1.LabelFailureDomainBetaZone: v1.LabelTopologyZone, + v1.LabelFailureDomainBetaRegion: v1.LabelTopologyRegion, + kubeletapis.LabelOS: v1.LabelOSStable, + kubeletapis.LabelArch: v1.LabelArchStable, + v1.LabelInstanceType: v1.LabelInstanceTypeStable, +} + +var ( + maskNodeSelectorLabelChangeEqualities conversion.Equalities + initMaskNodeSelectorLabelChangeEqualities sync.Once +) + +func getMaskNodeSelectorLabelChangeEqualities() conversion.Equalities { + initMaskNodeSelectorLabelChangeEqualities.Do(func() { + var eqs = apiequality.Semantic.Copy() + err := eqs.AddFunc( + func(newReq, oldReq core.NodeSelectorRequirement) bool { + // allow newReq to change to a GA key + if oldReq.Key != newReq.Key && betaToGALabel[oldReq.Key] == newReq.Key { + oldReq.Key = newReq.Key // +k8s:verify-mutation:reason=clone + } + return apiequality.Semantic.DeepEqual(newReq, oldReq) + }, + ) + if err != nil { + panic(fmt.Errorf("failed to instantiate semantic equalities: %w", err)) + } + maskNodeSelectorLabelChangeEqualities = eqs + }) + return maskNodeSelectorLabelChangeEqualities +} + +func validatePvNodeAffinity(newPvNodeAffinity, oldPvNodeAffinity *core.VolumeNodeAffinity, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if !getMaskNodeSelectorLabelChangeEqualities().DeepEqual(newPvNodeAffinity, oldPvNodeAffinity) { + allErrs = append(allErrs, field.Invalid(fldPath, newPvNodeAffinity, fieldImmutableErrorMsg+", except for updating from beta label to GA")) + } + return allErrs +} + +func validateNodeSelectorMutation(fldPath *field.Path, newNodeSelector, oldNodeSelector map[string]string) field.ErrorList { + var allErrs field.ErrorList + + // Validate no existing node selectors were deleted or mutated. + for k, v1 := range oldNodeSelector { + if v2, ok := newNodeSelector[k]; !ok || v1 != v2 { + allErrs = append(allErrs, field.Invalid(fldPath, newNodeSelector, "only additions to spec.nodeSelector are allowed (no mutations or deletions)")) + return allErrs + } + } + return allErrs +} + +func validateNodeAffinityMutation(nodeAffinityPath *field.Path, newNodeAffinity, oldNodeAffinity *core.NodeAffinity) field.ErrorList { + var allErrs field.ErrorList + // If old node affinity was nil, anything can be set. + if oldNodeAffinity == nil || oldNodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil { + return allErrs + } + + oldTerms := oldNodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms + var newTerms []core.NodeSelectorTerm + if newNodeAffinity != nil && newNodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil { + newTerms = newNodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms + } + + // If there are no old terms, we can set the new terms to anything. + // If there are old terms, we cannot add any new ones. + if len(oldTerms) > 0 && len(oldTerms) != len(newTerms) { + return append(allErrs, field.Invalid(nodeAffinityPath.Child("requiredDuringSchedulingIgnoredDuringExecution").Child("nodeSelectorTerms"), newTerms, "no additions/deletions to non-empty NodeSelectorTerms list are allowed")) + } + + // For requiredDuringSchedulingIgnoredDuringExecution, if old NodeSelectorTerms + // was empty, anything can be set. If non-empty, only additions of NodeSelectorRequirements + // to matchExpressions or fieldExpressions are allowed. + for i := range oldTerms { + if !validateNodeSelectorTermHasOnlyAdditions(newTerms[i], oldTerms[i]) { + allErrs = append(allErrs, field.Invalid(nodeAffinityPath.Child("requiredDuringSchedulingIgnoredDuringExecution").Child("nodeSelectorTerms").Index(i), newTerms[i], "only additions are allowed (no mutations or deletions)")) + } + } + return allErrs +} + +func validateNodeSelectorTermHasOnlyAdditions(newTerm, oldTerm core.NodeSelectorTerm) bool { + if len(oldTerm.MatchExpressions) == 0 && len(oldTerm.MatchFields) == 0 { + if len(newTerm.MatchExpressions) > 0 || len(newTerm.MatchFields) > 0 { + return false + } + } + + // Validate MatchExpressions only has additions (no deletions or mutations) + if l := len(oldTerm.MatchExpressions); l > 0 { + if len(newTerm.MatchExpressions) < l { + return false + } + if !apiequality.Semantic.DeepEqual(newTerm.MatchExpressions[:l], oldTerm.MatchExpressions) { + return false + } + } + // Validate MatchFields only has additions (no deletions or mutations) + if l := len(oldTerm.MatchFields); l > 0 { + if len(newTerm.MatchFields) < l { + return false + } + if !apiequality.Semantic.DeepEqual(newTerm.MatchFields[:l], oldTerm.MatchFields) { + return false + } + } + return true +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go index 857843371..f8d32ea9d 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go @@ -788,6 +788,11 @@ func (in *Container) DeepCopyInto(out *Container) { } } in.Resources.DeepCopyInto(&out.Resources) + if in.ResizePolicy != nil { + in, out := &in.ResizePolicy, &out.ResizePolicy + *out = make([]ContainerResizePolicy, len(*in)) + copy(*out, *in) + } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts *out = make([]VolumeMount, len(*in)) @@ -875,6 +880,22 @@ func (in *ContainerPort) DeepCopy() *ContainerPort { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerResizePolicy) DeepCopyInto(out *ContainerResizePolicy) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResizePolicy. +func (in *ContainerResizePolicy) DeepCopy() *ContainerResizePolicy { + if in == nil { + return nil + } + out := new(ContainerResizePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ContainerState) DeepCopyInto(out *ContainerState) { *out = *in @@ -967,6 +988,18 @@ func (in *ContainerStatus) DeepCopyInto(out *ContainerStatus) { *out = new(bool) **out = **in } + if in.AllocatedResources != nil { + in, out := &in.AllocatedResources, &out.AllocatedResources + *out = make(ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(ResourceRequirements) + (*in).DeepCopyInto(*out) + } return } @@ -1382,6 +1415,11 @@ func (in *EphemeralContainerCommon) DeepCopyInto(out *EphemeralContainerCommon) } } in.Resources.DeepCopyInto(&out.Resources) + if in.ResizePolicy != nil { + in, out := &in.ResizePolicy, &out.ResizePolicy + *out = make([]ContainerResizePolicy, len(*in)) + copy(*out, *in) + } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts *out = make([]VolumeMount, len(*in)) @@ -5502,7 +5540,7 @@ func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { } if in.InternalTrafficPolicy != nil { in, out := &in.InternalTrafficPolicy, &out.InternalTrafficPolicy - *out = new(ServiceInternalTrafficPolicyType) + *out = new(ServiceInternalTrafficPolicy) **out = **in } return diff --git a/vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go b/vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go index 4abb1afa2..e82911b2a 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/extensions/register.go @@ -22,7 +22,6 @@ import ( "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/networking" - "k8s.io/kubernetes/pkg/apis/policy" ) // GroupName is the group name use in this package @@ -60,8 +59,6 @@ func addKnownTypes(scheme *runtime.Scheme) error { &networking.IngressList{}, &apps.ReplicaSet{}, &apps.ReplicaSetList{}, - &policy.PodSecurityPolicy{}, - &policy.PodSecurityPolicyList{}, &autoscaling.Scale{}, &networking.NetworkPolicy{}, &networking.NetworkPolicyList{}, diff --git a/vendor/k8s.io/kubernetes/pkg/apis/networking/register.go b/vendor/k8s.io/kubernetes/pkg/apis/networking/register.go index 486bf834b..570a6a4db 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/networking/register.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/networking/register.go @@ -54,6 +54,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &IngressClassList{}, &ClusterCIDR{}, &ClusterCIDRList{}, + &IPAddress{}, + &IPAddressList{}, ) return nil } diff --git a/vendor/k8s.io/kubernetes/pkg/apis/networking/types.go b/vendor/k8s.io/kubernetes/pkg/apis/networking/types.go index 7edd4cb34..6c9eaa7a4 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/networking/types.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/networking/types.go @@ -18,23 +18,25 @@ package networking import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" api "k8s.io/kubernetes/pkg/apis/core" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// NetworkPolicy describes what network traffic is allowed for a set of Pods +// NetworkPolicy describes what network traffic is allowed for a set of pods type NetworkPolicy struct { metav1.TypeMeta + // +optional metav1.ObjectMeta - // Specification of the desired behavior for this NetworkPolicy. + // spec represents the specification of the desired behavior for this NetworkPolicy. // +optional Spec NetworkPolicySpec - // Status is the current state of the NetworkPolicy. + // status represents the current state of the NetworkPolicy. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status NetworkPolicyStatus @@ -53,16 +55,16 @@ const ( // NetworkPolicySpec provides the specification of a NetworkPolicy type NetworkPolicySpec struct { - // Selects the pods to which this NetworkPolicy object applies. The array of - // ingress rules is applied to any pods selected by this field. Multiple network - // policies can select the same set of pods. In this case, the ingress rules for - // each are combined additively. This field is NOT optional and follows standard - // label selector semantics. An empty podSelector matches all pods in this - // namespace. + // podSelector selects the pods to which this NetworkPolicy object applies. + // The array of ingress rules is applied to any pods selected by this field. + // Multiple network policies can select the same set of pods. In this case, + // the ingress rules for each are combined additively. + // This field is NOT optional and follows standard label selector semantics. + // An empty podSelector matches all pods in this namespace. PodSelector metav1.LabelSelector - // List of ingress rules to be applied to the selected pods. Traffic is allowed to - // a pod if there are no NetworkPolicies selecting the pod + // ingress is a list of ingress rules to be applied to the selected pods. + // Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod // (and cluster policy otherwise allows the traffic), OR if the traffic source is // the pod's local node, OR if the traffic matches at least one ingress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If @@ -71,8 +73,8 @@ type NetworkPolicySpec struct { // +optional Ingress []NetworkPolicyIngressRule - // List of egress rules to be applied to the selected pods. Outgoing traffic is - // allowed if there are no NetworkPolicies selecting the pod (and cluster policy + // egress is a list of egress rules to be applied to the selected pods. Outgoing traffic + // is allowed if there are no NetworkPolicies selecting the pod (and cluster policy // otherwise allows the traffic), OR if the traffic matches at least one egress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If // this field is empty then this NetworkPolicy limits all outgoing traffic (and serves @@ -81,15 +83,15 @@ type NetworkPolicySpec struct { // +optional Egress []NetworkPolicyEgressRule - // List of rule types that the NetworkPolicy relates to. + // policyTypes is a list of rule types that the NetworkPolicy relates to. // Valid options are ["Ingress"], ["Egress"], or ["Ingress", "Egress"]. - // If this field is not specified, it will default based on the existence of Ingress or Egress rules; - // policies that contain an Egress section are assumed to affect Egress, and all policies - // (whether or not they contain an Ingress section) are assumed to affect Ingress. + // If this field is not specified, it will default based on the existence of ingress or egress rules; + // policies that contain an egress section are assumed to affect egress, and all policies + // (whether or not they contain an ingress section) are assumed to affect ingress. // If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. // Likewise, if you want to write a policy that specifies that no egress is allowed, // you must specify a policyTypes value that include "Egress" (since such a policy would not include - // an Egress section and would otherwise default to just [ "Ingress" ]). + // an egress section and would otherwise default to just [ "Ingress" ]). // This field is beta-level in 1.8 // +optional PolicyTypes []PolicyType @@ -98,15 +100,15 @@ type NetworkPolicySpec struct { // NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from. type NetworkPolicyIngressRule struct { - // List of ports which should be made accessible on the pods selected for this - // rule. Each item in this list is combined using a logical OR. If this field is + // ports is a list of ports which should be made accessible on the pods selected for + // this rule. Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows // traffic only if the traffic matches at least one port in the list. // +optional Ports []NetworkPolicyPort - // List of sources which should be able to access the pods selected for this rule. + // from is a list of sources which should be able to access the pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all sources (traffic not restricted by // source). If this field is present and contains at least one item, this rule @@ -119,7 +121,7 @@ type NetworkPolicyIngressRule struct { // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. // This type is beta-level in 1.8 type NetworkPolicyEgressRule struct { - // List of destination ports for outgoing traffic. + // ports is a list of destination ports for outgoing traffic. // Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows @@ -127,7 +129,7 @@ type NetworkPolicyEgressRule struct { // +optional Ports []NetworkPolicyPort - // List of destinations for outgoing traffic of pods selected for this rule. + // to is a list of destinations for outgoing traffic of pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all destinations (traffic not restricted by // destination). If this field is present and contains at least one item, this rule @@ -138,19 +140,19 @@ type NetworkPolicyEgressRule struct { // NetworkPolicyPort describes a port to allow traffic on type NetworkPolicyPort struct { - // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this - // field defaults to TCP. + // protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. + // If not specified, this field defaults to TCP. // +optional Protocol *api.Protocol - // The port on the given protocol. This can either be a numerical or named + // port represents the port on the given protocol. This can either be a numerical or named // port on a pod. If this field is not provided, this matches all port names and // numbers. // If present, only traffic on the specified protocol AND port will be matched. // +optional Port *intstr.IntOrString - // If set, indicates that the range of ports from port to endPort, inclusive, + // endPort indicates that the range of ports from port to endPort if set, inclusive, // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. @@ -162,37 +164,38 @@ type NetworkPolicyPort struct { // to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs // that should not be included within this rule. type IPBlock struct { - // CIDR is a string representing the IP Block + // cidr is a string representing the IPBlock // Valid examples are "192.168.1.0/24" or "2001:db8::/64" CIDR string - // Except is a slice of CIDRs that should not be included within an IP Block + + // except is a list of CIDRs that should not be included within the IPBlock // Valid examples are "192.168.1.0/24" or "2001:db8::/64" - // Except values will be rejected if they are outside the CIDR range + // Except values will be rejected if they are outside the cidr range // +optional Except []string } // NetworkPolicyPeer describes a peer to allow traffic to/from. type NetworkPolicyPeer struct { - // This is a label selector which selects Pods. This field follows standard label + // podSelector is a label selector which selects pods. This field follows standard label // selector semantics; if present but empty, it selects all pods. // - // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. + // If namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the Namespaces selected by namespaceSelector. + // Otherwise it selects the pods matching podSelector in the policy's own namespace. // +optional PodSelector *metav1.LabelSelector - // Selects Namespaces using cluster-scoped labels. This field follows standard label - // selector semantics; if present but empty, it selects all namespaces. + // namespaceSelector selects namespaces using cluster-scoped labels. This field follows + // standard label selector semantics; if present but empty, it selects all namespaces. // - // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. + // If podSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the namespaces selected by namespaceSelector. + // Otherwise it selects all pods in the namespaces selected by namespaceSelector. // +optional NamespaceSelector *metav1.LabelSelector - // IPBlock defines policy on a particular IPBlock. If this field is set then + // ipBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional IPBlock *IPBlock @@ -228,9 +231,9 @@ const ( NetworkPolicyConditionReasonFeatureNotSupported NetworkPolicyConditionReason = "FeatureNotSupported" ) -// NetworkPolicyStatus describe the current state of the NetworkPolicy. +// NetworkPolicyStatus describes the current state of the NetworkPolicy. type NetworkPolicyStatus struct { - // Conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. + // conditions holds an array of metav1.Condition that describes the state of the NetworkPolicy. Conditions []metav1.Condition } @@ -239,6 +242,7 @@ type NetworkPolicyStatus struct { // NetworkPolicyList is a list of NetworkPolicy objects. type NetworkPolicyList struct { metav1.TypeMeta + // +optional metav1.ListMeta @@ -253,17 +257,18 @@ type NetworkPolicyList struct { // based virtual hosting etc. type Ingress struct { metav1.TypeMeta + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ObjectMeta - // Spec is the desired state of the Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressSpec - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status IngressStatus @@ -274,18 +279,19 @@ type Ingress struct { // IngressList is a collection of Ingress. type IngressList struct { metav1.TypeMeta + // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional metav1.ListMeta - // Items is the list of Ingress. + // items is the list of Ingress. Items []Ingress } // IngressSpec describes the Ingress the user wishes to exist. type IngressSpec struct { - // IngressClassName is the name of the IngressClass cluster resource. The + // ingressClassName is the name of the IngressClass cluster resource. The // associated IngressClass defines which controller will implement the // resource. This replaces the deprecated `kubernetes.io/ingress.class` // annotation. For backwards compatibility, when that annotation is set, it @@ -298,23 +304,23 @@ type IngressSpec struct { // +optional IngressClassName *string - // DefaultBackend is the backend that should handle requests that don't + // defaultBackend is the backend that should handle requests that don't // match any rule. If Rules are not specified, DefaultBackend must be specified. // If DefaultBackend is not set, the handling of requests that do not match any // of the rules will be up to the Ingress controller. // +optional DefaultBackend *IngressBackend - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +listType=atomic // +optional TLS []IngressTLS - // A list of host rules used to configure the Ingress. If unspecified, or + // rules is a list of host rules used to configure the Ingress. If unspecified, or // no rule matches, all traffic is sent to the default backend. // +listType=atomic // +optional @@ -330,9 +336,10 @@ type IngressSpec struct { // resources without a class specified will be assigned this default class. type IngressClass struct { metav1.TypeMeta + metav1.ObjectMeta - // Spec is the desired state of the IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressClassSpec @@ -340,15 +347,15 @@ type IngressClass struct { // IngressClassSpec provides information about the class of an Ingress. type IngressClassSpec struct { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. Controller string - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -367,20 +374,24 @@ const ( // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. type IngressClassParametersReference struct { - // APIGroup is the group for the resource being referenced. If APIGroup is - // not specified, the specified Kind must be in the core API group. For any - // other third-party types, APIGroup is required. + // apiGroup is the group for the resource being referenced. If apiGroup is + // not specified, the specified kind must be in the core API group. For any + // other third-party types, apiGroup is required. // +optional APIGroup *string - // Kind is the type of resource being referenced. + + // kind is the type of resource being referenced. Kind string - // Name is the name of resource being referenced. + + // name is the name of resource being referenced. Name string - // Scope represents if this refers to a cluster or namespace scoped resource. + + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". // +optional Scope *string - // Namespace is the namespace of the resource being referenced. This field is + + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -392,71 +403,73 @@ type IngressClassParametersReference struct { // IngressClassList is a collection of IngressClasses. type IngressClassList struct { metav1.TypeMeta + // Standard object's metadata. // +optional metav1.ListMeta - // Items is the list of IngressClasses. + // items is the list of IngressClasses. Items []IngressClass } -// IngressTLS describes the transport layer security associated with an Ingress. +// IngressTLS describes the transport layer security associated with an ingress. type IngressTLS struct { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. // +listType=atomic // +optional Hosts []string - // SecretName is the name of the secret used to terminate TLS traffic on + + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination - // and value of the Host header is used for routing. + // and value of the "Host" header is used for routing. // +optional SecretName string // TODO: Consider specifying different modes of termination, protocols etc. } -// IngressStatus describe the current state of the Ingress. +// IngressStatus describes the current state of the Ingress. type IngressStatus struct { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. // +optional LoadBalancer IngressLoadBalancerStatus } // IngressLoadBalancerStatus represents the status of a load-balancer type IngressLoadBalancerStatus struct { - // Ingress is a list containing ingress points for the load-balancer. + // ingress is a list containing ingress points for the load-balancer. // +optional Ingress []IngressLoadBalancerIngress } // IngressLoadBalancerIngress represents the status of a load-balancer ingress point. type IngressLoadBalancerIngress struct { - // IP is set for load-balancer ingress points that are IP based. + // ip is set for load-balancer ingress points that are IP based. // +optional IP string - // Hostname is set for load-balancer ingress points that are DNS based. + // hostname is set for load-balancer ingress points that are DNS based. // +optional Hostname string - // Ports provides information about the ports exposed by this LoadBalancer. + // ports provides information about the ports exposed by this LoadBalancer. // +optional Ports []IngressPortStatus } // IngressPortStatus represents the error condition of an ingress port type IngressPortStatus struct { - // Port is the port number of the ingress port. + // port is the port number of the ingress port. Port int32 - // Protocol is the protocol of the ingress port. + // protocol is the protocol of the ingress port. Protocol api.Protocol - // Error indicates a problem on this port. + // error indicates a problem on this port. // The format of the error must comply with the following rules: // - Kubernetes-defined error values use CamelCase names // - Provider-specific error values must follow label-name style (e.g. @@ -469,7 +482,7 @@ type IngressPortStatus struct { // host match, then routed to the backend associated with the matching // IngressRuleValue. type IngressRule struct { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -482,17 +495,18 @@ type IngressRule struct { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and // matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*"). - // Requests will be matched against the Host field in the following way: - // 1. If Host is precise, the request matches this rule if the http host header is equal to Host. - // 2. If Host is a wildcard, then the request matches this rule if the http host header + // Requests will be matched against the host field in the following way: + // 1. If host is precise, the request matches this rule if the http host header is equal to Host. + // 2. If host is a wildcard, then the request matches this rule if the http host header // is to equal to the suffix (removing the first label) of the wildcard rule. // +optional Host string + // IngressRuleValue represents a rule to route requests for this // IngressRule. If unspecified, the rule defaults to a http catch-all. // Whether that sends just traffic matching the host to the default backend @@ -524,7 +538,7 @@ type IngressRuleValue struct { // to match against everything after the last '/' and before the first '?' // or '#'. type HTTPIngressRuleValue struct { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. // +listType=atomic Paths []HTTPIngressPath // TODO: Consider adding fields for ingress-type specific global @@ -564,32 +578,32 @@ const ( // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. type HTTPIngressPath struct { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional Path string - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of Exact, Prefix, or ImplementationSpecific. Implementations are // required to support all path types. // +optional PathType *PathType - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. Backend IngressBackend } // IngressBackend describes all endpoints for a given service and port. type IngressBackend struct { - // Service references a Service as a Backend. + // service references a service as a backend. // This is a mutually exclusive setting with "Resource". // +optional Service *IngressServiceBackend - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, a service.Name and // service.Port must not be specified. // This is a mutually exclusive setting with "Service". @@ -599,24 +613,24 @@ type IngressBackend struct { // IngressServiceBackend references a Kubernetes Service as a Backend. type IngressServiceBackend struct { - // Name is the referenced service. The service must exist in + // name is the referenced service. The service must exist in // the same namespace as the Ingress object. Name string - // Port of the referenced service. A port name or port number + // port of the referenced service. A port name or port number // is required for a IngressServiceBackend. Port ServiceBackendPort } // ServiceBackendPort is the service port being referenced. type ServiceBackendPort struct { - // Name is the name of the port on the Service. + // name is the name of the port on the Service. // This must be an IANA_SVC_NAME (following RFC6335). // This is a mutually exclusive setting with "Number". // +optional Name string - // Number is the numerical port number (e.g. 80) on the Service. + // number is the numerical port number (e.g. 80) on the Service. // This is a mutually exclusive setting with "Name". // +optional Number int32 @@ -637,6 +651,7 @@ type ServiceBackendPort struct { // selector matches the Node may be used. type ClusterCIDR struct { metav1.TypeMeta + metav1.ObjectMeta Spec ClusterCIDRSpec @@ -644,13 +659,13 @@ type ClusterCIDR struct { // ClusterCIDRSpec defines the desired state of ClusterCIDR. type ClusterCIDRSpec struct { - // NodeSelector defines which nodes the config is applicable to. - // An empty or nil NodeSelector selects all nodes. + // nodeSelector defines which nodes the config is applicable to. + // An empty or nil nodeSelector selects all nodes. // This field is immutable. // +optional NodeSelector *api.NodeSelector - // PerNodeHostBits defines the number of host bits to be configured per node. + // perNodeHostBits defines the number of host bits to be configured per node. // A subnet mask determines how much of the address is used for network bits // and host bits. For example an IPv4 address of 192.168.0.0/24, splits the // address into 24 bits for the network portion and 8 bits for the host portion. @@ -660,14 +675,14 @@ type ClusterCIDRSpec struct { // +required PerNodeHostBits int32 - // IPv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8"). - // At least one of IPv4 and IPv6 must be specified. + // ipv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8"). + // At least one of ipv4 and ipv6 must be specified. // This field is immutable. // +optional IPv4 string - // IPv6 defines an IPv6 IP block in CIDR notation(e.g. "2001:db8::/64"). - // At least one of IPv4 and IPv6 must be specified. + // ipv6 defines an IPv6 IP block in CIDR notation(e.g. "2001:db8::/64"). + // At least one of ipv4 and ipv6 must be specified. // This field is immutable. // +optional IPv6 string @@ -682,6 +697,58 @@ type ClusterCIDRList struct { // +optional metav1.ListMeta - // Items is the list of ClusterCIDRs. + // items is the list of ClusterCIDRs. Items []ClusterCIDR } + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// 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 + // +optional + metav1.ObjectMeta + // +optional + Spec IPAddressSpec +} + +// 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 +} +type ParentReference struct { + // Group is the group of the object being referenced. + Group string + // Resource is the resource of the object being referenced. + Resource string + // Namespace is the namespace of the object being referenced. + Namespace string + // Name is the name of the object being referenced. + Name string + // UID is the uid of the object being referenced. + // +optional + UID types.UID +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// IPAddressList contains a list of IPAddress. +type IPAddressList struct { + metav1.TypeMeta + // +optional + metav1.ListMeta + + // Items is the list of IPAddress + Items []IPAddress +} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go index 57deaa239..e6a47cc1b 100644 --- a/vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go @@ -154,6 +154,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 @@ -816,6 +897,22 @@ func (in *NetworkPolicyStatus) DeepCopy() *NetworkPolicyStatus { 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 diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/OWNERS b/vendor/k8s.io/kubernetes/pkg/apis/policy/OWNERS deleted file mode 100644 index 55cce6cfb..000000000 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/OWNERS +++ /dev/null @@ -1,11 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -# approval on api packages bubbles to api-approvers -reviewers: - - sig-apps-api-reviewers - - sig-apps-api-approvers - - sig-auth-policy-approvers - - sig-auth-policy-reviewers -labels: - - sig/auth - - sig/apps diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/helper.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/helper.go deleted file mode 100644 index 4dd1658ab..000000000 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/helper.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2021 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 policy - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - PDBV1beta1Label = "pdb.kubernetes.io/deprecated-v1beta1-empty-selector-match" -) - -var ( - NonV1beta1MatchAllSelector = &metav1.LabelSelector{} - NonV1beta1MatchNoneSelector = &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{{Key: PDBV1beta1Label, Operator: metav1.LabelSelectorOpExists}}, - } - - V1beta1MatchNoneSelector = &metav1.LabelSelector{} - V1beta1MatchAllSelector = &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{{Key: PDBV1beta1Label, Operator: metav1.LabelSelectorOpDoesNotExist}}, - } -) - -func StripPDBV1beta1Label(selector *metav1.LabelSelector) { - if selector == nil { - return - } - - trimmedMatchExpressions := selector.MatchExpressions[:0] - for _, exp := range selector.MatchExpressions { - if exp.Key != PDBV1beta1Label { - trimmedMatchExpressions = append(trimmedMatchExpressions, exp) - } - } - selector.MatchExpressions = trimmedMatchExpressions -} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/types.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/types.go deleted file mode 100644 index b83ebd390..000000000 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/types.go +++ /dev/null @@ -1,529 +0,0 @@ -/* -Copyright 2016 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 policy - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" - api "k8s.io/kubernetes/pkg/apis/core" -) - -// PodDisruptionBudgetSpec is a description of a PodDisruptionBudget. -type PodDisruptionBudgetSpec struct { - // 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%". - // +optional - MinAvailable *intstr.IntOrString - - // Label query over pods whose evictions are managed by the disruption - // budget. - // +optional - Selector *metav1.LabelSelector - - // 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". - // +optional - MaxUnavailable *intstr.IntOrString - - // 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". - // - // Valid policies are IfHealthyBudget and AlwaysAllow. - // If no policy is specified, the default behavior will be used, - // which corresponds to the IfHealthyBudget policy. - // - // IfHealthyBudget 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. - // - // AlwaysAllow 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. - // - // 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 alpha-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (disabled by default). - // +optional - UnhealthyPodEvictionPolicy *UnhealthyPodEvictionPolicyType -} - -// UnhealthyPodEvictionPolicyType defines the criteria for when unhealthy pods -// should be considered for eviction. -// +enum -type UnhealthyPodEvictionPolicyType string - -const ( - // IfHealthyBudget 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. - IfHealthyBudget UnhealthyPodEvictionPolicyType = "IfHealthyBudget" - - // AlwaysAllow 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. - AlwaysAllow UnhealthyPodEvictionPolicyType = "AlwaysAllow" -) - -// PodDisruptionBudgetStatus represents information about the status of a -// PodDisruptionBudget. Status may trail the actual state of a system. -type PodDisruptionBudgetStatus struct { - // Most recent generation observed when updating this PDB status. DisruptionsAllowed and other - // status information is valid only if observedGeneration equals to PDB's object generation. - // +optional - ObservedGeneration int64 - - // DisruptedPods contains information about pods whose eviction was - // processed by the API server eviction subresource handler but has not - // yet been observed by the PodDisruptionBudget controller. - // A pod will be in this map from the time when the API server processed the - // eviction request to the time when the pod is seen by PDB controller - // as having been marked for deletion (or after a timeout). The key in the map is the name of the pod - // and the value is the time when the API server processed the eviction request. If - // the deletion didn't occur and a pod is still there it will be removed from - // the list automatically by PodDisruptionBudget controller after some time. - // If everything goes smooth this map should be empty for the most of the time. - // Large number of entries in the map may indicate problems with pod deletions. - // +optional - DisruptedPods map[string]metav1.Time - - // Number of pod disruptions that are currently allowed. - DisruptionsAllowed int32 - - // current number of healthy pods - CurrentHealthy int32 - - // minimum desired number of healthy pods - DesiredHealthy int32 - - // total number of pods counted by this disruption budget - ExpectedPods int32 - - // Conditions contain conditions for PDB - // +optional - Conditions []metav1.Condition -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// PodDisruptionBudget is an object to define the max disruption that can be caused to a collection of pods -type PodDisruptionBudget struct { - metav1.TypeMeta - // +optional - metav1.ObjectMeta - - // Specification of the desired behavior of the PodDisruptionBudget. - // +optional - Spec PodDisruptionBudgetSpec - // Most recently observed status of the PodDisruptionBudget. - // +optional - Status PodDisruptionBudgetStatus -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// PodDisruptionBudgetList is a collection of PodDisruptionBudgets. -type PodDisruptionBudgetList struct { - metav1.TypeMeta - // +optional - metav1.ListMeta - Items []PodDisruptionBudget -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// Eviction evicts a pod from its node subject to certain policies and safety constraints. -// This is a subresource of Pod. A request to cause such an eviction is -// created by POSTing to .../pods//eviction. -type Eviction struct { - metav1.TypeMeta - - // ObjectMeta describes the pod that is being evicted. - // +optional - metav1.ObjectMeta - - // DeleteOptions may be provided - // +optional - DeleteOptions *metav1.DeleteOptions -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// PodSecurityPolicy governs the ability to make requests that affect the SecurityContext -// that will be applied to a pod and container. -type PodSecurityPolicy struct { - metav1.TypeMeta - // +optional - metav1.ObjectMeta - - // Spec defines the policy enforced. - // +optional - Spec PodSecurityPolicySpec -} - -// PodSecurityPolicySpec defines the policy enforced. -type PodSecurityPolicySpec struct { - // Privileged determines if a pod can request to be run as privileged. - // +optional - Privileged bool - // DefaultAddCapabilities is the default set of capabilities that will be added to the container - // unless the pod spec specifically drops the capability. You may not list a capability in both - // DefaultAddCapabilities and RequiredDropCapabilities. Capabilities added here are implicitly - // allowed, and need not be included in the AllowedCapabilities list. - // +optional - DefaultAddCapabilities []api.Capability - // RequiredDropCapabilities are the capabilities that will be dropped from the container. These - // are required to be dropped and cannot be added. - // +optional - RequiredDropCapabilities []api.Capability - // AllowedCapabilities is a list of capabilities that can be requested to add to the container. - // Capabilities in this field may be added at the pod author's discretion. - // You must not list a capability in both AllowedCapabilities and RequiredDropCapabilities. - // To allow all capabilities you may use '*'. - // +optional - AllowedCapabilities []api.Capability - // Volumes is an allowlist of volume plugins. Empty indicates that - // no volumes may be used. To allow all volumes you may use '*'. - // +optional - Volumes []FSType - // HostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - // +optional - HostNetwork bool - // HostPorts determines which host port ranges are allowed to be exposed. - // +optional - HostPorts []HostPortRange - // HostPID determines if the policy allows the use of HostPID in the pod spec. - // +optional - HostPID bool - // HostIPC determines if the policy allows the use of HostIPC in the pod spec. - // +optional - HostIPC bool - // SELinux is the strategy that will dictate the allowable labels that may be set. - SELinux SELinuxStrategyOptions - // RunAsUser is the strategy that will dictate the allowable RunAsUser values that may be set. - RunAsUser RunAsUserStrategyOptions - // RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. - // If this field is omitted, the pod's RunAsGroup can take any value. This field requires the - // RunAsGroup feature gate to be enabled. - RunAsGroup *RunAsGroupStrategyOptions - // SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - SupplementalGroups SupplementalGroupsStrategyOptions - // FSGroup is the strategy that will dictate what fs group is used by the SecurityContext. - FSGroup FSGroupStrategyOptions - // ReadOnlyRootFilesystem when set to true will force containers to run with a read only root file - // system. If the container specifically requests to run with a non-read only root file system - // the PSP should deny the pod. - // If set to false the container may run with a read only root file system if it wishes but it - // will not be forced to. - // +optional - ReadOnlyRootFilesystem bool - // DefaultAllowPrivilegeEscalation controls the default setting for whether a - // process can gain more privileges than its parent process. - // +optional - DefaultAllowPrivilegeEscalation *bool - // AllowPrivilegeEscalation determines if a pod can request to allow - // privilege escalation. If unspecified, defaults to true. - // +optional - AllowPrivilegeEscalation bool - // AllowedHostPaths is an allowlist of host paths. Empty indicates that all host paths may be used. - // +optional - AllowedHostPaths []AllowedHostPath - // AllowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all - // Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes - // is allowed in the "Volumes" field. - // +optional - AllowedFlexVolumes []AllowedFlexVolume - // AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. - // An empty value indicates that any CSI driver can be used for inline ephemeral volumes. - // +optional - AllowedCSIDrivers []AllowedCSIDriver - // AllowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. - // Kubelet has to allowlist all unsafe sysctls explicitly to avoid rejection. - // - // Examples: - // e.g. "foo/*" allows "foo/bar", "foo/baz", etc. - // e.g. "foo.*" allows "foo.bar", "foo.baz", etc. - // +optional - AllowedUnsafeSysctls []string - // ForbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. - // - // Examples: - // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. - // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. - // +optional - ForbiddenSysctls []string - // AllowedProcMountTypes is an allowlist of ProcMountTypes. - // Empty or nil indicates that only the DefaultProcMountType may be used. - // +optional - AllowedProcMountTypes []api.ProcMountType - // runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. - // If this field is omitted, the pod's runtimeClassName field is unrestricted. - // Enforcement of this field depends on the RuntimeClass feature gate being enabled. - // +optional - RuntimeClass *RuntimeClassStrategyOptions -} - -// AllowedHostPath defines the host volume conditions that will be enabled by a policy -// for pods to use. It requires the path prefix to be defined. -type AllowedHostPath struct { - // PathPrefix is the path prefix that the host volume must match. - // PathPrefix does not support `*`. - // Trailing slashes are trimmed when validating the path prefix with a host path. - // - // Examples: - // `/foo` would allow `/foo`, `/foo/` and `/foo/bar` - // `/foo` would not allow `/food` or `/etc/foo` - PathPrefix string - - // when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly. - ReadOnly bool -} - -// HostPortRange defines a range of host ports that will be enabled by a policy -// for pods to use. It requires both the start and end to be defined. -type HostPortRange struct { - // Min is the start of the range, inclusive. - Min int32 - // Max is the end of the range, inclusive. - Max int32 -} - -// AllowAllCapabilities can be used as a value for the PodSecurityPolicy.AllowAllCapabilities -// field and means that any capabilities are allowed to be requested. -var AllowAllCapabilities api.Capability = "*" - -// FSType gives strong typing to different file systems that are used by volumes. -type FSType string - -// Exported FSTypes. -const ( - AzureFile FSType = "azureFile" - Flocker FSType = "flocker" - FlexVolume FSType = "flexVolume" - HostPath FSType = "hostPath" - EmptyDir FSType = "emptyDir" - GCEPersistentDisk FSType = "gcePersistentDisk" - AWSElasticBlockStore FSType = "awsElasticBlockStore" - GitRepo FSType = "gitRepo" - Secret FSType = "secret" - NFS FSType = "nfs" - ISCSI FSType = "iscsi" - Glusterfs FSType = "glusterfs" - PersistentVolumeClaim FSType = "persistentVolumeClaim" - RBD FSType = "rbd" - Cinder FSType = "cinder" - CephFS FSType = "cephFS" - DownwardAPI FSType = "downwardAPI" - FC FSType = "fc" - ConfigMap FSType = "configMap" - VsphereVolume FSType = "vsphereVolume" - Quobyte FSType = "quobyte" - AzureDisk FSType = "azureDisk" - PhotonPersistentDisk FSType = "photonPersistentDisk" - StorageOS FSType = "storageos" - Projected FSType = "projected" - PortworxVolume FSType = "portworxVolume" - ScaleIO FSType = "scaleIO" - CSI FSType = "csi" - Ephemeral FSType = "ephemeral" - All FSType = "*" -) - -// AllowedFlexVolume represents a single Flexvolume that is allowed to be used. -type AllowedFlexVolume struct { - // Driver is the name of the Flexvolume driver. - Driver string -} - -// AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used. -type AllowedCSIDriver struct { - // Name is the registered name of the CSI driver - Name string -} - -// SELinuxStrategyOptions defines the strategy type and any options used to create the strategy. -type SELinuxStrategyOptions struct { - // Rule is the strategy that will dictate the allowable labels that may be set. - Rule SELinuxStrategy - // SELinuxOptions required to run as; required for MustRunAs - // More info: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#selinux - // +optional - SELinuxOptions *api.SELinuxOptions -} - -// SELinuxStrategy denotes strategy types for generating SELinux options for a -// Security. -type SELinuxStrategy string - -const ( - // SELinuxStrategyMustRunAs means that container must have SELinux labels of X applied. - SELinuxStrategyMustRunAs SELinuxStrategy = "MustRunAs" - // SELinuxStrategyRunAsAny means that container may make requests for any SELinux context labels. - SELinuxStrategyRunAsAny SELinuxStrategy = "RunAsAny" -) - -// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. -type RunAsUserStrategyOptions struct { - // Rule is the strategy that will dictate the allowable RunAsUser values that may be set. - Rule RunAsUserStrategy - // Ranges are the allowed ranges of uids that may be used. If you would like to force a single uid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange -} - -// RunAsGroupStrategyOptions defines the strategy type and any options used to create the strategy. -type RunAsGroupStrategyOptions struct { - // Rule is the strategy that will dictate the allowable RunAsGroup values that may be set. - Rule RunAsGroupStrategy - // Ranges are the allowed ranges of gids that may be used. If you would like to force a single gid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange -} - -// IDRange provides a min/max of an allowed range of IDs. -type IDRange struct { - // Min is the start of the range, inclusive. - Min int64 - // Max is the end of the range, inclusive. - Max int64 -} - -// RunAsUserStrategy denotes strategy types for generating RunAsUser values for a -// SecurityContext. -type RunAsUserStrategy string - -const ( - // RunAsUserStrategyMustRunAs means that container must run as a particular uid. - RunAsUserStrategyMustRunAs RunAsUserStrategy = "MustRunAs" - // RunAsUserStrategyMustRunAsNonRoot means that container must run as a non-root uid - RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategy = "MustRunAsNonRoot" - // RunAsUserStrategyRunAsAny means that container may make requests for any uid. - RunAsUserStrategyRunAsAny RunAsUserStrategy = "RunAsAny" -) - -// RunAsGroupStrategy denotes strategy types for generating RunAsGroup values for a -// SecurityContext. -type RunAsGroupStrategy string - -const ( - // RunAsGroupStrategyMayRunAs means that container does not need to run with a particular gid. - // However, when RunAsGroup are specified, they have to fall in the defined range. - RunAsGroupStrategyMayRunAs RunAsGroupStrategy = "MayRunAs" - // RunAsGroupStrategyMustRunAs means that container must run as a particular gid. - RunAsGroupStrategyMustRunAs RunAsGroupStrategy = "MustRunAs" - // RunAsGroupStrategyRunAsAny means that container may make requests for any gid. - RunAsGroupStrategyRunAsAny RunAsGroupStrategy = "RunAsAny" -) - -// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. -type FSGroupStrategyOptions struct { - // Rule is the strategy that will dictate what FSGroup is used in the SecurityContext. - // +optional - Rule FSGroupStrategyType - // Ranges are the allowed ranges of fs groups. If you would like to force a single - // fs group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange -} - -// FSGroupStrategyType denotes strategy types for generating FSGroup values for a -// SecurityContext -type FSGroupStrategyType string - -const ( - // FSGroupStrategyMayRunAs means that container does not need to have FSGroup of X applied. - // However, when FSGroups are specified, they have to fall in the defined range. - FSGroupStrategyMayRunAs FSGroupStrategyType = "MayRunAs" - // FSGroupStrategyMustRunAs means that container must have FSGroup of X applied. - FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" - // FSGroupStrategyRunAsAny means that container may make requests for any FSGroup labels. - FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" -) - -// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. -type SupplementalGroupsStrategyOptions struct { - // Rule is the strategy that will dictate what supplemental groups is used in the SecurityContext. - // +optional - Rule SupplementalGroupsStrategyType - // Ranges are the allowed ranges of supplemental groups. If you would like to force a single - // supplemental group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange -} - -// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental -// groups for a SecurityContext. -type SupplementalGroupsStrategyType string - -const ( - // SupplementalGroupsStrategyMayRunAs means that container does not need to run with a particular gid. - // However, when gids are specified, they have to fall in the defined range. - SupplementalGroupsStrategyMayRunAs SupplementalGroupsStrategyType = "MayRunAs" - // SupplementalGroupsStrategyMustRunAs means that container must run as a particular gid. - SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" - // SupplementalGroupsStrategyRunAsAny means that container may make requests for any gid. - SupplementalGroupsStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" -) - -// RuntimeClassStrategyOptions define the strategy that will dictate the allowable RuntimeClasses -// for a pod. -type RuntimeClassStrategyOptions struct { - // allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod. - // A value of "*" means that any RuntimeClass name is allowed, and must be the only item in the - // list. An empty list requires the RuntimeClassName field to be unset. - AllowedRuntimeClassNames []string - // defaultRuntimeClassName is the default RuntimeClassName to set on the pod. - // The default MUST be allowed by the allowedRuntimeClassNames list. - // A value of nil does not mutate the Pod. - // +optional - DefaultRuntimeClassName *string -} - -// AllowAllRuntimeClassNames can be used as a value for the -// RuntimeClassStrategyOptions.allowedRuntimeClassNames field and means that any runtimeClassName is -// allowed. -const AllowAllRuntimeClassNames = "*" - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// PodSecurityPolicyList is a list of PodSecurityPolicy objects. -type PodSecurityPolicyList struct { - metav1.TypeMeta - // +optional - metav1.ListMeta - - Items []PodSecurityPolicy -} diff --git a/vendor/k8s.io/kubernetes/pkg/apis/policy/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/apis/policy/zz_generated.deepcopy.go deleted file mode 100644 index 972599147..000000000 --- a/vendor/k8s.io/kubernetes/pkg/apis/policy/zz_generated.deepcopy.go +++ /dev/null @@ -1,548 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright 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. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package policy - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - intstr "k8s.io/apimachinery/pkg/util/intstr" - core "k8s.io/kubernetes/pkg/apis/core" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedCSIDriver) DeepCopyInto(out *AllowedCSIDriver) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedCSIDriver. -func (in *AllowedCSIDriver) DeepCopy() *AllowedCSIDriver { - if in == nil { - return nil - } - out := new(AllowedCSIDriver) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedFlexVolume) DeepCopyInto(out *AllowedFlexVolume) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedFlexVolume. -func (in *AllowedFlexVolume) DeepCopy() *AllowedFlexVolume { - if in == nil { - return nil - } - out := new(AllowedFlexVolume) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedHostPath) DeepCopyInto(out *AllowedHostPath) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedHostPath. -func (in *AllowedHostPath) DeepCopy() *AllowedHostPath { - if in == nil { - return nil - } - out := new(AllowedHostPath) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Eviction) DeepCopyInto(out *Eviction) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - if in.DeleteOptions != nil { - in, out := &in.DeleteOptions, &out.DeleteOptions - *out = new(v1.DeleteOptions) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Eviction. -func (in *Eviction) DeepCopy() *Eviction { - if in == nil { - return nil - } - out := new(Eviction) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Eviction) 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 *FSGroupStrategyOptions) DeepCopyInto(out *FSGroupStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FSGroupStrategyOptions. -func (in *FSGroupStrategyOptions) DeepCopy() *FSGroupStrategyOptions { - if in == nil { - return nil - } - out := new(FSGroupStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *HostPortRange) DeepCopyInto(out *HostPortRange) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPortRange. -func (in *HostPortRange) DeepCopy() *HostPortRange { - if in == nil { - return nil - } - out := new(HostPortRange) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IDRange) DeepCopyInto(out *IDRange) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IDRange. -func (in *IDRange) DeepCopy() *IDRange { - if in == nil { - return nil - } - out := new(IDRange) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodDisruptionBudget) DeepCopyInto(out *PodDisruptionBudget) { - *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 PodDisruptionBudget. -func (in *PodDisruptionBudget) DeepCopy() *PodDisruptionBudget { - if in == nil { - return nil - } - out := new(PodDisruptionBudget) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodDisruptionBudget) 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 *PodDisruptionBudgetList) DeepCopyInto(out *PodDisruptionBudgetList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PodDisruptionBudget, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodDisruptionBudgetList. -func (in *PodDisruptionBudgetList) DeepCopy() *PodDisruptionBudgetList { - if in == nil { - return nil - } - out := new(PodDisruptionBudgetList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodDisruptionBudgetList) 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 *PodDisruptionBudgetSpec) DeepCopyInto(out *PodDisruptionBudgetSpec) { - *out = *in - if in.MinAvailable != nil { - in, out := &in.MinAvailable, &out.MinAvailable - *out = new(intstr.IntOrString) - **out = **in - } - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(v1.LabelSelector) - (*in).DeepCopyInto(*out) - } - if in.MaxUnavailable != nil { - in, out := &in.MaxUnavailable, &out.MaxUnavailable - *out = new(intstr.IntOrString) - **out = **in - } - if in.UnhealthyPodEvictionPolicy != nil { - in, out := &in.UnhealthyPodEvictionPolicy, &out.UnhealthyPodEvictionPolicy - *out = new(UnhealthyPodEvictionPolicyType) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodDisruptionBudgetSpec. -func (in *PodDisruptionBudgetSpec) DeepCopy() *PodDisruptionBudgetSpec { - if in == nil { - return nil - } - out := new(PodDisruptionBudgetSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodDisruptionBudgetStatus) DeepCopyInto(out *PodDisruptionBudgetStatus) { - *out = *in - if in.DisruptedPods != nil { - in, out := &in.DisruptedPods, &out.DisruptedPods - *out = make(map[string]v1.Time, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.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 PodDisruptionBudgetStatus. -func (in *PodDisruptionBudgetStatus) DeepCopy() *PodDisruptionBudgetStatus { - if in == nil { - return nil - } - out := new(PodDisruptionBudgetStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodSecurityPolicy) DeepCopyInto(out *PodSecurityPolicy) { - *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 PodSecurityPolicy. -func (in *PodSecurityPolicy) DeepCopy() *PodSecurityPolicy { - if in == nil { - return nil - } - out := new(PodSecurityPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodSecurityPolicy) 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 *PodSecurityPolicyList) DeepCopyInto(out *PodSecurityPolicyList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PodSecurityPolicy, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityPolicyList. -func (in *PodSecurityPolicyList) DeepCopy() *PodSecurityPolicyList { - if in == nil { - return nil - } - out := new(PodSecurityPolicyList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodSecurityPolicyList) 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 *PodSecurityPolicySpec) DeepCopyInto(out *PodSecurityPolicySpec) { - *out = *in - if in.DefaultAddCapabilities != nil { - in, out := &in.DefaultAddCapabilities, &out.DefaultAddCapabilities - *out = make([]core.Capability, len(*in)) - copy(*out, *in) - } - if in.RequiredDropCapabilities != nil { - in, out := &in.RequiredDropCapabilities, &out.RequiredDropCapabilities - *out = make([]core.Capability, len(*in)) - copy(*out, *in) - } - if in.AllowedCapabilities != nil { - in, out := &in.AllowedCapabilities, &out.AllowedCapabilities - *out = make([]core.Capability, len(*in)) - copy(*out, *in) - } - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make([]FSType, len(*in)) - copy(*out, *in) - } - if in.HostPorts != nil { - in, out := &in.HostPorts, &out.HostPorts - *out = make([]HostPortRange, len(*in)) - copy(*out, *in) - } - in.SELinux.DeepCopyInto(&out.SELinux) - in.RunAsUser.DeepCopyInto(&out.RunAsUser) - if in.RunAsGroup != nil { - in, out := &in.RunAsGroup, &out.RunAsGroup - *out = new(RunAsGroupStrategyOptions) - (*in).DeepCopyInto(*out) - } - in.SupplementalGroups.DeepCopyInto(&out.SupplementalGroups) - in.FSGroup.DeepCopyInto(&out.FSGroup) - if in.DefaultAllowPrivilegeEscalation != nil { - in, out := &in.DefaultAllowPrivilegeEscalation, &out.DefaultAllowPrivilegeEscalation - *out = new(bool) - **out = **in - } - if in.AllowedHostPaths != nil { - in, out := &in.AllowedHostPaths, &out.AllowedHostPaths - *out = make([]AllowedHostPath, len(*in)) - copy(*out, *in) - } - if in.AllowedFlexVolumes != nil { - in, out := &in.AllowedFlexVolumes, &out.AllowedFlexVolumes - *out = make([]AllowedFlexVolume, len(*in)) - copy(*out, *in) - } - if in.AllowedCSIDrivers != nil { - in, out := &in.AllowedCSIDrivers, &out.AllowedCSIDrivers - *out = make([]AllowedCSIDriver, len(*in)) - copy(*out, *in) - } - if in.AllowedUnsafeSysctls != nil { - in, out := &in.AllowedUnsafeSysctls, &out.AllowedUnsafeSysctls - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ForbiddenSysctls != nil { - in, out := &in.ForbiddenSysctls, &out.ForbiddenSysctls - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.AllowedProcMountTypes != nil { - in, out := &in.AllowedProcMountTypes, &out.AllowedProcMountTypes - *out = make([]core.ProcMountType, len(*in)) - copy(*out, *in) - } - if in.RuntimeClass != nil { - in, out := &in.RuntimeClass, &out.RuntimeClass - *out = new(RuntimeClassStrategyOptions) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityPolicySpec. -func (in *PodSecurityPolicySpec) DeepCopy() *PodSecurityPolicySpec { - if in == nil { - return nil - } - out := new(PodSecurityPolicySpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RunAsGroupStrategyOptions) DeepCopyInto(out *RunAsGroupStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunAsGroupStrategyOptions. -func (in *RunAsGroupStrategyOptions) DeepCopy() *RunAsGroupStrategyOptions { - if in == nil { - return nil - } - out := new(RunAsGroupStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RunAsUserStrategyOptions) DeepCopyInto(out *RunAsUserStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunAsUserStrategyOptions. -func (in *RunAsUserStrategyOptions) DeepCopy() *RunAsUserStrategyOptions { - if in == nil { - return nil - } - out := new(RunAsUserStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RuntimeClassStrategyOptions) DeepCopyInto(out *RuntimeClassStrategyOptions) { - *out = *in - if in.AllowedRuntimeClassNames != nil { - in, out := &in.AllowedRuntimeClassNames, &out.AllowedRuntimeClassNames - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.DefaultRuntimeClassName != nil { - in, out := &in.DefaultRuntimeClassName, &out.DefaultRuntimeClassName - *out = new(string) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeClassStrategyOptions. -func (in *RuntimeClassStrategyOptions) DeepCopy() *RuntimeClassStrategyOptions { - if in == nil { - return nil - } - out := new(RuntimeClassStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SELinuxStrategyOptions) DeepCopyInto(out *SELinuxStrategyOptions) { - *out = *in - if in.SELinuxOptions != nil { - in, out := &in.SELinuxOptions, &out.SELinuxOptions - *out = new(core.SELinuxOptions) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SELinuxStrategyOptions. -func (in *SELinuxStrategyOptions) DeepCopy() *SELinuxStrategyOptions { - if in == nil { - return nil - } - out := new(SELinuxStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SupplementalGroupsStrategyOptions) DeepCopyInto(out *SupplementalGroupsStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SupplementalGroupsStrategyOptions. -func (in *SupplementalGroupsStrategyOptions) DeepCopy() *SupplementalGroupsStrategyOptions { - if in == nil { - return nil - } - out := new(SupplementalGroupsStrategyOptions) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/kubernetes/pkg/client/conditions/conditions.go b/vendor/k8s.io/kubernetes/pkg/client/conditions/conditions.go index 162551195..4a1a39bba 100644 --- a/vendor/k8s.io/kubernetes/pkg/client/conditions/conditions.go +++ b/vendor/k8s.io/kubernetes/pkg/client/conditions/conditions.go @@ -64,17 +64,3 @@ func PodCompleted(event watch.Event) (bool, error) { } return false, nil } - -// ServiceAccountHasSecrets returns true if the service account has at least one secret, -// false if it does not, or an error. -func ServiceAccountHasSecrets(event watch.Event) (bool, error) { - switch event.Type { - case watch.Deleted: - return false, errors.NewNotFound(schema.GroupResource{Resource: "serviceaccounts"}, "") - } - switch t := event.Object.(type) { - case *v1.ServiceAccount: - return len(t.Secrets) > 0, nil - } - return false, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/cluster/ports/ports.go b/vendor/k8s.io/kubernetes/pkg/cluster/ports/ports.go index 10ded2ad7..01f9f2dbd 100644 --- a/vendor/k8s.io/kubernetes/pkg/cluster/ports/ports.go +++ b/vendor/k8s.io/kubernetes/pkg/cluster/ports/ports.go @@ -16,6 +16,10 @@ limitations under the License. package ports +import ( + cpoptions "k8s.io/cloud-provider/options" +) + // In this file, we can see all default port of cluster. // It's also an important documentation for us. So don't remove them easily. const ( @@ -43,4 +47,8 @@ const ( // CloudControllerManagerPort is the default port for the cloud controller manager server. // This value may be overridden by a flag at startup. CloudControllerManagerPort = 10258 + // CloudControllerManagerWebhookPort is the default port for the cloud + // controller manager webhook server. May be overridden by a flag at + // startup. + CloudControllerManagerWebhookPort = cpoptions.CloudControllerManagerWebhookPort ) diff --git a/vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go b/vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go index 0b3a397f8..740c98d32 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go @@ -143,9 +143,8 @@ type PodControllerRefManager struct { // If CanAdopt() returns a non-nil error, all adoptions will fail. // // NOTE: Once CanAdopt() is called, it will not be called again by the same -// -// PodControllerRefManager instance. Create a new instance if it makes -// sense to check CanAdopt() again (e.g. in a different sync pass). +// PodControllerRefManager instance. Create a new instance if it makes +// sense to check CanAdopt() again (e.g. in a different sync pass). func NewPodControllerRefManager( podControl PodControlInterface, controller metav1.Object, @@ -284,9 +283,8 @@ type ReplicaSetControllerRefManager struct { // If CanAdopt() returns a non-nil error, all adoptions will fail. // // NOTE: Once CanAdopt() is called, it will not be called again by the same -// -// ReplicaSetControllerRefManager instance. Create a new instance if it -// makes sense to check CanAdopt() again (e.g. in a different sync pass). +// ReplicaSetControllerRefManager instance. Create a new instance if it +// makes sense to check CanAdopt() again (e.g. in a different sync pass). func NewReplicaSetControllerRefManager( rsControl RSControlInterface, controller metav1.Object, @@ -423,9 +421,8 @@ type ControllerRevisionControllerRefManager struct { // If canAdopt() returns a non-nil error, all adoptions will fail. // // NOTE: Once canAdopt() is called, it will not be called again by the same -// -// ControllerRevisionControllerRefManager instance. Create a new instance if it -// makes sense to check canAdopt() again (e.g. in a different sync pass). +// ControllerRevisionControllerRefManager instance. Create a new instance if it +// makes sense to check canAdopt() again (e.g. in a different sync pass). func NewControllerRevisionControllerRefManager( crControl ControllerRevisionControlInterface, controller metav1.Object, diff --git a/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go b/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go index 5c897da43..2f4bc44be 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go @@ -1039,12 +1039,12 @@ func AddOrUpdateTaintOnNode(ctx context.Context, c clientset.Interface, nodeName var oldNode *v1.Node // First we try getting node from the API server cache, as it's cheaper. If it fails // we get it from etcd to be sure to have fresh data. + option := metav1.GetOptions{} if firstTry { - oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{ResourceVersion: "0"}) + option.ResourceVersion = "0" firstTry = false - } else { - oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) } + oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, option) if err != nil { return err } @@ -1096,12 +1096,12 @@ func RemoveTaintOffNode(ctx context.Context, c clientset.Interface, nodeName str var oldNode *v1.Node // First we try getting node from the API server cache, as it's cheaper. If it fails // we get it from etcd to be sure to have fresh data. + option := metav1.GetOptions{} if firstTry { - oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{ResourceVersion: "0"}) + option.ResourceVersion = "0" firstTry = false - } else { - oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) } + oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, option) if err != nil { return err } @@ -1178,12 +1178,12 @@ func AddOrUpdateLabelsOnNode(kubeClient clientset.Interface, nodeName string, la var node *v1.Node // First we try getting node from the API server cache, as it's cheaper. If it fails // we get it from etcd to be sure to have fresh data. + option := metav1.GetOptions{} if firstTry { - node, err = kubeClient.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{ResourceVersion: "0"}) + option.ResourceVersion = "0" firstTry = false - } else { - node, err = kubeClient.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) } + node, err = kubeClient.CoreV1().Nodes().Get(context.TODO(), nodeName, option) if err != nil { return err } diff --git a/vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go b/vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go index cb2fac363..347c284cc 100644 --- a/vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go +++ b/vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go @@ -189,7 +189,7 @@ func MaxRevision(allRSs []*apps.ReplicaSet) int64 { for _, rs := range allRSs { if v, err := Revision(rs); err != nil { // Skip the replica sets when it failed to parse their revision information - klog.V(4).Infof("Error: %v. Couldn't parse revision for replica set %#v, deployment controller will skip it when reconciling revisions.", err, rs) + klog.V(4).Info("Couldn't parse revision for replica set, deployment controller will skip it when reconciling revisions", "replicaSet", klog.KObj(rs), "err", err) } else if v > max { max = v } @@ -203,7 +203,7 @@ func LastRevision(allRSs []*apps.ReplicaSet) int64 { for _, rs := range allRSs { if v, err := Revision(rs); err != nil { // Skip the replica sets when it failed to parse their revision information - klog.V(4).Infof("Error: %v. Couldn't parse revision for replica set %#v, deployment controller will skip it when reconciling revisions.", err, rs) + klog.V(4).Info("Couldn't parse revision for replica set, deployment controller will skip it when reconciling revisions", "replicaSet", klog.KObj(rs), "err", err) } else if v >= max { secMax = max max = v @@ -229,7 +229,8 @@ func Revision(obj runtime.Object) (int64, error) { // SetNewReplicaSetAnnotations sets new replica set's annotations appropriately by updating its revision and // copying required deployment annotations to it; it returns true if replica set's annotation is changed. -func SetNewReplicaSetAnnotations(deployment *apps.Deployment, newRS *apps.ReplicaSet, newRevision string, exists bool, revHistoryLimitInChars int) bool { +func SetNewReplicaSetAnnotations(ctx context.Context, deployment *apps.Deployment, newRS *apps.ReplicaSet, newRevision string, exists bool, revHistoryLimitInChars int) bool { + logger := klog.FromContext(ctx) // First, copy deployment's annotations (except for apply and revision annotations) annotationChanged := copyDeploymentAnnotationsToReplicaSet(deployment, newRS) // Then, update replica set's revision annotation @@ -244,7 +245,7 @@ func SetNewReplicaSetAnnotations(deployment *apps.Deployment, newRS *apps.Replic oldRevisionInt, err := strconv.ParseInt(oldRevision, 10, 64) if err != nil { if oldRevision != "" { - klog.Warningf("Updating replica set revision OldRevision not int %s", err) + logger.Info("Updating replica set revision OldRevision not int", "err", err) return false } //If the RS annotation is empty then initialise it to 0 @@ -252,13 +253,13 @@ func SetNewReplicaSetAnnotations(deployment *apps.Deployment, newRS *apps.Replic } newRevisionInt, err := strconv.ParseInt(newRevision, 10, 64) if err != nil { - klog.Warningf("Updating replica set revision NewRevision not int %s", err) + logger.Info("Updating replica set revision NewRevision not int", "err", err) return false } if oldRevisionInt < newRevisionInt { newRS.Annotations[RevisionAnnotation] = newRevision annotationChanged = true - klog.V(4).Infof("Updating replica set %q revision to %s", newRS.Name, newRevision) + logger.V(4).Info("Updating replica set revision", "replicaSet", klog.KObj(newRS), "newRevision", newRevision) } // If a revision annotation already existed and this replica set was updated with a new revision // then that means we are rolling back to this replica set. We need to preserve the old revisions @@ -280,7 +281,7 @@ func SetNewReplicaSetAnnotations(deployment *apps.Deployment, newRS *apps.Replic oldRevisions = append(oldRevisions[start:], oldRevision) newRS.Annotations[RevisionHistoryAnnotation] = strings.Join(oldRevisions, ",") } else { - klog.Warningf("Not appending revision due to length limit of %v reached", revHistoryLimitInChars) + logger.Info("Not appending revision due to revision history length limit reached", "revisionHistoryLimit", revHistoryLimitInChars) } } } @@ -303,7 +304,7 @@ var annotationsToSkip = map[string]bool{ // skipCopyAnnotation returns true if we should skip copying the annotation with the given annotation key // TODO: How to decide which annotations should / should not be copied? // -// See https://github.com/kubernetes/kubernetes/pull/20035#issuecomment-179558615 +// See https://github.com/kubernetes/kubernetes/pull/20035#issuecomment-179558615 func skipCopyAnnotation(key string) bool { return annotationsToSkip[key] } @@ -376,22 +377,22 @@ func FindActiveOrLatest(newRS *apps.ReplicaSet, oldRSs []*apps.ReplicaSet) *apps } // GetDesiredReplicasAnnotation returns the number of desired replicas -func GetDesiredReplicasAnnotation(rs *apps.ReplicaSet) (int32, bool) { - return getIntFromAnnotation(rs, DesiredReplicasAnnotation) +func GetDesiredReplicasAnnotation(logger klog.Logger, rs *apps.ReplicaSet) (int32, bool) { + return getIntFromAnnotation(logger, rs, DesiredReplicasAnnotation) } -func getMaxReplicasAnnotation(rs *apps.ReplicaSet) (int32, bool) { - return getIntFromAnnotation(rs, MaxReplicasAnnotation) +func getMaxReplicasAnnotation(logger klog.Logger, rs *apps.ReplicaSet) (int32, bool) { + return getIntFromAnnotation(logger, rs, MaxReplicasAnnotation) } -func getIntFromAnnotation(rs *apps.ReplicaSet, annotationKey string) (int32, bool) { +func getIntFromAnnotation(logger klog.Logger, rs *apps.ReplicaSet, annotationKey string) (int32, bool) { annotationValue, ok := rs.Annotations[annotationKey] if !ok { return int32(0), false } intValue, err := strconv.Atoi(annotationValue) if err != nil { - klog.V(2).Infof("Cannot convert the value %q with annotation key %q for the replica set %q", annotationValue, annotationKey, rs.Name) + logger.V(2).Info("Could not convert the value with annotation key for the replica set", "annotationValue", annotationValue, "annotationKey", annotationKey, "replicaSet", klog.KObj(rs)) return int32(0), false } return int32(intValue), true @@ -466,12 +467,12 @@ func MaxSurge(deployment apps.Deployment) int32 { // GetProportion will estimate the proportion for the provided replica set using 1. the current size // of the parent deployment, 2. the replica count that needs be added on the replica sets of the // deployment, and 3. the total replicas added in the replica sets of the deployment so far. -func GetProportion(rs *apps.ReplicaSet, d apps.Deployment, deploymentReplicasToAdd, deploymentReplicasAdded int32) int32 { +func GetProportion(logger klog.Logger, rs *apps.ReplicaSet, d apps.Deployment, deploymentReplicasToAdd, deploymentReplicasAdded int32) int32 { if rs == nil || *(rs.Spec.Replicas) == 0 || deploymentReplicasToAdd == 0 || deploymentReplicasToAdd == deploymentReplicasAdded { return int32(0) } - rsFraction := getReplicaSetFraction(*rs, d) + rsFraction := getReplicaSetFraction(logger, *rs, d) allowed := deploymentReplicasToAdd - deploymentReplicasAdded if deploymentReplicasToAdd > 0 { @@ -488,14 +489,14 @@ func GetProportion(rs *apps.ReplicaSet, d apps.Deployment, deploymentReplicasToA // getReplicaSetFraction estimates the fraction of replicas a replica set can have in // 1. a scaling event during a rollout or 2. when scaling a paused deployment. -func getReplicaSetFraction(rs apps.ReplicaSet, d apps.Deployment) int32 { +func getReplicaSetFraction(logger klog.Logger, rs apps.ReplicaSet, d apps.Deployment) int32 { // If we are scaling down to zero then the fraction of this replica set is its whole size (negative) if *(d.Spec.Replicas) == int32(0) { return -*(rs.Spec.Replicas) } deploymentReplicas := *(d.Spec.Replicas) + MaxSurge(d) - annotatedReplicas, ok := getMaxReplicasAnnotation(&rs) + annotatedReplicas, ok := getMaxReplicasAnnotation(logger, &rs) if !ok { // If we cannot find the annotation then fallback to the current deployment size. Note that this // will not be an accurate proportion estimation in case other replica sets have different values @@ -734,7 +735,7 @@ var nowFn = func() time.Time { return time.Now() } // DeploymentTimedOut considers a deployment to have timed out once its condition that reports progress // is older than progressDeadlineSeconds or a Progressing condition with a TimedOutReason reason already // exists. -func DeploymentTimedOut(deployment *apps.Deployment, newStatus *apps.DeploymentStatus) bool { +func DeploymentTimedOut(ctx context.Context, deployment *apps.Deployment, newStatus *apps.DeploymentStatus) bool { if !HasProgressDeadline(deployment) { return false } @@ -763,7 +764,7 @@ func DeploymentTimedOut(deployment *apps.Deployment, newStatus *apps.DeploymentS if condition.Reason == TimedOutReason { return true } - + logger := klog.FromContext(ctx) // Look at the difference in seconds between now and the last time we reported any // progress or tried to create a replica set, or resumed a paused deployment and // compare against progressDeadlineSeconds. @@ -772,7 +773,7 @@ func DeploymentTimedOut(deployment *apps.Deployment, newStatus *apps.DeploymentS delta := time.Duration(*deployment.Spec.ProgressDeadlineSeconds) * time.Second timedOut := from.Add(delta).Before(now) - klog.V(4).Infof("Deployment %q timed out (%t) [last progress check: %v - now: %v]", deployment.Name, timedOut, from, now) + logger.V(4).Info("Deployment timed out from last progress check", "deployment", klog.KObj(deployment), "timeout", timedOut, "from", from, "now", now) return timedOut } diff --git a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go index 8847b8309..bf641bfa8 100644 --- a/vendor/k8s.io/kubernetes/pkg/features/kube_features.go +++ b/vendor/k8s.io/kubernetes/pkg/features/kube_features.go @@ -52,6 +52,7 @@ const ( // owner: @nabokihms // alpha: v1.26 + // beta: v1.27 // // Enables API to get self subject attributes after authentication. APISelfSubjectReview featuregate.Feature = "APISelfSubjectReview" @@ -60,6 +61,18 @@ const ( // beta: v1.4 AppArmor featuregate.Feature = "AppArmor" + // owner: @danwinship + // alpha: v1.27 + // + // Enables dual-stack --node-ip in kubelet with external cloud providers + CloudDualStackNodeIPs featuregate.Feature = "CloudDualStackNodeIPs" + + // owner: @ahmedtd + // alpha: v1.26 + // + // Enable ClusterTrustBundle objects and Kubelet integration. + ClusterTrustBundle featuregate.Feature = "ClusterTrustBundle" + // owner: @szuecs // alpha: v1.12 // @@ -108,37 +121,6 @@ const ( // Allow the usage of options to fine-tune the cpumanager policies. CPUManagerPolicyOptions featuregate.Feature = "CPUManagerPolicyOptions" - // owner: @pohly - // alpha: v1.14 - // beta: v1.16 - // GA: v1.25 - // - // Enables CSI Inline volumes support for pods - CSIInlineVolume featuregate.Feature = "CSIInlineVolume" - - // owner: @davidz627 - // alpha: v1.14 - // beta: v1.17 - // - // Enables the in-tree storage to CSI Plugin migration feature. - CSIMigration featuregate.Feature = "CSIMigration" - - // owner: @leakingtapan - // alpha: v1.14 - // beta: v1.17 - // GA: v1.25 - // - // Enables the AWS EBS in-tree driver to AWS EBS CSI Driver migration feature. - CSIMigrationAWS featuregate.Feature = "CSIMigrationAWS" - - // owner: @andyzhangx - // alpha: v1.15 - // beta: v1.19 - // GA: v1.24 - // - // Enables the Azure Disk in-tree driver to Azure Disk Driver migration feature. - CSIMigrationAzureDisk featuregate.Feature = "CSIMigrationAzureDisk" - // owner: @andyzhangx // alpha: v1.15 // beta: v1.21 @@ -176,6 +158,7 @@ const ( // owner: @humblec, @zhucan // kep: https://kep.k8s.io/3171 // alpha: v1.25 + // beta: v1.27 // // Enables SecretRef field in CSI NodeExpandVolume request. CSINodeExpandSecret featuregate.Feature = "CSINodeExpandSecret" @@ -194,6 +177,12 @@ const ( // Enables kubelet to detect CSI volume condition and send the event of the abnormal volume to the corresponding pod that is using it. CSIVolumeHealth featuregate.Feature = "CSIVolumeHealth" + // owner: @nckturner + // kep: http://kep.k8s.io/2699 + // alpha: v1.27 + // Enable webhooks in cloud controller manager + CloudControllerManagerWebhook featuregate.Feature = "CloudControllerManagerWebhook" + // owner: @adrianreber // kep: https://kep.k8s.io/2008 // alpha: v1.25 @@ -207,29 +196,15 @@ const ( // Normalize HttpGet URL and Header passing for lifecycle handlers with probers. ConsistentHTTPGetHandlers featuregate.Feature = "ConsistentHTTPGetHandlers" - // owner: @jiahuif - // alpha: v1.21 - // beta: v1.22 - // GA: v1.24 - // - // Enables Leader Migration for kube-controller-manager and cloud-controller-manager - ControllerManagerLeaderMigration featuregate.Feature = "ControllerManagerLeaderMigration" - // owner: @deejross, @soltysh // kep: https://kep.k8s.io/3140 // alpha: v1.24 // beta: v1.25 + // GA: 1.27 // // Enables support for time zones in CronJobs. CronJobTimeZone featuregate.Feature = "CronJobTimeZone" - // owner: @smarterclayton - // alpha: v1.21 - // beta: v1.22 - // GA: v1.25 - // DaemonSets allow workloads to maintain availability during update per node - DaemonSetUpdateSurge featuregate.Feature = "DaemonSetUpdateSurge" - // owner: @gnufied, @verult, @bertinatto // alpha: v1.22 // beta: v1.23 @@ -270,6 +245,7 @@ const ( // owner: @derekwaynecarr // alpha: v1.20 // beta: v1.21 (off by default until 1.22) + // ga: v1.27 // // Enables usage of hugepages- in downward API. DownwardAPIHugePages featuregate.Feature = "DownwardAPIHugePages" @@ -291,17 +267,10 @@ const ( // Enable Terminating condition in Endpoint Slices. EndpointSliceTerminatingCondition featuregate.Feature = "EndpointSliceTerminatingCondition" - // owner: @verb - // alpha: v1.16 - // beta: v1.23 - // GA: v1.25 - // - // Allows running an ephemeral container in pod namespaces to troubleshoot a running pod. - EphemeralContainers featuregate.Feature = "EphemeralContainers" - // owner: @harche // kep: http://kep.k8s.io/3386 // alpha: v1.25 + // beta: v1.27 // // Allows using event-driven PLEG (pod lifecycle event generator) through kubelet // which avoids frequent relisting of containers which helps optimize performance. @@ -315,25 +284,6 @@ const ( // Lock to default and remove after v1.22 based on user feedback that should be reflected in KEP #1972 update ExecProbeTimeout featuregate.Feature = "ExecProbeTimeout" - // owner: @gnufied - // alpha: v1.14 - // beta: v1.16 - // GA: 1.24 - // Ability to expand CSI volumes - ExpandCSIVolumes featuregate.Feature = "ExpandCSIVolumes" - - // owner: @mlmhl @gnufied - // beta: v1.15 - // GA: 1.24 - // Ability to expand persistent volumes' file system without unmounting volumes. - ExpandInUsePersistentVolumes featuregate.Feature = "ExpandInUsePersistentVolumes" - - // owner: @gnufied - // beta: v1.11 - // GA: 1.24 - // Ability to Expand persistent volumes - ExpandPersistentVolumes featuregate.Feature = "ExpandPersistentVolumes" - // owner: @gjkim42 // kep: https://kep.k8s.io/2595 // alpha: v1.22 @@ -354,6 +304,7 @@ const ( // kep: https://kep.k8s.io/2727 // alpha: v1.23 // beta: v1.24 + // stable: v1.27 // // Enables GRPC probe method for {Liveness,Readiness,Startup}Probe. GRPCContainerProbe featuregate.Feature = "GRPCContainerProbe" @@ -370,8 +321,10 @@ const ( // Make the kubelet use shutdown configuration based on pod priority values for graceful shutdown. GracefulNodeShutdownBasedOnPodPriority featuregate.Feature = "GracefulNodeShutdownBasedOnPodPriority" - // owner: @arjunrn @mwielgus @josephburnett + // owner: @arjunrn @mwielgus @josephburnett @sanposhiho + // kep: https://kep.k8s.io/1610 // alpha: v1.20 + // beta: v1.27 // // Add support for the HPA to scale based on metrics from individual containers // in target pods @@ -391,14 +344,6 @@ const ( // deletion ordering. HonorPVReclaimPolicy featuregate.Feature = "HonorPVReclaimPolicy" - // owner: @ravig - // alpha: v1.23 - // beta: v1.24 - // GA: v1.25 - // IdentifyPodOS allows user to specify OS on which they'd like the Pod run. The user should still set the nodeSelector - // with appropriate `kubernetes.io/os` label for scheduler to identify appropriate node for the pod to run. - IdentifyPodOS featuregate.Feature = "IdentifyPodOS" - // owner: @leakingtapan // alpha: v1.21 // @@ -450,6 +395,7 @@ const ( // owner: @danwinship // kep: https://kep.k8s.io/3178 // alpha: v1.25 + // beta: v1.27 // // Causes kubelet to no longer create legacy IPTables rules IPTablesOwnershipCleanup featuregate.Feature = "IPTablesOwnershipCleanup" @@ -465,6 +411,7 @@ const ( // owner: @ahg // beta: v1.23 + // stable: v1.27 // // Allow updating node scheduling directives in the pod template of jobs. Specifically, // node affinity, selector and tolerations. This is allowed only for suspended jobs @@ -512,6 +459,18 @@ const ( // Enables the kubelet's pod resources grpc endpoint KubeletPodResources featuregate.Feature = "KubeletPodResources" + // owner: @moshe010 + // alpha: v1.27 + // + // Enable POD resources API to return resources allocated by Dynamic Resource Allocation + KubeletPodResourcesDynamicResources featuregate.Feature = "KubeletPodResourcesDynamicResources" + + // owner: @moshe010 + // alpha: v1.27 + // + // Enable POD resources API with Get method + KubeletPodResourcesGet featuregate.Feature = "KubeletPodResourcesGet" + // owner: @fromanirh // alpha: v1.21 // beta: v1.23 @@ -521,6 +480,7 @@ const ( // owner: @sallyom // kep: https://kep.k8s.io/2832 // alpha: v1.25 + // beta: v1.27 // // Add support for distributed tracing in the kubelet KubeletTracing featuregate.Feature = "KubeletTracing" @@ -528,24 +488,19 @@ const ( // owner: @zshihang // kep: https://kep.k8s.io/2800 // beta: v1.24 + // ga: v1.26 // // Stop auto-generation of secret-based service account tokens. LegacyServiceAccountTokenNoAutoGeneration featuregate.Feature = "LegacyServiceAccountTokenNoAutoGeneration" // owner: @zshihang // kep: http://kep.k8s.io/2800 - // alpha: v1.25 + // alpha: v1.26 + // beta: v1.27 // // Enables tracking of secret-based service account tokens usage. LegacyServiceAccountTokenTracking featuregate.Feature = "LegacyServiceAccountTokenTracking" - // owner: @jinxu - // beta: v1.10 - // stable: v1.25 - // - // Support local ephemeral storage types for local storage capacity isolation feature. - LocalStorageCapacityIsolation featuregate.Feature = "LocalStorageCapacityIsolation" - // owner: @RobertKrawitz // alpha: v1.15 // @@ -563,6 +518,7 @@ const ( // owner: @denkensk // kep: https://kep.k8s.io/3243 // alpha: v1.25 + // beta: v1.27 // // Enable MatchLabelKeys in PodTopologySpread. MatchLabelKeysInPodTopologySpread featuregate.Feature = "MatchLabelKeysInPodTopologySpread" @@ -597,6 +553,7 @@ const ( // owner: @danwinship // kep: http://kep.k8s.io/3453 // alpha: v1.26 + // beta: v1.27 // // Enables new performance-improving code in kube-proxy iptables mode MinimizeIPTablesRestore featuregate.Feature = "MinimizeIPTablesRestore" @@ -617,14 +574,12 @@ const ( // Enables the MultiCIDR Range allocator. MultiCIDRRangeAllocator featuregate.Feature = "MultiCIDRRangeAllocator" - // owner: @rikatz - // kep: https://kep.k8s.io/2079 - // alpha: v1.21 - // beta: v1.22 - // ga: v1.25 + // owner: @aojea + // kep: https://kep.k8s.io/1880 + // alpha: v1.27 // - // Enables the endPort field in NetworkPolicy to enable a Port Range behavior in Network Policies. - NetworkPolicyEndPort featuregate.Feature = "NetworkPolicyEndPort" + // Enables the dynamic configuration of Service IP ranges + MultiCIDRServiceAllocator featuregate.Feature = "MultiCIDRServiceAllocator" // owner: @rikatz // kep: https://kep.k8s.io/2943 @@ -633,6 +588,20 @@ const ( // Enables NetworkPolicy status subresource NetworkPolicyStatus featuregate.Feature = "NetworkPolicyStatus" + // owner: @jsafrane + // kep: https://kep.k8s.io/3756 + // alpha: v1.25 (as part of SELinuxMountReadWriteOncePod) + // beta: v1.27 + // Robust VolumeManager reconstruction after kubelet restart. + NewVolumeManagerReconstruction featuregate.Feature = "NewVolumeManagerReconstruction" + + // owner: @aravindhp @LorbusChris + // kep: http://kep.k8s.io/2271 + // alpha: v1.27 + // + // Enables querying logs of node services using the /logs endpoint + NodeLogQuery featuregate.Feature = "NodeLogQuery" + // owner: @xing-yang @sonasingh46 // kep: https://kep.k8s.io/2268 // alpha: v1.24 @@ -650,6 +619,7 @@ const ( // owner: @mortent, @atiratree, @ravig // kep: http://kep.k8s.io/3018 // alpha: v1.26 + // beta: v1.27 // // Enables PDBUnhealthyPodEvictionPolicy for PodDisruptionBudgets PDBUnhealthyPodEvictionPolicy featuregate.Feature = "PDBUnhealthyPodEvictionPolicy" @@ -688,6 +658,7 @@ const ( // owner: @Huang-Wei // kep: https://kep.k8s.io/3521 // alpha: v1.26 + // beta: v1.27 // // Enable users to specify when a Pod is ready for scheduling. PodSchedulingReadiness featuregate.Feature = "PodSchedulingReadiness" @@ -729,7 +700,9 @@ const ( QOSReserved featuregate.Feature = "QOSReserved" // owner: @chrishenzie + // kep: https://kep.k8s.io/2485 // alpha: v1.22 + // beta: v1.27 // // Enables usage of the ReadWriteOncePod PersistentVolume access mode. ReadWriteOncePod featuregate.Feature = "ReadWriteOncePod" @@ -757,14 +730,32 @@ const ( // certificate as expiration approaches. RotateKubeletServerCertificate featuregate.Feature = "RotateKubeletServerCertificate" + // owner: @danielvegamyhre + // kep: https://kep.k8s.io/2413 + // beta: v1.27 + // + // Allows mutating spec.completions for Indexed job when done in tandem with + // spec.parallelism. Specifically, spec.completions is mutable iff spec.completions + // equals to spec.parallelism before and after the update. + ElasticIndexedJob featuregate.Feature = "ElasticIndexedJob" + // owner: @saschagrunert // kep: https://kep.k8s.io/2413 // alpha: v1.22 // beta: v1.25 + // ga: v1.27 // // Enables the use of `RuntimeDefault` as the default seccomp profile for all workloads. SeccompDefault featuregate.Feature = "SeccompDefault" + // owner: @mtardy + // alpha: v1.0 + // + // Putting this admission plugin behind a feature gate is part of the + // deprecation process. For details about the removal see: + // https://github.com/kubernetes/kubernetes/issues/111516 + SecurityContextDeny featuregate.Feature = "SecurityContextDeny" + // owner: @maplain @andrewsykim // kep: https://kep.k8s.io/2086 // alpha: v1.21 @@ -783,6 +774,13 @@ const ( // Subdivide the ClusterIP range for dynamic and static IP allocation. ServiceIPStaticSubrange featuregate.Feature = "ServiceIPStaticSubrange" + // owner: @xuzhenglun + // kep: http://kep.k8s.io/3682 + // alpha: v1.27 + // + // Subdivide the NodePort range for dynamic and static port allocation. + ServiceNodePortStaticSubrange featuregate.Feature = "ServiceNodePortStaticSubrange" + // owner: @derekwaynecarr // alpha: v1.20 // beta: v1.22 @@ -790,22 +788,24 @@ const ( // Enables kubelet support to size memory backed volumes SizeMemoryBackedVolumes featuregate.Feature = "SizeMemoryBackedVolumes" + // owner: @alexanderConstantinescu + // kep: http://kep.k8s.io/3458 + // beta: v1.27 + // + // Enables less load balancer re-configurations by the service controller + // (KCCM) as an effect of changing node state. + StableLoadBalancerNodeSet featuregate.Feature = "StableLoadBalancerNodeSet" + // owner: @mattcary // alpha: v1.22 + // beta: v1.27 // // Enables policies controlling deletion of PVCs created by a StatefulSet. StatefulSetAutoDeletePVC featuregate.Feature = "StatefulSetAutoDeletePVC" - // owner: @ravig - // kep: https://kep.k8s.io/2607 - // alpha: v1.22 - // beta: v1.23 - // GA: v1.25 - // StatefulSetMinReadySeconds allows minReadySeconds to be respected by StatefulSet controller - StatefulSetMinReadySeconds featuregate.Feature = "StatefulSetMinReadySeconds" - // owner: @psch // alpha: v1.26 + // beta: v1.27 // // Enables a StatefulSet to start from an arbitrary non zero ordinal StatefulSetStartOrdinal featuregate.Feature = "StatefulSetStartOrdinal" @@ -818,9 +818,10 @@ const ( // Enables topology aware hints for EndpointSlices TopologyAwareHints featuregate.Feature = "TopologyAwareHints" - // owner: @lmdaly + // owner: @lmdaly, @swatisehgal (for GA graduation) // alpha: v1.16 // beta: v1.18 + // GA: v1.27 // // Enable resource managers to make NUMA aligned decisions TopologyManager featuregate.Feature = "TopologyManager" @@ -904,10 +905,18 @@ const ( // owner: @jsafrane // kep: https://kep.k8s.io/1710 // alpha: v1.25 + // beta: v1.27 // Speed up container startup by mounting volumes with the correct SELinux label // instead of changing each file on the volumes recursively. // Initial implementation focused on ReadWriteOncePod volumes. SELinuxMountReadWriteOncePod featuregate.Feature = "SELinuxMountReadWriteOncePod" + + // owner: @vinaykul + // kep: http://kep.k8s.io/1287 + // alpha: v1.27 + // + // Enables In-Place Pod Vertical Scaling + InPlacePodVerticalScaling featuregate.Feature = "InPlacePodVerticalScaling" ) func init() { @@ -925,10 +934,14 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS AnyVolumeDataSource: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.24 - APISelfSubjectReview: {Default: false, PreRelease: featuregate.Alpha}, + APISelfSubjectReview: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.27 AppArmor: {Default: true, PreRelease: featuregate.Beta}, + CloudDualStackNodeIPs: {Default: false, PreRelease: featuregate.Alpha}, + + ClusterTrustBundle: {Default: false, PreRelease: featuregate.Alpha}, + CPUCFSQuotaPeriod: {Default: false, PreRelease: featuregate.Alpha}, CPUManager: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.26 @@ -939,15 +952,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS CPUManagerPolicyOptions: {Default: true, PreRelease: featuregate.Beta}, - CSIInlineVolume: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 - - CSIMigration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 - - CSIMigrationAWS: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 - - CSIMigrationAzureDisk: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26 - - CSIMigrationAzureFile: {Default: true, PreRelease: featuregate.GA}, // remove in 1.28 + CSIMigrationAzureFile: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 CSIMigrationGCE: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 @@ -955,23 +960,21 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS CSIMigrationRBD: {Default: false, PreRelease: featuregate.Alpha}, // Off by default (requires RBD CSI driver) - CSIMigrationvSphere: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 + CSIMigrationvSphere: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 - CSINodeExpandSecret: {Default: false, PreRelease: featuregate.Alpha}, + CSINodeExpandSecret: {Default: true, PreRelease: featuregate.Beta}, CSIStorageCapacity: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26 CSIVolumeHealth: {Default: false, PreRelease: featuregate.Alpha}, + CloudControllerManagerWebhook: {Default: false, PreRelease: featuregate.Alpha}, + ContainerCheckpoint: {Default: false, PreRelease: featuregate.Alpha}, ConsistentHTTPGetHandlers: {Default: true, PreRelease: featuregate.GA}, - ControllerManagerLeaderMigration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26 - - CronJobTimeZone: {Default: true, PreRelease: featuregate.Beta}, - - DaemonSetUpdateSurge: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 + CronJobTimeZone: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 DelegateFSGroupToCSIDriver: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 @@ -983,40 +986,30 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS DisableKubeletCloudCredentialProviders: {Default: false, PreRelease: featuregate.Alpha}, - DownwardAPIHugePages: {Default: true, PreRelease: featuregate.Beta}, // on by default in 1.22 + DownwardAPIHugePages: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in v1.29 EndpointSliceTerminatingCondition: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in v1.28 DynamicResourceAllocation: {Default: false, PreRelease: featuregate.Alpha}, - EphemeralContainers: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 - - EventedPLEG: {Default: false, PreRelease: featuregate.Alpha}, + EventedPLEG: {Default: false, PreRelease: featuregate.Beta}, // off by default, requires CRI Runtime support ExecProbeTimeout: {Default: true, PreRelease: featuregate.GA}, // lock to default and remove after v1.22 based on KEP #1972 update - ExpandCSIVolumes: {Default: true, PreRelease: featuregate.GA}, // remove in 1.26 - - ExpandInUsePersistentVolumes: {Default: true, PreRelease: featuregate.GA}, // remove in 1.26 - - ExpandPersistentVolumes: {Default: true, PreRelease: featuregate.GA}, // remove in 1.26 - ExpandedDNSConfig: {Default: true, PreRelease: featuregate.Beta}, ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: featuregate.Beta}, - GRPCContainerProbe: {Default: true, PreRelease: featuregate.Beta}, + GRPCContainerProbe: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, //remove in 1.29 GracefulNodeShutdown: {Default: true, PreRelease: featuregate.Beta}, GracefulNodeShutdownBasedOnPodPriority: {Default: true, PreRelease: featuregate.Beta}, - HPAContainerMetrics: {Default: false, PreRelease: featuregate.Alpha}, + HPAContainerMetrics: {Default: true, PreRelease: featuregate.Beta}, HonorPVReclaimPolicy: {Default: false, PreRelease: featuregate.Alpha}, - IdentifyPodOS: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 - InTreePluginAWSUnregister: {Default: false, PreRelease: featuregate.Alpha}, InTreePluginAzureDiskUnregister: {Default: false, PreRelease: featuregate.Alpha}, @@ -1033,11 +1026,11 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS InTreePluginvSphereUnregister: {Default: false, PreRelease: featuregate.Alpha}, - IPTablesOwnershipCleanup: {Default: false, PreRelease: featuregate.Alpha}, + IPTablesOwnershipCleanup: {Default: true, PreRelease: featuregate.Beta}, JobPodFailurePolicy: {Default: true, PreRelease: featuregate.Beta}, - JobMutableNodeSchedulingDirectives: {Default: true, PreRelease: featuregate.Beta}, + JobMutableNodeSchedulingDirectives: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 JobReadyPods: {Default: true, PreRelease: featuregate.Beta}, @@ -1049,21 +1042,23 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS KubeletPodResources: {Default: true, PreRelease: featuregate.Beta}, + KubeletPodResourcesDynamicResources: {Default: false, PreRelease: featuregate.Alpha}, + + KubeletPodResourcesGet: {Default: false, PreRelease: featuregate.Alpha}, + KubeletPodResourcesGetAllocatable: {Default: true, PreRelease: featuregate.Beta}, - KubeletTracing: {Default: false, PreRelease: featuregate.Alpha}, + KubeletTracing: {Default: true, PreRelease: featuregate.Beta}, - LegacyServiceAccountTokenNoAutoGeneration: {Default: true, PreRelease: featuregate.GA}, + LegacyServiceAccountTokenNoAutoGeneration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 - LegacyServiceAccountTokenTracking: {Default: false, PreRelease: featuregate.Alpha}, - - LocalStorageCapacityIsolation: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 + LegacyServiceAccountTokenTracking: {Default: true, PreRelease: featuregate.Beta}, LocalStorageCapacityIsolationFSQuotaMonitoring: {Default: false, PreRelease: featuregate.Alpha}, LogarithmicScaleDown: {Default: true, PreRelease: featuregate.Beta}, - MatchLabelKeysInPodTopologySpread: {Default: false, PreRelease: featuregate.Alpha}, + MatchLabelKeysInPodTopologySpread: {Default: true, PreRelease: featuregate.Beta}, MaxUnavailableStatefulSet: {Default: false, PreRelease: featuregate.Alpha}, @@ -1071,23 +1066,27 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS MemoryQoS: {Default: false, PreRelease: featuregate.Alpha}, - MinDomainsInPodTopologySpread: {Default: false, PreRelease: featuregate.Beta}, + MinDomainsInPodTopologySpread: {Default: true, PreRelease: featuregate.Beta}, - MinimizeIPTablesRestore: {Default: false, PreRelease: featuregate.Alpha}, + MinimizeIPTablesRestore: {Default: true, PreRelease: featuregate.Beta}, MixedProtocolLBService: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 MultiCIDRRangeAllocator: {Default: false, PreRelease: featuregate.Alpha}, - NetworkPolicyEndPort: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 + MultiCIDRServiceAllocator: {Default: false, PreRelease: featuregate.Alpha}, NetworkPolicyStatus: {Default: false, PreRelease: featuregate.Alpha}, + NewVolumeManagerReconstruction: {Default: false, PreRelease: featuregate.Beta}, // disabled for https://github.com/kubernetes/kubernetes/issues/117745 + + NodeLogQuery: {Default: false, PreRelease: featuregate.Alpha}, + NodeOutOfServiceVolumeDetach: {Default: true, PreRelease: featuregate.Beta}, NodeSwap: {Default: false, PreRelease: featuregate.Alpha}, - PDBUnhealthyPodEvictionPolicy: {Default: false, PreRelease: featuregate.Alpha}, + PDBUnhealthyPodEvictionPolicy: {Default: true, PreRelease: featuregate.Beta}, PodAndContainerStatsFromCRI: {Default: false, PreRelease: featuregate.Alpha}, @@ -1097,7 +1096,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS PodHasNetworkCondition: {Default: false, PreRelease: featuregate.Alpha}, - PodSchedulingReadiness: {Default: false, PreRelease: featuregate.Alpha}, + PodSchedulingReadiness: {Default: true, PreRelease: featuregate.Beta}, PodSecurity: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, @@ -1109,7 +1108,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS QOSReserved: {Default: false, PreRelease: featuregate.Alpha}, - ReadWriteOncePod: {Default: false, PreRelease: featuregate.Alpha}, + ReadWriteOncePod: {Default: true, PreRelease: featuregate.Beta}, RecoverVolumeExpansionFailure: {Default: false, PreRelease: featuregate.Alpha}, @@ -1117,23 +1116,29 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS RotateKubeletServerCertificate: {Default: true, PreRelease: featuregate.Beta}, - SeccompDefault: {Default: true, PreRelease: featuregate.Beta}, + ElasticIndexedJob: {Default: true, PreRelease: featuregate.Beta}, + + SeccompDefault: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 + + SecurityContextDeny: {Default: false, PreRelease: featuregate.Alpha}, ServiceIPStaticSubrange: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 ServiceInternalTrafficPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 + ServiceNodePortStaticSubrange: {Default: false, PreRelease: featuregate.Alpha}, + SizeMemoryBackedVolumes: {Default: true, PreRelease: featuregate.Beta}, - StatefulSetAutoDeletePVC: {Default: false, PreRelease: featuregate.Alpha}, + StableLoadBalancerNodeSet: {Default: true, PreRelease: featuregate.Beta}, - StatefulSetMinReadySeconds: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27 + StatefulSetAutoDeletePVC: {Default: true, PreRelease: featuregate.Beta}, - StatefulSetStartOrdinal: {Default: false, PreRelease: featuregate.Alpha}, + StatefulSetStartOrdinal: {Default: true, PreRelease: featuregate.Beta}, TopologyAwareHints: {Default: true, PreRelease: featuregate.Beta}, - TopologyManager: {Default: true, PreRelease: featuregate.Beta}, + TopologyManager: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA in 1.27; remove in 1.29 TopologyManagerPolicyAlphaOptions: {Default: false, PreRelease: featuregate.Alpha}, @@ -1155,12 +1160,16 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS NodeInclusionPolicyInPodTopologySpread: {Default: true, PreRelease: featuregate.Beta}, - SELinuxMountReadWriteOncePod: {Default: false, PreRelease: featuregate.Alpha}, + SELinuxMountReadWriteOncePod: {Default: false, PreRelease: featuregate.Beta}, // disabled for https://github.com/kubernetes/kubernetes/issues/117745 + + InPlacePodVerticalScaling: {Default: false, PreRelease: featuregate.Alpha}, // inherited features from generic apiserver, relisted here to get a conflict if it is changed // unintentionally on either side: - genericfeatures.AggregatedDiscoveryEndpoint: {Default: false, PreRelease: featuregate.Alpha}, + genericfeatures.AdmissionWebhookMatchConditions: {Default: false, PreRelease: featuregate.Alpha}, + + genericfeatures.AggregatedDiscoveryEndpoint: {Default: true, PreRelease: featuregate.Beta}, genericfeatures.APIListChunking: {Default: true, PreRelease: featuregate.Beta}, @@ -1168,7 +1177,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS genericfeatures.APIResponseCompression: {Default: true, PreRelease: featuregate.Beta}, - genericfeatures.AdvancedAuditing: {Default: true, PreRelease: featuregate.GA}, + genericfeatures.AdvancedAuditing: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 genericfeatures.ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Alpha}, @@ -1178,11 +1187,11 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS genericfeatures.OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta}, - genericfeatures.OpenAPIV3: {Default: true, PreRelease: featuregate.Beta}, + genericfeatures.OpenAPIV3: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 genericfeatures.ServerSideApply: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 - genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta}, + genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 // features that enable backwards compatibility but are scheduled to be removed // ... diff --git a/vendor/k8s.io/kubernetes/pkg/fieldpath/fieldpath.go b/vendor/k8s.io/kubernetes/pkg/fieldpath/fieldpath.go index 20fa8eaaa..f8466d403 100644 --- a/vendor/k8s.io/kubernetes/pkg/fieldpath/fieldpath.go +++ b/vendor/k8s.io/kubernetes/pkg/fieldpath/fieldpath.go @@ -18,26 +18,36 @@ package fieldpath import ( "fmt" + "sort" + "strconv" "strings" "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" ) // FormatMap formats map[string]string to a string. func FormatMap(m map[string]string) (fmtStr string) { // output with keys in sorted order to provide stable output - keys := sets.NewString() - for key := range m { - keys.Insert(key) + keys := make([]string, 0, len(m)) + var grow int + for k, v := range m { + keys = append(keys, k) + // why add 4: (for =, \n, " and ") + grow += len(k) + len(v) + 4 } - for _, key := range keys.List() { - fmtStr += fmt.Sprintf("%v=%q\n", key, m[key]) + sort.Strings(keys) + // allocate space to avoid expansion + dst := make([]byte, 0, grow) + for _, key := range keys { + if len(dst) > 0 { + dst = append(dst, '\n') + } + dst = append(dst, key...) + dst = append(dst, '=') + dst = strconv.AppendQuote(dst, m[key]) } - fmtStr = strings.TrimSuffix(fmtStr, "\n") - - return + return string(dst) } // ExtractFieldPathAsString extracts the field from the given object diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go index 04432b9fc..91e3b9ba5 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go @@ -159,7 +159,7 @@ type KubeletConfiguration struct { // enableDebuggingHandlers enables server endpoints for log collection // and local running of containers and commands EnableDebuggingHandlers bool - // enableContentionProfiling enables lock contention profiling, if enableDebuggingHandlers is true. + // enableContentionProfiling enables block profiling, if enableDebuggingHandlers is true. EnableContentionProfiling bool // healthzPort is the port of the localhost healthz endpoint (set to 0 to disable) HealthzPort int32 @@ -233,11 +233,9 @@ type KubeletConfiguration struct { // Requires the MemoryManager feature gate to be enabled. MemoryManagerPolicy string // TopologyManagerPolicy is the name of the policy to use. - // Policies other than "none" require the TopologyManager feature gate to be enabled. TopologyManagerPolicy string // TopologyManagerScope represents the scope of topology hint generation // that topology manager requests and hint providers generate. - // "pod" scope requires the TopologyManager feature gate to be enabled. // Default: "container" // +optional TopologyManagerScope string @@ -292,6 +290,8 @@ type KubeletConfiguration struct { KubeAPIBurst int32 // serializeImagePulls when enabled, tells the Kubelet to pull images one at a time. SerializeImagePulls bool + // MaxParallelImagePulls sets the maximum number of image pulls in parallel. + MaxParallelImagePulls *int32 // Map of signal names to quantities that defines hard eviction thresholds. For example: {"memory.available": "300Mi"}. // Some default signals are Linux only: nodefs.inodesFree EvictionHard map[string]string @@ -369,14 +369,14 @@ type KubeletConfiguration struct { // See http://kubernetes.io/docs/user-guide/compute-resources for more detail. KubeReserved map[string]string // This flag helps kubelet identify absolute name of top level cgroup used to enforce `SystemReserved` compute resource reservation for OS system daemons. - // Refer to [Node Allocatable](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md) doc for more information. + // Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information. SystemReservedCgroup string // This flag helps kubelet identify absolute name of top level cgroup used to enforce `KubeReserved` compute resource reservation for Kubernetes node system daemons. - // Refer to [Node Allocatable](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md) doc for more information. + // Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information. KubeReservedCgroup string // This flag specifies the various Node Allocatable enforcements that Kubelet needs to perform. // This flag accepts a list of options. Acceptable options are `pods`, `system-reserved` & `kube-reserved`. - // Refer to [Node Allocatable](https://github.com/kubernetes/design-proposals-archive/blob/main/node/node-allocatable.md) doc for more information. + // Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information. EnforceNodeAllocatable []string // This option specifies the cpu list reserved for the host level system threads and kubernetes related threads. // This provide a "static" CPU list rather than the "dynamic" list by system-reserved and kube-reserved. @@ -393,6 +393,11 @@ type KubeletConfiguration struct { Logging logsapi.LoggingConfiguration // EnableSystemLogHandler enables /logs handler. EnableSystemLogHandler bool + // EnableSystemLogQuery enables the node log query feature on the /logs endpoint. + // EnableSystemLogHandler has to be enabled in addition for this feature to work. + // +featureGate=NodeLogQuery + // +optional + EnableSystemLogQuery bool // ShutdownGracePeriod specifies the total duration that the node should delay the shutdown and total grace period for pod termination during a node shutdown. // Defaults to 0 seconds. // +featureGate=GracefulNodeShutdown @@ -438,7 +443,7 @@ type KubeletConfiguration struct { // Decreasing this factor will set lower high limit for container cgroups and put heavier reclaim pressure // while increasing will put less reclaim pressure. // See https://kep.k8s.io/2570 for more details. - // Default: 0.8 + // Default: 0.9 // +featureGate=MemoryQoS // +optional MemoryThrottlingFactor *float64 @@ -450,6 +455,7 @@ type KubeletConfiguration struct { // registerNode enables automatic registration with the apiserver. // +optional RegisterNode bool + // Tracing specifies the versioned configuration for OpenTelemetry tracing clients. // See https://kep.k8s.io/2832 for more details. // +featureGate=KubeletTracing @@ -465,6 +471,16 @@ type KubeletConfiguration struct { // disabled. Once disabled, user should not set request/limit for container's ephemeral storage, or sizeLimit for emptyDir. // +optional LocalStorageCapacityIsolation bool + + // ContainerRuntimeEndpoint is the endpoint of container runtime. + // unix domain sockets supported on Linux while npipes and tcp endpoints are supported for windows. + // Examples:'unix:///path/to/runtime.sock', 'npipe:////./pipe/runtime' + ContainerRuntimeEndpoint string + + // ImageServiceEndpoint is the endpoint of container image service. + // If not specified the default value is ContainerRuntimeEndpoint + // +optional + ImageServiceEndpoint string } // KubeletAuthorizationMode denotes the authorization mode for the kubelet diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go index 9436182f3..a4af47e4a 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go @@ -227,6 +227,11 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) { } out.RuntimeRequestTimeout = in.RuntimeRequestTimeout out.CPUCFSQuotaPeriod = in.CPUCFSQuotaPeriod + if in.MaxParallelImagePulls != nil { + in, out := &in.MaxParallelImagePulls, &out.MaxParallelImagePulls + *out = new(int32) + **out = **in + } if in.EvictionHard != nil { in, out := &in.EvictionHard, &out.EvictionHard *out = make(map[string]string, len(*in)) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go index 734a4ffd9..65fc8cf54 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go @@ -18,7 +18,6 @@ package format import ( "fmt" - "time" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -40,16 +39,3 @@ func PodDesc(podName, podNamespace string, podUID types.UID) string { // (DNS subdomain format), while allowed in the container name format. return fmt.Sprintf("%s_%s(%s)", podName, podNamespace, podUID) } - -// PodWithDeletionTimestamp is the same as Pod. In addition, it prints the -// deletion timestamp of the pod if it's not nil. -func PodWithDeletionTimestamp(pod *v1.Pod) string { - if pod == nil { - return "" - } - var deletionTimestamp string - if pod.DeletionTimestamp != nil { - deletionTimestamp = ":DeletionTimestamp=" + pod.DeletionTimestamp.UTC().Format(time.RFC3339) - } - return Pod(pod) + deletionTimestamp -} diff --git a/vendor/k8s.io/kubernetes/pkg/proxy/util/nodeport_addresses.go b/vendor/k8s.io/kubernetes/pkg/proxy/util/nodeport_addresses.go new file mode 100644 index 000000000..aebe5f071 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/proxy/util/nodeport_addresses.go @@ -0,0 +1,127 @@ +/* +Copyright 2022 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 util + +import ( + "fmt" + "net" + + "k8s.io/apimachinery/pkg/util/sets" + netutils "k8s.io/utils/net" +) + +// NodePortAddresses is used to handle the --nodeport-addresses flag +type NodePortAddresses struct { + cidrStrings []string + + cidrs []*net.IPNet + containsIPv4Loopback bool +} + +// RFC 5735 127.0.0.0/8 - This block is assigned for use as the Internet host loopback address +var ipv4LoopbackStart = net.IPv4(127, 0, 0, 0) + +// NewNodePortAddresses takes the `--nodeport-addresses` value (which is assumed to +// contain only valid CIDRs) and returns a NodePortAddresses object. If cidrStrings is +// empty, this is treated as `["0.0.0.0/0", "::/0"]`. +func NewNodePortAddresses(cidrStrings []string) *NodePortAddresses { + if len(cidrStrings) == 0 { + cidrStrings = []string{IPv4ZeroCIDR, IPv6ZeroCIDR} + } + + npa := &NodePortAddresses{ + cidrStrings: cidrStrings, + } + + for _, str := range npa.cidrStrings { + _, cidr, _ := netutils.ParseCIDRSloppy(str) + npa.cidrs = append(npa.cidrs, cidr) + + if netutils.IsIPv4CIDR(cidr) { + if cidr.IP.IsLoopback() || cidr.Contains(ipv4LoopbackStart) { + npa.containsIPv4Loopback = true + } + } + } + + return npa +} + +func (npa *NodePortAddresses) String() string { + return fmt.Sprintf("%v", npa.cidrStrings) +} + +// GetNodeAddresses return all matched node IP addresses for npa's CIDRs. +// If npa's CIDRs include "0.0.0.0/0" and/or "::/0", then those values will be returned +// verbatim in the response and no actual IPs of that family will be returned. +// If no matching IPs are found, GetNodeAddresses will return an error. +// NetworkInterfacer is injected for test purpose. +func (npa *NodePortAddresses) GetNodeAddresses(nw NetworkInterfacer) (sets.String, error) { + uniqueAddressList := sets.NewString() + + // First round of iteration to pick out `0.0.0.0/0` or `::/0` for the sake of excluding non-zero IPs. + for _, cidr := range npa.cidrStrings { + if IsZeroCIDR(cidr) { + uniqueAddressList.Insert(cidr) + } + } + + addrs, err := nw.InterfaceAddrs() + if err != nil { + return nil, fmt.Errorf("error listing all interfaceAddrs from host, error: %v", err) + } + + // Second round of iteration to parse IPs based on cidr. + for _, cidr := range npa.cidrs { + if IsZeroCIDR(cidr.String()) { + continue + } + + for _, addr := range addrs { + var ip net.IP + // nw.InterfaceAddrs may return net.IPAddr or net.IPNet on windows, and it will return net.IPNet on linux. + switch v := addr.(type) { + case *net.IPAddr: + ip = v.IP + case *net.IPNet: + ip = v.IP + default: + continue + } + + if cidr.Contains(ip) { + if netutils.IsIPv6(ip) && !uniqueAddressList.Has(IPv6ZeroCIDR) { + uniqueAddressList.Insert(ip.String()) + } + if !netutils.IsIPv6(ip) && !uniqueAddressList.Has(IPv4ZeroCIDR) { + uniqueAddressList.Insert(ip.String()) + } + } + } + } + + if uniqueAddressList.Len() == 0 { + return nil, fmt.Errorf("no addresses found for cidrs %v", npa.cidrStrings) + } + + return uniqueAddressList, nil +} + +// ContainsIPv4Loopback returns true if npa's CIDRs contain an IPv4 loopback address. +func (npa *NodePortAddresses) ContainsIPv4Loopback() bool { + return npa.containsIPv4Loopback +} diff --git a/vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go b/vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go index 92ef46580..319daf27b 100644 --- a/vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go +++ b/vendor/k8s.io/kubernetes/pkg/proxy/util/utils.go @@ -78,37 +78,6 @@ func BuildPortsToEndpointsMap(endpoints *v1.Endpoints) map[string][]string { return portsToEndpoints } -// ContainsIPv4Loopback returns true if the input is empty or one of the CIDR contains an IPv4 loopback address. -func ContainsIPv4Loopback(cidrStrings []string) bool { - if len(cidrStrings) == 0 { - return true - } - // RFC 5735 127.0.0.0/8 - This block is assigned for use as the Internet host loopback address - ipv4LoopbackStart := netutils.ParseIPSloppy("127.0.0.0") - for _, cidr := range cidrStrings { - if IsZeroCIDR(cidr) { - return true - } - - ip, ipnet, err := netutils.ParseCIDRSloppy(cidr) - if err != nil { - continue - } - - if netutils.IsIPv6CIDR(ipnet) { - continue - } - - if ip.IsLoopback() { - return true - } - if ipnet.Contains(ipv4LoopbackStart) { - return true - } - } - return false -} - // IsZeroCIDR checks whether the input CIDR string is either // the IPv4 or IPv6 zero CIDR func IsZeroCIDR(cidr string) bool { @@ -228,74 +197,10 @@ func ShouldSkipService(service *v1.Service) bool { return false } -// GetNodeAddresses return all matched node IP addresses based on given cidr slice. -// Some callers, e.g. IPVS proxier, need concrete IPs, not ranges, which is why this exists. -// NetworkInterfacer is injected for test purpose. -// We expect the cidrs passed in is already validated. -// Given an empty input `[]`, it will return `0.0.0.0/0` and `::/0` directly. -// If multiple cidrs is given, it will return the minimal IP sets, e.g. given input `[1.2.0.0/16, 0.0.0.0/0]`, it will -// only return `0.0.0.0/0`. -// NOTE: GetNodeAddresses only accepts CIDRs, if you want concrete IPs, e.g. 1.2.3.4, then the input should be 1.2.3.4/32. -func GetNodeAddresses(cidrs []string, nw NetworkInterfacer) (sets.String, error) { - uniqueAddressList := sets.NewString() - if len(cidrs) == 0 { - uniqueAddressList.Insert(IPv4ZeroCIDR) - uniqueAddressList.Insert(IPv6ZeroCIDR) - return uniqueAddressList, nil - } - // First round of iteration to pick out `0.0.0.0/0` or `::/0` for the sake of excluding non-zero IPs. - for _, cidr := range cidrs { - if IsZeroCIDR(cidr) { - uniqueAddressList.Insert(cidr) - } - } - - addrs, err := nw.InterfaceAddrs() - if err != nil { - return nil, fmt.Errorf("error listing all interfaceAddrs from host, error: %v", err) - } - - // Second round of iteration to parse IPs based on cidr. - for _, cidr := range cidrs { - if IsZeroCIDR(cidr) { - continue - } - - _, ipNet, _ := netutils.ParseCIDRSloppy(cidr) - for _, addr := range addrs { - var ip net.IP - // nw.InterfaceAddrs may return net.IPAddr or net.IPNet on windows, and it will return net.IPNet on linux. - switch v := addr.(type) { - case *net.IPAddr: - ip = v.IP - case *net.IPNet: - ip = v.IP - default: - continue - } - - if ipNet.Contains(ip) { - if netutils.IsIPv6(ip) && !uniqueAddressList.Has(IPv6ZeroCIDR) { - uniqueAddressList.Insert(ip.String()) - } - if !netutils.IsIPv6(ip) && !uniqueAddressList.Has(IPv4ZeroCIDR) { - uniqueAddressList.Insert(ip.String()) - } - } - } - } - - if uniqueAddressList.Len() == 0 { - return nil, fmt.Errorf("no addresses found for cidrs %v", cidrs) - } - - return uniqueAddressList, nil -} - // AddressSet validates the addresses in the slice using the "isValid" function. // Addresses that pass the validation are returned as a string Set. -func AddressSet(isValid func(ip net.IP) bool, addrs []net.Addr) sets.String { - ips := sets.NewString() +func AddressSet(isValid func(ip net.IP) bool, addrs []net.Addr) sets.Set[string] { + ips := sets.New[string]() for _, a := range addrs { var ip net.IP switch v := a.(type) { diff --git a/vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go b/vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go index 283181a77..ca787ee54 100644 --- a/vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go +++ b/vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go @@ -31,6 +31,7 @@ type PodSecurityContextAccessor interface { RunAsUser() *int64 RunAsGroup() *int64 RunAsNonRoot() *bool + SeccompProfile() *api.SeccompProfile SupplementalGroups() []int64 FSGroup() *int64 } @@ -46,6 +47,7 @@ type PodSecurityContextMutator interface { SetRunAsUser(*int64) SetRunAsGroup(*int64) SetRunAsNonRoot(*bool) + SetSeccompProfile(*api.SeccompProfile) SetSupplementalGroups([]int64) SetFSGroup(*int64) @@ -171,6 +173,19 @@ func (w *podSecurityContextWrapper) SetRunAsNonRoot(v *bool) { w.ensurePodSC() w.podSC.RunAsNonRoot = v } +func (w *podSecurityContextWrapper) SeccompProfile() *api.SeccompProfile { + if w.podSC == nil { + return nil + } + return w.podSC.SeccompProfile +} +func (w *podSecurityContextWrapper) SetSeccompProfile(p *api.SeccompProfile) { + if w.podSC == nil && p == nil { + return + } + w.ensurePodSC() + w.podSC.SeccompProfile = p +} func (w *podSecurityContextWrapper) SupplementalGroups() []int64 { if w.podSC == nil { return nil @@ -211,6 +226,7 @@ type ContainerSecurityContextAccessor interface { RunAsGroup() *int64 RunAsNonRoot() *bool ReadOnlyRootFilesystem() *bool + SeccompProfile() *api.SeccompProfile AllowPrivilegeEscalation() *bool } @@ -227,6 +243,7 @@ type ContainerSecurityContextMutator interface { SetRunAsGroup(*int64) SetRunAsNonRoot(*bool) SetReadOnlyRootFilesystem(*bool) + SetSeccompProfile(*api.SeccompProfile) SetAllowPrivilegeEscalation(*bool) } @@ -357,6 +374,20 @@ func (w *containerSecurityContextWrapper) SetReadOnlyRootFilesystem(v *bool) { w.ensureContainerSC() w.containerSC.ReadOnlyRootFilesystem = v } +func (w *containerSecurityContextWrapper) SeccompProfile() *api.SeccompProfile { + if w.containerSC == nil { + return nil + } + return w.containerSC.SeccompProfile +} +func (w *containerSecurityContextWrapper) SetSeccompProfile(p *api.SeccompProfile) { + if w.containerSC == nil && p == nil { + return + } + w.ensureContainerSC() + w.containerSC.SeccompProfile = p +} + func (w *containerSecurityContextWrapper) AllowPrivilegeEscalation() *bool { if w.containerSC == nil { return nil @@ -464,6 +495,14 @@ func (w *effectiveContainerSecurityContextWrapper) SetReadOnlyRootFilesystem(v * w.containerSC.SetReadOnlyRootFilesystem(v) } } +func (w *effectiveContainerSecurityContextWrapper) SeccompProfile() *api.SeccompProfile { + return w.containerSC.SeccompProfile() +} +func (w *effectiveContainerSecurityContextWrapper) SetSeccompProfile(p *api.SeccompProfile) { + if !reflect.DeepEqual(w.SeccompProfile(), p) { + w.containerSC.SetSeccompProfile(p) + } +} func (w *effectiveContainerSecurityContextWrapper) AllowPrivilegeEscalation() *bool { return w.containerSC.AllowPrivilegeEscalation() } diff --git a/vendor/k8s.io/kubernetes/pkg/securitycontext/util.go b/vendor/k8s.io/kubernetes/pkg/securitycontext/util.go index 82a2fc5e0..5895df0c7 100644 --- a/vendor/k8s.io/kubernetes/pkg/securitycontext/util.go +++ b/vendor/k8s.io/kubernetes/pkg/securitycontext/util.go @@ -20,30 +20,6 @@ import ( v1 "k8s.io/api/core/v1" ) -// HasPrivilegedRequest returns the value of SecurityContext.Privileged, taking into account -// the possibility of nils -func HasPrivilegedRequest(container *v1.Container) bool { - if container.SecurityContext == nil { - return false - } - if container.SecurityContext.Privileged == nil { - return false - } - return *container.SecurityContext.Privileged -} - -// HasCapabilitiesRequest returns true if Adds or Drops are defined in the security context -// capabilities, taking into account nils -func HasCapabilitiesRequest(container *v1.Container) bool { - if container.SecurityContext == nil { - return false - } - if container.SecurityContext.Capabilities == nil { - return false - } - return len(container.SecurityContext.Capabilities.Add) > 0 || len(container.SecurityContext.Capabilities.Drop) > 0 -} - // HasWindowsHostProcessRequest returns true if container should run as HostProcess container, // taking into account nils func HasWindowsHostProcessRequest(pod *v1.Pod, container *v1.Container) bool { @@ -212,9 +188,10 @@ func AddNoNewPrivileges(sc *v1.SecurityContext) bool { var ( // These *must* be kept in sync with moby/moby. - // https://github.com/moby/moby/blob/master/oci/defaults.go#L116-L134 + // https://github.com/moby/moby/blob/master/oci/defaults.go#L105-L123 // @jessfraz will watch changes to those files upstream. defaultMaskedPaths = []string{ + "/proc/asound", "/proc/acpi", "/proc/kcore", "/proc/keys", @@ -226,7 +203,6 @@ var ( "/sys/firmware", } defaultReadonlyPaths = []string{ - "/proc/asound", "/proc/bus", "/proc/fs", "/proc/irq", diff --git a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go index c0ec12f0c..e56d410a5 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go @@ -213,7 +213,7 @@ type DeletableVolumePlugin interface { // NewDeleter creates a new volume.Deleter which knows how to delete this // resource in accordance with the underlying storage provider after the // volume's release from a claim - NewDeleter(spec *Spec) (Deleter, error) + NewDeleter(logger klog.Logger, spec *Spec) (Deleter, error) } // ProvisionableVolumePlugin is an extended interface of VolumePlugin and is @@ -223,7 +223,7 @@ type ProvisionableVolumePlugin interface { // NewProvisioner creates a new volume.Provisioner which knows how to // create PersistentVolumes in accordance with the plugin's underlying // storage provider - NewProvisioner(options VolumeOptions) (Provisioner, error) + NewProvisioner(logger klog.Logger, options VolumeOptions) (Provisioner, error) } // AttachableVolumePlugin is an extended interface of VolumePlugin and is used for volumes that require attachment @@ -334,13 +334,6 @@ type KubeletVolumeHost interface { WaitForCacheSync() error // Returns hostutil.HostUtils GetHostUtil() hostutil.HostUtils - // GetHostIDsForPod if the pod uses user namespaces, takes the uid and - // gid inside the container and returns the host UID and GID those are - // mapped to on the host. If containerUID/containerGID is nil, then it - // returns the host UID/GID for ID 0 inside the container. - // If the pod is not using user namespaces, as there is no mapping needed, the - // same containerUID and containerGID params are returned. - GetHostIDsForPod(pod *v1.Pod, containerUID, containerGID *int64) (hostUID, hostGID *int64, err error) } // AttachDetachVolumeHost is a AttachDetach Controller specific interface that plugins can use diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go index 94428f6ff..91ee77a9f 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/atomic_writer.go @@ -86,11 +86,16 @@ const ( // Write does an atomic projection of the given payload into the writer's target // directory. Input paths must not begin with '..'. +// setPerms is an optional pointer to a function that caller can provide to set the +// permissions of the newly created files before they are published. The function is +// passed subPath which is the name of the timestamped directory that was created +// under target directory. // // The Write algorithm is: // // 1. The payload is validated; if the payload is invalid, the function returns -// 2.  The current timestamped directory is detected by reading the data directory +// +// 2. The current timestamped directory is detected by reading the data directory // symlink // // 3. The old version of the volume is walked to determine whether any @@ -98,13 +103,19 @@ const ( // // 4. The data in the current timestamped directory is compared to the projected // data to determine if an update is required. -// 5.  A new timestamped dir is created // -// 6. The payload is written to the new timestamped directory -// 7.  A symlink to the new timestamped directory ..data_tmp is created that will -// become the new data directory -// 8.  The new data directory symlink is renamed to the data directory; rename is atomic -// 9.  Symlinks and directory for new user-visible files are created (if needed). +// 5. A new timestamped dir is created. +// +// 6. The payload is written to the new timestamped directory. +// +// 7. Permissions are set (if setPerms is not nil) on the new timestamped directory and files. +// +// 8. A symlink to the new timestamped directory ..data_tmp is created that will +// become the new data directory. +// +// 9. The new data directory symlink is renamed to the data directory; rename is atomic. +// +// 10. Symlinks and directory for new user-visible files are created (if needed). // // For example, consider the files: // /podName @@ -123,9 +134,10 @@ const ( // linking everything else. On Windows, if a target does not exist, the created symlink // will not work properly if the target ends up being a directory. // -// 10. Old paths are removed from the user-visible portion of the target directory -// 11.  The previous timestamped directory is removed, if it exists -func (w *AtomicWriter) Write(payload map[string]FileProjection) error { +// 11. Old paths are removed from the user-visible portion of the target directory. +// +// 12. The previous timestamped directory is removed, if it exists. +func (w *AtomicWriter) Write(payload map[string]FileProjection, setPerms func(subPath string) error) error { // (1) cleanPayload, err := validatePayload(payload) if err != nil { @@ -185,6 +197,14 @@ func (w *AtomicWriter) Write(payload map[string]FileProjection) error { klog.V(4).Infof("%s: performed write of new data to ts data directory: %s", w.logContext, tsDir) // (7) + if setPerms != nil { + if err := setPerms(tsDirName); err != nil { + klog.Errorf("%s: error applying ownership settings: %v", w.logContext, err) + return err + } + } + + // (8) newDataDirPath := filepath.Join(w.targetDir, newDataDirName) if err = os.Symlink(tsDirName, newDataDirPath); err != nil { os.RemoveAll(tsDir) @@ -192,7 +212,7 @@ func (w *AtomicWriter) Write(payload map[string]FileProjection) error { return err } - // (8) + // (9) if runtime.GOOS == "windows" { os.Remove(dataDirPath) err = os.Symlink(tsDirName, dataDirPath) @@ -207,19 +227,19 @@ func (w *AtomicWriter) Write(payload map[string]FileProjection) error { return err } - // (9) + // (10) if err = w.createUserVisibleFiles(cleanPayload); err != nil { klog.Errorf("%s: error creating visible symlinks in %s: %v", w.logContext, w.targetDir, err) return err } - // (10) + // (11) if err = w.removeUserVisiblePaths(pathsToRemove); err != nil { klog.Errorf("%s: error removing old visible symlinks: %v", w.logContext, err) return err } - // (11) + // (12) if len(oldTsDir) > 0 { if err = os.RemoveAll(oldTsPath); err != nil { klog.Errorf("%s: error removing old data directory %s: %v", w.logContext, oldTsDir, err) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common.go new file mode 100644 index 000000000..425944207 --- /dev/null +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common.go @@ -0,0 +1,28 @@ +/* +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 common + +// QuotaID is generic quota identifier. +// Data type based on quotactl(2). +type QuotaID int32 + +const ( + // UnknownQuotaID -- cannot determine whether a quota is in force + UnknownQuotaID QuotaID = -1 + // BadQuotaID -- Invalid quota + BadQuotaID QuotaID = 0 +) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_linux_common.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux.go similarity index 92% rename from vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_linux_common.go rename to vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux.go index 8275a7f1c..77f845837 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_linux_common.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux.go @@ -23,17 +23,6 @@ import ( "regexp" ) -// QuotaID is generic quota identifier. -// Data type based on quotactl(2). -type QuotaID int32 - -const ( - // UnknownQuotaID -- cannot determine whether a quota is in force - UnknownQuotaID QuotaID = -1 - // BadQuotaID -- Invalid quota - BadQuotaID QuotaID = 0 -) - // QuotaType -- type of quota to be applied type QuotaType int diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_linux_common_impl.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux_impl.go similarity index 100% rename from vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_linux_common_impl.go rename to vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/common/quota_common_linux_impl.go diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go index 3861f9905..8ebc00687 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/project.go @@ -164,6 +164,9 @@ func readProjectFiles(projects *os.File, projid *os.File) projectsList { return projectsList{parseProjFile(projects, parseProject), parseProjFile(projid, parseProjid)} } +// findAvailableQuota finds the next available quota from the FirstQuota +// it returns error if QuotaIDIsInUse returns error when getting quota id in use; +// it searches at most maxUnusedQuotasToSearch(128) time func findAvailableQuota(path string, idMap map[common.QuotaID]bool) (common.QuotaID, error) { unusedQuotasSearched := 0 for id := common.FirstQuota; true; id++ { @@ -187,13 +190,13 @@ func addDirToProject(path string, id common.QuotaID, list *projectsList) (common idMap := make(map[common.QuotaID]bool) for _, project := range list.projects { if project.data == path { - if id != project.id { + if id != common.BadQuotaID && id != project.id { return common.BadQuotaID, false, fmt.Errorf("attempt to reassign project ID for %s", path) } // Trying to reassign a directory to the project it's // already in. Maybe this should be an error, but for // now treat it as an idempotent operation - return id, false, nil + return project.id, false, nil } idMap[project.id] = true } @@ -318,6 +321,7 @@ func writeProjectFiles(fProjects *os.File, fProjid *os.File, writeProjid bool, l return fmt.Errorf("unable to write project files: %v", err) } +// if ID is common.BadQuotaID, generate new project id if the dir is not in a project func createProjectID(path string, ID common.QuotaID) (common.QuotaID, error) { quotaIDLock.Lock() defer quotaIDLock.Unlock() diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota.go index fbd29fba7..eb0048d37 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota.go @@ -23,10 +23,15 @@ import ( "k8s.io/apimachinery/pkg/types" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/kubernetes/pkg/features" + "k8s.io/kubernetes/pkg/volume/util/fsquota/common" ) // Interface -- quota interface type Interface interface { + // GetQuotaOnDir gets the quota ID (if any) that applies to + // this directory + GetQuotaOnDir(m mount.Interface, path string) (common.QuotaID, error) + // Does the path provided support quotas, and if so, what types SupportsQuotas(m mount.Interface, path string) (bool, error) // Assign a quota (picked by the quota mechanism) to a path, diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go index 85784204a..240cc356e 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_linux.go @@ -35,6 +35,9 @@ import ( "k8s.io/kubernetes/pkg/volume/util/fsquota/common" ) +// Pod -> External Pod UID +var podUidMap = make(map[types.UID]types.UID) + // Pod -> ID var podQuotaMap = make(map[types.UID]common.QuotaID) @@ -214,7 +217,7 @@ func setQuotaOnDir(path string, id common.QuotaID, bytes int64) error { return getApplier(path).SetQuotaOnDir(path, id, bytes) } -func getQuotaOnDir(m mount.Interface, path string) (common.QuotaID, error) { +func GetQuotaOnDir(m mount.Interface, path string) (common.QuotaID, error) { _, _, err := getFSInfo(m, path) if err != nil { return common.BadQuotaID, err @@ -235,7 +238,7 @@ func clearQuotaOnDir(m mount.Interface, path string) error { if !supportsQuotas { return nil } - projid, err := getQuotaOnDir(m, path) + projid, err := GetQuotaOnDir(m, path) if err == nil && projid != common.BadQuotaID { // This means that we have a quota on the directory but // we can't clear it. That's not good. @@ -304,7 +307,7 @@ func SupportsQuotas(m mount.Interface, path string) (bool, error) { // AssignQuota chooses the quota ID based on the pod UID and path. // If the pod UID is identical to another one known, it may (but presently // doesn't) choose the same quota ID as other volumes in the pod. -func AssignQuota(m mount.Interface, path string, poduid types.UID, bytes *resource.Quantity) error { //nolint:staticcheck // SA4009 poduid is overwritten by design, see comment below +func AssignQuota(m mount.Interface, path string, poduid types.UID, bytes *resource.Quantity) error { //nolint:staticcheck if bytes == nil { return fmt.Errorf("attempting to assign null quota to %s", path) } @@ -314,20 +317,32 @@ func AssignQuota(m mount.Interface, path string, poduid types.UID, bytes *resour } quotaLock.Lock() defer quotaLock.Unlock() - // Current policy is to set individual quotas on each volumes. + // Current policy is to set individual quotas on each volume, + // for each new volume we generate a random UUID and we use that as + // the internal pod uid. + // From fsquota point of view each volume is attached to a + // single unique pod. // If we decide later that we want to assign one quota for all - // volumes in a pod, we can simply remove this line of code. + // volumes in a pod, we can simply use poduid parameter directly // If and when we decide permanently that we're going to adopt // one quota per volume, we can rip all of the pod code out. - poduid = types.UID(uuid.NewUUID()) //nolint:staticcheck // SA4009 poduid is overwritten by design, see comment above - if pod, ok := dirPodMap[path]; ok && pod != poduid { - return fmt.Errorf("requesting quota on existing directory %s but different pod %s %s", path, pod, poduid) + externalPodUid := poduid + internalPodUid, ok := dirPodMap[path] + if ok { + if podUidMap[internalPodUid] != externalPodUid { + return fmt.Errorf("requesting quota on existing directory %s but different pod %s %s", path, podUidMap[internalPodUid], externalPodUid) + } + } else { + internalPodUid = types.UID(uuid.NewUUID()) } - oid, ok := podQuotaMap[poduid] + oid, ok := podQuotaMap[internalPodUid] if ok { if quotaSizeMap[oid] != ibytes { return fmt.Errorf("requesting quota of different size: old %v new %v", quotaSizeMap[oid], bytes) } + if _, ok := dirPodMap[path]; ok { + return nil + } } else { oid = common.BadQuotaID } @@ -342,12 +357,13 @@ func AssignQuota(m mount.Interface, path string, poduid types.UID, bytes *resour ibytes = -1 } if err = setQuotaOnDir(path, id, ibytes); err == nil { - quotaPodMap[id] = poduid + quotaPodMap[id] = internalPodUid quotaSizeMap[id] = ibytes - podQuotaMap[poduid] = id + podQuotaMap[internalPodUid] = id dirQuotaMap[path] = id - dirPodMap[path] = poduid - podDirCountMap[poduid]++ + dirPodMap[path] = internalPodUid + podUidMap[internalPodUid] = externalPodUid + podDirCountMap[internalPodUid]++ klog.V(4).Infof("Assigning quota ID %d (%d) to %s", id, ibytes, path) return nil } @@ -415,7 +431,7 @@ func ClearQuota(m mount.Interface, path string) error { if !ok { return fmt.Errorf("clearQuota: No quota available for %s", path) } - projid, err := getQuotaOnDir(m, path) + projid, err := GetQuotaOnDir(m, path) if err != nil { // Log-and-continue instead of returning an error for now // due to unspecified backwards compatibility concerns (a subject to revise) @@ -436,6 +452,7 @@ func ClearQuota(m mount.Interface, path string) error { delete(quotaPodMap, podQuotaMap[poduid]) delete(podDirCountMap, poduid) delete(podQuotaMap, poduid) + delete(podUidMap, poduid) } else { err = removeProjectID(path, projid) podDirCountMap[poduid]-- diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_unsupported.go index 8579f5389..c5b89a697 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/fsquota/quota_unsupported.go @@ -22,6 +22,7 @@ package fsquota import ( "errors" + "k8s.io/kubernetes/pkg/volume/util/fsquota/common" "k8s.io/mount-utils" "k8s.io/apimachinery/pkg/api/resource" @@ -33,6 +34,10 @@ import ( var errNotImplemented = errors.New("not implemented") +func GetQuotaOnDir(_ mount.Interface, _ string) (common.QuotaID, error) { + return common.BadQuotaID, errNotImplemented +} + // SupportsQuotas -- dummy implementation func SupportsQuotas(_ mount.Interface, _ string) (bool, error) { return false, errNotImplemented diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/fake_hostutil.go b/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/fake_hostutil.go index 0efccb3e3..0660222b4 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/fake_hostutil.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/hostutil/fake_hostutil.go @@ -120,5 +120,6 @@ func (hu *FakeHostUtil) GetMode(pathname string) (os.FileMode, error) { // GetSELinuxMountContext returns value of -o context=XYZ mount option on // given mount point. func (hu *FakeHostUtil) GetSELinuxMountContext(pathname string) (string, error) { - return "", errors.New("not implemented") + // This pretends the OS does not support SELinux. + return "", nil } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go b/vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go index d070f2f29..d6d028b0d 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go @@ -229,23 +229,6 @@ func MarkFSResizeFinished( return updatedPVC, err } -func MarkControllerExpansionFailed(pvc *v1.PersistentVolumeClaim, kubeClient clientset.Interface) (*v1.PersistentVolumeClaim, error) { - expansionFailedOnController := v1.PersistentVolumeClaimControllerExpansionFailed - newPVC := pvc.DeepCopy() - newPVC.Status.ResizeStatus = &expansionFailedOnController - patchBytes, err := createPVCPatch(pvc, newPVC, false /* addResourceVersionCheck */) - if err != nil { - return pvc, fmt.Errorf("patchPVCStatus failed to patch PVC %q: %v", pvc.Name, err) - } - - updatedClaim, updateErr := kubeClient.CoreV1().PersistentVolumeClaims(pvc.Namespace). - Patch(context.TODO(), pvc.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status") - if updateErr != nil { - return pvc, fmt.Errorf("patchPVCStatus failed to patch PVC %q: %v", pvc.Name, updateErr) - } - return updatedClaim, nil -} - // MarkNodeExpansionFailed marks a PVC for node expansion as failed. Kubelet should not retry expansion // of volumes which are in failed state. func MarkNodeExpansionFailed(pvc *v1.PersistentVolumeClaim, kubeClient clientset.Interface) (*v1.PersistentVolumeClaim, error) { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go index f6f5a3f99..bc33f5f2d 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go @@ -576,6 +576,44 @@ func IsLocalEphemeralVolume(volume v1.Volume) bool { volume.ConfigMap != nil } +// GetLocalPersistentVolumeNodeNames returns the node affinity node name(s) for +// local PersistentVolumes. nil is returned if the PV does not have any +// specific node affinity node selector terms and match expressions. +// PersistentVolume with node affinity has select and match expressions +// in the form of: +// +// nodeAffinity: +// required: +// nodeSelectorTerms: +// - matchExpressions: +// - key: kubernetes.io/hostname +// operator: In +// values: +// - +// - +func GetLocalPersistentVolumeNodeNames(pv *v1.PersistentVolume) []string { + if pv == nil || pv.Spec.NodeAffinity == nil || pv.Spec.NodeAffinity.Required == nil { + return nil + } + + var result sets.Set[string] + for _, term := range pv.Spec.NodeAffinity.Required.NodeSelectorTerms { + var nodes sets.Set[string] + for _, matchExpr := range term.MatchExpressions { + if matchExpr.Key == v1.LabelHostname && matchExpr.Operator == v1.NodeSelectorOpIn { + if nodes == nil { + nodes = sets.New(matchExpr.Values...) + } else { + nodes = nodes.Intersection(sets.New(matchExpr.Values...)) + } + } + } + result = result.Union(nodes) + } + + return sets.List(result) +} + // GetPodVolumeNames returns names of volumes that are used in a pod, // either as filesystem mount or raw block device, together with list // of all SELinux contexts of all containers that use the volumes. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_linux.go index aae1b39ac..2e55df4cc 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler_linux.go @@ -139,7 +139,7 @@ func getLoopDeviceFromSysfs(path string) (string, error) { } // Return the first match. - backingFilePath := strings.TrimSpace(string(data)) + backingFilePath := cleanBackingFilePath(string(data)) if backingFilePath == path || backingFilePath == realPath { return fmt.Sprintf("/dev/%s", filepath.Base(device)), nil } @@ -148,6 +148,14 @@ func getLoopDeviceFromSysfs(path string) (string, error) { return "", errors.New(ErrDeviceNotFound) } +// cleanPath remove any trailing substrings that are not part of the backing file path. +func cleanBackingFilePath(path string) string { + // If the block device was deleted, the path will contain a "(deleted)" suffix + path = strings.TrimSpace(path) + path = strings.TrimSuffix(path, "(deleted)") + return strings.TrimSpace(path) +} + // FindGlobalMapPathUUIDFromPod finds {pod uuid} bind mount under globalMapPath // corresponding to map path symlink, and then return global map path with pod uuid. // (See pkg/volume/volume.go for details on a global map path and a pod device map path.) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go index 57c028150..ec7f6da4b 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go @@ -40,22 +40,22 @@ const ( // SetVolumeOwnership modifies the given volume to be owned by // fsGroup, and sets SetGid so that newly created files are owned by // fsGroup. If fsGroup is nil nothing is done. -func SetVolumeOwnership(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) error { +func SetVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) error { if fsGroup == nil { return nil } timer := time.AfterFunc(30*time.Second, func() { - klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", mounter.GetPath()) + klog.Warningf("Setting volume ownership for %s and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699", dir) }) defer timer.Stop() - if skipPermissionChange(mounter, fsGroup, fsGroupChangePolicy) { - klog.V(3).InfoS("Skipping permission and ownership change for volume", "path", mounter.GetPath()) + if skipPermissionChange(mounter, dir, fsGroup, fsGroupChangePolicy) { + klog.V(3).InfoS("Skipping permission and ownership change for volume", "path", dir) return nil } - err := walkDeep(mounter.GetPath(), func(path string, info os.FileInfo, err error) error { + err := walkDeep(dir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } @@ -104,14 +104,12 @@ func changeFilePermission(filename string, fsGroup *int64, readonly bool, info o return nil } -func skipPermissionChange(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy) bool { - dir := mounter.GetPath() - +func skipPermissionChange(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy) bool { if fsGroupChangePolicy == nil || *fsGroupChangePolicy != v1.FSGroupChangeOnRootMismatch { klog.V(4).InfoS("Perform recursive ownership change for directory", "path", dir) return false } - return !requiresPermissionChange(mounter.GetPath(), fsGroup, mounter.GetAttributes().ReadOnly) + return !requiresPermissionChange(dir, fsGroup, mounter.GetAttributes().ReadOnly) } func requiresPermissionChange(rootDir string, fsGroup *int64, readonly bool) bool { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go index 20c56d4b6..3b5a200a6 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go @@ -24,6 +24,6 @@ import ( "k8s.io/kubernetes/pkg/volume/util/types" ) -func SetVolumeOwnership(mounter Mounter, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) error { +func SetVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) error { return nil } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/.import-restrictions index 8e171cee3..44671a731 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/.import-restrictions +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/.import-restrictions @@ -1,272 +1,34 @@ rules: - - selectorRegexp: k8s[.]io/kubernetes/pkg/ + # The core E2E framework is meant to be a normal Kubernetes client, + # which means that it shouldn't depend on internal + # code. But we are not there yet, so some exceptions + # have to be allowed. Over time the list of allowed + # packages should get shorter, not longer. + - selectorRegexp: ^k8s[.]io/kubernetes/pkg/ allowedPrefixes: - - k8s.io/kubernetes/pkg/api/legacyscheme - - k8s.io/kubernetes/pkg/api/service - - k8s.io/kubernetes/pkg/api/v1/pod - - k8s.io/kubernetes/pkg/api/v1/resource - - k8s.io/kubernetes/pkg/api/v1/service - - k8s.io/kubernetes/pkg/api/pod - - k8s.io/kubernetes/pkg/api/node - - k8s.io/kubernetes/pkg/api/persistentvolumeclaim - - k8s.io/kubernetes/pkg/apis/apps - - k8s.io/kubernetes/pkg/apis/apps/validation - - k8s.io/kubernetes/pkg/apis/autoscaling - - k8s.io/kubernetes/pkg/apis/batch - - k8s.io/kubernetes/pkg/apis/certificates - - k8s.io/kubernetes/pkg/apis/certificates/v1 - - k8s.io/kubernetes/pkg/apis/core - - k8s.io/kubernetes/pkg/apis/core/helper - - k8s.io/kubernetes/pkg/apis/core/install - - k8s.io/kubernetes/pkg/apis/core/pods - - k8s.io/kubernetes/pkg/apis/core/v1 - - k8s.io/kubernetes/pkg/apis/core/v1/helper - - k8s.io/kubernetes/pkg/apis/core/v1/helper/qos - - k8s.io/kubernetes/pkg/apis/core/validation - - k8s.io/kubernetes/pkg/apis/extensions - - k8s.io/kubernetes/pkg/apis/networking - - k8s.io/kubernetes/pkg/apis/node - - k8s.io/kubernetes/pkg/apis/policy - - k8s.io/kubernetes/pkg/apis/policy/validation - - k8s.io/kubernetes/pkg/apis/scheduling - - k8s.io/kubernetes/pkg/apis/storage/v1/util - - k8s.io/kubernetes/pkg/capabilities - - k8s.io/kubernetes/pkg/client/conditions - - k8s.io/kubernetes/pkg/cloudprovider/providers - - k8s.io/kubernetes/pkg/controller - - k8s.io/kubernetes/pkg/controller/deployment/util - - k8s.io/kubernetes/pkg/controller/nodelifecycle - - k8s.io/kubernetes/pkg/controller/nodelifecycle/scheduler - - k8s.io/kubernetes/pkg/controller/service - - k8s.io/kubernetes/pkg/controller/util/node - - k8s.io/kubernetes/pkg/controller/volume/persistentvolume/util - - k8s.io/kubernetes/pkg/credentialprovider - - k8s.io/kubernetes/pkg/credentialprovider/aws - - k8s.io/kubernetes/pkg/credentialprovider/azure - - k8s.io/kubernetes/pkg/credentialprovider/gcp - - k8s.io/kubernetes/pkg/credentialprovider/secrets - - k8s.io/kubernetes/pkg/features - - k8s.io/kubernetes/pkg/fieldpath - - k8s.io/kubernetes/pkg/kubectl - - k8s.io/kubernetes/pkg/kubectl/apps - - k8s.io/kubernetes/pkg/kubectl/describe - - k8s.io/kubernetes/pkg/kubectl/describe/versioned - - k8s.io/kubernetes/pkg/kubectl/scheme - - k8s.io/kubernetes/pkg/kubectl/util - - k8s.io/kubernetes/pkg/kubectl/util/certificate - - k8s.io/kubernetes/pkg/kubectl/util/deployment - - k8s.io/kubernetes/pkg/kubectl/util/event - - k8s.io/kubernetes/pkg/kubectl/util/fieldpath - - k8s.io/kubernetes/pkg/kubectl/util/podutils - - k8s.io/kubernetes/pkg/kubectl/util/qos - - k8s.io/kubernetes/pkg/kubectl/util/rbac - - k8s.io/kubernetes/pkg/kubectl/util/resource - - k8s.io/kubernetes/pkg/kubectl/util/slice - - k8s.io/kubernetes/pkg/kubectl/util/storage - - k8s.io/kubernetes/pkg/kubelet - - k8s.io/kubernetes/pkg/kubelet/apis - - k8s.io/kubernetes/pkg/kubelet/apis/config - - k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1 - - k8s.io/kubernetes/pkg/kubelet/cadvisor - - k8s.io/kubernetes/pkg/kubelet/certificate - - k8s.io/kubernetes/pkg/kubelet/certificate/bootstrap - - k8s.io/kubernetes/pkg/kubelet/checkpoint - - k8s.io/kubernetes/pkg/kubelet/checkpointmanager - - k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum - - k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors - - k8s.io/kubernetes/pkg/kubelet/cloudresource - - k8s.io/kubernetes/pkg/kubelet/cm - - k8s.io/kubernetes/pkg/kubelet/cm/cpumanager - - k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/containermap - - k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state - - k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology - - k8s.io/kubernetes/pkg/kubelet/cm/cpuset - - k8s.io/kubernetes/pkg/kubelet/cm/devicemanager - - k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/checkpoint - - k8s.io/kubernetes/pkg/kubelet/cm/topologymanager - - k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask - - k8s.io/kubernetes/pkg/kubelet/cm/util - - k8s.io/kubernetes/pkg/kubelet/config - - k8s.io/kubernetes/pkg/kubelet/configmap - - k8s.io/kubernetes/pkg/kubelet/container - - k8s.io/kubernetes/pkg/kubelet/envvars - - k8s.io/kubernetes/pkg/kubelet/eviction - - k8s.io/kubernetes/pkg/kubelet/eviction/api - - k8s.io/kubernetes/pkg/kubelet/events - - k8s.io/kubernetes/pkg/kubelet/images - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig/checkpoint - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig/checkpoint/store - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig/configfiles - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig/status - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/codec - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/files - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/log - - k8s.io/kubernetes/pkg/kubelet/kubeletconfig/util/panic - - k8s.io/kubernetes/pkg/kubelet/kuberuntime - - k8s.io/kubernetes/pkg/kubelet/kuberuntime/logs - - k8s.io/kubernetes/pkg/kubelet/leaky - - k8s.io/kubernetes/pkg/kubelet/lifecycle - - k8s.io/kubernetes/pkg/kubelet/logs - - k8s.io/kubernetes/pkg/kubelet/metrics - - k8s.io/kubernetes/pkg/kubelet/network/dns - - k8s.io/kubernetes/pkg/kubelet/nodelease - - k8s.io/kubernetes/pkg/kubelet/nodestatus - - k8s.io/kubernetes/pkg/kubelet/oom - - k8s.io/kubernetes/pkg/kubelet/pleg - - k8s.io/kubernetes/pkg/kubelet/pluginmanager - - k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache - - k8s.io/kubernetes/pkg/kubelet/pluginmanager/metrics - - k8s.io/kubernetes/pkg/kubelet/pluginmanager/operationexecutor - - k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher - - k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/example_plugin_apis/v1beta1 - - k8s.io/kubernetes/pkg/kubelet/pluginmanager/pluginwatcher/example_plugin_apis/v1beta2 - - k8s.io/kubernetes/pkg/kubelet/pluginmanager/reconciler - - k8s.io/kubernetes/pkg/kubelet/pod - - k8s.io/kubernetes/pkg/kubelet/preemption - - k8s.io/kubernetes/pkg/kubelet/prober - - k8s.io/kubernetes/pkg/kubelet/prober/results - - k8s.io/kubernetes/pkg/kubelet/qos - - k8s.io/kubernetes/pkg/kubelet/remote - - k8s.io/kubernetes/pkg/kubelet/runtimeclass - - k8s.io/kubernetes/pkg/kubelet/server - - k8s.io/kubernetes/pkg/kubelet/server/metrics - - k8s.io/kubernetes/pkg/kubelet/server/portforward - - k8s.io/kubernetes/pkg/kubelet/server/remotecommand - - k8s.io/kubernetes/pkg/kubelet/server/stats - - k8s.io/kubernetes/pkg/kubelet/server/streaming - - k8s.io/kubernetes/pkg/kubelet/stats - - k8s.io/kubernetes/pkg/kubelet/stats/pidlimit - - k8s.io/kubernetes/pkg/kubelet/status - - k8s.io/kubernetes/pkg/kubelet/secret - - k8s.io/kubernetes/pkg/kubelet/sysctl - - k8s.io/kubernetes/pkg/kubelet/types - - k8s.io/kubernetes/pkg/kubelet/token - - k8s.io/kubernetes/pkg/kubelet/util - - k8s.io/kubernetes/pkg/kubelet/util/format - - k8s.io/kubernetes/pkg/kubelet/util/manager - - k8s.io/kubernetes/pkg/kubelet/util/store - - k8s.io/kubernetes/pkg/kubelet/volumemanager - - k8s.io/kubernetes/pkg/kubelet/volumemanager/cache - - k8s.io/kubernetes/pkg/kubelet/volumemanager/metrics - - k8s.io/kubernetes/pkg/kubelet/volumemanager/populator - - k8s.io/kubernetes/pkg/kubelet/volumemanager/reconciler - - k8s.io/kubernetes/pkg/kubemark - - k8s.io/kubernetes/pkg/cluster/ports - - k8s.io/kubernetes/pkg/probe - - k8s.io/kubernetes/pkg/probe/exec - - k8s.io/kubernetes/pkg/probe/http - - k8s.io/kubernetes/pkg/probe/tcp - - k8s.io/kubernetes/pkg/proxy - - k8s.io/kubernetes/pkg/proxy/apis - - k8s.io/kubernetes/pkg/proxy/apis/config - - k8s.io/kubernetes/pkg/proxy/apis/config/scheme - - k8s.io/kubernetes/pkg/proxy/apis/config/v1alpha1 - - k8s.io/kubernetes/pkg/proxy/apis/config/validation - - k8s.io/kubernetes/pkg/proxy/config - - k8s.io/kubernetes/pkg/proxy/healthcheck - - k8s.io/kubernetes/pkg/proxy/iptables - - k8s.io/kubernetes/pkg/proxy/ipvs - - k8s.io/kubernetes/pkg/proxy/metaproxier - - k8s.io/kubernetes/pkg/proxy/metrics - - k8s.io/kubernetes/pkg/proxy/util - - k8s.io/kubernetes/pkg/registry/core/service/allocator - - k8s.io/kubernetes/pkg/registry/core/service/portallocator - - k8s.io/kubernetes/pkg/scheduler/api - - k8s.io/kubernetes/pkg/scheduler/framework - - k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper - - k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity - - k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename - - k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports - - k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources - - k8s.io/kubernetes/pkg/scheduler/framework/runtime - - k8s.io/kubernetes/pkg/scheduler/internal/heap - - k8s.io/kubernetes/pkg/scheduler/internal/parallelize - - k8s.io/kubernetes/pkg/scheduler/internal/queue - - k8s.io/kubernetes/pkg/scheduler/listers - - k8s.io/kubernetes/pkg/scheduler/testing - - k8s.io/kubernetes/pkg/scheduler/metrics - - k8s.io/kubernetes/pkg/scheduler/nodeinfo - - k8s.io/kubernetes/pkg/scheduler/util - - k8s.io/kubernetes/pkg/scheduler/volumebinder - - k8s.io/kubernetes/pkg/scheduler - - k8s.io/kubernetes/pkg/scheduler/profile - - k8s.io/kubernetes/pkg/scheduler/testing - - k8s.io/kubernetes/pkg/security/apparmor - - k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp - - k8s.io/kubernetes/pkg/security/podsecuritypolicy/sysctl - - k8s.io/kubernetes/pkg/security/podsecuritypolicy/util - - k8s.io/kubernetes/pkg/securitycontext - - k8s.io/kubernetes/pkg/serviceaccount - - k8s.io/kubernetes/pkg/util/async - - k8s.io/kubernetes/pkg/util/bandwidth - - k8s.io/kubernetes/pkg/util/config - - k8s.io/kubernetes/pkg/util/configz - - k8s.io/kubernetes/pkg/util/conntrack - - k8s.io/kubernetes/pkg/util/env - - k8s.io/kubernetes/pkg/util/filesystem - - k8s.io/kubernetes/pkg/util/flag - - k8s.io/kubernetes/pkg/util/flock - - k8s.io/kubernetes/pkg/util/goroutinemap - - k8s.io/kubernetes/pkg/util/goroutinemap/exponentialbackoff - - k8s.io/kubernetes/pkg/util/hash - - k8s.io/kubernetes/pkg/util/ipset - - k8s.io/kubernetes/pkg/util/iptables - - k8s.io/kubernetes/pkg/util/ipvs - - k8s.io/kubernetes/pkg/util/labels - - k8s.io/kubernetes/pkg/util/node - - k8s.io/kubernetes/pkg/util/oom - - k8s.io/kubernetes/pkg/util/parsers - - k8s.io/kubernetes/pkg/util/pod - - k8s.io/kubernetes/pkg/util/procfs - - k8s.io/kubernetes/pkg/util/removeall - - k8s.io/kubernetes/pkg/util/resizefs - - k8s.io/kubernetes/pkg/util/rlimit - - k8s.io/kubernetes/pkg/util/selinux - - k8s.io/kubernetes/pkg/util/slice - - k8s.io/kubernetes/pkg/util/sysctl - - k8s.io/kubernetes/pkg/util/system - - k8s.io/kubernetes/pkg/util/tail - - k8s.io/kubernetes/pkg/util/taints - - k8s.io/kubernetes/pkg/volume - - k8s.io/kubernetes/pkg/volume/util - - k8s.io/kubernetes/pkg/volume/util/fs - - k8s.io/kubernetes/pkg/volume/util/fsquota - - k8s.io/kubernetes/pkg/volume/util/recyclerclient - - k8s.io/kubernetes/pkg/volume/util/subpath - - k8s.io/kubernetes/pkg/volume/util/types - - k8s.io/kubernetes/pkg/volume/util/volumepathhandler - # TODO: I have no idea why import-boss --include-test-files is yelling about these for k8s.io/kubernetes/test/e2e/framework/providers/kubemark - - k8s.io/kubernetes/pkg/apis/authentication - - k8s.io/kubernetes/pkg/apis/authentication/v1 - - k8s.io/kubernetes/pkg/apis/certificates/v1beta1 - - k8s.io/kubernetes/pkg/apis/storage/v1 - - k8s.io/kubernetes/pkg/scheduler/internal/cache - - selectorRegexp: k8s[.]io/kubernetes/test/ - allowedPrefixes: - - k8s.io/kubernetes/test/e2e/common - - k8s.io/kubernetes/test/e2e/framework - - k8s.io/kubernetes/test/e2e/framework/auth - - k8s.io/kubernetes/test/e2e/framework/ginkgowrapper - - k8s.io/kubernetes/test/e2e/framework/kubectl - - k8s.io/kubernetes/test/e2e/framework/log - - k8s.io/kubernetes/test/e2e/framework/metrics - - k8s.io/kubernetes/test/e2e/framework/network - - k8s.io/kubernetes/test/e2e/framework/node - - k8s.io/kubernetes/test/e2e/framework/pod - - k8s.io/kubernetes/test/e2e/framework/rc - - k8s.io/kubernetes/test/e2e/framework/resource - - k8s.io/kubernetes/test/e2e/framework/service - - k8s.io/kubernetes/test/e2e/framework/ssh - - k8s.io/kubernetes/test/e2e/framework/testfiles - - k8s.io/kubernetes/test/e2e/framework/websocket - - k8s.io/kubernetes/test/e2e/manifest - - k8s.io/kubernetes/test/e2e/perftype - - k8s.io/kubernetes/test/e2e/storage/utils - - k8s.io/kubernetes/test/e2e/system - - k8s.io/kubernetes/test/utils - - k8s.io/kubernetes/test/utils/image - # TODO: why is this here? - - selectorRegexp: k8s[.]io/kubernetes/third_party/ - allowedPrefixes: - - k8s.io/kubernetes/third_party/forked/golang/expansion + - k8s.io/kubernetes/pkg/kubelet/apis/ + + # The following packages are okay to use: + # + # public API + - selectorRegexp: ^k8s[.]io/(api|apimachinery|client-go|component-base|klog|pod-security-admission|utils)/|^[a-z]+(/|$)|github.com/onsi/(ginkgo|gomega)|^k8s[.]io/kubernetes/test/(e2e/framework/internal/|utils) + allowedPrefixes: [ "" ] + + # stdlib + - selectorRegexp: ^[a-z]+(/|$) + allowedPrefixes: [ "" ] + + # Ginkgo + Gomega. + - selectorRegexp: github.com/onsi/(ginkgo|gomega)|^k8s[.]io/kubernetes/test/(e2e/framework/internal/|utils) + allowedPrefixes: [ "" ] + + # some of the shared test helpers (but not E2E sub-packages!) + - selectorRegexp: ^k8s[.]io/kubernetes/test/(e2e/framework/internal/|utils) + allowedPrefixes: [ "" ] + + # Everything else isn't. + # + # In particular importing any test/e2e/framework/* package would be a + # violation (sub-packages get to use the framework, not the other way + # around). + - selectorRegexp: . diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/OWNERS b/vendor/k8s.io/kubernetes/test/e2e/framework/OWNERS index 0f377351b..f12bdef92 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/OWNERS +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/OWNERS @@ -1,7 +1,6 @@ # See the OWNERS docs at https://go.k8s.io/owners approvers: - - sig-testing-approvers - andrewsykim - fabriziopandini - pohly diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/README.md b/vendor/k8s.io/kubernetes/test/e2e/framework/README.md index 23194dec9..f8ed1eff2 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/README.md +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/README.md @@ -57,7 +57,7 @@ ginkgo.AfterEach(func() { # Do something with f.ClientSet. } -ginkgo.It("test something", func() { +ginkgo.It("test something", func(ctx context.Context) { # The actual test. }) ``` diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/config/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/config/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/config/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/dump.go b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/dump.go index 9244bf0e0..0f78d70ea 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/dump.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/dump.go @@ -58,25 +58,25 @@ func dumpEventsInNamespace(eventsLister EventsLister, namespace string) { } // DumpAllNamespaceInfo dumps events, pods and nodes information in the given namespace. -func DumpAllNamespaceInfo(c clientset.Interface, namespace string) { +func DumpAllNamespaceInfo(ctx context.Context, c clientset.Interface, namespace string) { dumpEventsInNamespace(func(opts metav1.ListOptions, ns string) (*v1.EventList, error) { - return c.CoreV1().Events(ns).List(context.TODO(), opts) + return c.CoreV1().Events(ns).List(ctx, opts) }, namespace) - e2epod.DumpAllPodInfoForNamespace(c, namespace, framework.TestContext.ReportDir) + e2epod.DumpAllPodInfoForNamespace(ctx, c, namespace, framework.TestContext.ReportDir) // If cluster is large, then the following logs are basically useless, because: // 1. it takes tens of minutes or hours to grab all of them // 2. there are so many of them that working with them are mostly impossible // So we dump them only if the cluster is relatively small. maxNodesForDump := framework.TestContext.MaxNodesToGather - nodes, err := c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) + nodes, err := c.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { framework.Logf("unable to fetch node list: %v", err) return } if len(nodes.Items) <= maxNodesForDump { - dumpAllNodeInfo(c, nodes) + dumpAllNodeInfo(ctx, c, nodes) } else { framework.Logf("skipping dumping cluster info - cluster too large") } @@ -95,31 +95,31 @@ func (o byFirstTimestamp) Less(i, j int) bool { return o[i].FirstTimestamp.Before(&o[j].FirstTimestamp) } -func dumpAllNodeInfo(c clientset.Interface, nodes *v1.NodeList) { +func dumpAllNodeInfo(ctx context.Context, c clientset.Interface, nodes *v1.NodeList) { names := make([]string, len(nodes.Items)) for ix := range nodes.Items { names[ix] = nodes.Items[ix].Name } - DumpNodeDebugInfo(c, names, framework.Logf) + DumpNodeDebugInfo(ctx, c, names, framework.Logf) } // DumpNodeDebugInfo dumps debug information of the given nodes. -func DumpNodeDebugInfo(c clientset.Interface, nodeNames []string, logFunc func(fmt string, args ...interface{})) { +func DumpNodeDebugInfo(ctx context.Context, c clientset.Interface, nodeNames []string, logFunc func(fmt string, args ...interface{})) { for _, n := range nodeNames { logFunc("\nLogging node info for node %v", n) - node, err := c.CoreV1().Nodes().Get(context.TODO(), n, metav1.GetOptions{}) + node, err := c.CoreV1().Nodes().Get(ctx, n, metav1.GetOptions{}) if err != nil { logFunc("Error getting node info %v", err) } logFunc("Node Info: %v", node) logFunc("\nLogging kubelet events for node %v", n) - for _, e := range getNodeEvents(c, n) { + for _, e := range getNodeEvents(ctx, c, n) { logFunc("source %v type %v message %v reason %v first ts %v last ts %v, involved obj %+v", e.Source, e.Type, e.Message, e.Reason, e.FirstTimestamp, e.LastTimestamp, e.InvolvedObject) } logFunc("\nLogging pods the kubelet thinks is on node %v", n) - podList, err := getKubeletPods(c, n) + podList, err := getKubeletPods(ctx, c, n) if err != nil { logFunc("Unable to retrieve kubelet pods for node %v: %v", n, err) continue @@ -135,13 +135,14 @@ func DumpNodeDebugInfo(c clientset.Interface, nodeNames []string, logFunc func(f c.Name, c.Ready, c.RestartCount) } } - e2emetrics.HighLatencyKubeletOperations(c, 10*time.Second, n, logFunc) + _, err = e2emetrics.HighLatencyKubeletOperations(ctx, c, 10*time.Second, n, logFunc) + framework.ExpectNoError(err) // TODO: Log node resource info } } // getKubeletPods retrieves the list of pods on the kubelet. -func getKubeletPods(c clientset.Interface, node string) (*v1.PodList, error) { +func getKubeletPods(ctx context.Context, c clientset.Interface, node string) (*v1.PodList, error) { var client restclient.Result finished := make(chan struct{}, 1) go func() { @@ -151,7 +152,7 @@ func getKubeletPods(c clientset.Interface, node string) (*v1.PodList, error) { SubResource("proxy"). Name(fmt.Sprintf("%v:%v", node, framework.KubeletPort)). Suffix("pods"). - Do(context.TODO()) + Do(ctx) finished <- struct{}{} }() @@ -170,7 +171,7 @@ func getKubeletPods(c clientset.Interface, node string) (*v1.PodList, error) { // logNodeEvents logs kubelet events from the given node. This includes kubelet // restart and node unhealthy events. Note that listing events like this will mess // with latency metrics, beware of calling it during a test. -func getNodeEvents(c clientset.Interface, nodeName string) []v1.Event { +func getNodeEvents(ctx context.Context, c clientset.Interface, nodeName string) []v1.Event { selector := fields.Set{ "involvedObject.kind": "Node", "involvedObject.name": nodeName, @@ -178,7 +179,7 @@ func getNodeEvents(c clientset.Interface, nodeName string) []v1.Event { "source": "kubelet", }.AsSelector().String() options := metav1.ListOptions{FieldSelector: selector} - events, err := c.CoreV1().Events(metav1.NamespaceSystem).List(context.TODO(), options) + events, err := c.CoreV1().Events(metav1.NamespaceSystem).List(ctx, options) if err != nil { framework.Logf("Unexpected error retrieving node events %v", err) return []v1.Event{} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/log_size_monitoring.go b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/log_size_monitoring.go index b5f53a208..073cbe891 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/log_size_monitoring.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/log_size_monitoring.go @@ -18,6 +18,7 @@ package debug import ( "bytes" + "context" "fmt" "strconv" "strings" @@ -156,8 +157,8 @@ func (d *LogsSizeData) addNewData(ip, path string, timestamp time.Time, size int } // NewLogsVerifier creates a new LogsSizeVerifier which will stop when stopChannel is closed -func NewLogsVerifier(c clientset.Interface, stopChannel chan bool) *LogsSizeVerifier { - nodeAddresses, err := e2essh.NodeSSHHosts(c) +func NewLogsVerifier(ctx context.Context, c clientset.Interface) *LogsSizeVerifier { + nodeAddresses, err := e2essh.NodeSSHHosts(ctx, c) framework.ExpectNoError(err) instanceAddress := framework.APIAddress() + ":22" @@ -166,7 +167,6 @@ func NewLogsVerifier(c clientset.Interface, stopChannel chan bool) *LogsSizeVeri verifier := &LogsSizeVerifier{ client: c, - stopChannel: stopChannel, data: prepareData(instanceAddress, nodeAddresses), masterAddress: instanceAddress, nodeAddresses: nodeAddresses, @@ -177,7 +177,6 @@ func NewLogsVerifier(c clientset.Interface, stopChannel chan bool) *LogsSizeVeri verifier.wg.Add(workersNo) for i := 0; i < workersNo; i++ { workers[i] = &LogSizeGatherer{ - stopChannel: stopChannel, data: verifier.data, wg: &verifier.wg, workChannel: workChannel, @@ -207,7 +206,7 @@ func (s *LogsSizeVerifier) GetSummary() *LogsSizeDataSummary { } // Run starts log size gathering. It starts a gorouting for every worker and then blocks until stopChannel is closed -func (s *LogsSizeVerifier) Run() { +func (s *LogsSizeVerifier) Run(ctx context.Context) { s.workChannel <- WorkItem{ ip: s.masterAddress, paths: masterLogsToCheck, @@ -221,15 +220,15 @@ func (s *LogsSizeVerifier) Run() { } } for _, worker := range s.workers { - go worker.Run() + go worker.Run(ctx) } <-s.stopChannel s.wg.Wait() } // Run starts log size gathering. -func (g *LogSizeGatherer) Run() { - for g.Work() { +func (g *LogSizeGatherer) Run(ctx context.Context) { + for g.Work(ctx) { } } @@ -245,7 +244,7 @@ func (g *LogSizeGatherer) pushWorkItem(workItem WorkItem) { // Work does a single unit of work: tries to take out a WorkItem from the queue, ssh-es into a given machine, // gathers data, writes it to the shared map, and creates a gorouting which reinserts work item into // the queue with a delay. Returns false if worker should exit. -func (g *LogSizeGatherer) Work() bool { +func (g *LogSizeGatherer) Work(ctx context.Context) bool { var workItem WorkItem select { case <-g.stopChannel: @@ -254,6 +253,7 @@ func (g *LogSizeGatherer) Work() bool { case workItem = <-g.workChannel: } sshResult, err := e2essh.SSH( + ctx, fmt.Sprintf("ls -l %v | awk '{print $9, $5}' | tr '\n' ' '", strings.Join(workItem.paths, " ")), workItem.ip, framework.TestContext.Provider, diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go index f401cac27..9c6537ed9 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go @@ -181,10 +181,10 @@ type resourceGatherWorker struct { printVerboseLogs bool } -func (w *resourceGatherWorker) singleProbe() { +func (w *resourceGatherWorker) singleProbe(ctx context.Context) { data := make(ResourceUsagePerContainer) if w.inKubemark { - kubemarkData := getKubemarkMasterComponentsResourceUsage() + kubemarkData := getKubemarkMasterComponentsResourceUsage(ctx) if kubemarkData == nil { return } @@ -319,22 +319,26 @@ func removeUint64Ptr(ptr *uint64) uint64 { return *ptr } -func (w *resourceGatherWorker) gather(initialSleep time.Duration) { +func (w *resourceGatherWorker) gather(ctx context.Context, initialSleep time.Duration) { defer utilruntime.HandleCrash() defer w.wg.Done() defer framework.Logf("Closing worker for %v", w.nodeName) defer func() { w.finished = true }() select { case <-time.After(initialSleep): - w.singleProbe() + w.singleProbe(ctx) for { select { case <-time.After(w.resourceDataGatheringPeriod): - w.singleProbe() + w.singleProbe(ctx) + case <-ctx.Done(): + return case <-w.stopCh: return } } + case <-ctx.Done(): + return case <-w.stopCh: return } @@ -373,11 +377,11 @@ const ( // nodeHasControlPlanePods returns true if specified node has control plane pods // (kube-scheduler and/or kube-controller-manager). -func nodeHasControlPlanePods(c clientset.Interface, nodeName string) (bool, error) { +func nodeHasControlPlanePods(ctx context.Context, c clientset.Interface, nodeName string) (bool, error) { regKubeScheduler := regexp.MustCompile("kube-scheduler-.*") regKubeControllerManager := regexp.MustCompile("kube-controller-manager-.*") - podList, err := c.CoreV1().Pods(metav1.NamespaceSystem).List(context.TODO(), metav1.ListOptions{ + podList, err := c.CoreV1().Pods(metav1.NamespaceSystem).List(ctx, metav1.ListOptions{ FieldSelector: fields.OneTermEqualSelector("spec.nodeName", nodeName).String(), }) if err != nil { @@ -395,7 +399,7 @@ func nodeHasControlPlanePods(c clientset.Interface, nodeName string) (bool, erro } // NewResourceUsageGatherer returns a new ContainerResourceGatherer. -func NewResourceUsageGatherer(c clientset.Interface, options ResourceGathererOptions, pods *v1.PodList) (*ContainerResourceGatherer, error) { +func NewResourceUsageGatherer(ctx context.Context, c clientset.Interface, options ResourceGathererOptions, pods *v1.PodList) (*ContainerResourceGatherer, error) { g := ContainerResourceGatherer{ client: c, stopCh: make(chan struct{}), @@ -420,7 +424,7 @@ func NewResourceUsageGatherer(c clientset.Interface, options ResourceGathererOpt // Tracks kube-system pods if no valid PodList is passed in. var err error if pods == nil { - pods, err = c.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) + pods, err = c.CoreV1().Pods("kube-system").List(ctx, metav1.ListOptions{}) if err != nil { framework.Logf("Error while listing Pods: %v", err) return nil, err @@ -429,7 +433,7 @@ func NewResourceUsageGatherer(c clientset.Interface, options ResourceGathererOpt dnsNodes := make(map[string]bool) for _, pod := range pods.Items { if options.Nodes == MasterNodes { - isControlPlane, err := nodeHasControlPlanePods(c, pod.Spec.NodeName) + isControlPlane, err := nodeHasControlPlanePods(ctx, c, pod.Spec.NodeName) if err != nil { return nil, err } @@ -438,7 +442,7 @@ func NewResourceUsageGatherer(c clientset.Interface, options ResourceGathererOpt } } if options.Nodes == MasterAndDNSNodes { - isControlPlane, err := nodeHasControlPlanePods(c, pod.Spec.NodeName) + isControlPlane, err := nodeHasControlPlanePods(ctx, c, pod.Spec.NodeName) if err != nil { return nil, err } @@ -456,14 +460,14 @@ func NewResourceUsageGatherer(c clientset.Interface, options ResourceGathererOpt dnsNodes[pod.Spec.NodeName] = true } } - nodeList, err := c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) + nodeList, err := c.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { framework.Logf("Error while listing Nodes: %v", err) return nil, err } for _, node := range nodeList.Items { - isControlPlane, err := nodeHasControlPlanePods(c, node.Name) + isControlPlane, err := nodeHasControlPlanePods(ctx, c, node.Name) if err != nil { return nil, err } @@ -491,14 +495,14 @@ func NewResourceUsageGatherer(c clientset.Interface, options ResourceGathererOpt // StartGatheringData starts a stat gathering worker blocks for each node to track, // and blocks until StopAndSummarize is called. -func (g *ContainerResourceGatherer) StartGatheringData() { +func (g *ContainerResourceGatherer) StartGatheringData(ctx context.Context) { if len(g.workers) == 0 { return } delayPeriod := g.options.ResourceDataGatheringPeriod / time.Duration(len(g.workers)) delay := time.Duration(0) for i := range g.workers { - go g.workers[i].gather(delay) + go g.workers[i].gather(ctx, delay) delay += delayPeriod } g.workerWg.Wait() @@ -603,8 +607,8 @@ type kubemarkResourceUsage struct { CPUUsageInCores float64 } -func getMasterUsageByPrefix(prefix string) (string, error) { - sshResult, err := e2essh.SSH(fmt.Sprintf("ps ax -o %%cpu,rss,command | tail -n +2 | grep %v | sed 's/\\s+/ /g'", prefix), framework.APIAddress()+":22", framework.TestContext.Provider) +func getMasterUsageByPrefix(ctx context.Context, prefix string) (string, error) { + sshResult, err := e2essh.SSH(ctx, fmt.Sprintf("ps ax -o %%cpu,rss,command | tail -n +2 | grep %v | sed 's/\\s+/ /g'", prefix), framework.APIAddress()+":22", framework.TestContext.Provider) if err != nil { return "", err } @@ -612,10 +616,10 @@ func getMasterUsageByPrefix(prefix string) (string, error) { } // getKubemarkMasterComponentsResourceUsage returns the resource usage of kubemark which contains multiple combinations of cpu and memory usage for each pod name. -func getKubemarkMasterComponentsResourceUsage() map[string]*kubemarkResourceUsage { +func getKubemarkMasterComponentsResourceUsage(ctx context.Context) map[string]*kubemarkResourceUsage { result := make(map[string]*kubemarkResourceUsage) // Get kubernetes component resource usage - sshResult, err := getMasterUsageByPrefix("kube") + sshResult, err := getMasterUsageByPrefix(ctx, "kube") if err != nil { framework.Logf("Error when trying to SSH to master machine. Skipping probe. %v", err) return nil @@ -633,7 +637,7 @@ func getKubemarkMasterComponentsResourceUsage() map[string]*kubemarkResourceUsag } } // Get etcd resource usage - sshResult, err = getMasterUsageByPrefix("bin/etcd") + sshResult, err = getMasterUsageByPrefix(ctx, "bin/etcd") if err != nil { framework.Logf("Error when trying to SSH to master machine. Skipping probe") return nil diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/expect.go b/vendor/k8s.io/kubernetes/test/e2e/framework/expect.go index 7b7fe7f41..7908cdcf3 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/expect.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/expect.go @@ -17,23 +17,300 @@ limitations under the License. package framework import ( + "context" + "errors" "fmt" + "strings" + "time" + ginkgotypes "github.com/onsi/ginkgo/v2/types" "github.com/onsi/gomega" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/types" ) +// MakeMatcher builds a gomega.Matcher based on a single callback function. +// That function is passed the actual value that is to be checked. +// There are three possible outcomes of the check: +// - An error is returned, which then is converted into a failure +// by Gomega. +// - A non-nil failure function is returned, which then is called +// by Gomega once a failure string is needed. This is useful +// to avoid unnecessarily preparing a failure string for intermediate +// failures in Eventually or Consistently. +// - Both function and error are nil, which means that the check +// succeeded. +func MakeMatcher[T interface{}](match func(actual T) (failure func() string, err error)) types.GomegaMatcher { + return &matcher[T]{ + match: match, + } +} + +type matcher[T interface{}] struct { + match func(actual T) (func() string, error) + failure func() string +} + +func (m *matcher[T]) Match(actual interface{}) (success bool, err error) { + if actual, ok := actual.(T); ok { + failure, err := m.match(actual) + if err != nil { + return false, err + } + m.failure = failure + if failure != nil { + return false, nil + } + return true, nil + } + var empty T + return false, gomega.StopTrying(fmt.Sprintf("internal error: expected %T, got:\n%s", empty, format.Object(actual, 1))) +} + +func (m *matcher[T]) FailureMessage(actual interface{}) string { + return m.failure() +} + +func (m matcher[T]) NegatedFailureMessage(actual interface{}) string { + return m.failure() +} + +var _ types.GomegaMatcher = &matcher[string]{} + +// Gomega returns an interface that can be used like gomega to express +// assertions. The difference is that failed assertions are returned as an +// error: +// +// if err := Gomega().Expect(pod.Status.Phase).To(gomega.BeEqual(v1.Running)); err != nil { +// return fmt.Errorf("test pod not running: %w", err) +// } +// +// This error can get wrapped to provide additional context for the +// failure. The test then should use ExpectNoError to turn a non-nil error into +// a failure. +// +// When using this approach, there is no need for call offsets and extra +// descriptions for the Expect call because the call stack will be dumped when +// ExpectNoError is called and the additional description(s) can be added by +// wrapping the error. +// +// Asynchronous assertions use the framework's Poll interval and PodStart timeout +// by default. +func Gomega() GomegaInstance { + return gomegaInstance{} +} + +type GomegaInstance interface { + Expect(actual interface{}) Assertion + Eventually(ctx context.Context, args ...interface{}) AsyncAssertion + Consistently(ctx context.Context, args ...interface{}) AsyncAssertion +} + +type Assertion interface { + Should(matcher types.GomegaMatcher) error + ShouldNot(matcher types.GomegaMatcher) error + To(matcher types.GomegaMatcher) error + ToNot(matcher types.GomegaMatcher) error + NotTo(matcher types.GomegaMatcher) error +} + +type AsyncAssertion interface { + Should(matcher types.GomegaMatcher) error + ShouldNot(matcher types.GomegaMatcher) error + + WithTimeout(interval time.Duration) AsyncAssertion + WithPolling(interval time.Duration) AsyncAssertion +} + +type gomegaInstance struct{} + +var _ GomegaInstance = gomegaInstance{} + +func (g gomegaInstance) Expect(actual interface{}) Assertion { + return assertion{actual: actual} +} + +func (g gomegaInstance) Eventually(ctx context.Context, args ...interface{}) AsyncAssertion { + return newAsyncAssertion(ctx, args, false) +} + +func (g gomegaInstance) Consistently(ctx context.Context, args ...interface{}) AsyncAssertion { + return newAsyncAssertion(ctx, args, true) +} + +func newG() (*FailureError, gomega.Gomega) { + var failure FailureError + g := gomega.NewGomega(func(msg string, callerSkip ...int) { + failure = FailureError{ + msg: msg, + } + }) + + return &failure, g +} + +type assertion struct { + actual interface{} +} + +func (a assertion) Should(matcher types.GomegaMatcher) error { + err, g := newG() + if !g.Expect(a.actual).Should(matcher) { + err.backtrace() + return *err + } + return nil +} + +func (a assertion) ShouldNot(matcher types.GomegaMatcher) error { + err, g := newG() + if !g.Expect(a.actual).ShouldNot(matcher) { + err.backtrace() + return *err + } + return nil +} + +func (a assertion) To(matcher types.GomegaMatcher) error { + err, g := newG() + if !g.Expect(a.actual).To(matcher) { + err.backtrace() + return *err + } + return nil +} + +func (a assertion) ToNot(matcher types.GomegaMatcher) error { + err, g := newG() + if !g.Expect(a.actual).ToNot(matcher) { + err.backtrace() + return *err + } + return nil +} + +func (a assertion) NotTo(matcher types.GomegaMatcher) error { + err, g := newG() + if !g.Expect(a.actual).NotTo(matcher) { + err.backtrace() + return *err + } + return nil +} + +type asyncAssertion struct { + ctx context.Context + args []interface{} + timeout time.Duration + interval time.Duration + consistently bool +} + +func newAsyncAssertion(ctx context.Context, args []interface{}, consistently bool) asyncAssertion { + return asyncAssertion{ + ctx: ctx, + args: args, + // PodStart is used as default because waiting for a pod is the + // most common operation. + timeout: TestContext.timeouts.PodStart, + interval: TestContext.timeouts.Poll, + } +} + +func (a asyncAssertion) newAsync() (*FailureError, gomega.AsyncAssertion) { + err, g := newG() + var assertion gomega.AsyncAssertion + if a.consistently { + assertion = g.Consistently(a.ctx, a.args...) + } else { + assertion = g.Eventually(a.ctx, a.args...) + } + assertion = assertion.WithTimeout(a.timeout).WithPolling(a.interval) + return err, assertion +} + +func (a asyncAssertion) Should(matcher types.GomegaMatcher) error { + err, assertion := a.newAsync() + if !assertion.Should(matcher) { + err.backtrace() + return *err + } + return nil +} + +func (a asyncAssertion) ShouldNot(matcher types.GomegaMatcher) error { + err, assertion := a.newAsync() + if !assertion.ShouldNot(matcher) { + err.backtrace() + return *err + } + return nil +} + +func (a asyncAssertion) WithTimeout(timeout time.Duration) AsyncAssertion { + a.timeout = timeout + return a +} + +func (a asyncAssertion) WithPolling(interval time.Duration) AsyncAssertion { + a.interval = interval + return a +} + +// FailureError is an error where the error string is meant to be passed to +// ginkgo.Fail directly, i.e. adding some prefix like "unexpected error" is not +// necessary. It is also not necessary to dump the error struct. +type FailureError struct { + msg string + fullStackTrace string +} + +func (f FailureError) Error() string { + return f.msg +} + +func (f FailureError) Backtrace() string { + return f.fullStackTrace +} + +func (f FailureError) Is(target error) bool { + return target == ErrFailure +} + +func (f *FailureError) backtrace() { + f.fullStackTrace = ginkgotypes.NewCodeLocationWithStackTrace(2).FullStackTrace +} + +// ErrFailure is an empty error that can be wrapped to indicate that an error +// is a FailureError. It can also be used to test for a FailureError:. +// +// return fmt.Errorf("some problem%w", ErrFailure) +// ... +// err := someOperation() +// if errors.Is(err, ErrFailure) { +// ... +// } +var ErrFailure error = FailureError{} + // ExpectEqual expects the specified two are the same, otherwise an exception raises +// +// Deprecated: use gomega.Expect().To(gomega.BeEqual()) func ExpectEqual(actual interface{}, extra interface{}, explain ...interface{}) { gomega.ExpectWithOffset(1, actual).To(gomega.Equal(extra), explain...) } // ExpectNotEqual expects the specified two are not the same, otherwise an exception raises +// +// Deprecated: use gomega.Expect().ToNot(gomega.BeEqual()) func ExpectNotEqual(actual interface{}, extra interface{}, explain ...interface{}) { gomega.ExpectWithOffset(1, actual).NotTo(gomega.Equal(extra), explain...) } // ExpectError expects an error happens, otherwise an exception raises +// +// Deprecated: use gomega.Expect().To(gomega.HaveOccurred()) or (better!) check +// specifically for the error that is expected with +// gomega.Expect().To(gomega.MatchError(gomega.ContainSubstring())) func ExpectError(err error, explain ...interface{}) { gomega.ExpectWithOffset(1, err).To(gomega.HaveOccurred(), explain...) } @@ -72,21 +349,37 @@ func ExpectNoErrorWithOffset(offset int, err error, explain ...interface{}) { // failures at the same code line might not be matched in // https://go.k8s.io/triage because the error details are too // different. - Logf("Unexpected error: %s\n%s", prefix, format.Object(err, 1)) + // + // Some errors include all relevant information in the Error + // string. For those we can skip the redundant log message. + // For our own failures we only log the additional stack backtrace + // because it is not included in the failure message. + var failure FailureError + if errors.As(err, &failure) && failure.Backtrace() != "" { + Logf("Failed inside E2E framework:\n %s", strings.ReplaceAll(failure.Backtrace(), "\n", "\n ")) + } else if !errors.Is(err, ErrFailure) { + Logf("Unexpected error: %s\n%s", prefix, format.Object(err, 1)) + } Fail(prefix+err.Error(), 1+offset) } // ExpectConsistOf expects actual contains precisely the extra elements. The ordering of the elements does not matter. +// +// Deprecated: use gomega.Expect().To(gomega.ConsistOf()) instead func ExpectConsistOf(actual interface{}, extra interface{}, explain ...interface{}) { gomega.ExpectWithOffset(1, actual).To(gomega.ConsistOf(extra), explain...) } // ExpectHaveKey expects the actual map has the key in the keyset +// +// Deprecated: use gomega.Expect().To(gomega.HaveKey()) instead func ExpectHaveKey(actual interface{}, key interface{}, explain ...interface{}) { gomega.ExpectWithOffset(1, actual).To(gomega.HaveKey(key), explain...) } // ExpectEmpty expects actual is empty +// +// Deprecated: use gomega.Expect().To(gomega.BeEmpty()) instead func ExpectEmpty(actual interface{}, explain ...interface{}) { gomega.ExpectWithOffset(1, actual).To(gomega.BeEmpty(), explain...) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go index 3f64ab391..ecd547059 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go @@ -27,6 +27,7 @@ import ( "math/rand" "os" "path" + "reflect" "strings" "time" @@ -38,6 +39,7 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" + v1svc "k8s.io/client-go/applyconfigurations/core/v1" "k8s.io/client-go/discovery" cacheddiscovery "k8s.io/client-go/discovery/cached/memory" "k8s.io/client-go/dynamic" @@ -54,6 +56,7 @@ import ( const ( // DefaultNamespaceDeletionTimeout is timeout duration for waiting for a namespace deletion. DefaultNamespaceDeletionTimeout = 5 * time.Minute + defaultServiceAccountName = "default" ) var ( @@ -103,6 +106,7 @@ type Framework struct { ScalesGetter scaleclient.ScalesGetter SkipNamespaceCreation bool // Whether to skip creating a namespace + SkipSecretCreation bool // Whether to skip creating secret for a test Namespace *v1.Namespace // Every test has at least one namespace unless creation is skipped namespacesToDelete []*v1.Namespace // Some tests have more than one. NamespaceDeletionTimeout time.Duration @@ -128,7 +132,7 @@ type Framework struct { // DumpAllNamespaceInfoAction is called after each failed test for namespaces // created for the test. -type DumpAllNamespaceInfoAction func(f *Framework, namespace string) +type DumpAllNamespaceInfoAction func(ctx context.Context, f *Framework, namespace string) // TestDataSummary is an interface for managing test data. type TestDataSummary interface { @@ -144,10 +148,19 @@ type Options struct { GroupVersion *schema.GroupVersion } -// NewFrameworkWithCustomTimeouts makes a framework with with custom timeouts. +// NewFrameworkWithCustomTimeouts makes a framework with custom timeouts. +// For timeout values that are zero the normal default value continues to +// be used. func NewFrameworkWithCustomTimeouts(baseName string, timeouts *TimeoutContext) *Framework { f := NewDefaultFramework(baseName) - f.Timeouts = timeouts + in := reflect.ValueOf(timeouts).Elem() + out := reflect.ValueOf(f.Timeouts).Elem() + for i := 0; i < in.NumField(); i++ { + value := in.Field(i) + if !value.IsZero() { + out.Field(i).Set(value) + } + } return f } @@ -169,7 +182,7 @@ func NewFramework(baseName string, options Options, client clientset.Interface) BaseName: baseName, Options: options, ClientSet: client, - Timeouts: NewTimeoutContextWithDefaults(), + Timeouts: NewTimeoutContext(), } // The order is important here: if the extension calls ginkgo.BeforeEach @@ -184,7 +197,7 @@ func NewFramework(baseName string, options Options, client clientset.Interface) } // BeforeEach gets a client and makes a namespace. -func (f *Framework) BeforeEach() { +func (f *Framework) BeforeEach(ctx context.Context) { // DeferCleanup, in contrast to AfterEach, triggers execution in // first-in-last-out order. This ensures that the framework instance // remains valid as long as possible. @@ -235,7 +248,7 @@ func (f *Framework) BeforeEach() { if !f.SkipNamespaceCreation { ginkgo.By(fmt.Sprintf("Building a namespace api object, basename %s", f.BaseName)) - namespace, err := f.CreateNamespace(f.BaseName, map[string]string{ + namespace, err := f.CreateNamespace(ctx, f.BaseName, map[string]string{ "e2e-framework": f.BaseName, }) ExpectNoError(err) @@ -244,14 +257,15 @@ func (f *Framework) BeforeEach() { if TestContext.VerifyServiceAccount { ginkgo.By("Waiting for a default service account to be provisioned in namespace") - err = WaitForDefaultServiceAccountInNamespace(f.ClientSet, namespace.Name) + err = WaitForDefaultServiceAccountInNamespace(ctx, f.ClientSet, namespace.Name) ExpectNoError(err) ginkgo.By("Waiting for kube-root-ca.crt to be provisioned in namespace") - err = WaitForKubeRootCAInNamespace(f.ClientSet, namespace.Name) + err = WaitForKubeRootCAInNamespace(ctx, f.ClientSet, namespace.Name) ExpectNoError(err) } else { Logf("Skipping waiting for service account") } + f.UniqueName = f.Namespace.GetName() } else { // not guaranteed to be unique, but very likely @@ -261,17 +275,20 @@ func (f *Framework) BeforeEach() { f.flakeReport = NewFlakeReport() } -func (f *Framework) dumpNamespaceInfo() { +func (f *Framework) dumpNamespaceInfo(ctx context.Context) { if !ginkgo.CurrentSpecReport().Failed() { return } if !TestContext.DumpLogsOnFailure { return } + if f.DumpAllNamespaceInfo == nil { + return + } ginkgo.By("dump namespace information after failure", func() { if !f.SkipNamespaceCreation { for _, ns := range f.namespacesToDelete { - f.DumpAllNamespaceInfo(f, ns.Name) + f.DumpAllNamespaceInfo(ctx, f, ns.Name) } } }) @@ -315,7 +332,7 @@ func printSummaries(summaries []TestDataSummary, testBaseName string) { } // AfterEach deletes the namespace, after reading its events. -func (f *Framework) AfterEach() { +func (f *Framework) AfterEach(ctx context.Context) { // This should not happen. Given ClientSet is a public field a test must have updated it! // Error out early before any API calls during cleanup. if f.ClientSet == nil { @@ -332,13 +349,13 @@ func (f *Framework) AfterEach() { if TestContext.DeleteNamespace && (TestContext.DeleteNamespaceOnFailure || !ginkgo.CurrentSpecReport().Failed()) { for _, ns := range f.namespacesToDelete { ginkgo.By(fmt.Sprintf("Destroying namespace %q for this suite.", ns.Name)) - if err := f.ClientSet.CoreV1().Namespaces().Delete(context.TODO(), ns.Name, metav1.DeleteOptions{}); err != nil { + if err := f.ClientSet.CoreV1().Namespaces().Delete(ctx, ns.Name, metav1.DeleteOptions{}); err != nil { if !apierrors.IsNotFound(err) { nsDeletionErrors[ns.Name] = err // Dump namespace if we are unable to delete the namespace and the dump was not already performed. if !ginkgo.CurrentSpecReport().Failed() && TestContext.DumpLogsOnFailure && f.DumpAllNamespaceInfo != nil { - f.DumpAllNamespaceInfo(f, ns.Name) + f.DumpAllNamespaceInfo(ctx, f, ns.Name) } } else { Logf("Namespace %v was already deleted", ns.Name) @@ -385,14 +402,14 @@ func (f *Framework) AfterEach() { // DeleteNamespace can be used to delete a namespace. Additionally it can be used to // dump namespace information so as it can be used as an alternative of framework // deleting the namespace towards the end. -func (f *Framework) DeleteNamespace(name string) { +func (f *Framework) DeleteNamespace(ctx context.Context, name string) { defer func() { - err := f.ClientSet.CoreV1().Namespaces().Delete(context.TODO(), name, metav1.DeleteOptions{}) + err := f.ClientSet.CoreV1().Namespaces().Delete(ctx, name, metav1.DeleteOptions{}) if err != nil && !apierrors.IsNotFound(err) { Logf("error deleting namespace %s: %v", name, err) return } - err = WaitForNamespacesDeleted(f.ClientSet, []string{name}, DefaultNamespaceDeletionTimeout) + err = WaitForNamespacesDeleted(ctx, f.ClientSet, []string{name}, DefaultNamespaceDeletionTimeout) if err != nil { Logf("error deleting namespace %s: %v", name, err) return @@ -409,13 +426,13 @@ func (f *Framework) DeleteNamespace(name string) { }() // if current test failed then we should dump namespace information if !f.SkipNamespaceCreation && ginkgo.CurrentSpecReport().Failed() && TestContext.DumpLogsOnFailure && f.DumpAllNamespaceInfo != nil { - f.DumpAllNamespaceInfo(f, name) + f.DumpAllNamespaceInfo(ctx, f, name) } } // CreateNamespace creates a namespace for e2e testing. -func (f *Framework) CreateNamespace(baseName string, labels map[string]string) (*v1.Namespace, error) { +func (f *Framework) CreateNamespace(ctx context.Context, baseName string, labels map[string]string) (*v1.Namespace, error) { createTestingNS := TestContext.CreateTestingNS if createTestingNS == nil { createTestingNS = CreateTestingNS @@ -437,14 +454,53 @@ func (f *Framework) CreateNamespace(baseName string, labels map[string]string) ( } labels[admissionapi.EnforceLevelLabel] = string(enforceLevel) - ns, err := createTestingNS(baseName, f.ClientSet, labels) + ns, err := createTestingNS(ctx, baseName, f.ClientSet, labels) // check ns instead of err to see if it's nil as we may // fail to create serviceAccount in it. f.AddNamespacesToDelete(ns) + if TestContext.E2EDockerConfigFile != "" && !f.SkipSecretCreation { + // With the Secret created, the default service account (in the new namespace) + // is patched with the secret and can then be referenced by all the pods spawned by E2E process, and repository authentication should be successful. + secret, err := f.createSecretFromDockerConfig(ctx, ns.Name) + if err != nil { + return ns, fmt.Errorf("failed to create secret from docker config file: %v", err) + } + + serviceAccountClient := f.ClientSet.CoreV1().ServiceAccounts(ns.Name) + serviceAccountConfig := v1svc.ServiceAccount(defaultServiceAccountName, ns.Name) + serviceAccountConfig.ImagePullSecrets = append(serviceAccountConfig.ImagePullSecrets, v1svc.LocalObjectReferenceApplyConfiguration{Name: &secret.Name}) + + svc, err := serviceAccountClient.Apply(ctx, serviceAccountConfig, metav1.ApplyOptions{FieldManager: "e2e-framework"}) + if err != nil { + return ns, fmt.Errorf("failed to patch imagePullSecret [%s] to service account [%s]: %v", secret.Name, svc.Name, err) + } + + } + return ns, err } +// createSecretFromDockerConfig creates a secret using the private image registry credentials. +// The credentials are provided by --e2e-docker-config-file flag. +func (f *Framework) createSecretFromDockerConfig(ctx context.Context, namespace string) (*v1.Secret, error) { + contents, err := os.ReadFile(TestContext.E2EDockerConfigFile) + if err != nil { + return nil, fmt.Errorf("error reading docker config file: %v", err) + } + + secretObject := &v1.Secret{ + Data: map[string][]byte{v1.DockerConfigJsonKey: contents}, + Type: v1.SecretTypeDockerConfigJson, + } + secretObject.GenerateName = "registry-cred" + Logf("create image pull secret %s", secretObject.Name) + + secret, err := f.ClientSet.CoreV1().Secrets(namespace).Create(ctx, secretObject, metav1.CreateOptions{}) + + return secret, err +} + // RecordFlakeIfError records flakeness info if error happens. // NOTE: This function is not used at any places yet, but we are in progress for https://github.com/kubernetes/kubernetes/issues/66239 which requires this. Please don't remove this. func (f *Framework) RecordFlakeIfError(err error, optionalDescription ...interface{}) { @@ -526,11 +582,6 @@ func (kc *KubeConfig) FindCluster(name string) *KubeCluster { return nil } -// ConformanceIt is wrapper function for ginkgo It. Adds "[Conformance]" tag and makes static analysis easier. -func ConformanceIt(text string, body interface{}) bool { - return ginkgo.It(text+" [Conformance]", ginkgo.Offset(1), body) -} - // PodStateVerification represents a verification of pod state. // Any time you have a set of pods that you want to operate against or query, // this struct can be used to declaratively identify those pods. @@ -596,7 +647,7 @@ func passesPhasesFilter(pod v1.Pod, validPhases []v1.PodPhase) bool { } // filterLabels returns a list of pods which have labels. -func filterLabels(selectors map[string]string, cli clientset.Interface, ns string) (*v1.PodList, error) { +func filterLabels(ctx context.Context, selectors map[string]string, cli clientset.Interface, ns string) (*v1.PodList, error) { var err error var selector labels.Selector var pl *v1.PodList @@ -605,9 +656,9 @@ func filterLabels(selectors map[string]string, cli clientset.Interface, ns strin if len(selectors) > 0 { selector = labels.SelectorFromSet(labels.Set(selectors)) options := metav1.ListOptions{LabelSelector: selector.String()} - pl, err = cli.CoreV1().Pods(ns).List(context.TODO(), options) + pl, err = cli.CoreV1().Pods(ns).List(ctx, options) } else { - pl, err = cli.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) + pl, err = cli.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{}) } return pl, err } @@ -615,13 +666,13 @@ func filterLabels(selectors map[string]string, cli clientset.Interface, ns strin // filter filters pods which pass a filter. It can be used to compose // the more useful abstractions like ForEach, WaitFor, and so on, which // can be used directly by tests. -func (p *PodStateVerification) filter(c clientset.Interface, namespace *v1.Namespace) ([]v1.Pod, error) { +func (p *PodStateVerification) filter(ctx context.Context, c clientset.Interface, namespace *v1.Namespace) ([]v1.Pod, error) { if len(p.ValidPhases) == 0 || namespace == nil { panic(fmt.Errorf("Need to specify a valid pod phases (%v) and namespace (%v). ", p.ValidPhases, namespace)) } ns := namespace.Name - pl, err := filterLabels(p.Selectors, c, ns) // Build an v1.PodList to operate against. + pl, err := filterLabels(ctx, p.Selectors, c, ns) // Build an v1.PodList to operate against. Logf("Selector matched %v pods for %v", len(pl.Items), p.Selectors) if len(pl.Items) == 0 || err != nil { return pl.Items, err @@ -649,12 +700,12 @@ ReturnPodsSoFar: // WaitFor waits for some minimum number of pods to be verified, according to the PodStateVerification // definition. -func (cl *ClusterVerification) WaitFor(atLeast int, timeout time.Duration) ([]v1.Pod, error) { +func (cl *ClusterVerification) WaitFor(ctx context.Context, atLeast int, timeout time.Duration) ([]v1.Pod, error) { pods := []v1.Pod{} var returnedErr error - err := wait.Poll(1*time.Second, timeout, func() (bool, error) { - pods, returnedErr = cl.podState.filter(cl.client, cl.namespace) + err := wait.PollWithContext(ctx, 1*time.Second, timeout, func(ctx context.Context) (bool, error) { + pods, returnedErr = cl.podState.filter(ctx, cl.client, cl.namespace) // Failure if returnedErr != nil { @@ -677,8 +728,8 @@ func (cl *ClusterVerification) WaitFor(atLeast int, timeout time.Duration) ([]v1 } // WaitForOrFail provides a shorthand WaitFor with failure as an option if anything goes wrong. -func (cl *ClusterVerification) WaitForOrFail(atLeast int, timeout time.Duration) { - pods, err := cl.WaitFor(atLeast, timeout) +func (cl *ClusterVerification) WaitForOrFail(ctx context.Context, atLeast int, timeout time.Duration) { + pods, err := cl.WaitFor(ctx, atLeast, timeout) if err != nil || len(pods) < atLeast { Failf("Verified %v of %v pods , error : %v", len(pods), atLeast, err) } @@ -689,8 +740,8 @@ func (cl *ClusterVerification) WaitForOrFail(atLeast int, timeout time.Duration) // // For example, if you require at least 5 pods to be running before your test will pass, // its smart to first call "clusterVerification.WaitFor(5)" before you call clusterVerification.ForEach. -func (cl *ClusterVerification) ForEach(podFunc func(v1.Pod)) error { - pods, err := cl.podState.filter(cl.client, cl.namespace) +func (cl *ClusterVerification) ForEach(ctx context.Context, podFunc func(v1.Pod)) error { + pods, err := cl.podState.filter(ctx, cl.client, cl.namespace) if err == nil { if len(pods) == 0 { Failf("No pods matched the filter.") diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/get.go b/vendor/k8s.io/kubernetes/test/e2e/framework/get.go new file mode 100644 index 000000000..ffa26d307 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/get.go @@ -0,0 +1,145 @@ +/* +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 framework + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/onsi/gomega" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// GetFunc is a function which retrieves a certain object. +type GetFunc[T any] func(ctx context.Context) (T, error) + +// APIGetFunc is a get functions as used in client-go. +type APIGetFunc[T any] func(ctx context.Context, name string, getOptions metav1.GetOptions) (T, error) + +// APIListFunc is a list functions as used in client-go. +type APIListFunc[T any] func(ctx context.Context, listOptions metav1.ListOptions) (T, error) + +// GetObject takes a get function like clientset.CoreV1().Pods(ns).Get +// and the parameters for it and returns a function that executes that get +// operation in a [gomega.Eventually] or [gomega.Consistently]. +// +// Delays and retries are handled by [HandleRetry]. A "not found" error is +// a fatal error that causes polling to stop immediately. If that is not +// desired, then wrap the result with [IgnoreNotFound]. +func GetObject[T any](get APIGetFunc[T], name string, getOptions metav1.GetOptions) GetFunc[T] { + return HandleRetry(func(ctx context.Context) (T, error) { + return get(ctx, name, getOptions) + }) +} + +// ListObjects takes a list function like clientset.CoreV1().Pods(ns).List +// and the parameters for it and returns a function that executes that list +// operation in a [gomega.Eventually] or [gomega.Consistently]. +// +// Delays and retries are handled by [HandleRetry]. +func ListObjects[T any](list APIListFunc[T], listOptions metav1.ListOptions) GetFunc[T] { + return HandleRetry(func(ctx context.Context) (T, error) { + return list(ctx, listOptions) + }) +} + +// HandleRetry wraps an arbitrary get function. When the wrapped function +// returns an error, HandleGetError will decide whether the call should be +// retried and if requested, will sleep before doing so. +// +// This is meant to be used inside [gomega.Eventually] or [gomega.Consistently]. +func HandleRetry[T any](get GetFunc[T]) GetFunc[T] { + return func(ctx context.Context) (T, error) { + t, err := get(ctx) + if err != nil { + if retry, delay := ShouldRetry(err); retry { + if delay > 0 { + // We could return + // gomega.TryAgainAfter(delay) here, + // but then we need to funnel that + // error through any other + // wrappers. Waiting directly is simpler. + ctx, cancel := context.WithTimeout(ctx, delay) + defer cancel() + <-ctx.Done() + } + return t, err + } + // Give up polling immediately. + var null T + return t, gomega.StopTrying(fmt.Sprintf("Unexpected final error while getting %T", null)).Wrap(err) + } + return t, nil + } +} + +// ShouldRetry decides whether to retry an API request. Optionally returns a +// delay to retry after. +func ShouldRetry(err error) (retry bool, retryAfter time.Duration) { + // if the error sends the Retry-After header, we respect it as an explicit confirmation we should retry. + if delay, shouldRetry := apierrors.SuggestsClientDelay(err); shouldRetry { + return shouldRetry, time.Duration(delay) * time.Second + } + + // these errors indicate a transient error that should be retried. + if apierrors.IsTimeout(err) || apierrors.IsTooManyRequests(err) || errors.As(err, &transientError{}) { + return true, 0 + } + + return false, 0 +} + +// RetryNotFound wraps an arbitrary get function. When the wrapped function +// encounters a "not found" error, that error is treated as a transient problem +// and polling continues. +// +// This is meant to be used inside [gomega.Eventually] or [gomega.Consistently]. +func RetryNotFound[T any](get GetFunc[T]) GetFunc[T] { + return func(ctx context.Context) (T, error) { + t, err := get(ctx) + if apierrors.IsNotFound(err) { + // If we are wrapping HandleRetry, then the error will + // be gomega.StopTrying. We need to get rid of that, + // otherwise gomega.Eventually will stop. + var stopTryingErr gomega.PollingSignalError + if errors.As(err, &stopTryingErr) { + if wrappedErr := errors.Unwrap(stopTryingErr); wrappedErr != nil { + err = wrappedErr + } + } + + // Mark the error as transient in case that we get + // wrapped by HandleRetry. + err = transientError{error: err} + } + return t, err + } +} + +// transientError wraps some other error and indicates that the +// wrapper error is something that may go away. +type transientError struct { + error +} + +func (err transientError) Unwrap() error { + return err.error +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go b/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go index d81179348..e35fc4ae9 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go @@ -18,16 +18,55 @@ package framework import ( "path" + "reflect" + "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/types" + + apierrors "k8s.io/apimachinery/pkg/api/errors" ) +var errInterface = reflect.TypeOf((*error)(nil)).Elem() + +// IgnoreNotFound can be used to wrap an arbitrary function in a call to +// [ginkgo.DeferCleanup]. When the wrapped function returns an error that +// `apierrors.IsNotFound` considers as "not found", the error is ignored +// instead of failing the test during cleanup. This is useful for cleanup code +// that just needs to ensure that some object does not exist anymore. +func IgnoreNotFound(in any) any { + inType := reflect.TypeOf(in) + inValue := reflect.ValueOf(in) + return reflect.MakeFunc(inType, func(args []reflect.Value) []reflect.Value { + out := inValue.Call(args) + if len(out) > 0 { + lastValue := out[len(out)-1] + last := lastValue.Interface() + if last != nil && lastValue.Type().Implements(errInterface) && apierrors.IsNotFound(last.(error)) { + out[len(out)-1] = reflect.Zero(errInterface) + } + } + return out + }).Interface() +} + // AnnotatedLocation can be used to provide more informative source code // locations by passing the result as additional parameter to a // BeforeEach/AfterEach/DeferCleanup/It/etc. func AnnotatedLocation(annotation string) types.CodeLocation { - codeLocation := types.NewCodeLocation(1) + return AnnotatedLocationWithOffset(annotation, 1) +} + +// AnnotatedLocationWithOffset skips additional call stack levels. With 0 as offset +// it is identical to [AnnotatedLocation]. +func AnnotatedLocationWithOffset(annotation string, offset int) types.CodeLocation { + codeLocation := types.NewCodeLocation(offset + 1) codeLocation.FileName = path.Base(codeLocation.FileName) codeLocation = types.NewCustomCodeLocation(annotation + " | " + codeLocation.String()) return codeLocation } + +// ConformanceIt is wrapper function for ginkgo It. Adds "[Conformance]" tag and makes static analysis easier. +func ConformanceIt(text string, args ...interface{}) bool { + args = append(args, ginkgo.Offset(1)) + return ginkgo.It(text+" [Conformance]", args...) +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/internal/junit/junit.go b/vendor/k8s.io/kubernetes/test/e2e/framework/internal/junit/junit.go new file mode 100644 index 000000000..2f61c869c --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/internal/junit/junit.go @@ -0,0 +1,42 @@ +/* +Copyright 2022 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 junit + +import ( + "github.com/onsi/ginkgo/v2" + "github.com/onsi/ginkgo/v2/reporters" + "github.com/onsi/ginkgo/v2/types" +) + +// WriteJUnitReport generates a JUnit file that is shorter than the one +// normally written by `ginkgo --junit-report`. This is needed because the full +// report can become too large for tools like Spyglass +// (https://github.com/kubernetes/kubernetes/issues/111510). +func WriteJUnitReport(report ginkgo.Report, filename string) error { + config := reporters.JunitReportConfig{ + // Remove details for specs where we don't care. + OmitTimelinesForSpecState: types.SpecStatePassed | types.SpecStateSkipped, + + // Don't write . The same text is + // also in the full text for the failure. If we were to write + // both, then tools like kettle and spyglass would concatenate + // the two strings and thus show duplicated information. + OmitFailureMessageAttr: true, + } + + return reporters.GenerateJUnitReportWithConfig(report, filename, config) +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go index 916389589..3811fa572 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go @@ -22,6 +22,7 @@ import ( "io" "net" "net/url" + "os" "os/exec" "strings" "syscall" @@ -48,9 +49,12 @@ func NewKubectlCommand(namespace string, args ...string) *KubectlBuilder { return b } -// WithEnv sets the given environment and returns itself. -func (b *KubectlBuilder) WithEnv(env []string) *KubectlBuilder { - b.cmd.Env = env +// WithEnv appends the given environment and returns itself. +func (b *KubectlBuilder) AppendEnv(env []string) *KubectlBuilder { + if b.cmd.Env == nil { + b.cmd.Env = os.Environ() + } + b.cmd.Env = append(b.cmd.Env, env...) return b } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go index 56e4bf75b..b3fe86b8b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/kubectl_utils.go @@ -100,8 +100,8 @@ func (tk *TestKubeconfig) KubectlCmd(args ...string) *exec.Cmd { } // LogFailedContainers runs `kubectl logs` on a failed containers. -func LogFailedContainers(c clientset.Interface, ns string, logFunc func(ftm string, args ...interface{})) { - podList, err := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) +func LogFailedContainers(ctx context.Context, c clientset.Interface, ns string, logFunc func(ftm string, args ...interface{})) { + podList, err := c.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{}) if err != nil { logFunc("Error getting pods in namespace '%s': %v", ns, err) return @@ -109,18 +109,18 @@ func LogFailedContainers(c clientset.Interface, ns string, logFunc func(ftm stri logFunc("Running kubectl logs on non-ready containers in %v", ns) for _, pod := range podList.Items { if res, err := testutils.PodRunningReady(&pod); !res || err != nil { - kubectlLogPod(c, pod, "", framework.Logf) + kubectlLogPod(ctx, c, pod, "", framework.Logf) } } } -func kubectlLogPod(c clientset.Interface, pod v1.Pod, containerNameSubstr string, logFunc func(ftm string, args ...interface{})) { +func kubectlLogPod(ctx context.Context, c clientset.Interface, pod v1.Pod, containerNameSubstr string, logFunc func(ftm string, args ...interface{})) { for _, container := range pod.Spec.Containers { if strings.Contains(container.Name, containerNameSubstr) { // Contains() matches all strings if substr is empty - logs, err := e2epod.GetPodLogs(c, pod.Namespace, pod.Name, container.Name) + logs, err := e2epod.GetPodLogs(ctx, c, pod.Namespace, pod.Name, container.Name) if err != nil { - logs, err = e2epod.GetPreviousPodLogs(c, pod.Namespace, pod.Name, container.Name) + logs, err = e2epod.GetPreviousPodLogs(ctx, c, pod.Namespace, pod.Name, container.Name) if err != nil { logFunc("Failed to get logs of pod %v, container %v, err: %v", pod.Name, container.Name, err) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/log.go b/vendor/k8s.io/kubernetes/test/e2e/framework/log.go index e41c8329b..58b6748ff 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/log.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/log.go @@ -17,14 +17,10 @@ limitations under the License. package framework import ( - "bytes" "fmt" - "regexp" - "runtime/debug" "time" "github.com/onsi/ginkgo/v2" - // TODO: Remove the following imports (ref: https://github.com/kubernetes/kubernetes/issues/81245) ) func nowStamp() string { @@ -45,61 +41,9 @@ func Logf(format string, args ...interface{}) { func Failf(format string, args ...interface{}) { msg := fmt.Sprintf(format, args...) skip := 1 - log("FAIL", "%s\n\nFull Stack Trace\n%s", msg, PrunedStack(skip)) - ginkgo.Fail(nowStamp()+": "+msg, skip) + ginkgo.Fail(msg, skip) panic("unreachable") } -// Fail is a replacement for ginkgo.Fail which logs the problem as it occurs -// together with a stack trace and then calls ginkgowrapper.Fail. -func Fail(msg string, callerSkip ...int) { - skip := 1 - if len(callerSkip) > 0 { - skip += callerSkip[0] - } - log("FAIL", "%s\n\nFull Stack Trace\n%s", msg, PrunedStack(skip)) - ginkgo.Fail(nowStamp()+": "+msg, skip) -} - -var codeFilterRE = regexp.MustCompile(`/github.com/onsi/ginkgo/v2/`) - -// PrunedStack is a wrapper around debug.Stack() that removes information -// about the current goroutine and optionally skips some of the initial stack entries. -// With skip == 0, the returned stack will start with the caller of PruneStack. -// From the remaining entries it automatically filters out useless ones like -// entries coming from Ginkgo. -// -// This is a modified copy of PruneStack in https://github.com/onsi/ginkgo/v2/blob/f90f37d87fa6b1dd9625e2b1e83c23ffae3de228/internal/codelocation/code_location.go#L25: -// - simplified API and thus renamed (calls debug.Stack() instead of taking a parameter) -// - source code filtering updated to be specific to Kubernetes -// - optimized to use bytes and in-place slice filtering from -// https://github.com/golang/go/wiki/SliceTricks#filter-in-place -func PrunedStack(skip int) []byte { - fullStackTrace := debug.Stack() - stack := bytes.Split(fullStackTrace, []byte("\n")) - // Ensure that the even entries are the method names and - // the odd entries the source code information. - if len(stack) > 0 && bytes.HasPrefix(stack[0], []byte("goroutine ")) { - // Ignore "goroutine 29 [running]:" line. - stack = stack[1:] - } - // The "+2" is for skipping over: - // - runtime/debug.Stack() - // - PrunedStack() - skip += 2 - if len(stack) > 2*skip { - stack = stack[2*skip:] - } - n := 0 - for i := 0; i < len(stack)/2; i++ { - // We filter out based on the source code file name. - if !codeFilterRE.Match([]byte(stack[i*2+1])) { - stack[n] = stack[i*2] - stack[n+1] = stack[i*2+1] - n += 2 - } - } - stack = stack[:n] - - return bytes.Join(stack, []byte("\n")) -} +// Fail is an alias for ginkgo.Fail. +var Fail = ginkgo.Fail diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/OWNERS b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/OWNERS new file mode 100644 index 000000000..e31c11166 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/OWNERS @@ -0,0 +1,14 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - sig-instrumentation-approvers +emeritus_approvers: + - fabxc + - piosz + - fgrzadkowski + - kawych + - x13n +reviewers: + - sig-instrumentation-reviewers +labels: + - sig/instrumentation diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/api_server_metrics.go b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/api_server_metrics.go index 3b7e376ce..78b46c733 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/api_server_metrics.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/api_server_metrics.go @@ -17,8 +17,6 @@ limitations under the License. package metrics import ( - "context" - "k8s.io/component-base/metrics/testutil" ) @@ -42,11 +40,3 @@ func parseAPIServerMetrics(data string) (APIServerMetrics, error) { } return result, nil } - -func (g *Grabber) getMetricsFromAPIServer() (string, error) { - rawOutput, err := g.client.CoreV1().RESTClient().Get().RequestURI("/metrics").Do(context.TODO()).Raw() - if err != nil { - return "", err - } - return string(rawOutput), nil -} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/grab.go b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/grab.go index 2264f9f37..23e9ad2b4 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/grab.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/grab.go @@ -17,24 +17,26 @@ limitations under the License. package metrics import ( + "context" + "github.com/onsi/ginkgo/v2" "k8s.io/kubernetes/test/e2e/framework" ) -func GrabBeforeEach(f *framework.Framework) (result *Collection) { +func GrabBeforeEach(ctx context.Context, f *framework.Framework) (result *Collection) { gatherMetricsAfterTest := framework.TestContext.GatherMetricsAfterTest == "true" || framework.TestContext.GatherMetricsAfterTest == "master" if !gatherMetricsAfterTest || !framework.TestContext.IncludeClusterAutoscalerMetrics { return nil } ginkgo.By("Gathering metrics before test", func() { - grabber, err := NewMetricsGrabber(f.ClientSet, f.KubemarkExternalClusterClientSet, f.ClientConfig(), !framework.ProviderIs("kubemark"), false, false, false, framework.TestContext.IncludeClusterAutoscalerMetrics, false) + grabber, err := NewMetricsGrabber(ctx, f.ClientSet, f.KubemarkExternalClusterClientSet, f.ClientConfig(), !framework.ProviderIs("kubemark"), false, false, false, framework.TestContext.IncludeClusterAutoscalerMetrics, false) if err != nil { framework.Logf("Failed to create MetricsGrabber (skipping ClusterAutoscaler metrics gathering before test): %v", err) return } - metrics, err := grabber.Grab() + metrics, err := grabber.Grab(ctx) if err != nil { framework.Logf("MetricsGrabber failed to grab CA metrics before test (skipping metrics gathering): %v", err) return @@ -46,7 +48,7 @@ func GrabBeforeEach(f *framework.Framework) (result *Collection) { return } -func GrabAfterEach(f *framework.Framework, before *Collection) { +func GrabAfterEach(ctx context.Context, f *framework.Framework, before *Collection) { if framework.TestContext.GatherMetricsAfterTest == "false" { return } @@ -54,12 +56,12 @@ func GrabAfterEach(f *framework.Framework, before *Collection) { ginkgo.By("Gathering metrics after test", func() { // Grab apiserver, scheduler, controller-manager metrics and (optionally) nodes' kubelet metrics. grabMetricsFromKubelets := framework.TestContext.GatherMetricsAfterTest != "master" && !framework.ProviderIs("kubemark") - grabber, err := NewMetricsGrabber(f.ClientSet, f.KubemarkExternalClusterClientSet, f.ClientConfig(), grabMetricsFromKubelets, true, true, true, framework.TestContext.IncludeClusterAutoscalerMetrics, false) + grabber, err := NewMetricsGrabber(ctx, f.ClientSet, f.KubemarkExternalClusterClientSet, f.ClientConfig(), grabMetricsFromKubelets, true, true, true, framework.TestContext.IncludeClusterAutoscalerMetrics, false) if err != nil { framework.Logf("Failed to create MetricsGrabber (skipping metrics gathering): %v", err) return } - received, err := grabber.Grab() + received, err := grabber.Grab(ctx) if err != nil { framework.Logf("MetricsGrabber failed to grab some of the metrics: %v", err) return diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/kubelet_metrics.go b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/kubelet_metrics.go index 12becf9b8..545f61388 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/kubelet_metrics.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/kubelet_metrics.go @@ -68,9 +68,12 @@ func NewKubeletMetrics() KubeletMetrics { } // GrabKubeletMetricsWithoutProxy retrieve metrics from the kubelet on the given node using a simple GET over http. -// Currently only used in integration tests. -func GrabKubeletMetricsWithoutProxy(nodeName, path string) (KubeletMetrics, error) { - resp, err := http.Get(fmt.Sprintf("http://%s%s", nodeName, path)) +func GrabKubeletMetricsWithoutProxy(ctx context.Context, nodeName, path string) (KubeletMetrics, error) { + req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("http://%s%s", nodeName, path), nil) + if err != nil { + return KubeletMetrics{}, err + } + resp, err := http.DefaultClient.Do(req) if err != nil { return KubeletMetrics{}, err } @@ -90,31 +93,6 @@ func parseKubeletMetrics(data string) (KubeletMetrics, error) { return result, nil } -func (g *Grabber) getMetricsFromNode(nodeName string, kubeletPort int) (string, error) { - // There's a problem with timing out during proxy. Wrapping this in a goroutine to prevent deadlock. - finished := make(chan struct{}, 1) - var err error - var rawOutput []byte - go func() { - rawOutput, err = g.client.CoreV1().RESTClient().Get(). - Resource("nodes"). - SubResource("proxy"). - Name(fmt.Sprintf("%v:%v", nodeName, kubeletPort)). - Suffix("metrics"). - Do(context.TODO()).Raw() - finished <- struct{}{} - }() - select { - case <-time.After(proxyTimeout): - return "", fmt.Errorf("Timed out when waiting for proxy to gather metrics from %v", nodeName) - case <-finished: - if err != nil { - return "", err - } - return string(rawOutput), nil - } -} - // KubeletLatencyMetric stores metrics scraped from the kubelet server's /metric endpoint. // TODO: Get some more structure around the metrics and this type type KubeletLatencyMetric struct { @@ -137,21 +115,21 @@ func (a KubeletLatencyMetrics) Less(i, j int) bool { return a[i].Latency > a[j]. // If a apiserver client is passed in, the function will try to get kubelet metrics from metrics grabber; // or else, the function will try to get kubelet metrics directly from the node. -func getKubeletMetricsFromNode(c clientset.Interface, nodeName string) (KubeletMetrics, error) { +func getKubeletMetricsFromNode(ctx context.Context, c clientset.Interface, nodeName string) (KubeletMetrics, error) { if c == nil { - return GrabKubeletMetricsWithoutProxy(nodeName, "/metrics") + return GrabKubeletMetricsWithoutProxy(ctx, nodeName, "/metrics") } - grabber, err := NewMetricsGrabber(c, nil, nil, true, false, false, false, false, false) + grabber, err := NewMetricsGrabber(ctx, c, nil, nil, true, false, false, false, false, false) if err != nil { return KubeletMetrics{}, err } - return grabber.GrabFromKubelet(nodeName) + return grabber.GrabFromKubelet(ctx, nodeName) } // GetKubeletMetrics gets all metrics in kubelet subsystem from specified node and trims // the subsystem prefix. -func GetKubeletMetrics(c clientset.Interface, nodeName string) (KubeletMetrics, error) { - ms, err := getKubeletMetricsFromNode(c, nodeName) +func GetKubeletMetrics(ctx context.Context, c clientset.Interface, nodeName string) (KubeletMetrics, error) { + ms, err := getKubeletMetricsFromNode(ctx, c, nodeName) if err != nil { return KubeletMetrics{}, err } @@ -217,8 +195,8 @@ func GetKubeletLatencyMetrics(ms KubeletMetrics, filterMetricNames sets.String) } // HighLatencyKubeletOperations logs and counts the high latency metrics exported by the kubelet server via /metrics. -func HighLatencyKubeletOperations(c clientset.Interface, threshold time.Duration, nodeName string, logFunc func(fmt string, args ...interface{})) (KubeletLatencyMetrics, error) { - ms, err := GetKubeletMetrics(c, nodeName) +func HighLatencyKubeletOperations(ctx context.Context, c clientset.Interface, threshold time.Duration, nodeName string, logFunc func(fmt string, args ...interface{})) (KubeletLatencyMetrics, error) { + ms, err := GetKubeletMetrics(ctx, c, nodeName) if err != nil { return KubeletLatencyMetrics{}, err } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/metrics_grabber.go b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/metrics_grabber.go index 63c90c3ed..2fdcd842d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/metrics_grabber.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/metrics/metrics_grabber.go @@ -54,6 +54,7 @@ var MetricsGrabbingDisabledError = errors.New("metrics grabbing disabled") // Collection is metrics collection of components type Collection struct { APIServerMetrics APIServerMetrics + APIServerMetricsSLIs APIServerMetrics ControllerManagerMetrics ControllerManagerMetrics SnapshotControllerMetrics SnapshotControllerMetrics KubeletMetrics map[string]KubeletMetrics @@ -88,7 +89,7 @@ type Grabber struct { // Collecting metrics data is an optional debug feature. Not all clusters will // support it. If disabled for a component, the corresponding Grab function // will immediately return an error derived from MetricsGrabbingDisabledError. -func NewMetricsGrabber(c clientset.Interface, ec clientset.Interface, config *rest.Config, kubelets bool, scheduler bool, controllers bool, apiServer bool, clusterAutoscaler bool, snapshotController bool) (*Grabber, error) { +func NewMetricsGrabber(ctx context.Context, c clientset.Interface, ec clientset.Interface, config *rest.Config, kubelets bool, scheduler bool, controllers bool, apiServer bool, clusterAutoscaler bool, snapshotController bool) (*Grabber, error) { kubeScheduler := "" kubeControllerManager := "" @@ -102,7 +103,7 @@ func NewMetricsGrabber(c clientset.Interface, ec clientset.Interface, config *re return nil, errors.New("a rest config is required for grabbing kube-controller and kube-controller-manager metrics") } - podList, err := c.CoreV1().Pods(metav1.NamespaceSystem).List(context.TODO(), metav1.ListOptions{}) + podList, err := c.CoreV1().Pods(metav1.NamespaceSystem).List(ctx, metav1.ListOptions{}) if err != nil { return nil, err } @@ -132,18 +133,18 @@ func NewMetricsGrabber(c clientset.Interface, ec clientset.Interface, config *re externalClient: ec, config: config, grabFromAPIServer: apiServer, - grabFromControllerManager: checkPodDebugHandlers(c, controllers, "kube-controller-manager", kubeControllerManager), + grabFromControllerManager: checkPodDebugHandlers(ctx, c, controllers, "kube-controller-manager", kubeControllerManager), grabFromKubelets: kubelets, - grabFromScheduler: checkPodDebugHandlers(c, scheduler, "kube-scheduler", kubeScheduler), + grabFromScheduler: checkPodDebugHandlers(ctx, c, scheduler, "kube-scheduler", kubeScheduler), grabFromClusterAutoscaler: clusterAutoscaler, - grabFromSnapshotController: checkPodDebugHandlers(c, snapshotController, "snapshot-controller", snapshotControllerManager), + grabFromSnapshotController: checkPodDebugHandlers(ctx, c, snapshotController, "snapshot-controller", snapshotControllerManager), kubeScheduler: kubeScheduler, kubeControllerManager: kubeControllerManager, snapshotController: snapshotControllerManager, }, nil } -func checkPodDebugHandlers(c clientset.Interface, requested bool, component, podName string) bool { +func checkPodDebugHandlers(ctx context.Context, c clientset.Interface, requested bool, component, podName string) bool { if !requested { return false } @@ -155,7 +156,7 @@ func checkPodDebugHandlers(c clientset.Interface, requested bool, component, pod // The debug handlers on the host where the pod runs might be disabled. // We can check that indirectly by trying to retrieve log output. limit := int64(1) - if _, err := c.CoreV1().Pods(metav1.NamespaceSystem).GetLogs(podName, &v1.PodLogOptions{LimitBytes: &limit}).DoRaw(context.TODO()); err != nil { + if _, err := c.CoreV1().Pods(metav1.NamespaceSystem).GetLogs(podName, &v1.PodLogOptions{LimitBytes: &limit}).DoRaw(ctx); err != nil { klog.Warningf("Can't retrieve log output of %s (%q). Debug handlers might be disabled in kubelet. Grabbing metrics from %s is disabled.", podName, err, component) return false @@ -171,8 +172,8 @@ func (g *Grabber) HasControlPlanePods() bool { } // GrabFromKubelet returns metrics from kubelet -func (g *Grabber) GrabFromKubelet(nodeName string) (KubeletMetrics, error) { - nodes, err := g.client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{FieldSelector: fields.Set{"metadata.name": nodeName}.AsSelector().String()}) +func (g *Grabber) GrabFromKubelet(ctx context.Context, nodeName string) (KubeletMetrics, error) { + nodes, err := g.client.CoreV1().Nodes().List(ctx, metav1.ListOptions{FieldSelector: fields.Set{"metadata.name": nodeName}.AsSelector().String()}) if err != nil { return KubeletMetrics{}, err } @@ -180,22 +181,47 @@ func (g *Grabber) GrabFromKubelet(nodeName string) (KubeletMetrics, error) { return KubeletMetrics{}, fmt.Errorf("Error listing nodes with name %v, got %v", nodeName, nodes.Items) } kubeletPort := nodes.Items[0].Status.DaemonEndpoints.KubeletEndpoint.Port - return g.grabFromKubeletInternal(nodeName, int(kubeletPort)) + return g.grabFromKubeletInternal(ctx, nodeName, int(kubeletPort)) } -func (g *Grabber) grabFromKubeletInternal(nodeName string, kubeletPort int) (KubeletMetrics, error) { +func (g *Grabber) grabFromKubeletInternal(ctx context.Context, nodeName string, kubeletPort int) (KubeletMetrics, error) { if kubeletPort <= 0 || kubeletPort > 65535 { return KubeletMetrics{}, fmt.Errorf("Invalid Kubelet port %v. Skipping Kubelet's metrics gathering", kubeletPort) } - output, err := g.getMetricsFromNode(nodeName, int(kubeletPort)) + output, err := g.getMetricsFromNode(ctx, nodeName, int(kubeletPort)) if err != nil { return KubeletMetrics{}, err } return parseKubeletMetrics(output) } +func (g *Grabber) getMetricsFromNode(ctx context.Context, nodeName string, kubeletPort int) (string, error) { + // There's a problem with timing out during proxy. Wrapping this in a goroutine to prevent deadlock. + finished := make(chan struct{}, 1) + var err error + var rawOutput []byte + go func() { + rawOutput, err = g.client.CoreV1().RESTClient().Get(). + Resource("nodes"). + SubResource("proxy"). + Name(fmt.Sprintf("%v:%v", nodeName, kubeletPort)). + Suffix("metrics"). + Do(ctx).Raw() + finished <- struct{}{} + }() + select { + case <-time.After(proxyTimeout): + return "", fmt.Errorf("Timed out when waiting for proxy to gather metrics from %v", nodeName) + case <-finished: + if err != nil { + return "", err + } + return string(rawOutput), nil + } +} + // GrabFromScheduler returns metrics from scheduler -func (g *Grabber) GrabFromScheduler() (SchedulerMetrics, error) { +func (g *Grabber) GrabFromScheduler(ctx context.Context) (SchedulerMetrics, error) { if !g.grabFromScheduler { return SchedulerMetrics{}, fmt.Errorf("kube-scheduler: %w", MetricsGrabbingDisabledError) } @@ -203,7 +229,7 @@ func (g *Grabber) GrabFromScheduler() (SchedulerMetrics, error) { var err error g.waitForSchedulerReadyOnce.Do(func() { - if readyErr := e2epod.WaitTimeoutForPodReadyInNamespace(g.client, g.kubeScheduler, metav1.NamespaceSystem, 5*time.Minute); readyErr != nil { + if readyErr := e2epod.WaitTimeoutForPodReadyInNamespace(ctx, g.client, g.kubeScheduler, metav1.NamespaceSystem, 5*time.Minute); readyErr != nil { err = fmt.Errorf("error waiting for kube-scheduler pod to be ready: %w", readyErr) } }) @@ -213,8 +239,8 @@ func (g *Grabber) GrabFromScheduler() (SchedulerMetrics, error) { var lastMetricsFetchErr error var output string - if metricsWaitErr := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) { - output, lastMetricsFetchErr = g.getSecureMetricsFromPod(g.kubeScheduler, metav1.NamespaceSystem, kubeSchedulerPort) + if metricsWaitErr := wait.PollImmediateWithContext(ctx, time.Second, time.Minute, func(ctx context.Context) (bool, error) { + output, lastMetricsFetchErr = g.getSecureMetricsFromPod(ctx, g.kubeScheduler, metav1.NamespaceSystem, kubeSchedulerPort) return lastMetricsFetchErr == nil, nil }); metricsWaitErr != nil { err := fmt.Errorf("error waiting for kube-scheduler pod to expose metrics: %v; %v", metricsWaitErr, lastMetricsFetchErr) @@ -225,7 +251,7 @@ func (g *Grabber) GrabFromScheduler() (SchedulerMetrics, error) { } // GrabFromClusterAutoscaler returns metrics from cluster autoscaler -func (g *Grabber) GrabFromClusterAutoscaler() (ClusterAutoscalerMetrics, error) { +func (g *Grabber) GrabFromClusterAutoscaler(ctx context.Context) (ClusterAutoscalerMetrics, error) { if !g.HasControlPlanePods() && g.externalClient == nil { return ClusterAutoscalerMetrics{}, fmt.Errorf("ClusterAutoscaler: %w", MetricsGrabbingDisabledError) } @@ -238,7 +264,7 @@ func (g *Grabber) GrabFromClusterAutoscaler() (ClusterAutoscalerMetrics, error) client = g.client namespace = metav1.NamespaceSystem } - output, err := g.getMetricsFromPod(client, "cluster-autoscaler", namespace, 8085) + output, err := g.getMetricsFromPod(ctx, client, "cluster-autoscaler", namespace, 8085) if err != nil { return ClusterAutoscalerMetrics{}, err } @@ -246,7 +272,7 @@ func (g *Grabber) GrabFromClusterAutoscaler() (ClusterAutoscalerMetrics, error) } // GrabFromControllerManager returns metrics from controller manager -func (g *Grabber) GrabFromControllerManager() (ControllerManagerMetrics, error) { +func (g *Grabber) GrabFromControllerManager(ctx context.Context) (ControllerManagerMetrics, error) { if !g.grabFromControllerManager { return ControllerManagerMetrics{}, fmt.Errorf("kube-controller-manager: %w", MetricsGrabbingDisabledError) } @@ -254,7 +280,7 @@ func (g *Grabber) GrabFromControllerManager() (ControllerManagerMetrics, error) var err error g.waitForControllerManagerReadyOnce.Do(func() { - if readyErr := e2epod.WaitTimeoutForPodReadyInNamespace(g.client, g.kubeControllerManager, metav1.NamespaceSystem, 5*time.Minute); readyErr != nil { + if readyErr := e2epod.WaitTimeoutForPodReadyInNamespace(ctx, g.client, g.kubeControllerManager, metav1.NamespaceSystem, 5*time.Minute); readyErr != nil { err = fmt.Errorf("error waiting for kube-controller-manager pod to be ready: %w", readyErr) } }) @@ -264,8 +290,8 @@ func (g *Grabber) GrabFromControllerManager() (ControllerManagerMetrics, error) var output string var lastMetricsFetchErr error - if metricsWaitErr := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) { - output, lastMetricsFetchErr = g.getSecureMetricsFromPod(g.kubeControllerManager, metav1.NamespaceSystem, kubeControllerManagerPort) + if metricsWaitErr := wait.PollImmediateWithContext(ctx, time.Second, time.Minute, func(ctx context.Context) (bool, error) { + output, lastMetricsFetchErr = g.getSecureMetricsFromPod(ctx, g.kubeControllerManager, metav1.NamespaceSystem, kubeControllerManagerPort) return lastMetricsFetchErr == nil, nil }); metricsWaitErr != nil { err := fmt.Errorf("error waiting for kube-controller-manager to expose metrics: %v; %v", metricsWaitErr, lastMetricsFetchErr) @@ -276,7 +302,7 @@ func (g *Grabber) GrabFromControllerManager() (ControllerManagerMetrics, error) } // GrabFromSnapshotController returns metrics from controller manager -func (g *Grabber) GrabFromSnapshotController(podName string, port int) (SnapshotControllerMetrics, error) { +func (g *Grabber) GrabFromSnapshotController(ctx context.Context, podName string, port int) (SnapshotControllerMetrics, error) { if !g.grabFromSnapshotController { return SnapshotControllerMetrics{}, fmt.Errorf("volume-snapshot-controller: %w", MetricsGrabbingDisabledError) } @@ -293,7 +319,7 @@ func (g *Grabber) GrabFromSnapshotController(podName string, port int) (Snapshot var err error g.waitForSnapshotControllerReadyOnce.Do(func() { - if readyErr := e2epod.WaitTimeoutForPodReadyInNamespace(g.client, podName, metav1.NamespaceSystem, 5*time.Minute); readyErr != nil { + if readyErr := e2epod.WaitTimeoutForPodReadyInNamespace(ctx, g.client, podName, metav1.NamespaceSystem, 5*time.Minute); readyErr != nil { err = fmt.Errorf("error waiting for volume-snapshot-controller pod to be ready: %w", readyErr) } }) @@ -303,8 +329,8 @@ func (g *Grabber) GrabFromSnapshotController(podName string, port int) (Snapshot var output string var lastMetricsFetchErr error - if metricsWaitErr := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) { - output, lastMetricsFetchErr = g.getMetricsFromPod(g.client, podName, metav1.NamespaceSystem, port) + if metricsWaitErr := wait.PollImmediateWithContext(ctx, time.Second, time.Minute, func(ctx context.Context) (bool, error) { + output, lastMetricsFetchErr = g.getMetricsFromPod(ctx, g.client, podName, metav1.NamespaceSystem, port) return lastMetricsFetchErr == nil, nil }); metricsWaitErr != nil { err = fmt.Errorf("error waiting for volume-snapshot-controller pod to expose metrics: %v; %v", metricsWaitErr, lastMetricsFetchErr) @@ -315,28 +341,59 @@ func (g *Grabber) GrabFromSnapshotController(podName string, port int) (Snapshot } // GrabFromAPIServer returns metrics from API server -func (g *Grabber) GrabFromAPIServer() (APIServerMetrics, error) { - output, err := g.getMetricsFromAPIServer() +func (g *Grabber) GrabFromAPIServer(ctx context.Context) (APIServerMetrics, error) { + output, err := g.getMetricsFromAPIServer(ctx) if err != nil { return APIServerMetrics{}, err } return parseAPIServerMetrics(output) } +// GrabMetricsSLIsFromAPIServer returns metrics from API server +func (g *Grabber) GrabMetricsSLIsFromAPIServer(ctx context.Context) (APIServerMetrics, error) { + output, err := g.getMetricsSLIsFromAPIServer(ctx) + if err != nil { + return APIServerMetrics{}, err + } + return parseAPIServerMetrics(output) +} + +func (g *Grabber) getMetricsFromAPIServer(ctx context.Context) (string, error) { + rawOutput, err := g.client.CoreV1().RESTClient().Get().RequestURI("/metrics").Do(ctx).Raw() + if err != nil { + return "", err + } + return string(rawOutput), nil +} + +func (g *Grabber) getMetricsSLIsFromAPIServer(ctx context.Context) (string, error) { + rawOutput, err := g.client.CoreV1().RESTClient().Get().RequestURI("/metrics/slis").Do(ctx).Raw() + if err != nil { + return "", err + } + return string(rawOutput), nil +} + // Grab returns metrics from corresponding component -func (g *Grabber) Grab() (Collection, error) { +func (g *Grabber) Grab(ctx context.Context) (Collection, error) { result := Collection{} var errs []error if g.grabFromAPIServer { - metrics, err := g.GrabFromAPIServer() + metrics, err := g.GrabFromAPIServer(ctx) if err != nil { errs = append(errs, err) } else { result.APIServerMetrics = metrics } + metrics, err = g.GrabMetricsSLIsFromAPIServer(ctx) + if err != nil { + errs = append(errs, err) + } else { + result.APIServerMetricsSLIs = metrics + } } if g.grabFromScheduler { - metrics, err := g.GrabFromScheduler() + metrics, err := g.GrabFromScheduler(ctx) if err != nil { errs = append(errs, err) } else { @@ -344,7 +401,7 @@ func (g *Grabber) Grab() (Collection, error) { } } if g.grabFromControllerManager { - metrics, err := g.GrabFromControllerManager() + metrics, err := g.GrabFromControllerManager(ctx) if err != nil { errs = append(errs, err) } else { @@ -352,7 +409,7 @@ func (g *Grabber) Grab() (Collection, error) { } } if g.grabFromSnapshotController { - metrics, err := g.GrabFromSnapshotController(g.snapshotController, snapshotControllerPort) + metrics, err := g.GrabFromSnapshotController(ctx, g.snapshotController, snapshotControllerPort) if err != nil { errs = append(errs, err) } else { @@ -360,7 +417,7 @@ func (g *Grabber) Grab() (Collection, error) { } } if g.grabFromClusterAutoscaler { - metrics, err := g.GrabFromClusterAutoscaler() + metrics, err := g.GrabFromClusterAutoscaler(ctx) if err != nil { errs = append(errs, err) } else { @@ -369,13 +426,13 @@ func (g *Grabber) Grab() (Collection, error) { } if g.grabFromKubelets { result.KubeletMetrics = make(map[string]KubeletMetrics) - nodes, err := g.client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) + nodes, err := g.client.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { errs = append(errs, err) } else { for _, node := range nodes.Items { kubeletPort := node.Status.DaemonEndpoints.KubeletEndpoint.Port - metrics, err := g.grabFromKubeletInternal(node.Name, int(kubeletPort)) + metrics, err := g.grabFromKubeletInternal(ctx, node.Name, int(kubeletPort)) if err != nil { errs = append(errs, err) } @@ -390,14 +447,14 @@ func (g *Grabber) Grab() (Collection, error) { } // getMetricsFromPod retrieves metrics data from an insecure port. -func (g *Grabber) getMetricsFromPod(client clientset.Interface, podName string, namespace string, port int) (string, error) { +func (g *Grabber) getMetricsFromPod(ctx context.Context, client clientset.Interface, podName string, namespace string, port int) (string, error) { rawOutput, err := client.CoreV1().RESTClient().Get(). Namespace(namespace). Resource("pods"). SubResource("proxy"). Name(fmt.Sprintf("%s:%d", podName, port)). Suffix("metrics"). - Do(context.TODO()).Raw() + Do(ctx).Raw() if err != nil { return "", err } @@ -409,7 +466,7 @@ func (g *Grabber) getMetricsFromPod(client clientset.Interface, podName string, // similar to "kubectl port-forward" + "kubectl get --raw // https://localhost:/metrics". It uses the same credentials // as kubelet. -func (g *Grabber) getSecureMetricsFromPod(podName string, namespace string, port int) (string, error) { +func (g *Grabber) getSecureMetricsFromPod(ctx context.Context, podName string, namespace string, port int) (string, error) { dialer := e2epod.NewDialer(g.client, g.config) metricConfig := rest.CopyConfig(g.config) addr := e2epod.Addr{ @@ -444,7 +501,7 @@ func (g *Grabber) getSecureMetricsFromPod(podName string, namespace string, port rawOutput, err := metricClient.RESTClient().Get(). AbsPath("metrics"). - Do(context.TODO()).Raw() + Do(ctx).Raw() if err != nil { return "", err } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/namespacedname.go b/vendor/k8s.io/kubernetes/test/e2e/framework/namespacedname.go new file mode 100644 index 000000000..531d950a6 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/namespacedname.go @@ -0,0 +1,49 @@ +/* +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 framework + +// NamespacedName comprises a resource name, with a mandatory namespace, +// rendered as "/". It implements NamedObject and thus can be +// used as function parameter instead of a full API object. +type NamespacedName struct { + Namespace string + Name string +} + +var _ NamedObject = NamespacedName{} + +// NamedObject is a subset of metav1.Object which provides read-only access +// to name and namespace of an object. +type NamedObject interface { + GetNamespace() string + GetName() string +} + +// GetNamespace implements NamedObject. +func (n NamespacedName) GetNamespace() string { + return n.Namespace +} + +// GetName implements NamedObject. +func (n NamespacedName) GetName() string { + return n.Name +} + +// String returns the general purpose string representation +func (n NamespacedName) String() string { + return n.Namespace + "/" + n.Name +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/node/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/helper.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/helper.go index 945577ad3..90a9dbb59 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/helper.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/helper.go @@ -39,16 +39,17 @@ const ( // WaitForAllNodesSchedulable waits up to timeout for all // (but TestContext.AllowedNotReadyNodes) to become schedulable. -func WaitForAllNodesSchedulable(c clientset.Interface, timeout time.Duration) error { +func WaitForAllNodesSchedulable(ctx context.Context, c clientset.Interface, timeout time.Duration) error { if framework.TestContext.AllowedNotReadyNodes == -1 { return nil } framework.Logf("Waiting up to %v for all (but %d) nodes to be schedulable", timeout, framework.TestContext.AllowedNotReadyNodes) - return wait.PollImmediate( + return wait.PollImmediateWithContext( + ctx, 30*time.Second, timeout, - CheckReadyForTests(c, framework.TestContext.NonblockingTaints, framework.TestContext.AllowedNotReadyNodes, largeClusterThreshold), + CheckReadyForTests(ctx, c, framework.TestContext.NonblockingTaints, framework.TestContext.AllowedNotReadyNodes, largeClusterThreshold), ) } @@ -58,9 +59,9 @@ func AddOrUpdateLabelOnNode(c clientset.Interface, nodeName string, labelKey, la } // ExpectNodeHasLabel expects that the given node has the given label pair. -func ExpectNodeHasLabel(c clientset.Interface, nodeName string, labelKey string, labelValue string) { +func ExpectNodeHasLabel(ctx context.Context, c clientset.Interface, nodeName string, labelKey string, labelValue string) { ginkgo.By("verifying the node has the label " + labelKey + " " + labelValue) - node, err := c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) + node, err := c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) framework.ExpectNoError(err) framework.ExpectEqual(node.Labels[labelKey], labelValue) } @@ -76,17 +77,17 @@ func RemoveLabelOffNode(c clientset.Interface, nodeName string, labelKey string) } // ExpectNodeHasTaint expects that the node has the given taint. -func ExpectNodeHasTaint(c clientset.Interface, nodeName string, taint *v1.Taint) { +func ExpectNodeHasTaint(ctx context.Context, c clientset.Interface, nodeName string, taint *v1.Taint) { ginkgo.By("verifying the node has the taint " + taint.ToString()) - if has, err := NodeHasTaint(c, nodeName, taint); !has { + if has, err := NodeHasTaint(ctx, c, nodeName, taint); !has { framework.ExpectNoError(err) framework.Failf("Failed to find taint %s on node %s", taint.ToString(), nodeName) } } // NodeHasTaint returns true if the node has the given taint, else returns false. -func NodeHasTaint(c clientset.Interface, nodeName string, taint *v1.Taint) (bool, error) { - node, err := c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) +func NodeHasTaint(ctx context.Context, c clientset.Interface, nodeName string, taint *v1.Taint) (bool, error) { + node, err := c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) if err != nil { return false, err } @@ -104,14 +105,14 @@ func NodeHasTaint(c clientset.Interface, nodeName string, taint *v1.Taint) (bool // TODO: we should change the AllNodesReady call in AfterEach to WaitForAllNodesHealthy, // and figure out how to do it in a configurable way, as we can't expect all setups to run // default test add-ons. -func AllNodesReady(c clientset.Interface, timeout time.Duration) error { - if err := allNodesReady(c, timeout); err != nil { - return fmt.Errorf("checking for ready nodes: %v", err) +func AllNodesReady(ctx context.Context, c clientset.Interface, timeout time.Duration) error { + if err := allNodesReady(ctx, c, timeout); err != nil { + return fmt.Errorf("checking for ready nodes: %w", err) } return nil } -func allNodesReady(c clientset.Interface, timeout time.Duration) error { +func allNodesReady(ctx context.Context, c clientset.Interface, timeout time.Duration) error { if framework.TestContext.AllowedNotReadyNodes == -1 { return nil } @@ -119,10 +120,10 @@ func allNodesReady(c clientset.Interface, timeout time.Duration) error { framework.Logf("Waiting up to %v for all (but %d) nodes to be ready", timeout, framework.TestContext.AllowedNotReadyNodes) var notReady []*v1.Node - err := wait.PollImmediate(framework.Poll, timeout, func() (bool, error) { + err := wait.PollImmediateWithContext(ctx, framework.Poll, timeout, func(ctx context.Context) (bool, error) { notReady = nil // It should be OK to list unschedulable Nodes here. - nodes, err := c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) + nodes, err := c.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { return false, err } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/node_killer.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/node_killer.go index 1634aeb4e..fafb6b6a6 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/node_killer.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/node_killer.go @@ -17,6 +17,7 @@ limitations under the License. package node import ( + "context" "sync" "time" @@ -39,31 +40,31 @@ type NodeKiller struct { // NewNodeKiller creates new NodeKiller. func NewNodeKiller(config framework.NodeKillerConfig, client clientset.Interface, provider string) *NodeKiller { - config.NodeKillerStopCh = make(chan struct{}) + config.NodeKillerStopCtx, config.NodeKillerStop = context.WithCancel(context.Background()) return &NodeKiller{config, client, provider} } // Run starts NodeKiller until stopCh is closed. -func (k *NodeKiller) Run(stopCh <-chan struct{}) { +func (k *NodeKiller) Run(ctx context.Context) { // wait.JitterUntil starts work immediately, so wait first. time.Sleep(wait.Jitter(k.config.Interval, k.config.JitterFactor)) - wait.JitterUntil(func() { - nodes := k.pickNodes() - k.kill(nodes) - }, k.config.Interval, k.config.JitterFactor, true, stopCh) + wait.JitterUntilWithContext(ctx, func(ctx context.Context) { + nodes := k.pickNodes(ctx) + k.kill(ctx, nodes) + }, k.config.Interval, k.config.JitterFactor, true) } -func (k *NodeKiller) pickNodes() []v1.Node { - nodes, err := GetReadySchedulableNodes(k.client) +func (k *NodeKiller) pickNodes(ctx context.Context) []v1.Node { + nodes, err := GetReadySchedulableNodes(ctx, k.client) framework.ExpectNoError(err) numNodes := int(k.config.FailureRatio * float64(len(nodes.Items))) - nodes, err = GetBoundedReadySchedulableNodes(k.client, numNodes) + nodes, err = GetBoundedReadySchedulableNodes(ctx, k.client, numNodes) framework.ExpectNoError(err) return nodes.Items } -func (k *NodeKiller) kill(nodes []v1.Node) { +func (k *NodeKiller) kill(ctx context.Context, nodes []v1.Node) { wg := sync.WaitGroup{} wg.Add(len(nodes)) for _, node := range nodes { @@ -73,7 +74,7 @@ func (k *NodeKiller) kill(nodes []v1.Node) { defer wg.Done() framework.Logf("Stopping docker and kubelet on %q to simulate failure", node.Name) - err := e2essh.IssueSSHCommand("sudo systemctl stop docker kubelet", k.provider, &node) + err := e2essh.IssueSSHCommand(ctx, "sudo systemctl stop docker kubelet", k.provider, &node) if err != nil { framework.Logf("ERROR while stopping node %q: %v", node.Name, err) return @@ -82,7 +83,7 @@ func (k *NodeKiller) kill(nodes []v1.Node) { time.Sleep(k.config.SimulatedDowntime) framework.Logf("Rebooting %q to repair the node", node.Name) - err = e2essh.IssueSSHCommand("sudo reboot", k.provider, &node) + err = e2essh.IssueSSHCommand(ctx, "sudo reboot", k.provider, &node) if err != nil { framework.Logf("ERROR while rebooting node %q: %v", node.Name, err) return diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go index 6d33380ac..a8b166c65 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/resource.go @@ -193,8 +193,8 @@ func Filter(nodeList *v1.NodeList, fn func(node v1.Node) bool) { } // TotalRegistered returns number of schedulable Nodes. -func TotalRegistered(c clientset.Interface) (int, error) { - nodes, err := waitListSchedulableNodes(c) +func TotalRegistered(ctx context.Context, c clientset.Interface) (int, error) { + nodes, err := waitListSchedulableNodes(ctx, c) if err != nil { framework.Logf("Failed to list nodes: %v", err) return 0, err @@ -203,8 +203,8 @@ func TotalRegistered(c clientset.Interface) (int, error) { } // TotalReady returns number of ready schedulable Nodes. -func TotalReady(c clientset.Interface) (int, error) { - nodes, err := waitListSchedulableNodes(c) +func TotalReady(ctx context.Context, c clientset.Interface) (int, error) { + nodes, err := waitListSchedulableNodes(ctx, c) if err != nil { framework.Logf("Failed to list nodes: %v", err) return 0, err @@ -217,36 +217,28 @@ func TotalReady(c clientset.Interface) (int, error) { return len(nodes.Items), nil } -// GetExternalIP returns node external IP concatenated with port 22 for ssh +// GetSSHExternalIP returns node external IP concatenated with port 22 for ssh // e.g. 1.2.3.4:22 -func GetExternalIP(node *v1.Node) (string, error) { +func GetSSHExternalIP(node *v1.Node) (string, error) { framework.Logf("Getting external IP address for %s", node.Name) - host := "" + for _, a := range node.Status.Addresses { if a.Type == v1.NodeExternalIP && a.Address != "" { - host = net.JoinHostPort(a.Address, sshPort) - break + return net.JoinHostPort(a.Address, sshPort), nil } } - if host == "" { - return "", fmt.Errorf("Couldn't get the external IP of host %s with addresses %v", node.Name, node.Status.Addresses) - } - return host, nil + return "", fmt.Errorf("Couldn't get the external IP of host %s with addresses %v", node.Name, node.Status.Addresses) } -// GetInternalIP returns node internal IP -func GetInternalIP(node *v1.Node) (string, error) { - host := "" +// GetSSHInternalIP returns node internal IP concatenated with port 22 for ssh +func GetSSHInternalIP(node *v1.Node) (string, error) { for _, address := range node.Status.Addresses { if address.Type == v1.NodeInternalIP && address.Address != "" { - host = net.JoinHostPort(address.Address, sshPort) - break + return net.JoinHostPort(address.Address, sshPort), nil } } - if host == "" { - return "", fmt.Errorf("Couldn't get the internal IP of host %s with addresses %v", node.Name, node.Status.Addresses) - } - return host, nil + + return "", fmt.Errorf("Couldn't get the internal IP of host %s with addresses %v", node.Name, node.Status.Addresses) } // FirstAddressByTypeAndFamily returns the first address that matches the given type and family of the list of nodes @@ -301,10 +293,10 @@ func CollectAddresses(nodes *v1.NodeList, addressType v1.NodeAddressType) []stri } // PickIP picks one public node IP -func PickIP(c clientset.Interface) (string, error) { - publicIps, err := GetPublicIps(c) +func PickIP(ctx context.Context, c clientset.Interface) (string, error) { + publicIps, err := GetPublicIps(ctx, c) if err != nil { - return "", fmt.Errorf("get node public IPs error: %s", err) + return "", fmt.Errorf("get node public IPs error: %w", err) } if len(publicIps) == 0 { return "", fmt.Errorf("got unexpected number (%d) of public IPs", len(publicIps)) @@ -314,10 +306,10 @@ func PickIP(c clientset.Interface) (string, error) { } // GetPublicIps returns a public IP list of nodes. -func GetPublicIps(c clientset.Interface) ([]string, error) { - nodes, err := GetReadySchedulableNodes(c) +func GetPublicIps(ctx context.Context, c clientset.Interface) ([]string, error) { + nodes, err := GetReadySchedulableNodes(ctx, c) if err != nil { - return nil, fmt.Errorf("get schedulable and ready nodes error: %s", err) + return nil, fmt.Errorf("get schedulable and ready nodes error: %w", err) } ips := CollectAddresses(nodes, v1.NodeExternalIP) if len(ips) == 0 { @@ -332,10 +324,10 @@ func GetPublicIps(c clientset.Interface) ([]string, error) { // 2) Needs to be ready. // If EITHER 1 or 2 is not true, most tests will want to ignore the node entirely. // If there are no nodes that are both ready and schedulable, this will return an error. -func GetReadySchedulableNodes(c clientset.Interface) (nodes *v1.NodeList, err error) { - nodes, err = checkWaitListSchedulableNodes(c) +func GetReadySchedulableNodes(ctx context.Context, c clientset.Interface) (nodes *v1.NodeList, err error) { + nodes, err = checkWaitListSchedulableNodes(ctx, c) if err != nil { - return nil, fmt.Errorf("listing schedulable nodes error: %s", err) + return nil, fmt.Errorf("listing schedulable nodes error: %w", err) } Filter(nodes, func(node v1.Node) bool { return IsNodeSchedulable(&node) && isNodeUntainted(&node) @@ -349,8 +341,8 @@ func GetReadySchedulableNodes(c clientset.Interface) (nodes *v1.NodeList, err er // GetBoundedReadySchedulableNodes is like GetReadySchedulableNodes except that it returns // at most maxNodes nodes. Use this to keep your test case from blowing up when run on a // large cluster. -func GetBoundedReadySchedulableNodes(c clientset.Interface, maxNodes int) (nodes *v1.NodeList, err error) { - nodes, err = GetReadySchedulableNodes(c) +func GetBoundedReadySchedulableNodes(ctx context.Context, c clientset.Interface, maxNodes int) (nodes *v1.NodeList, err error) { + nodes, err = GetReadySchedulableNodes(ctx, c) if err != nil { return nil, err } @@ -369,58 +361,22 @@ func GetBoundedReadySchedulableNodes(c clientset.Interface, maxNodes int) (nodes // GetRandomReadySchedulableNode gets a single randomly-selected node which is available for // running pods on. If there are no available nodes it will return an error. -func GetRandomReadySchedulableNode(c clientset.Interface) (*v1.Node, error) { - nodes, err := GetReadySchedulableNodes(c) +func GetRandomReadySchedulableNode(ctx context.Context, c clientset.Interface) (*v1.Node, error) { + nodes, err := GetReadySchedulableNodes(ctx, c) if err != nil { return nil, err } return &nodes.Items[rand.Intn(len(nodes.Items))], nil } -// GetSubnetPrefix gets first 2 number of an IP in the node subnet. [IPv4] -// It assumes that the subnet mask is /16. -func GetSubnetPrefix(c clientset.Interface) ([]string, error) { - node, err := GetReadySchedulableWorkerNode(c) - if err != nil { - return nil, fmt.Errorf("error getting a ready schedulable worker Node, err: %v", err) - } - internalIP, err := GetInternalIP(node) - if err != nil { - return nil, fmt.Errorf("error getting Node internal IP, err: %v", err) - } - splitted := strings.Split(internalIP, ".") - if len(splitted) == 4 { - return splitted[:2], nil - } - return nil, fmt.Errorf("invalid IP address format: %s", internalIP) -} - -// GetReadySchedulableWorkerNode gets a single worker node which is available for -// running pods on. If there are no such available nodes it will return an error. -func GetReadySchedulableWorkerNode(c clientset.Interface) (*v1.Node, error) { - nodes, err := GetReadySchedulableNodes(c) - if err != nil { - return nil, err - } - for i := range nodes.Items { - node := nodes.Items[i] - _, isMaster := node.Labels["node-role.kubernetes.io/master"] - _, isControlPlane := node.Labels["node-role.kubernetes.io/control-plane"] - if !isMaster && !isControlPlane { - return &node, nil - } - } - return nil, fmt.Errorf("there are currently no ready, schedulable worker nodes in the cluster") -} - // GetReadyNodesIncludingTainted returns all ready nodes, even those which are tainted. // There are cases when we care about tainted nodes // E.g. in tests related to nodes with gpu we care about nodes despite // presence of nvidia.com/gpu=present:NoSchedule taint -func GetReadyNodesIncludingTainted(c clientset.Interface) (nodes *v1.NodeList, err error) { - nodes, err = checkWaitListSchedulableNodes(c) +func GetReadyNodesIncludingTainted(ctx context.Context, c clientset.Interface) (nodes *v1.NodeList, err error) { + nodes, err = checkWaitListSchedulableNodes(ctx, c) if err != nil { - return nil, fmt.Errorf("listing schedulable nodes error: %s", err) + return nil, fmt.Errorf("listing schedulable nodes error: %w", err) } Filter(nodes, func(node v1.Node) bool { return IsNodeSchedulable(&node) @@ -437,25 +393,6 @@ func isNodeUntainted(node *v1.Node) bool { // isNodeUntaintedWithNonblocking tests whether a fake pod can be scheduled on "node" // but allows for taints in the list of non-blocking taints. func isNodeUntaintedWithNonblocking(node *v1.Node, nonblockingTaints string) bool { - fakePod := &v1.Pod{ - TypeMeta: metav1.TypeMeta{ - Kind: "Pod", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "fake-not-scheduled", - Namespace: "fake-not-scheduled", - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: "fake-not-scheduled", - Image: "fake-not-scheduled", - }, - }, - }, - } - // Simple lookup for nonblocking taints based on comma-delimited list. nonblockingTaintsMap := map[string]struct{}{} for _, t := range strings.Split(nonblockingTaints, ",") { @@ -475,7 +412,8 @@ func isNodeUntaintedWithNonblocking(node *v1.Node, nonblockingTaints string) boo } n = nodeCopy } - return toleratesTaintsWithNoScheduleNoExecuteEffects(n.Spec.Taints, fakePod.Spec.Tolerations) + + return toleratesTaintsWithNoScheduleNoExecuteEffects(n.Spec.Taints, nil) } func toleratesTaintsWithNoScheduleNoExecuteEffects(taints []v1.Taint, tolerations []v1.Toleration) bool { @@ -558,10 +496,10 @@ func hasNonblockingTaint(node *v1.Node, nonblockingTaints string) bool { } // PodNodePairs return podNode pairs for all pods in a namespace -func PodNodePairs(c clientset.Interface, ns string) ([]PodNode, error) { +func PodNodePairs(ctx context.Context, c clientset.Interface, ns string) ([]PodNode, error) { var result []PodNode - podList, err := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) + podList, err := c.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{}) if err != nil { return result, err } @@ -577,10 +515,10 @@ func PodNodePairs(c clientset.Interface, ns string) ([]PodNode, error) { } // GetClusterZones returns the values of zone label collected from all nodes. -func GetClusterZones(c clientset.Interface) (sets.String, error) { - nodes, err := c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) +func GetClusterZones(ctx context.Context, c clientset.Interface) (sets.String, error) { + nodes, err := c.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { - return nil, fmt.Errorf("Error getting nodes while attempting to list cluster zones: %v", err) + return nil, fmt.Errorf("Error getting nodes while attempting to list cluster zones: %w", err) } // collect values of zone label from all nodes @@ -598,11 +536,11 @@ func GetClusterZones(c clientset.Interface) (sets.String, error) { } // GetSchedulableClusterZones returns the values of zone label collected from all nodes which are schedulable. -func GetSchedulableClusterZones(c clientset.Interface) (sets.String, error) { +func GetSchedulableClusterZones(ctx context.Context, c clientset.Interface) (sets.String, error) { // GetReadySchedulableNodes already filters our tainted and unschedulable nodes. - nodes, err := GetReadySchedulableNodes(c) + nodes, err := GetReadySchedulableNodes(ctx, c) if err != nil { - return nil, fmt.Errorf("error getting nodes while attempting to list cluster zones: %v", err) + return nil, fmt.Errorf("error getting nodes while attempting to list cluster zones: %w", err) } // collect values of zone label from all nodes @@ -620,8 +558,8 @@ func GetSchedulableClusterZones(c clientset.Interface) (sets.String, error) { } // CreatePodsPerNodeForSimpleApp creates pods w/ labels. Useful for tests which make a bunch of pods w/o any networking. -func CreatePodsPerNodeForSimpleApp(c clientset.Interface, namespace, appName string, podSpec func(n v1.Node) v1.PodSpec, maxCount int) map[string]string { - nodes, err := GetBoundedReadySchedulableNodes(c, maxCount) +func CreatePodsPerNodeForSimpleApp(ctx context.Context, c clientset.Interface, namespace, appName string, podSpec func(n v1.Node) v1.PodSpec, maxCount int) map[string]string { + nodes, err := GetBoundedReadySchedulableNodes(ctx, c, maxCount) // TODO use wrapper methods in expect.go after removing core e2e dependency on node gomega.ExpectWithOffset(2, err).NotTo(gomega.HaveOccurred()) podLabels := map[string]string{ @@ -629,7 +567,7 @@ func CreatePodsPerNodeForSimpleApp(c clientset.Interface, namespace, appName str } for i, node := range nodes.Items { framework.Logf("%v/%v : Creating container with label app=%v-pod", i, maxCount, appName) - _, err := c.CoreV1().Pods(namespace).Create(context.TODO(), &v1.Pod{ + _, err := c.CoreV1().Pods(namespace).Create(ctx, &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf(appName+"-pod-%v", i), Labels: podLabels, @@ -644,33 +582,33 @@ func CreatePodsPerNodeForSimpleApp(c clientset.Interface, namespace, appName str // RemoveTaintsOffNode removes a list of taints from the given node // It is simply a helper wrapper for RemoveTaintOffNode -func RemoveTaintsOffNode(c clientset.Interface, nodeName string, taints []v1.Taint) { +func RemoveTaintsOffNode(ctx context.Context, c clientset.Interface, nodeName string, taints []v1.Taint) { for _, taint := range taints { - RemoveTaintOffNode(c, nodeName, taint) + RemoveTaintOffNode(ctx, c, nodeName, taint) } } // RemoveTaintOffNode removes the given taint from the given node. -func RemoveTaintOffNode(c clientset.Interface, nodeName string, taint v1.Taint) { - err := removeNodeTaint(c, nodeName, nil, &taint) +func RemoveTaintOffNode(ctx context.Context, c clientset.Interface, nodeName string, taint v1.Taint) { + err := removeNodeTaint(ctx, c, nodeName, nil, &taint) // TODO use wrapper methods in expect.go after removing core e2e dependency on node gomega.ExpectWithOffset(2, err).NotTo(gomega.HaveOccurred()) - verifyThatTaintIsGone(c, nodeName, &taint) + verifyThatTaintIsGone(ctx, c, nodeName, &taint) } // AddOrUpdateTaintOnNode adds the given taint to the given node or updates taint. -func AddOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taint v1.Taint) { +func AddOrUpdateTaintOnNode(ctx context.Context, c clientset.Interface, nodeName string, taint v1.Taint) { // TODO use wrapper methods in expect.go after removing the dependency on this // package from the core e2e framework. - err := addOrUpdateTaintOnNode(c, nodeName, &taint) + err := addOrUpdateTaintOnNode(ctx, c, nodeName, &taint) gomega.ExpectWithOffset(2, err).NotTo(gomega.HaveOccurred()) } // addOrUpdateTaintOnNode add taints to the node. If taint was added into node, it'll issue API calls // to update nodes; otherwise, no API calls. Return error if any. // copied from pkg/controller/controller_utils.go AddOrUpdateTaintOnNode() -func addOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taints ...*v1.Taint) error { +func addOrUpdateTaintOnNode(ctx context.Context, c clientset.Interface, nodeName string, taints ...*v1.Taint) error { if len(taints) == 0 { return nil } @@ -681,10 +619,10 @@ func addOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taints ...*v // First we try getting node from the API server cache, as it's cheaper. If it fails // we get it from etcd to be sure to have fresh data. if firstTry { - oldNode, err = c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{ResourceVersion: "0"}) + oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{ResourceVersion: "0"}) firstTry = false } else { - oldNode, err = c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) + oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) } if err != nil { return err @@ -705,7 +643,7 @@ func addOrUpdateTaintOnNode(c clientset.Interface, nodeName string, taints ...*v if !updated { return nil } - return patchNodeTaints(c, nodeName, oldNode, newNode) + return patchNodeTaints(ctx, c, nodeName, oldNode, newNode) }) } @@ -768,7 +706,7 @@ var semantic = conversion.EqualitiesOrDie( // won't fail if target taint doesn't exist or has been removed. // If passed a node it'll check if there's anything to be done, if taint is not present it won't issue // any API calls. -func removeNodeTaint(c clientset.Interface, nodeName string, node *v1.Node, taints ...*v1.Taint) error { +func removeNodeTaint(ctx context.Context, c clientset.Interface, nodeName string, node *v1.Node, taints ...*v1.Taint) error { if len(taints) == 0 { return nil } @@ -793,10 +731,10 @@ func removeNodeTaint(c clientset.Interface, nodeName string, node *v1.Node, tain // First we try getting node from the API server cache, as it's cheaper. If it fails // we get it from etcd to be sure to have fresh data. if firstTry { - oldNode, err = c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{ResourceVersion: "0"}) + oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{ResourceVersion: "0"}) firstTry = false } else { - oldNode, err = c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) + oldNode, err = c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) } if err != nil { return err @@ -817,15 +755,15 @@ func removeNodeTaint(c clientset.Interface, nodeName string, node *v1.Node, tain if !updated { return nil } - return patchNodeTaints(c, nodeName, oldNode, newNode) + return patchNodeTaints(ctx, c, nodeName, oldNode, newNode) }) } // patchNodeTaints patches node's taints. -func patchNodeTaints(c clientset.Interface, nodeName string, oldNode *v1.Node, newNode *v1.Node) error { +func patchNodeTaints(ctx context.Context, c clientset.Interface, nodeName string, oldNode *v1.Node, newNode *v1.Node) error { oldData, err := json.Marshal(oldNode) if err != nil { - return fmt.Errorf("failed to marshal old node %#v for node %q: %v", oldNode, nodeName, err) + return fmt.Errorf("failed to marshal old node %#v for node %q: %w", oldNode, nodeName, err) } newTaints := newNode.Spec.Taints @@ -833,15 +771,15 @@ func patchNodeTaints(c clientset.Interface, nodeName string, oldNode *v1.Node, n newNodeClone.Spec.Taints = newTaints newData, err := json.Marshal(newNodeClone) if err != nil { - return fmt.Errorf("failed to marshal new node %#v for node %q: %v", newNodeClone, nodeName, err) + return fmt.Errorf("failed to marshal new node %#v for node %q: %w", newNodeClone, nodeName, err) } patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, v1.Node{}) if err != nil { - return fmt.Errorf("failed to create patch for node %q: %v", nodeName, err) + return fmt.Errorf("failed to create patch for node %q: %w", nodeName, err) } - _, err = c.CoreV1().Nodes().Patch(context.TODO(), nodeName, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) + _, err = c.CoreV1().Nodes().Patch(ctx, nodeName, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) return err } @@ -877,9 +815,9 @@ func deleteTaint(taints []v1.Taint, taintToDelete *v1.Taint) ([]v1.Taint, bool) return newTaints, deleted } -func verifyThatTaintIsGone(c clientset.Interface, nodeName string, taint *v1.Taint) { +func verifyThatTaintIsGone(ctx context.Context, c clientset.Interface, nodeName string, taint *v1.Taint) { ginkgo.By("verifying the node doesn't have the taint " + taint.ToString()) - nodeUpdated, err := c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) + nodeUpdated, err := c.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) // TODO use wrapper methods in expect.go after removing core e2e dependency on node gomega.ExpectWithOffset(2, err).NotTo(gomega.HaveOccurred()) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/runtimeclass.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/runtimeclass.go deleted file mode 100644 index a813233ed..000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/runtimeclass.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2020 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 node - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - imageutils "k8s.io/kubernetes/test/utils/image" - utilpointer "k8s.io/utils/pointer" -) - -const ( - // PreconfiguredRuntimeClassHandler is the name of the runtime handler - // that is expected to be preconfigured in the test environment. - PreconfiguredRuntimeClassHandler = "test-handler" -) - -// NewRuntimeClassPod returns a test pod with the given runtimeClassName -func NewRuntimeClassPod(runtimeClassName string) *v1.Pod { - return &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: fmt.Sprintf("test-runtimeclass-%s-", runtimeClassName), - }, - Spec: v1.PodSpec{ - RuntimeClassName: &runtimeClassName, - Containers: []v1.Container{{ - Name: "test", - Image: imageutils.GetE2EImage(imageutils.BusyBox), - Command: []string{"true"}, - }}, - RestartPolicy: v1.RestartPolicyNever, - AutomountServiceAccountToken: utilpointer.BoolPtr(false), - }, - } -} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/ssh.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/ssh.go index 414d6ff5b..2e0b02c0f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/ssh.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/ssh.go @@ -17,6 +17,7 @@ limitations under the License. package node import ( + "context" "time" "k8s.io/apimachinery/pkg/util/wait" @@ -25,7 +26,7 @@ import ( ) // WaitForSSHTunnels waits for establishing SSH tunnel to busybox pod. -func WaitForSSHTunnels(namespace string) { +func WaitForSSHTunnels(ctx context.Context, namespace string) { framework.Logf("Waiting for SSH tunnels to establish") e2ekubectl.RunKubectl(namespace, "run", "ssh-tunnel-test", "--image=busybox", @@ -35,7 +36,7 @@ func WaitForSSHTunnels(namespace string) { defer e2ekubectl.RunKubectl(namespace, "delete", "pod", "ssh-tunnel-test") // allow up to a minute for new ssh tunnels to establish - wait.PollImmediate(5*time.Second, time.Minute, func() (bool, error) { + wait.PollImmediateWithContext(ctx, 5*time.Second, time.Minute, func(ctx context.Context) (bool, error) { _, err := e2ekubectl.RunKubectl(namespace, "logs", "ssh-tunnel-test") return err == nil, nil }) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/node/wait.go b/vendor/k8s.io/kubernetes/test/e2e/framework/node/wait.go index a3e324062..cc0294230 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/node/wait.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/node/wait.go @@ -40,21 +40,21 @@ var requiredPerNodePods = []*regexp.Regexp{ // WaitForReadyNodes waits up to timeout for cluster to has desired size and // there is no not-ready nodes in it. By cluster size we mean number of schedulable Nodes. -func WaitForReadyNodes(c clientset.Interface, size int, timeout time.Duration) error { - _, err := CheckReady(c, size, timeout) +func WaitForReadyNodes(ctx context.Context, c clientset.Interface, size int, timeout time.Duration) error { + _, err := CheckReady(ctx, c, size, timeout) return err } // WaitForTotalHealthy checks whether all registered nodes are ready and all required Pods are running on them. -func WaitForTotalHealthy(c clientset.Interface, timeout time.Duration) error { +func WaitForTotalHealthy(ctx context.Context, c clientset.Interface, timeout time.Duration) error { framework.Logf("Waiting up to %v for all nodes to be ready", timeout) var notReady []v1.Node var missingPodsPerNode map[string][]string - err := wait.PollImmediate(poll, timeout, func() (bool, error) { + err := wait.PollImmediateWithContext(ctx, poll, timeout, func(ctx context.Context) (bool, error) { notReady = nil // It should be OK to list unschedulable Nodes here. - nodes, err := c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{ResourceVersion: "0"}) + nodes, err := c.CoreV1().Nodes().List(ctx, metav1.ListOptions{ResourceVersion: "0"}) if err != nil { return false, err } @@ -63,7 +63,7 @@ func WaitForTotalHealthy(c clientset.Interface, timeout time.Duration) error { notReady = append(notReady, node) } } - pods, err := c.CoreV1().Pods(metav1.NamespaceAll).List(context.TODO(), metav1.ListOptions{ResourceVersion: "0"}) + pods, err := c.CoreV1().Pods(metav1.NamespaceAll).List(ctx, metav1.ListOptions{ResourceVersion: "0"}) if err != nil { return false, err } @@ -114,10 +114,10 @@ func WaitForTotalHealthy(c clientset.Interface, timeout time.Duration) error { // within timeout. If wantTrue is true, it will ensure the node condition status // is ConditionTrue; if it's false, it ensures the node condition is in any state // other than ConditionTrue (e.g. not true or unknown). -func WaitConditionToBe(c clientset.Interface, name string, conditionType v1.NodeConditionType, wantTrue bool, timeout time.Duration) bool { +func WaitConditionToBe(ctx context.Context, c clientset.Interface, name string, conditionType v1.NodeConditionType, wantTrue bool, timeout time.Duration) bool { framework.Logf("Waiting up to %v for node %s condition %s to be %t", timeout, name, conditionType, wantTrue) for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) { - node, err := c.CoreV1().Nodes().Get(context.TODO(), name, metav1.GetOptions{}) + node, err := c.CoreV1().Nodes().Get(ctx, name, metav1.GetOptions{}) if err != nil { framework.Logf("Couldn't get node %s", name) continue @@ -134,20 +134,37 @@ func WaitConditionToBe(c clientset.Interface, name string, conditionType v1.Node // WaitForNodeToBeNotReady returns whether node name is not ready (i.e. the // readiness condition is anything but ready, e.g false or unknown) within // timeout. -func WaitForNodeToBeNotReady(c clientset.Interface, name string, timeout time.Duration) bool { - return WaitConditionToBe(c, name, v1.NodeReady, false, timeout) +func WaitForNodeToBeNotReady(ctx context.Context, c clientset.Interface, name string, timeout time.Duration) bool { + return WaitConditionToBe(ctx, c, name, v1.NodeReady, false, timeout) } // WaitForNodeToBeReady returns whether node name is ready within timeout. -func WaitForNodeToBeReady(c clientset.Interface, name string, timeout time.Duration) bool { - return WaitConditionToBe(c, name, v1.NodeReady, true, timeout) +func WaitForNodeToBeReady(ctx context.Context, c clientset.Interface, name string, timeout time.Duration) bool { + return WaitConditionToBe(ctx, c, name, v1.NodeReady, true, timeout) +} + +func WaitForNodeSchedulable(ctx context.Context, c clientset.Interface, name string, timeout time.Duration, wantSchedulable bool) bool { + framework.Logf("Waiting up to %v for node %s to be schedulable: %t", timeout, name, wantSchedulable) + for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) { + node, err := c.CoreV1().Nodes().Get(ctx, name, metav1.GetOptions{}) + if err != nil { + framework.Logf("Couldn't get node %s", name) + continue + } + + if IsNodeSchedulable(node) == wantSchedulable { + return true + } + } + framework.Logf("Node %s didn't reach desired schedulable status (%t) within %v", name, wantSchedulable, timeout) + return false } // CheckReady waits up to timeout for cluster to has desired size and // there is no not-ready nodes in it. By cluster size we mean number of schedulable Nodes. -func CheckReady(c clientset.Interface, size int, timeout time.Duration) ([]v1.Node, error) { +func CheckReady(ctx context.Context, c clientset.Interface, size int, timeout time.Duration) ([]v1.Node, error) { for start := time.Now(); time.Since(start) < timeout; time.Sleep(sleepTime) { - nodes, err := waitListSchedulableNodes(c) + nodes, err := waitListSchedulableNodes(ctx, c) if err != nil { framework.Logf("Failed to list nodes: %v", err) continue @@ -172,11 +189,11 @@ func CheckReady(c clientset.Interface, size int, timeout time.Duration) ([]v1.No } // waitListSchedulableNodes is a wrapper around listing nodes supporting retries. -func waitListSchedulableNodes(c clientset.Interface) (*v1.NodeList, error) { +func waitListSchedulableNodes(ctx context.Context, c clientset.Interface) (*v1.NodeList, error) { var nodes *v1.NodeList var err error - if wait.PollImmediate(poll, singleCallTimeout, func() (bool, error) { - nodes, err = c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{FieldSelector: fields.Set{ + if wait.PollImmediateWithContext(ctx, poll, singleCallTimeout, func(ctx context.Context) (bool, error) { + nodes, err = c.CoreV1().Nodes().List(ctx, metav1.ListOptions{FieldSelector: fields.Set{ "spec.unschedulable": "false", }.AsSelector().String()}) if err != nil { @@ -190,8 +207,8 @@ func waitListSchedulableNodes(c clientset.Interface) (*v1.NodeList, error) { } // checkWaitListSchedulableNodes is a wrapper around listing nodes supporting retries. -func checkWaitListSchedulableNodes(c clientset.Interface) (*v1.NodeList, error) { - nodes, err := waitListSchedulableNodes(c) +func checkWaitListSchedulableNodes(ctx context.Context, c clientset.Interface) (*v1.NodeList, error) { + nodes, err := waitListSchedulableNodes(ctx, c) if err != nil { return nil, fmt.Errorf("error: %s. Non-retryable failure or timed out while listing nodes for e2e cluster", err) } @@ -199,9 +216,9 @@ func checkWaitListSchedulableNodes(c clientset.Interface) (*v1.NodeList, error) } // CheckReadyForTests returns a function which will return 'true' once the number of ready nodes is above the allowedNotReadyNodes threshold (i.e. to be used as a global gate for starting the tests). -func CheckReadyForTests(c clientset.Interface, nonblockingTaints string, allowedNotReadyNodes, largeClusterThreshold int) func() (bool, error) { +func CheckReadyForTests(ctx context.Context, c clientset.Interface, nonblockingTaints string, allowedNotReadyNodes, largeClusterThreshold int) func(ctx context.Context) (bool, error) { attempt := 0 - return func() (bool, error) { + return func(ctx context.Context) (bool, error) { if allowedNotReadyNodes == -1 { return true, nil } @@ -212,7 +229,7 @@ func CheckReadyForTests(c clientset.Interface, nonblockingTaints string, allowed // remove uncordoned nodes from our calculation, TODO refactor if node v2 API removes that semantic. FieldSelector: fields.Set{"spec.unschedulable": "false"}.AsSelector().String(), } - allNodes, err := c.CoreV1().Nodes().List(context.TODO(), opts) + allNodes, err := c.CoreV1().Nodes().List(ctx, opts) if err != nil { var terminalListNodesErr error framework.Logf("Unexpected error listing nodes: %v", err) diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go index fe817be8c..7469cd80c 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/create.go @@ -52,76 +52,76 @@ type Config struct { } // CreateUnschedulablePod with given claims based on node selector -func CreateUnschedulablePod(client clientset.Interface, namespace string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, isPrivileged bool, command string) (*v1.Pod, error) { +func CreateUnschedulablePod(ctx context.Context, client clientset.Interface, namespace string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, isPrivileged bool, command string) (*v1.Pod, error) { pod := MakePod(namespace, nodeSelector, pvclaims, isPrivileged, command) - pod, err := client.CoreV1().Pods(namespace).Create(context.TODO(), pod, metav1.CreateOptions{}) + pod, err := client.CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{}) if err != nil { - return nil, fmt.Errorf("pod Create API error: %v", err) + return nil, fmt.Errorf("pod Create API error: %w", err) } // Waiting for pod to become Unschedulable - err = WaitForPodNameUnschedulableInNamespace(client, pod.Name, namespace) + err = WaitForPodNameUnschedulableInNamespace(ctx, client, pod.Name, namespace) if err != nil { - return pod, fmt.Errorf("pod %q is not Unschedulable: %v", pod.Name, err) + return pod, fmt.Errorf("pod %q is not Unschedulable: %w", pod.Name, err) } // get fresh pod info - pod, err = client.CoreV1().Pods(namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{}) + pod, err = client.CoreV1().Pods(namespace).Get(ctx, pod.Name, metav1.GetOptions{}) if err != nil { - return pod, fmt.Errorf("pod Get API error: %v", err) + return pod, fmt.Errorf("pod Get API error: %w", err) } return pod, nil } // CreateClientPod defines and creates a pod with a mounted PV. Pod runs infinite loop until killed. -func CreateClientPod(c clientset.Interface, ns string, pvc *v1.PersistentVolumeClaim) (*v1.Pod, error) { - return CreatePod(c, ns, nil, []*v1.PersistentVolumeClaim{pvc}, true, "") +func CreateClientPod(ctx context.Context, c clientset.Interface, ns string, pvc *v1.PersistentVolumeClaim) (*v1.Pod, error) { + return CreatePod(ctx, c, ns, nil, []*v1.PersistentVolumeClaim{pvc}, true, "") } // CreatePod with given claims based on node selector -func CreatePod(client clientset.Interface, namespace string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, isPrivileged bool, command string) (*v1.Pod, error) { +func CreatePod(ctx context.Context, client clientset.Interface, namespace string, nodeSelector map[string]string, pvclaims []*v1.PersistentVolumeClaim, isPrivileged bool, command string) (*v1.Pod, error) { pod := MakePod(namespace, nodeSelector, pvclaims, isPrivileged, command) - pod, err := client.CoreV1().Pods(namespace).Create(context.TODO(), pod, metav1.CreateOptions{}) + pod, err := client.CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{}) if err != nil { - return nil, fmt.Errorf("pod Create API error: %v", err) + return nil, fmt.Errorf("pod Create API error: %w", err) } // Waiting for pod to be running - err = WaitForPodNameRunningInNamespace(client, pod.Name, namespace) + err = WaitForPodNameRunningInNamespace(ctx, client, pod.Name, namespace) if err != nil { - return pod, fmt.Errorf("pod %q is not Running: %v", pod.Name, err) + return pod, fmt.Errorf("pod %q is not Running: %w", pod.Name, err) } // get fresh pod info - pod, err = client.CoreV1().Pods(namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{}) + pod, err = client.CoreV1().Pods(namespace).Get(ctx, pod.Name, metav1.GetOptions{}) if err != nil { - return pod, fmt.Errorf("pod Get API error: %v", err) + return pod, fmt.Errorf("pod Get API error: %w", err) } return pod, nil } // CreateSecPod creates security pod with given claims -func CreateSecPod(client clientset.Interface, podConfig *Config, timeout time.Duration) (*v1.Pod, error) { - return CreateSecPodWithNodeSelection(client, podConfig, timeout) +func CreateSecPod(ctx context.Context, client clientset.Interface, podConfig *Config, timeout time.Duration) (*v1.Pod, error) { + return CreateSecPodWithNodeSelection(ctx, client, podConfig, timeout) } // CreateSecPodWithNodeSelection creates security pod with given claims -func CreateSecPodWithNodeSelection(client clientset.Interface, podConfig *Config, timeout time.Duration) (*v1.Pod, error) { +func CreateSecPodWithNodeSelection(ctx context.Context, client clientset.Interface, podConfig *Config, timeout time.Duration) (*v1.Pod, error) { pod, err := MakeSecPod(podConfig) if err != nil { - return nil, fmt.Errorf("Unable to create pod: %v", err) + return nil, fmt.Errorf("Unable to create pod: %w", err) } - pod, err = client.CoreV1().Pods(podConfig.NS).Create(context.TODO(), pod, metav1.CreateOptions{}) + pod, err = client.CoreV1().Pods(podConfig.NS).Create(ctx, pod, metav1.CreateOptions{}) if err != nil { - return nil, fmt.Errorf("pod Create API error: %v", err) + return nil, fmt.Errorf("pod Create API error: %w", err) } // Waiting for pod to be running - err = WaitTimeoutForPodRunningInNamespace(client, pod.Name, podConfig.NS, timeout) + err = WaitTimeoutForPodRunningInNamespace(ctx, client, pod.Name, podConfig.NS, timeout) if err != nil { - return pod, fmt.Errorf("pod %q is not Running: %v", pod.Name, err) + return pod, fmt.Errorf("pod %q is not Running: %w", pod.Name, err) } // get fresh pod info - pod, err = client.CoreV1().Pods(podConfig.NS).Get(context.TODO(), pod.Name, metav1.GetOptions{}) + pod, err = client.CoreV1().Pods(podConfig.NS).Get(ctx, pod.Name, metav1.GetOptions{}) if err != nil { - return pod, fmt.Errorf("pod Get API error: %v", err) + return pod, fmt.Errorf("pod Get API error: %w", err) } return pod, nil } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go index 07e4237e0..360862d34 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go @@ -37,9 +37,9 @@ const ( // DeletePodOrFail deletes the pod of the specified namespace and name. Resilient to the pod // not existing. -func DeletePodOrFail(c clientset.Interface, ns, name string) { +func DeletePodOrFail(ctx context.Context, c clientset.Interface, ns, name string) { ginkgo.By(fmt.Sprintf("Deleting pod %s in namespace %s", name, ns)) - err := c.CoreV1().Pods(ns).Delete(context.TODO(), name, metav1.DeleteOptions{}) + err := c.CoreV1().Pods(ns).Delete(ctx, name, metav1.DeleteOptions{}) if err != nil && apierrors.IsNotFound(err) { return } @@ -49,41 +49,41 @@ func DeletePodOrFail(c clientset.Interface, ns, name string) { // DeletePodWithWait deletes the passed-in pod and waits for the pod to be terminated. Resilient to the pod // not existing. -func DeletePodWithWait(c clientset.Interface, pod *v1.Pod) error { +func DeletePodWithWait(ctx context.Context, c clientset.Interface, pod *v1.Pod) error { if pod == nil { return nil } - return DeletePodWithWaitByName(c, pod.GetName(), pod.GetNamespace()) + return DeletePodWithWaitByName(ctx, c, pod.GetName(), pod.GetNamespace()) } // DeletePodWithWaitByName deletes the named and namespaced pod and waits for the pod to be terminated. Resilient to the pod // not existing. -func DeletePodWithWaitByName(c clientset.Interface, podName, podNamespace string) error { +func DeletePodWithWaitByName(ctx context.Context, c clientset.Interface, podName, podNamespace string) error { framework.Logf("Deleting pod %q in namespace %q", podName, podNamespace) - err := c.CoreV1().Pods(podNamespace).Delete(context.TODO(), podName, metav1.DeleteOptions{}) + err := c.CoreV1().Pods(podNamespace).Delete(ctx, podName, metav1.DeleteOptions{}) if err != nil { if apierrors.IsNotFound(err) { return nil // assume pod was already deleted } - return fmt.Errorf("pod Delete API error: %v", err) + return fmt.Errorf("pod Delete API error: %w", err) } framework.Logf("Wait up to %v for pod %q to be fully deleted", PodDeleteTimeout, podName) - err = WaitForPodNotFoundInNamespace(c, podName, podNamespace, PodDeleteTimeout) + err = WaitForPodNotFoundInNamespace(ctx, c, podName, podNamespace, PodDeleteTimeout) if err != nil { - return fmt.Errorf("pod %q was not deleted: %v", podName, err) + return fmt.Errorf("pod %q was not deleted: %w", podName, err) } return nil } // DeletePodWithGracePeriod deletes the passed-in pod. Resilient to the pod not existing. -func DeletePodWithGracePeriod(c clientset.Interface, pod *v1.Pod, grace int64) error { - return DeletePodWithGracePeriodByName(c, pod.GetName(), pod.GetNamespace(), grace) +func DeletePodWithGracePeriod(ctx context.Context, c clientset.Interface, pod *v1.Pod, grace int64) error { + return DeletePodWithGracePeriodByName(ctx, c, pod.GetName(), pod.GetNamespace(), grace) } // DeletePodsWithGracePeriod deletes the passed-in pods. Resilient to the pods not existing. -func DeletePodsWithGracePeriod(c clientset.Interface, pods []v1.Pod, grace int64) error { +func DeletePodsWithGracePeriod(ctx context.Context, c clientset.Interface, pods []v1.Pod, grace int64) error { for _, pod := range pods { - if err := DeletePodWithGracePeriod(c, &pod, grace); err != nil { + if err := DeletePodWithGracePeriod(ctx, c, &pod, grace); err != nil { return err } } @@ -91,14 +91,14 @@ func DeletePodsWithGracePeriod(c clientset.Interface, pods []v1.Pod, grace int64 } // DeletePodWithGracePeriodByName deletes a pod by name and namespace. Resilient to the pod not existing. -func DeletePodWithGracePeriodByName(c clientset.Interface, podName, podNamespace string, grace int64) error { +func DeletePodWithGracePeriodByName(ctx context.Context, c clientset.Interface, podName, podNamespace string, grace int64) error { framework.Logf("Deleting pod %q in namespace %q", podName, podNamespace) - err := c.CoreV1().Pods(podNamespace).Delete(context.TODO(), podName, *metav1.NewDeleteOptions(grace)) + err := c.CoreV1().Pods(podNamespace).Delete(ctx, podName, *metav1.NewDeleteOptions(grace)) if err != nil { if apierrors.IsNotFound(err) { return nil // assume pod was already deleted } - return fmt.Errorf("pod Delete API error: %v", err) + return fmt.Errorf("pod Delete API error: %w", err) } return nil } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go index f788fc6e4..ef223e86e 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/dial.go @@ -87,13 +87,13 @@ func (d *Dialer) DialContainerPort(ctx context.Context, addr Addr) (conn net.Con SubResource("portforward") transport, upgrader, err := spdy.RoundTripperFor(restConfig) if err != nil { - return nil, fmt.Errorf("create round tripper: %v", err) + return nil, fmt.Errorf("create round tripper: %w", err) } dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", req.URL()) streamConn, _, err := dialer.Dial(portforward.PortForwardProtocolV1Name) if err != nil { - return nil, fmt.Errorf("dialer failed: %v", err) + return nil, fmt.Errorf("dialer failed: %w", err) } requestID := "1" defer func() { @@ -112,7 +112,7 @@ func (d *Dialer) DialContainerPort(ctx context.Context, addr Addr) (conn net.Con // This happens asynchronously. errorStream, err := streamConn.CreateStream(headers) if err != nil { - return nil, fmt.Errorf("error creating error stream: %v", err) + return nil, fmt.Errorf("error creating error stream: %w", err) } errorStream.Close() go func() { @@ -129,7 +129,7 @@ func (d *Dialer) DialContainerPort(ctx context.Context, addr Addr) (conn net.Con headers.Set(v1.StreamType, v1.StreamTypeData) dataStream, err := streamConn.CreateStream(headers) if err != nil { - return nil, fmt.Errorf("error creating data stream: %v", err) + return nil, fmt.Errorf("error creating data stream: %w", err) } return &stream{ diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/exec_util.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/exec_util.go index a88aee2d7..e2e00de8a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/exec_util.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/exec_util.go @@ -87,6 +87,7 @@ func ExecWithOptions(f *framework.Framework, options ExecOptions) (string, strin // ExecCommandInContainerWithFullOutput executes a command in the // specified container and return stdout, stderr and error func ExecCommandInContainerWithFullOutput(f *framework.Framework, podName, containerName string, cmd ...string) (string, string, error) { + // TODO (pohly): add context support return ExecWithOptions(f, ExecOptions{ Command: cmd, Namespace: f.Namespace.Name, @@ -114,28 +115,28 @@ func ExecShellInContainer(f *framework.Framework, podName, containerName string, return ExecCommandInContainer(f, podName, containerName, "/bin/sh", "-c", cmd) } -func execCommandInPod(f *framework.Framework, podName string, cmd ...string) string { - pod, err := NewPodClient(f).Get(context.TODO(), podName, metav1.GetOptions{}) +func execCommandInPod(ctx context.Context, f *framework.Framework, podName string, cmd ...string) string { + pod, err := NewPodClient(f).Get(ctx, podName, metav1.GetOptions{}) framework.ExpectNoError(err, "failed to get pod %v", podName) gomega.Expect(pod.Spec.Containers).NotTo(gomega.BeEmpty()) return ExecCommandInContainer(f, podName, pod.Spec.Containers[0].Name, cmd...) } -func execCommandInPodWithFullOutput(f *framework.Framework, podName string, cmd ...string) (string, string, error) { - pod, err := NewPodClient(f).Get(context.TODO(), podName, metav1.GetOptions{}) +func execCommandInPodWithFullOutput(ctx context.Context, f *framework.Framework, podName string, cmd ...string) (string, string, error) { + pod, err := NewPodClient(f).Get(ctx, podName, metav1.GetOptions{}) framework.ExpectNoError(err, "failed to get pod %v", podName) gomega.Expect(pod.Spec.Containers).NotTo(gomega.BeEmpty()) return ExecCommandInContainerWithFullOutput(f, podName, pod.Spec.Containers[0].Name, cmd...) } // ExecShellInPod executes the specified command on the pod. -func ExecShellInPod(f *framework.Framework, podName string, cmd string) string { - return execCommandInPod(f, podName, "/bin/sh", "-c", cmd) +func ExecShellInPod(ctx context.Context, f *framework.Framework, podName string, cmd string) string { + return execCommandInPod(ctx, f, podName, "/bin/sh", "-c", cmd) } // ExecShellInPodWithFullOutput executes the specified command on the Pod and returns stdout, stderr and error. -func ExecShellInPodWithFullOutput(f *framework.Framework, podName string, cmd string) (string, string, error) { - return execCommandInPodWithFullOutput(f, podName, "/bin/sh", "-c", cmd) +func ExecShellInPodWithFullOutput(ctx context.Context, f *framework.Framework, podName string, cmd string) (string, string, error) { + return execCommandInPodWithFullOutput(ctx, f, podName, "/bin/sh", "-c", cmd) } func execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/get.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/get.go new file mode 100644 index 000000000..d83314d19 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/get.go @@ -0,0 +1,31 @@ +/* +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 pod + +import ( + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clientset "k8s.io/client-go/kubernetes" + "k8s.io/kubernetes/test/e2e/framework" +) + +// Get creates a function which retrieves the pod anew each time the function +// is called. Fatal errors are detected by framework.HandleRetry and cause +// polling to stop. +func Get(c clientset.Interface, pod framework.NamedObject) framework.GetFunc[*v1.Pod] { + return framework.HandleRetry(framework.GetObject(c.CoreV1().Pods(pod.GetNamespace()).Get, pod.GetName(), metav1.GetOptions{})) +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go index 856d99678..6cb80f37d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/output/output.go @@ -107,7 +107,7 @@ func RunHostCmdWithRetries(ns, name, cmd string, interval, timeout time.Duration return out, nil } if elapsed := time.Since(start); elapsed > timeout { - return out, fmt.Errorf("RunHostCmd still failed after %v: %v", elapsed, err) + return out, fmt.Errorf("RunHostCmd still failed after %v: %w", elapsed, err) } framework.Logf("Waiting %v to retry failed RunHostCmd: %v", interval, err) time.Sleep(interval) @@ -121,6 +121,15 @@ func LookForStringInLog(ns, podName, container, expectedString string, timeout t }) } +// LookForStringInLogWithoutKubectl looks for the given string in the log of a specific pod container +func LookForStringInLogWithoutKubectl(ctx context.Context, client clientset.Interface, ns string, podName string, container string, expectedString string, timeout time.Duration) (result string, err error) { + return lookForString(expectedString, timeout, func() string { + podLogs, err := e2epod.GetPodLogs(ctx, client, ns, podName, container) + framework.ExpectNoError(err) + return podLogs + }) +} + // CreateEmptyFileOnPod creates empty file at given path on the pod. func CreateEmptyFileOnPod(namespace string, podName string, filePath string) error { _, err := e2ekubectl.RunKubectl(namespace, "exec", podName, "--", "/bin/sh", "-c", fmt.Sprintf("touch %s", filePath)) @@ -128,8 +137,8 @@ func CreateEmptyFileOnPod(namespace string, podName string, filePath string) err } // DumpDebugInfo dumps debug info of tests. -func DumpDebugInfo(c clientset.Interface, ns string) { - sl, _ := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{LabelSelector: labels.Everything().String()}) +func DumpDebugInfo(ctx context.Context, c clientset.Interface, ns string) { + sl, _ := c.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{LabelSelector: labels.Everything().String()}) for _, s := range sl.Items { desc, _ := e2ekubectl.RunKubectl(ns, "describe", "po", s.Name) framework.Logf("\nOutput of kubectl describe %v:\n%v", s.Name, desc) @@ -142,6 +151,7 @@ func DumpDebugInfo(c clientset.Interface, ns string) { // MatchContainerOutput creates a pod and waits for all it's containers to exit with success. // It then tests that the matcher with each expectedOutput matches the output of the specified container. func MatchContainerOutput( + ctx context.Context, f *framework.Framework, pod *v1.Pod, containerName string, @@ -153,25 +163,25 @@ func MatchContainerOutput( } podClient := e2epod.PodClientNS(f, ns) - createdPod := podClient.Create(pod) + createdPod := podClient.Create(ctx, pod) defer func() { ginkgo.By("delete the pod") - podClient.DeleteSync(createdPod.Name, metav1.DeleteOptions{}, e2epod.DefaultPodDeletionTimeout) + podClient.DeleteSync(ctx, createdPod.Name, metav1.DeleteOptions{}, e2epod.DefaultPodDeletionTimeout) }() // Wait for client pod to complete. - podErr := e2epod.WaitForPodSuccessInNamespaceTimeout(f.ClientSet, createdPod.Name, ns, f.Timeouts.PodStart) + podErr := e2epod.WaitForPodSuccessInNamespaceTimeout(ctx, f.ClientSet, createdPod.Name, ns, f.Timeouts.PodStart) // Grab its logs. Get host first. - podStatus, err := podClient.Get(context.TODO(), createdPod.Name, metav1.GetOptions{}) + podStatus, err := podClient.Get(ctx, createdPod.Name, metav1.GetOptions{}) if err != nil { - return fmt.Errorf("failed to get pod status: %v", err) + return fmt.Errorf("failed to get pod status: %w", err) } if podErr != nil { // Pod failed. Dump all logs from all containers to see what's wrong _ = apiv1pod.VisitContainers(&podStatus.Spec, apiv1pod.AllFeatureEnabledContainers(), func(c *v1.Container, containerType apiv1pod.ContainerType) bool { - logs, err := e2epod.GetPodLogs(f.ClientSet, ns, podStatus.Name, c.Name) + logs, err := e2epod.GetPodLogs(ctx, f.ClientSet, ns, podStatus.Name, c.Name) if err != nil { framework.Logf("Failed to get logs from node %q pod %q container %q: %v", podStatus.Spec.NodeName, podStatus.Name, c.Name, err) @@ -187,18 +197,18 @@ func MatchContainerOutput( podStatus.Spec.NodeName, podStatus.Name, containerName, err) // Sometimes the actual containers take a second to get started, try to get logs for 60s - logs, err := e2epod.GetPodLogs(f.ClientSet, ns, podStatus.Name, containerName) + logs, err := e2epod.GetPodLogs(ctx, f.ClientSet, ns, podStatus.Name, containerName) if err != nil { framework.Logf("Failed to get logs from node %q pod %q container %q. %v", podStatus.Spec.NodeName, podStatus.Name, containerName, err) - return fmt.Errorf("failed to get logs from %s for %s: %v", podStatus.Name, containerName, err) + return fmt.Errorf("failed to get logs from %s for %s: %w", podStatus.Name, containerName, err) } for _, expected := range expectedOutput { m := matcher(expected) matches, err := m.Match(logs) if err != nil { - return fmt.Errorf("expected %q in container output: %v", expected, err) + return fmt.Errorf("expected %q in container output: %w", expected, err) } else if !matches { return fmt.Errorf("expected %q in container output: %s", expected, m.FailureMessage(logs)) } @@ -210,21 +220,21 @@ func MatchContainerOutput( // TestContainerOutput runs the given pod in the given namespace and waits // for all of the containers in the podSpec to move into the 'Success' status, and tests // the specified container log against the given expected output using a substring matcher. -func TestContainerOutput(f *framework.Framework, scenarioName string, pod *v1.Pod, containerIndex int, expectedOutput []string) { - TestContainerOutputMatcher(f, scenarioName, pod, containerIndex, expectedOutput, gomega.ContainSubstring) +func TestContainerOutput(ctx context.Context, f *framework.Framework, scenarioName string, pod *v1.Pod, containerIndex int, expectedOutput []string) { + TestContainerOutputMatcher(ctx, f, scenarioName, pod, containerIndex, expectedOutput, gomega.ContainSubstring) } // TestContainerOutputRegexp runs the given pod in the given namespace and waits // for all of the containers in the podSpec to move into the 'Success' status, and tests // the specified container log against the given expected output using a regexp matcher. -func TestContainerOutputRegexp(f *framework.Framework, scenarioName string, pod *v1.Pod, containerIndex int, expectedOutput []string) { - TestContainerOutputMatcher(f, scenarioName, pod, containerIndex, expectedOutput, gomega.MatchRegexp) +func TestContainerOutputRegexp(ctx context.Context, f *framework.Framework, scenarioName string, pod *v1.Pod, containerIndex int, expectedOutput []string) { + TestContainerOutputMatcher(ctx, f, scenarioName, pod, containerIndex, expectedOutput, gomega.MatchRegexp) } // TestContainerOutputMatcher runs the given pod in the given namespace and waits // for all of the containers in the podSpec to move into the 'Success' status, and tests // the specified container log against the given expected output using the given matcher. -func TestContainerOutputMatcher(f *framework.Framework, +func TestContainerOutputMatcher(ctx context.Context, f *framework.Framework, scenarioName string, pod *v1.Pod, containerIndex int, @@ -234,5 +244,5 @@ func TestContainerOutputMatcher(f *framework.Framework, if containerIndex < 0 || containerIndex >= len(pod.Spec.Containers) { framework.Failf("Invalid container index: %d", containerIndex) } - framework.ExpectNoError(MatchContainerOutput(f, pod, pod.Spec.Containers[containerIndex].Name, expectedOutput, matcher)) + framework.ExpectNoError(MatchContainerOutput(ctx, f, pod, pod.Spec.Containers[containerIndex].Name, expectedOutput, matcher)) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go index 54b52dd23..946587ae1 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go @@ -27,7 +27,6 @@ import ( v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/strategicpatch" @@ -93,26 +92,26 @@ type PodClient struct { } // Create creates a new pod according to the framework specifications (don't wait for it to start). -func (c *PodClient) Create(pod *v1.Pod) *v1.Pod { +func (c *PodClient) Create(ctx context.Context, pod *v1.Pod) *v1.Pod { c.mungeSpec(pod) - p, err := c.PodInterface.Create(context.TODO(), pod, metav1.CreateOptions{}) + p, err := c.PodInterface.Create(ctx, pod, metav1.CreateOptions{}) framework.ExpectNoError(err, "Error creating Pod") return p } // CreateSync creates a new pod according to the framework specifications, and wait for it to start and be running and ready. -func (c *PodClient) CreateSync(pod *v1.Pod) *v1.Pod { +func (c *PodClient) CreateSync(ctx context.Context, pod *v1.Pod) *v1.Pod { namespace := c.f.Namespace.Name - p := c.Create(pod) - framework.ExpectNoError(WaitTimeoutForPodReadyInNamespace(c.f.ClientSet, p.Name, namespace, framework.PodStartTimeout)) + p := c.Create(ctx, pod) + framework.ExpectNoError(WaitTimeoutForPodReadyInNamespace(ctx, c.f.ClientSet, p.Name, namespace, framework.PodStartTimeout)) // Get the newest pod after it becomes running and ready, some status may change after pod created, such as pod ip. - p, err := c.Get(context.TODO(), p.Name, metav1.GetOptions{}) + p, err := c.Get(ctx, p.Name, metav1.GetOptions{}) framework.ExpectNoError(err) return p } // CreateBatch create a batch of pods. All pods are created before waiting. -func (c *PodClient) CreateBatch(pods []*v1.Pod) []*v1.Pod { +func (c *PodClient) CreateBatch(ctx context.Context, pods []*v1.Pod) []*v1.Pod { ps := make([]*v1.Pod, len(pods)) var wg sync.WaitGroup for i, pod := range pods { @@ -120,7 +119,7 @@ func (c *PodClient) CreateBatch(pods []*v1.Pod) []*v1.Pod { go func(i int, pod *v1.Pod) { defer wg.Done() defer ginkgo.GinkgoRecover() - ps[i] = c.CreateSync(pod) + ps[i] = c.CreateSync(ctx, pod) }(i, pod) } wg.Wait() @@ -130,14 +129,14 @@ func (c *PodClient) CreateBatch(pods []*v1.Pod) []*v1.Pod { // Update updates the pod object. It retries if there is a conflict, throw out error if // there is any other apierrors. name is the pod name, updateFn is the function updating the // pod object. -func (c *PodClient) Update(name string, updateFn func(pod *v1.Pod)) { - framework.ExpectNoError(wait.Poll(time.Millisecond*500, time.Second*30, func() (bool, error) { - pod, err := c.PodInterface.Get(context.TODO(), name, metav1.GetOptions{}) +func (c *PodClient) Update(ctx context.Context, name string, updateFn func(pod *v1.Pod)) { + framework.ExpectNoError(wait.PollWithContext(ctx, time.Millisecond*500, time.Second*30, func(ctx context.Context) (bool, error) { + pod, err := c.PodInterface.Get(ctx, name, metav1.GetOptions{}) if err != nil { - return false, fmt.Errorf("failed to get pod %q: %v", name, err) + return false, fmt.Errorf("failed to get pod %q: %w", name, err) } updateFn(pod) - _, err = c.PodInterface.Update(context.TODO(), pod, metav1.UpdateOptions{}) + _, err = c.PodInterface.Update(ctx, pod, metav1.UpdateOptions{}) if err == nil { framework.Logf("Successfully updated pod %q", name) return true, nil @@ -146,12 +145,12 @@ func (c *PodClient) Update(name string, updateFn func(pod *v1.Pod)) { framework.Logf("Conflicting update to pod %q, re-get and re-update: %v", name, err) return false, nil } - return false, fmt.Errorf("failed to update pod %q: %v", name, err) + return false, fmt.Errorf("failed to update pod %q: %w", name, err) })) } // AddEphemeralContainerSync adds an EphemeralContainer to a pod and waits for it to be running. -func (c *PodClient) AddEphemeralContainerSync(pod *v1.Pod, ec *v1.EphemeralContainer, timeout time.Duration) error { +func (c *PodClient) AddEphemeralContainerSync(ctx context.Context, pod *v1.Pod, ec *v1.EphemeralContainer, timeout time.Duration) error { namespace := c.f.Namespace.Name podJS, err := json.Marshal(pod) @@ -166,24 +165,23 @@ func (c *PodClient) AddEphemeralContainerSync(pod *v1.Pod, ec *v1.EphemeralConta framework.ExpectNoError(err, "error creating patch to add ephemeral container %q", format.Pod(pod)) // Clients may optimistically attempt to add an ephemeral container to determine whether the EphemeralContainers feature is enabled. - if _, err := c.Patch(context.TODO(), pod.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{}, "ephemeralcontainers"); err != nil { + if _, err := c.Patch(ctx, pod.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{}, "ephemeralcontainers"); err != nil { return err } - framework.ExpectNoError(WaitForContainerRunning(c.f.ClientSet, namespace, pod.Name, ec.Name, timeout)) + framework.ExpectNoError(WaitForContainerRunning(ctx, c.f.ClientSet, namespace, pod.Name, ec.Name, timeout)) return nil } // DeleteSync deletes the pod and wait for the pod to disappear for `timeout`. If the pod doesn't // disappear before the timeout, it will fail the test. -func (c *PodClient) DeleteSync(name string, options metav1.DeleteOptions, timeout time.Duration) { +func (c *PodClient) DeleteSync(ctx context.Context, name string, options metav1.DeleteOptions, timeout time.Duration) { namespace := c.f.Namespace.Name - err := c.Delete(context.TODO(), name, options) + err := c.Delete(ctx, name, options) if err != nil && !apierrors.IsNotFound(err) { framework.Failf("Failed to delete pod %q: %v", name, err) } - gomega.Expect(WaitForPodToDisappear(c.f.ClientSet, namespace, name, labels.Everything(), - 2*time.Second, timeout)).To(gomega.Succeed(), "wait for pod %q to disappear", name) + framework.ExpectNoError(WaitForPodNotFoundInNamespace(ctx, c.f.ClientSet, name, namespace, timeout), "wait for pod %q to disappear", name) } // mungeSpec apply test-suite specific transformations to the pod spec. @@ -224,9 +222,9 @@ func (c *PodClient) mungeSpec(pod *v1.Pod) { // WaitForSuccess waits for pod to succeed. // TODO(random-liu): Move pod wait function into this file -func (c *PodClient) WaitForSuccess(name string, timeout time.Duration) { +func (c *PodClient) WaitForSuccess(ctx context.Context, name string, timeout time.Duration) { f := c.f - gomega.Expect(WaitForPodCondition(f.ClientSet, f.Namespace.Name, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout, + gomega.Expect(WaitForPodCondition(ctx, f.ClientSet, f.Namespace.Name, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout, func(pod *v1.Pod) (bool, error) { switch pod.Status.Phase { case v1.PodFailed: @@ -241,9 +239,9 @@ func (c *PodClient) WaitForSuccess(name string, timeout time.Duration) { } // WaitForFinish waits for pod to finish running, regardless of success or failure. -func (c *PodClient) WaitForFinish(name string, timeout time.Duration) { +func (c *PodClient) WaitForFinish(ctx context.Context, name string, timeout time.Duration) { f := c.f - gomega.Expect(WaitForPodCondition(f.ClientSet, f.Namespace.Name, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout, + gomega.Expect(WaitForPodCondition(ctx, f.ClientSet, f.Namespace.Name, name, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout, func(pod *v1.Pod) (bool, error) { switch pod.Status.Phase { case v1.PodFailed: @@ -258,12 +256,12 @@ func (c *PodClient) WaitForFinish(name string, timeout time.Duration) { } // WaitForErrorEventOrSuccess waits for pod to succeed or an error event for that pod. -func (c *PodClient) WaitForErrorEventOrSuccess(pod *v1.Pod) (*v1.Event, error) { +func (c *PodClient) WaitForErrorEventOrSuccess(ctx context.Context, pod *v1.Pod) (*v1.Event, error) { var ev *v1.Event - err := wait.Poll(framework.Poll, framework.PodStartTimeout, func() (bool, error) { + err := wait.PollWithContext(ctx, framework.Poll, framework.PodStartTimeout, func(ctx context.Context) (bool, error) { evnts, err := c.f.ClientSet.CoreV1().Events(pod.Namespace).Search(scheme.Scheme, pod) if err != nil { - return false, fmt.Errorf("error in listing events: %s", err) + return false, fmt.Errorf("error in listing events: %w", err) } for _, e := range evnts.Items { switch e.Reason { @@ -282,15 +280,15 @@ func (c *PodClient) WaitForErrorEventOrSuccess(pod *v1.Pod) (*v1.Event, error) { } // MatchContainerOutput gets output of a container and match expected regexp in the output. -func (c *PodClient) MatchContainerOutput(name string, containerName string, expectedRegexp string) error { +func (c *PodClient) MatchContainerOutput(ctx context.Context, name string, containerName string, expectedRegexp string) error { f := c.f - output, err := GetPodLogs(f.ClientSet, f.Namespace.Name, name, containerName) + output, err := GetPodLogs(ctx, f.ClientSet, f.Namespace.Name, name, containerName) if err != nil { return fmt.Errorf("failed to get output for container %q of pod %q", containerName, name) } regex, err := regexp.Compile(expectedRegexp) if err != nil { - return fmt.Errorf("failed to compile regexp %q: %v", expectedRegexp, err) + return fmt.Errorf("failed to compile regexp %q: %w", expectedRegexp, err) } if !regex.MatchString(output) { return fmt.Errorf("failed to match regexp %q in output %q", expectedRegexp, output) @@ -299,16 +297,16 @@ func (c *PodClient) MatchContainerOutput(name string, containerName string, expe } // PodIsReady returns true if the specified pod is ready. Otherwise false. -func (c *PodClient) PodIsReady(name string) bool { - pod, err := c.Get(context.TODO(), name, metav1.GetOptions{}) +func (c *PodClient) PodIsReady(ctx context.Context, name string) bool { + pod, err := c.Get(ctx, name, metav1.GetOptions{}) framework.ExpectNoError(err) return podutils.IsPodReady(pod) } // RemovePodFinalizer removes the pod's finalizer -func (c *PodClient) RemoveFinalizer(podName string, finalizerName string) { +func (c *PodClient) RemoveFinalizer(ctx context.Context, podName string, finalizerName string) { framework.Logf("Removing pod's %q finalizer: %q", podName, finalizerName) - c.Update(podName, func(pod *v1.Pod) { + c.Update(ctx, podName, func(pod *v1.Pod) { pod.ObjectMeta.Finalizers = slice.RemoveString(pod.ObjectMeta.Finalizers, finalizerName, nil) }) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go index 64c3447f8..3039a9bc8 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go @@ -18,7 +18,6 @@ package pod import ( "context" - "errors" "fmt" "os" "path/filepath" @@ -31,7 +30,6 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/types" clientset "k8s.io/client-go/kubernetes" "k8s.io/klog/v2" @@ -40,14 +38,6 @@ import ( imageutils "k8s.io/kubernetes/test/utils/image" ) -// errPodCompleted is returned by PodRunning or PodContainerRunning to indicate that -// the pod has already reached completed state. -var errPodCompleted = FinalError(errors.New("pod ran to completion successfully")) - -// errPodFailed is returned by PodRunning or PodContainerRunning to indicate that -// the pod has already reached a permanent failue state. -var errPodFailed = FinalError(errors.New("pod failed permanently")) - // LabelLogOnPodFailure can be used to mark which Pods will have their logs logged in the case of // a test failure. By default, if there are no Pods with this label, only the first 5 Pods will // have their logs fetched. @@ -69,109 +59,20 @@ func expectNoErrorWithOffset(offset int, err error, explain ...interface{}) { gomega.ExpectWithOffset(1+offset, err).NotTo(gomega.HaveOccurred(), explain...) } -func isElementOf(podUID types.UID, pods *v1.PodList) bool { - for _, pod := range pods.Items { - if pod.UID == podUID { - return true - } - } - return false -} - -// ProxyResponseChecker is a context for checking pods responses by issuing GETs to them (via the API -// proxy) and verifying that they answer with their own pod name. -type ProxyResponseChecker struct { - c clientset.Interface - ns string - label labels.Selector - controllerName string - respondName bool // Whether the pod should respond with its own name. - pods *v1.PodList -} - -// NewProxyResponseChecker returns a context for checking pods responses. -func NewProxyResponseChecker(c clientset.Interface, ns string, label labels.Selector, controllerName string, respondName bool, pods *v1.PodList) ProxyResponseChecker { - return ProxyResponseChecker{c, ns, label, controllerName, respondName, pods} -} - -// CheckAllResponses issues GETs to all pods in the context and verify they -// reply with their own pod name. -func (r ProxyResponseChecker) CheckAllResponses() (done bool, err error) { - successes := 0 - options := metav1.ListOptions{LabelSelector: r.label.String()} - currentPods, err := r.c.CoreV1().Pods(r.ns).List(context.TODO(), options) - expectNoError(err, "Failed to get list of currentPods in namespace: %s", r.ns) - for i, pod := range r.pods.Items { - // Check that the replica list remains unchanged, otherwise we have problems. - if !isElementOf(pod.UID, currentPods) { - return false, fmt.Errorf("pod with UID %s is no longer a member of the replica set. Must have been restarted for some reason. Current replica set: %v", pod.UID, currentPods) - } - - ctx, cancel := context.WithTimeout(context.Background(), singleCallTimeout) - defer cancel() - - body, err := r.c.CoreV1().RESTClient().Get(). - Namespace(r.ns). - Resource("pods"). - SubResource("proxy"). - Name(string(pod.Name)). - Do(ctx). - Raw() - - if err != nil { - if ctx.Err() != nil { - // We may encounter errors here because of a race between the pod readiness and apiserver - // proxy. So, we log the error and retry if this occurs. - framework.Logf("Controller %s: Failed to Get from replica %d [%s]: %v\n pod status: %#v", r.controllerName, i+1, pod.Name, err, pod.Status) - return false, nil - } - framework.Logf("Controller %s: Failed to GET from replica %d [%s]: %v\npod status: %#v", r.controllerName, i+1, pod.Name, err, pod.Status) - continue - } - // The response checker expects the pod's name unless !respondName, in - // which case it just checks for a non-empty response. - got := string(body) - what := "" - if r.respondName { - what = "expected" - want := pod.Name - if got != want { - framework.Logf("Controller %s: Replica %d [%s] expected response %q but got %q", - r.controllerName, i+1, pod.Name, want, got) - continue - } - } else { - what = "non-empty" - if len(got) == 0 { - framework.Logf("Controller %s: Replica %d [%s] expected non-empty response", - r.controllerName, i+1, pod.Name) - continue - } - } - successes++ - framework.Logf("Controller %s: Got %s result from replica %d [%s]: %q, %d of %d required successes so far", - r.controllerName, what, i+1, pod.Name, got, successes, len(r.pods.Items)) - } - if successes < len(r.pods.Items) { - return false, nil - } - return true, nil -} - // PodsCreated returns a pod list matched by the given name. -func PodsCreated(c clientset.Interface, ns, name string, replicas int32) (*v1.PodList, error) { +func PodsCreated(ctx context.Context, c clientset.Interface, ns, name string, replicas int32) (*v1.PodList, error) { label := labels.SelectorFromSet(labels.Set(map[string]string{"name": name})) - return PodsCreatedByLabel(c, ns, name, replicas, label) + return PodsCreatedByLabel(ctx, c, ns, name, replicas, label) } // PodsCreatedByLabel returns a created pod list matched by the given label. -func PodsCreatedByLabel(c clientset.Interface, ns, name string, replicas int32, label labels.Selector) (*v1.PodList, error) { +func PodsCreatedByLabel(ctx context.Context, c clientset.Interface, ns, name string, replicas int32, label labels.Selector) (*v1.PodList, error) { timeout := 2 * time.Minute for start := time.Now(); time.Since(start) < timeout; time.Sleep(5 * time.Second) { options := metav1.ListOptions{LabelSelector: label.String()} // List the pods, making sure we observe all the replicas. - pods, err := c.CoreV1().Pods(ns).List(context.TODO(), options) + pods, err := c.CoreV1().Pods(ns).List(ctx, options) if err != nil { return nil, err } @@ -194,34 +95,31 @@ func PodsCreatedByLabel(c clientset.Interface, ns, name string, replicas int32, } // VerifyPods checks if the specified pod is responding. -func VerifyPods(c clientset.Interface, ns, name string, wantName bool, replicas int32) error { - return podRunningMaybeResponding(c, ns, name, wantName, replicas, true) +func VerifyPods(ctx context.Context, c clientset.Interface, ns, name string, wantName bool, replicas int32) error { + return podRunningMaybeResponding(ctx, c, ns, name, wantName, replicas, true) } // VerifyPodsRunning checks if the specified pod is running. -func VerifyPodsRunning(c clientset.Interface, ns, name string, wantName bool, replicas int32) error { - return podRunningMaybeResponding(c, ns, name, wantName, replicas, false) +func VerifyPodsRunning(ctx context.Context, c clientset.Interface, ns, name string, wantName bool, replicas int32) error { + return podRunningMaybeResponding(ctx, c, ns, name, wantName, replicas, false) } -func podRunningMaybeResponding(c clientset.Interface, ns, name string, wantName bool, replicas int32, checkResponding bool) error { - pods, err := PodsCreated(c, ns, name, replicas) +func podRunningMaybeResponding(ctx context.Context, c clientset.Interface, ns, name string, wantName bool, replicas int32, checkResponding bool) error { + pods, err := PodsCreated(ctx, c, ns, name, replicas) if err != nil { return err } - e := podsRunning(c, pods) + e := podsRunning(ctx, c, pods) if len(e) > 0 { return fmt.Errorf("failed to wait for pods running: %v", e) } if checkResponding { - err = PodsResponding(c, ns, name, wantName, pods) - if err != nil { - return fmt.Errorf("failed to wait for pods responding: %v", err) - } + return WaitForPodsResponding(ctx, c, ns, name, wantName, podRespondingTimeout, pods) } return nil } -func podsRunning(c clientset.Interface, pods *v1.PodList) []error { +func podsRunning(ctx context.Context, c clientset.Interface, pods *v1.PodList) []error { // Wait for the pods to enter the running state. Waiting loops until the pods // are running so non-running pods cause a timeout for this test. ginkgo.By("ensuring each pod is running") @@ -230,7 +128,7 @@ func podsRunning(c clientset.Interface, pods *v1.PodList) []error { for _, pod := range pods.Items { go func(p v1.Pod) { - errorChan <- WaitForPodRunningInNamespace(c, &p) + errorChan <- WaitForPodRunningInNamespace(ctx, c, &p) }(pod) } @@ -302,7 +200,7 @@ func logPodTerminationMessages(pods []v1.Pod) { // We will log the Pods that have the LabelLogOnPodFailure label. If there aren't any, we default to // logging only the first 5 Pods. This requires the reportDir to be set, and the pods are logged into: // {report_dir}/pods/{namespace}/{pod}/{container_name}/logs.txt -func logPodLogs(c clientset.Interface, namespace string, pods []v1.Pod, reportDir string) { +func logPodLogs(ctx context.Context, c clientset.Interface, namespace string, pods []v1.Pod, reportDir string) { if reportDir == "" { return } @@ -328,7 +226,7 @@ func logPodLogs(c clientset.Interface, namespace string, pods []v1.Pod, reportDi for i := 0; i < maxPods; i++ { pod := logPods[i] for _, container := range pod.Spec.Containers { - logs, err := getPodLogsInternal(c, namespace, pod.Name, container.Name, false, nil, &tailLen) + logs, err := getPodLogsInternal(ctx, c, namespace, pod.Name, container.Name, false, nil, &tailLen) if err != nil { framework.Logf("Unable to fetch %s/%s/%s logs: %v", pod.Namespace, pod.Name, container.Name, err) continue @@ -351,14 +249,14 @@ func logPodLogs(c clientset.Interface, namespace string, pods []v1.Pod, reportDi } // DumpAllPodInfoForNamespace logs all pod information for a given namespace. -func DumpAllPodInfoForNamespace(c clientset.Interface, namespace, reportDir string) { - pods, err := c.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{}) +func DumpAllPodInfoForNamespace(ctx context.Context, c clientset.Interface, namespace, reportDir string) { + pods, err := c.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{}) if err != nil { framework.Logf("unable to fetch pod debug info: %v", err) } LogPodStates(pods.Items) logPodTerminationMessages(pods.Items) - logPodLogs(c, namespace, pods.Items, reportDir) + logPodLogs(ctx, c, namespace, pods.Items, reportDir) } // FilterNonRestartablePods filters out pods that will never get recreated if @@ -459,15 +357,15 @@ func newExecPodSpec(ns, generateName string) *v1.Pod { // CreateExecPodOrFail creates a agnhost pause pod used as a vessel for kubectl exec commands. // Pod name is uniquely generated. -func CreateExecPodOrFail(client clientset.Interface, ns, generateName string, tweak func(*v1.Pod)) *v1.Pod { +func CreateExecPodOrFail(ctx context.Context, client clientset.Interface, ns, generateName string, tweak func(*v1.Pod)) *v1.Pod { framework.Logf("Creating new exec pod") pod := newExecPodSpec(ns, generateName) if tweak != nil { tweak(pod) } - execPod, err := client.CoreV1().Pods(ns).Create(context.TODO(), pod, metav1.CreateOptions{}) + execPod, err := client.CoreV1().Pods(ns).Create(ctx, pod, metav1.CreateOptions{}) expectNoError(err, "failed to create new exec pod in namespace: %s", ns) - err = WaitForPodNameRunningInNamespace(client, execPod.Name, execPod.Namespace) + err = WaitForPodNameRunningInNamespace(ctx, client, execPod.Name, execPod.Namespace) expectNoError(err, "failed to create new exec pod in namespace: %s", ns) return execPod } @@ -497,20 +395,20 @@ func WithWindowsHostProcess(pod *v1.Pod, username string) { // CheckPodsRunningReady returns whether all pods whose names are listed in // podNames in namespace ns are running and ready, using c and waiting at most // timeout. -func CheckPodsRunningReady(c clientset.Interface, ns string, podNames []string, timeout time.Duration) bool { - return checkPodsCondition(c, ns, podNames, timeout, testutils.PodRunningReady, "running and ready") +func CheckPodsRunningReady(ctx context.Context, c clientset.Interface, ns string, podNames []string, timeout time.Duration) bool { + return checkPodsCondition(ctx, c, ns, podNames, timeout, testutils.PodRunningReady, "running and ready") } // CheckPodsRunningReadyOrSucceeded returns whether all pods whose names are // listed in podNames in namespace ns are running and ready, or succeeded; use // c and waiting at most timeout. -func CheckPodsRunningReadyOrSucceeded(c clientset.Interface, ns string, podNames []string, timeout time.Duration) bool { - return checkPodsCondition(c, ns, podNames, timeout, testutils.PodRunningReadyOrSucceeded, "running and ready, or succeeded") +func CheckPodsRunningReadyOrSucceeded(ctx context.Context, c clientset.Interface, ns string, podNames []string, timeout time.Duration) bool { + return checkPodsCondition(ctx, c, ns, podNames, timeout, testutils.PodRunningReadyOrSucceeded, "running and ready, or succeeded") } // checkPodsCondition returns whether all pods whose names are listed in podNames // in namespace ns are in the condition, using c and waiting at most timeout. -func checkPodsCondition(c clientset.Interface, ns string, podNames []string, timeout time.Duration, condition podCondition, desc string) bool { +func checkPodsCondition(ctx context.Context, c clientset.Interface, ns string, podNames []string, timeout time.Duration, condition podCondition, desc string) bool { np := len(podNames) framework.Logf("Waiting up to %v for %d pods to be %s: %s", timeout, np, desc, podNames) type waitPodResult struct { @@ -521,7 +419,7 @@ func checkPodsCondition(c clientset.Interface, ns string, podNames []string, tim for _, podName := range podNames { // Launch off pod readiness checkers. go func(name string) { - err := WaitForPodCondition(c, ns, name, desc, timeout, condition) + err := WaitForPodCondition(ctx, c, ns, name, desc, timeout, condition) result <- waitPodResult{err == nil, name} }(podName) } @@ -539,24 +437,24 @@ func checkPodsCondition(c clientset.Interface, ns string, podNames []string, tim } // GetPodLogs returns the logs of the specified container (namespace/pod/container). -func GetPodLogs(c clientset.Interface, namespace, podName, containerName string) (string, error) { - return getPodLogsInternal(c, namespace, podName, containerName, false, nil, nil) +func GetPodLogs(ctx context.Context, c clientset.Interface, namespace, podName, containerName string) (string, error) { + return getPodLogsInternal(ctx, c, namespace, podName, containerName, false, nil, nil) } // GetPodLogsSince returns the logs of the specified container (namespace/pod/container) since a timestamp. -func GetPodLogsSince(c clientset.Interface, namespace, podName, containerName string, since time.Time) (string, error) { +func GetPodLogsSince(ctx context.Context, c clientset.Interface, namespace, podName, containerName string, since time.Time) (string, error) { sinceTime := metav1.NewTime(since) - return getPodLogsInternal(c, namespace, podName, containerName, false, &sinceTime, nil) + return getPodLogsInternal(ctx, c, namespace, podName, containerName, false, &sinceTime, nil) } // GetPreviousPodLogs returns the logs of the previous instance of the // specified container (namespace/pod/container). -func GetPreviousPodLogs(c clientset.Interface, namespace, podName, containerName string) (string, error) { - return getPodLogsInternal(c, namespace, podName, containerName, true, nil, nil) +func GetPreviousPodLogs(ctx context.Context, c clientset.Interface, namespace, podName, containerName string) (string, error) { + return getPodLogsInternal(ctx, c, namespace, podName, containerName, true, nil, nil) } // utility function for gomega Eventually -func getPodLogsInternal(c clientset.Interface, namespace, podName, containerName string, previous bool, sinceTime *metav1.Time, tailLines *int) (string, error) { +func getPodLogsInternal(ctx context.Context, c clientset.Interface, namespace, podName, containerName string, previous bool, sinceTime *metav1.Time, tailLines *int) (string, error) { request := c.CoreV1().RESTClient().Get(). Resource("pods"). Namespace(namespace). @@ -569,7 +467,7 @@ func getPodLogsInternal(c clientset.Interface, namespace, podName, containerName if tailLines != nil { request.Param("tailLines", strconv.Itoa(*tailLines)) } - logs, err := request.Do(context.TODO()).Raw() + logs, err := request.Do(ctx).Raw() if err != nil { return "", err } @@ -580,8 +478,8 @@ func getPodLogsInternal(c clientset.Interface, namespace, podName, containerName } // GetPodsInNamespace returns the pods in the given namespace. -func GetPodsInNamespace(c clientset.Interface, ns string, ignoreLabels map[string]string) ([]*v1.Pod, error) { - pods, err := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) +func GetPodsInNamespace(ctx context.Context, c clientset.Interface, ns string, ignoreLabels map[string]string) ([]*v1.Pod, error) { + pods, err := c.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{}) if err != nil { return []*v1.Pod{}, err } @@ -598,10 +496,10 @@ func GetPodsInNamespace(c clientset.Interface, ns string, ignoreLabels map[strin } // GetPods return the label matched pods in the given ns -func GetPods(c clientset.Interface, ns string, matchLabels map[string]string) ([]v1.Pod, error) { +func GetPods(ctx context.Context, c clientset.Interface, ns string, matchLabels map[string]string) ([]v1.Pod, error) { label := labels.SelectorFromSet(matchLabels) listOpts := metav1.ListOptions{LabelSelector: label.String()} - pods, err := c.CoreV1().Pods(ns).List(context.TODO(), listOpts) + pods, err := c.CoreV1().Pods(ns).List(ctx, listOpts) if err != nil { return []v1.Pod{}, err } @@ -609,13 +507,13 @@ func GetPods(c clientset.Interface, ns string, matchLabels map[string]string) ([ } // GetPodSecretUpdateTimeout returns the timeout duration for updating pod secret. -func GetPodSecretUpdateTimeout(c clientset.Interface) time.Duration { +func GetPodSecretUpdateTimeout(ctx context.Context, c clientset.Interface) time.Duration { // With SecretManager(ConfigMapManager), we may have to wait up to full sync period + // TTL of secret(configmap) to elapse before the Kubelet projects the update into the // volume and the container picks it up. // So this timeout is based on default Kubelet sync period (1 minute) + maximum TTL for // secret(configmap) that's based on cluster size + additional time as a fudge factor. - secretTTL, err := getNodeTTLAnnotationValue(c) + secretTTL, err := getNodeTTLAnnotationValue(ctx, c) if err != nil { framework.Logf("Couldn't get node TTL annotation (using default value of 0): %v", err) } @@ -624,18 +522,18 @@ func GetPodSecretUpdateTimeout(c clientset.Interface) time.Duration { } // VerifyPodHasConditionWithType verifies the pod has the expected condition by type -func VerifyPodHasConditionWithType(f *framework.Framework, pod *v1.Pod, cType v1.PodConditionType) { - pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(context.TODO(), pod.Name, metav1.GetOptions{}) +func VerifyPodHasConditionWithType(ctx context.Context, f *framework.Framework, pod *v1.Pod, cType v1.PodConditionType) { + pod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(ctx, pod.Name, metav1.GetOptions{}) framework.ExpectNoError(err, "Failed to get the recent pod object for name: %q", pod.Name) if condition := FindPodConditionByType(&pod.Status, cType); condition == nil { framework.Failf("pod %q should have the condition: %q, pod status: %v", pod.Name, cType, pod.Status) } } -func getNodeTTLAnnotationValue(c clientset.Interface) (time.Duration, error) { - nodes, err := c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) +func getNodeTTLAnnotationValue(ctx context.Context, c clientset.Interface) (time.Duration, error) { + nodes, err := c.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil || len(nodes.Items) == 0 { - return time.Duration(0), fmt.Errorf("Couldn't list any nodes to get TTL annotation: %v", err) + return time.Duration(0), fmt.Errorf("Couldn't list any nodes to get TTL annotation: %w", err) } // Since TTL the kubelet is using is stored in node object, for the timeout // purpose we take it from the first node (all of them should be the same). @@ -674,15 +572,3 @@ func IsPodActive(p *v1.Pod) bool { v1.PodFailed != p.Status.Phase && p.DeletionTimestamp == nil } - -func podIdentifier(namespace, name string) string { - return fmt.Sprintf("%s/%s", namespace, name) -} - -func identifier(pod *v1.Pod) string { - id := podIdentifier(pod.Namespace, pod.Name) - if pod.UID != "" { - id += fmt.Sprintf("(%s)", pod.UID) - } - return id -} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go index a62c29a62..47b5385b5 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go @@ -141,14 +141,14 @@ const DefaultNonRootUserName = "ContainerUser" // Tests that require a specific user ID should override this. func GetRestrictedPodSecurityContext() *v1.PodSecurityContext { psc := &v1.PodSecurityContext{ - RunAsNonRoot: pointer.BoolPtr(true), + RunAsNonRoot: pointer.Bool(true), RunAsUser: GetDefaultNonRootUser(), SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}, } if NodeOSDistroIs("windows") { psc.WindowsOptions = &v1.WindowsSecurityContextOptions{} - psc.WindowsOptions.RunAsUserName = pointer.StringPtr(DefaultNonRootUserName) + psc.WindowsOptions.RunAsUserName = pointer.String(DefaultNonRootUserName) } return psc @@ -157,7 +157,7 @@ func GetRestrictedPodSecurityContext() *v1.PodSecurityContext { // GetRestrictedContainerSecurityContext returns a minimal restricted container security context. func GetRestrictedContainerSecurityContext() *v1.SecurityContext { return &v1.SecurityContext{ - AllowPrivilegeEscalation: pointer.BoolPtr(false), + AllowPrivilegeEscalation: pointer.Bool(false), Capabilities: &v1.Capabilities{Drop: []v1.Capability{"ALL"}}, } } @@ -181,7 +181,7 @@ func MixinRestrictedPodSecurity(pod *v1.Pod) error { pod.Spec.SecurityContext = GetRestrictedPodSecurityContext() } else { if pod.Spec.SecurityContext.RunAsNonRoot == nil { - pod.Spec.SecurityContext.RunAsNonRoot = pointer.BoolPtr(true) + pod.Spec.SecurityContext.RunAsNonRoot = pointer.Bool(true) } if pod.Spec.SecurityContext.RunAsUser == nil { pod.Spec.SecurityContext.RunAsUser = GetDefaultNonRootUser() @@ -191,7 +191,7 @@ func MixinRestrictedPodSecurity(pod *v1.Pod) error { } if NodeOSDistroIs("windows") && pod.Spec.SecurityContext.WindowsOptions == nil { pod.Spec.SecurityContext.WindowsOptions = &v1.WindowsSecurityContextOptions{} - pod.Spec.SecurityContext.WindowsOptions.RunAsUserName = pointer.StringPtr(DefaultNonRootUserName) + pod.Spec.SecurityContext.WindowsOptions.RunAsUserName = pointer.String(DefaultNonRootUserName) } } for i := range pod.Spec.Containers { @@ -241,3 +241,23 @@ func FindPodConditionByType(podStatus *v1.PodStatus, conditionType v1.PodConditi } return nil } + +// FindContainerStatusInPod finds a container status by its name in the provided pod +func FindContainerStatusInPod(pod *v1.Pod, containerName string) *v1.ContainerStatus { + for _, containerStatus := range pod.Status.InitContainerStatuses { + if containerStatus.Name == containerName { + return &containerStatus + } + } + for _, containerStatus := range pod.Status.ContainerStatuses { + if containerStatus.Name == containerName { + return &containerStatus + } + } + for _, containerStatus := range pod.Status.EphemeralContainerStatuses { + if containerStatus.Name == containerName { + return &containerStatus + } + } + return nil +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/wait.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/wait.go index 24ba76805..e462cc0bc 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/wait.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/wait.go @@ -17,25 +17,30 @@ limitations under the License. package pod import ( - "bytes" "context" "errors" "fmt" "reflect" - "text/tabwriter" + "strings" "time" "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + "github.com/onsi/gomega/gcustom" + "github.com/onsi/gomega/types" + appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/wait" + apitypes "k8s.io/apimachinery/pkg/types" clientset "k8s.io/client-go/kubernetes" "k8s.io/kubectl/pkg/util/podutils" + podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/test/e2e/framework" testutils "k8s.io/kubernetes/test/utils" + "k8s.io/kubernetes/test/utils/format" ) const ( @@ -53,9 +58,6 @@ const ( // podStartTimeout is how long to wait for the pod to be started. podStartTimeout = 5 * time.Minute - // poll is how often to poll pods, nodes and claims. - poll = 2 * time.Second - // singleCallTimeout is how long to try single API calls (like 'get' or 'list'). Used to prevent // transient failures from failing tests. singleCallTimeout = 5 * time.Minute @@ -66,106 +68,36 @@ const ( type podCondition func(pod *v1.Pod) (bool, error) -type timeoutError struct { - msg string - observedObjects []interface{} -} - -func (e *timeoutError) Error() string { - return e.msg -} - -func TimeoutError(msg string, observedObjects ...interface{}) *timeoutError { - return &timeoutError{ - msg: msg, - observedObjects: observedObjects, - } -} - -// FinalError constructs an error that indicates to a poll function that -// polling can be stopped immediately because some permanent error has been -// encountered that is not going to go away. -// -// TODO (@pohly): move this into framework once the refactoring from -// https://github.com/kubernetes/kubernetes/pull/112043 allows it. Right now it -// leads to circular dependencies. -func FinalError(err error) error { - return &FinalErr{Err: err} -} - -type FinalErr struct { - Err error -} - -func (err *FinalErr) Error() string { - if err.Err != nil { - return fmt.Sprintf("final error: %s", err.Err.Error()) - } - return "final error, exact problem unknown" -} - -func (err *FinalErr) Unwrap() error { - return err.Err -} - -// IsFinal checks whether the error was marked as final by wrapping some error -// with FinalError. -func IsFinal(err error) bool { - var finalErr *FinalErr - return errors.As(err, &finalErr) -} - -// maybeTimeoutError returns a TimeoutError if err is a timeout. Otherwise, wrap err. -// taskFormat and taskArgs should be the task being performed when the error occurred, -// e.g. "waiting for pod to be running". -func maybeTimeoutError(err error, taskFormat string, taskArgs ...interface{}) error { - if IsTimeout(err) { - return TimeoutError(fmt.Sprintf("timed out while "+taskFormat, taskArgs...)) - } else if err != nil { - return fmt.Errorf("error while %s: %w", fmt.Sprintf(taskFormat, taskArgs...), err) - } else { - return nil - } -} - -func IsTimeout(err error) bool { - if err == wait.ErrWaitTimeout { - return true - } - if _, ok := err.(*timeoutError); ok { - return true - } - return false -} - -// errorBadPodsStates create error message of basic info of bad pods for debugging. -func errorBadPodsStates(badPods []v1.Pod, desiredPods int, ns, desiredState string, timeout time.Duration, err error) error { - errStr := fmt.Sprintf("%d / %d pods in namespace %s are NOT in %s state in %v\n", len(badPods), desiredPods, ns, desiredState, timeout) - - // Print bad pods info only if there are fewer than 10 bad pods - if len(badPods) > 10 { - errStr += "There are too many bad pods. Please check log for details." - } else { - buf := bytes.NewBuffer(nil) - w := tabwriter.NewWriter(buf, 0, 0, 1, ' ', 0) - fmt.Fprintln(w, "POD\tNODE\tPHASE\tGRACE\tCONDITIONS") - for _, badPod := range badPods { - grace := "" - if badPod.DeletionGracePeriodSeconds != nil { - grace = fmt.Sprintf("%ds", *badPod.DeletionGracePeriodSeconds) +// BeRunningNoRetries verifies that a pod starts running. It's a permanent +// failure when the pod enters some other permanent phase. +func BeRunningNoRetries() types.GomegaMatcher { + return gomega.And( + // This additional matcher checks for the final error condition. + gcustom.MakeMatcher(func(pod *v1.Pod) (bool, error) { + switch pod.Status.Phase { + case v1.PodFailed, v1.PodSucceeded: + return false, gomega.StopTrying(fmt.Sprintf("Expected pod to reach phase %q, got final phase %q instead.", v1.PodRunning, pod.Status.Phase)) + default: + return true, nil } - podInfo := fmt.Sprintf("%s\t%s\t%s\t%s\t%+v", - badPod.ObjectMeta.Name, badPod.Spec.NodeName, badPod.Status.Phase, grace, badPod.Status.Conditions) - fmt.Fprintln(w, podInfo) - } - w.Flush() - errStr += buf.String() - } + }), + BeInPhase(v1.PodRunning), + ) +} - if err != nil && !IsTimeout(err) { - return fmt.Errorf("%s\nLast error: %w", errStr, err) - } - return TimeoutError(errStr) +// BeInPhase matches if pod.status.phase is the expected phase. +func BeInPhase(phase v1.PodPhase) types.GomegaMatcher { + // A simple implementation of this would be: + // return gomega.HaveField("Status.Phase", phase) + // + // But that produces a fairly generic + // Value for field 'Status.Phase' failed to satisfy matcher. + // failure message and doesn't show the pod. We can do better than + // that with a custom matcher. + + return gcustom.MakeMatcher(func(pod *v1.Pod) (bool, error) { + return pod.Status.Phase == phase, nil + }).WithTemplate("Expected Pod {{.To}} be in {{format .Data}}\nGot instead:\n{{.FormattedActual}}").WithTemplateData(phase) } // WaitForPodsRunningReady waits up to timeout to ensure that all pods in @@ -176,263 +108,265 @@ func errorBadPodsStates(badPods []v1.Pod, desiredPods int, ns, desiredState stri // example, in cluster startup, because the number of pods increases while // waiting. All pods that are in SUCCESS state are not counted. // -// If ignoreLabels is not empty, pods matching this selector are ignored. -// // If minPods or allowedNotReadyPods are -1, this method returns immediately // without waiting. -func WaitForPodsRunningReady(c clientset.Interface, ns string, minPods, allowedNotReadyPods int32, timeout time.Duration, ignoreLabels map[string]string) error { +func WaitForPodsRunningReady(ctx context.Context, c clientset.Interface, ns string, minPods, allowedNotReadyPods int32, timeout time.Duration) error { if minPods == -1 || allowedNotReadyPods == -1 { return nil } - ignoreSelector := labels.SelectorFromSet(map[string]string{}) - start := time.Now() - framework.Logf("Waiting up to %v for all pods (need at least %d) in namespace '%s' to be running and ready", - timeout, minPods, ns) - var ignoreNotReady bool - badPods := []v1.Pod{} - desiredPods := 0 - notReady := int32(0) - var lastAPIError error + // We get the new list of pods, replication controllers, and replica + // sets in every iteration because more pods come online during startup + // and we want to ensure they are also checked. + // + // This struct gets populated while polling, then gets checked, and in + // case of a timeout is included in the failure message. + type state struct { + ReplicationControllers []v1.ReplicationController + ReplicaSets []appsv1.ReplicaSet + Pods []v1.Pod + } - if wait.PollImmediate(poll, timeout, func() (bool, error) { - // We get the new list of pods, replication controllers, and - // replica sets in every iteration because more pods come - // online during startup and we want to ensure they are also - // checked. - replicas, replicaOk := int32(0), int32(0) - // Clear API error from the last attempt in case the following calls succeed. - lastAPIError = nil + // notReady is -1 for any failure other than a timeout. + // Otherwise it is the number of pods that we were still + // waiting for. + notReady := int32(-1) - rcList, err := c.CoreV1().ReplicationControllers(ns).List(context.TODO(), metav1.ListOptions{}) - lastAPIError = err + err := framework.Gomega().Eventually(ctx, framework.HandleRetry(func(ctx context.Context) (*state, error) { + // Reset notReady at the start of a poll attempt. + notReady = -1 + + rcList, err := c.CoreV1().ReplicationControllers(ns).List(ctx, metav1.ListOptions{}) if err != nil { - return handleWaitingAPIError(err, false, "listing replication controllers in namespace %s", ns) + return nil, fmt.Errorf("listing replication controllers in namespace %s: %w", ns, err) } - for _, rc := range rcList.Items { + rsList, err := c.AppsV1().ReplicaSets(ns).List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, fmt.Errorf("listing replication sets in namespace %s: %w", ns, err) + } + podList, err := c.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, fmt.Errorf("listing pods in namespace %s: %w", ns, err) + } + return &state{ + ReplicationControllers: rcList.Items, + ReplicaSets: rsList.Items, + Pods: podList.Items, + }, nil + })).WithTimeout(timeout).Should(framework.MakeMatcher(func(s *state) (func() string, error) { + replicas, replicaOk := int32(0), int32(0) + for _, rc := range s.ReplicationControllers { replicas += *rc.Spec.Replicas replicaOk += rc.Status.ReadyReplicas } - - rsList, err := c.AppsV1().ReplicaSets(ns).List(context.TODO(), metav1.ListOptions{}) - lastAPIError = err - if err != nil { - return handleWaitingAPIError(err, false, "listing replication sets in namespace %s", ns) - } - for _, rs := range rsList.Items { + for _, rs := range s.ReplicaSets { replicas += *rs.Spec.Replicas replicaOk += rs.Status.ReadyReplicas } - podList, err := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) - lastAPIError = err - if err != nil { - return handleWaitingAPIError(err, false, "listing pods in namespace %s", ns) - } nOk := int32(0) notReady = int32(0) - badPods = []v1.Pod{} - desiredPods = len(podList.Items) - for _, pod := range podList.Items { - if len(ignoreLabels) != 0 && ignoreSelector.Matches(labels.Set(pod.Labels)) { - continue - } + failedPods := []v1.Pod{} + otherPods := []v1.Pod{} + succeededPods := []string{} + for _, pod := range s.Pods { res, err := testutils.PodRunningReady(&pod) switch { case res && err == nil: nOk++ case pod.Status.Phase == v1.PodSucceeded: - framework.Logf("The status of Pod %s is Succeeded, skipping waiting", pod.ObjectMeta.Name) // it doesn't make sense to wait for this pod - continue - case pod.Status.Phase != v1.PodFailed: - framework.Logf("The status of Pod %s is %s (Ready = false), waiting for it to be either Running (with Ready = true) or Failed", pod.ObjectMeta.Name, pod.Status.Phase) - notReady++ - badPods = append(badPods, pod) - default: - if metav1.GetControllerOf(&pod) == nil { - framework.Logf("Pod %s is Failed, but it's not controlled by a controller", pod.ObjectMeta.Name) - badPods = append(badPods, pod) - } + succeededPods = append(succeededPods, pod.Name) + case pod.Status.Phase == v1.PodFailed: // ignore failed pods that are controlled by some controller + if metav1.GetControllerOf(&pod) == nil { + failedPods = append(failedPods, pod) + } + default: + notReady++ + otherPods = append(otherPods, pod) } } - - framework.Logf("%d / %d pods in namespace '%s' are running and ready (%d seconds elapsed)", - nOk, len(podList.Items), ns, int(time.Since(start).Seconds())) - framework.Logf("expected %d pod replicas in namespace '%s', %d are Running and Ready.", replicas, ns, replicaOk) - - if replicaOk == replicas && nOk >= minPods && len(badPods) == 0 { - return true, nil - } - ignoreNotReady = (notReady <= allowedNotReadyPods) - LogPodStates(badPods) - return false, nil - }) != nil { - if !ignoreNotReady { - return errorBadPodsStates(badPods, desiredPods, ns, "RUNNING and READY", timeout, lastAPIError) + done := replicaOk == replicas && nOk >= minPods && (len(failedPods)+len(otherPods)) == 0 + if done { + return nil, nil } + + // Delayed formatting of a failure message. + return func() string { + var buffer strings.Builder + buffer.WriteString(fmt.Sprintf("Expected all pods (need at least %d) in namespace %q to be running and ready (except for %d).\n", minPods, ns, allowedNotReadyPods)) + buffer.WriteString(fmt.Sprintf("%d / %d pods were running and ready.\n", nOk, len(s.Pods))) + buffer.WriteString(fmt.Sprintf("Expected %d pod replicas, %d are Running and Ready.\n", replicas, replicaOk)) + if len(succeededPods) > 0 { + buffer.WriteString(fmt.Sprintf("Pods that completed successfully:\n%s", format.Object(succeededPods, 1))) + } + if len(failedPods) > 0 { + buffer.WriteString(fmt.Sprintf("Pods that failed and were not controlled by some controller:\n%s", format.Object(failedPods, 1))) + } + if len(otherPods) > 0 { + buffer.WriteString(fmt.Sprintf("Pods that were neither completed nor running:\n%s", format.Object(otherPods, 1))) + } + return buffer.String() + }, nil + })) + + // An error might not be fatal. + if err != nil && notReady >= 0 && notReady <= allowedNotReadyPods { framework.Logf("Number of not-ready pods (%d) is below the allowed threshold (%d).", notReady, allowedNotReadyPods) + return nil } - return nil + return err } // WaitForPodCondition waits a pods to be matched to the given condition. -// If the condition callback returns an error that matches FinalErr (checked with IsFinal), -// then polling aborts early. -func WaitForPodCondition(c clientset.Interface, ns, podName, conditionDesc string, timeout time.Duration, condition podCondition) error { - framework.Logf("Waiting up to %v for pod %q in namespace %q to be %q", timeout, podName, ns, conditionDesc) - var ( - lastPodError error - lastPod *v1.Pod - start = time.Now() - ) - err := wait.PollImmediate(poll, timeout, func() (bool, error) { - pod, err := c.CoreV1().Pods(ns).Get(context.TODO(), podName, metav1.GetOptions{}) - lastPodError = err - if err != nil { - return handleWaitingAPIError(err, true, "getting pod %s", podIdentifier(ns, podName)) - } - lastPod = pod // Don't overwrite if an error occurs after successfully retrieving. - - // log now so that current pod info is reported before calling `condition()` - framework.Logf("Pod %q: Phase=%q, Reason=%q, readiness=%t. Elapsed: %v", - podName, pod.Status.Phase, pod.Status.Reason, podutils.IsPodReady(pod), time.Since(start)) - if done, err := condition(pod); done { - if err == nil { - framework.Logf("Pod %q satisfied condition %q", podName, conditionDesc) +// The condition callback may use gomega.StopTrying to abort early. +func WaitForPodCondition(ctx context.Context, c clientset.Interface, ns, podName, conditionDesc string, timeout time.Duration, condition podCondition) error { + return framework.Gomega(). + Eventually(ctx, framework.RetryNotFound(framework.GetObject(c.CoreV1().Pods(ns).Get, podName, metav1.GetOptions{}))). + WithTimeout(timeout). + Should(framework.MakeMatcher(func(pod *v1.Pod) (func() string, error) { + done, err := condition(pod) + if err != nil { + return nil, err } - return true, err - } else if err != nil { - framework.Logf("Error evaluating pod condition %s: %v", conditionDesc, err) - if IsFinal(err) { - return false, err + if done { + return nil, nil } - } - return false, nil - }) - if err == nil { - return nil - } - if IsTimeout(err) { - if lastPod != nil { - return TimeoutError(fmt.Sprintf("timed out while waiting for pod %s to be %s", podIdentifier(ns, podName), conditionDesc), - lastPod, - ) - } else if lastPodError != nil { - // If the last API call was an error, propagate that instead of the timeout error. - err = lastPodError - } - } - return maybeTimeoutError(err, "waiting for pod %s to be %s", podIdentifier(ns, podName), conditionDesc) + return func() string { + return fmt.Sprintf("expected pod to be %s, got instead:\n%s", conditionDesc, format.Object(pod, 1)) + }, nil + })) } -// WaitForAllPodsCondition waits for the listed pods to match the given condition. -// To succeed, at least minPods must be listed, and all listed pods must match the condition. -func WaitForAllPodsCondition(c clientset.Interface, ns string, opts metav1.ListOptions, minPods int, conditionDesc string, timeout time.Duration, condition podCondition) (*v1.PodList, error) { - framework.Logf("Waiting up to %v for at least %d pods in namespace %s to be %s", timeout, minPods, ns, conditionDesc) - var pods *v1.PodList - matched := 0 - err := wait.PollImmediate(poll, timeout, func() (done bool, err error) { - pods, err = c.CoreV1().Pods(ns).List(context.TODO(), opts) - if err != nil { - return handleWaitingAPIError(err, true, "listing pods") - } +// Range determines how many items must exist and how many must match a certain +// condition. Values <= 0 are ignored. +// TODO (?): move to test/e2e/framework/range +type Range struct { + // MinMatching must be <= actual matching items or <= 0. + MinMatching int + // MaxMatching must be >= actual matching items or <= 0. + // To check for "no matching items", set NonMatching. + MaxMatching int + // NoneMatching indicates that no item must match. + NoneMatching bool + // AllMatching indicates that all items must match. + AllMatching bool + // MinFound must be <= existing items or <= 0. + MinFound int +} + +// Min returns how many items must exist. +func (r Range) Min() int { + min := r.MinMatching + if min < r.MinFound { + min = r.MinFound + } + return min +} + +// WaitForPods waits for pods in the given namespace to match the given +// condition. How many pods must exist and how many must match the condition +// is determined by the range parameter. The condition callback may use +// gomega.StopTrying(...).Now() to abort early. The condition description +// will be used with "expected pods to ". +func WaitForPods(ctx context.Context, c clientset.Interface, ns string, opts metav1.ListOptions, r Range, timeout time.Duration, conditionDesc string, condition func(*v1.Pod) bool) (*v1.PodList, error) { + var finalPods *v1.PodList + minPods := r.Min() + match := func(pods *v1.PodList) (func() string, error) { + finalPods = pods + if len(pods.Items) < minPods { - framework.Logf("found %d pods, waiting for at least %d", len(pods.Items), minPods) - return false, nil + return func() string { + return fmt.Sprintf("expected at least %d pods, only got %d", minPods, len(pods.Items)) + }, nil } - nonMatchingPods := []string{} + var nonMatchingPods, matchingPods []v1.Pod for _, pod := range pods.Items { - done, err := condition(&pod) - if done && err != nil { - return false, fmt.Errorf("error evaluating pod %s: %w", identifier(&pod), err) - } - if !done { - nonMatchingPods = append(nonMatchingPods, identifier(&pod)) + if condition(&pod) { + matchingPods = append(matchingPods, pod) + } else { + nonMatchingPods = append(nonMatchingPods, pod) } } - matched = len(pods.Items) - len(nonMatchingPods) - if len(nonMatchingPods) <= 0 { - return true, nil // All pods match. + matching := len(pods.Items) - len(nonMatchingPods) + if matching < r.MinMatching && r.MinMatching > 0 { + return func() string { + return fmt.Sprintf("expected at least %d pods to %s, %d out of %d were not:\n%s", + r.MinMatching, conditionDesc, len(nonMatchingPods), len(pods.Items), + format.Object(nonMatchingPods, 1)) + }, nil } - framework.Logf("%d pods are not %s: %v", len(nonMatchingPods), conditionDesc, nonMatchingPods) - return false, nil - }) - return pods, maybeTimeoutError(err, "waiting for at least %d pods to be %s (matched %d)", minPods, conditionDesc, matched) + if len(nonMatchingPods) > 0 && r.AllMatching { + return func() string { + return fmt.Sprintf("expected all pods to %s, %d out of %d were not:\n%s", + conditionDesc, len(nonMatchingPods), len(pods.Items), + format.Object(nonMatchingPods, 1)) + }, nil + } + if matching > r.MaxMatching && r.MaxMatching > 0 { + return func() string { + return fmt.Sprintf("expected at most %d pods to %s, %d out of %d were:\n%s", + r.MinMatching, conditionDesc, len(matchingPods), len(pods.Items), + format.Object(matchingPods, 1)) + }, nil + } + if matching > 0 && r.NoneMatching { + return func() string { + return fmt.Sprintf("expected no pods to %s, %d out of %d were:\n%s", + conditionDesc, len(matchingPods), len(pods.Items), + format.Object(matchingPods, 1)) + }, nil + } + return nil, nil + } + + err := framework.Gomega(). + Eventually(ctx, framework.ListObjects(c.CoreV1().Pods(ns).List, opts)). + WithTimeout(timeout). + Should(framework.MakeMatcher(match)) + return finalPods, err +} + +// RunningReady checks whether pod p's phase is running and it has a ready +// condition of status true. +func RunningReady(p *v1.Pod) bool { + return p.Status.Phase == v1.PodRunning && podutil.IsPodReady(p) } // WaitForPodsRunning waits for a given `timeout` to evaluate if a certain amount of pods in given `ns` are running. func WaitForPodsRunning(c clientset.Interface, ns string, num int, timeout time.Duration) error { - matched := 0 - err := wait.PollImmediate(poll, timeout, func() (done bool, err error) { - pods, err := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) - if err != nil { - return handleWaitingAPIError(err, true, "listing pods") - } - matched = 0 - for _, pod := range pods.Items { - if ready, _ := testutils.PodRunningReady(&pod); ready { - matched++ - } - } - if matched == num { - return true, nil - } - framework.Logf("expect %d pods are running, but got %v", num, matched) - return false, nil - }) - return maybeTimeoutError(err, "waiting for pods to be running (want %v, matched %d)", num, matched) + _, err := WaitForPods(context.TODO(), c, ns, metav1.ListOptions{}, Range{MinMatching: num, MaxMatching: num}, timeout, + "be running and ready", func(pod *v1.Pod) bool { + ready, _ := testutils.PodRunningReady(pod) + return ready + }) + return err } // WaitForPodsSchedulingGated waits for a given `timeout` to evaluate if a certain amount of pods in given `ns` stay in scheduling gated state. func WaitForPodsSchedulingGated(c clientset.Interface, ns string, num int, timeout time.Duration) error { - matched := 0 - err := wait.PollImmediate(poll, timeout, func() (done bool, err error) { - pods, err := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) - if err != nil { - return handleWaitingAPIError(err, true, "listing pods") - } - matched = 0 - for _, pod := range pods.Items { + _, err := WaitForPods(context.TODO(), c, ns, metav1.ListOptions{}, Range{MinMatching: num, MaxMatching: num}, timeout, + "be in scheduling gated state", func(pod *v1.Pod) bool { for _, condition := range pod.Status.Conditions { if condition.Type == v1.PodScheduled && condition.Reason == v1.PodReasonSchedulingGated { - matched++ + return true } } - } - if matched == num { - return true, nil - } - framework.Logf("expect %d pods in scheduling gated state, but got %v", num, matched) - return false, nil - }) - return maybeTimeoutError(err, "waiting for pods to be scheduling gated (want %d, matched %d)", num, matched) + return false + }) + return err } // WaitForPodsWithSchedulingGates waits for a given `timeout` to evaluate if a certain amount of pods in given `ns` // match the given `schedulingGates`stay in scheduling gated state. func WaitForPodsWithSchedulingGates(c clientset.Interface, ns string, num int, timeout time.Duration, schedulingGates []v1.PodSchedulingGate) error { - matched := 0 - err := wait.PollImmediate(poll, timeout, func() (done bool, err error) { - pods, err := c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) - if err != nil { - return handleWaitingAPIError(err, true, "listing pods") - } - matched = 0 - for _, pod := range pods.Items { - if reflect.DeepEqual(pod.Spec.SchedulingGates, schedulingGates) { - matched++ - } - } - if matched == num { - return true, nil - } - framework.Logf("expect %d pods carry the expected scheduling gates, but got %v", num, matched) - return false, nil - }) - return maybeTimeoutError(err, "waiting for pods to carry the expected scheduling gates (want %d, matched %d)", num, matched) + _, err := WaitForPods(context.TODO(), c, ns, metav1.ListOptions{}, Range{MinMatching: num, MaxMatching: num}, timeout, + "have certain scheduling gates", func(pod *v1.Pod) bool { + return reflect.DeepEqual(pod.Spec.SchedulingGates, schedulingGates) + }) + return err } // WaitForPodTerminatedInNamespace returns an error if it takes too long for the pod to terminate, @@ -440,8 +374,8 @@ func WaitForPodsWithSchedulingGates(c clientset.Interface, ns string, num int, t // terminate) with an unexpected reason. Typically called to test that the passed-in pod is fully // terminated (reason==""), but may be called to detect if a pod did *not* terminate according to // the supplied reason. -func WaitForPodTerminatedInNamespace(c clientset.Interface, podName, reason, namespace string) error { - return WaitForPodCondition(c, namespace, podName, fmt.Sprintf("terminated with reason %s", reason), podStartTimeout, func(pod *v1.Pod) (bool, error) { +func WaitForPodTerminatedInNamespace(ctx context.Context, c clientset.Interface, podName, reason, namespace string) error { + return WaitForPodCondition(ctx, c, namespace, podName, fmt.Sprintf("terminated with reason %s", reason), podStartTimeout, func(pod *v1.Pod) (bool, error) { // Only consider Failed pods. Successful pods will be deleted and detected in // waitForPodCondition's Get call returning `IsNotFound` if pod.Status.Phase == v1.PodFailed { @@ -455,8 +389,8 @@ func WaitForPodTerminatedInNamespace(c clientset.Interface, podName, reason, nam } // WaitForPodTerminatingInNamespaceTimeout returns if the pod is terminating, or an error if it is not after the timeout. -func WaitForPodTerminatingInNamespaceTimeout(c clientset.Interface, podName, namespace string, timeout time.Duration) error { - return WaitForPodCondition(c, namespace, podName, "is terminating", timeout, func(pod *v1.Pod) (bool, error) { +func WaitForPodTerminatingInNamespaceTimeout(ctx context.Context, c clientset.Interface, podName, namespace string, timeout time.Duration) error { + return WaitForPodCondition(ctx, c, namespace, podName, "is terminating", timeout, func(pod *v1.Pod) (bool, error) { if pod.DeletionTimestamp != nil { return true, nil } @@ -465,9 +399,9 @@ func WaitForPodTerminatingInNamespaceTimeout(c clientset.Interface, podName, nam } // WaitForPodSuccessInNamespaceTimeout returns nil if the pod reached state success, or an error if it reached failure or ran too long. -func WaitForPodSuccessInNamespaceTimeout(c clientset.Interface, podName, namespace string, timeout time.Duration) error { - return WaitForPodCondition(c, namespace, podName, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout, func(pod *v1.Pod) (bool, error) { - if pod.Spec.RestartPolicy == v1.RestartPolicyAlways { +func WaitForPodSuccessInNamespaceTimeout(ctx context.Context, c clientset.Interface, podName, namespace string, timeout time.Duration) error { + return WaitForPodCondition(ctx, c, namespace, podName, fmt.Sprintf("%s or %s", v1.PodSucceeded, v1.PodFailed), timeout, func(pod *v1.Pod) (bool, error) { + if pod.DeletionTimestamp == nil && pod.Spec.RestartPolicy == v1.RestartPolicyAlways { return true, fmt.Errorf("pod %q will never terminate with a succeeded state since its restart policy is Always", podName) } switch pod.Status.Phase { @@ -486,8 +420,8 @@ func WaitForPodSuccessInNamespaceTimeout(c clientset.Interface, podName, namespa // and have condition Status equal to Unschedulable, // if the pod Get api returns an error (IsNotFound or other), or if the pod failed with an unexpected reason. // Typically called to test that the passed-in pod is Pending and Unschedulable. -func WaitForPodNameUnschedulableInNamespace(c clientset.Interface, podName, namespace string) error { - return WaitForPodCondition(c, namespace, podName, v1.PodReasonUnschedulable, podStartTimeout, func(pod *v1.Pod) (bool, error) { +func WaitForPodNameUnschedulableInNamespace(ctx context.Context, c clientset.Interface, podName, namespace string) error { + return WaitForPodCondition(ctx, c, namespace, podName, v1.PodReasonUnschedulable, podStartTimeout, func(pod *v1.Pod) (bool, error) { // Only consider Failed pods. Successful pods will be deleted and detected in // waitForPodCondition's Get call returning `IsNotFound` if pod.Status.Phase == v1.PodPending { @@ -506,44 +440,38 @@ func WaitForPodNameUnschedulableInNamespace(c clientset.Interface, podName, name // WaitForPodNameRunningInNamespace waits default amount of time (PodStartTimeout) for the specified pod to become running. // Returns an error if timeout occurs first, or pod goes in to failed state. -func WaitForPodNameRunningInNamespace(c clientset.Interface, podName, namespace string) error { - return WaitTimeoutForPodRunningInNamespace(c, podName, namespace, podStartTimeout) +func WaitForPodNameRunningInNamespace(ctx context.Context, c clientset.Interface, podName, namespace string) error { + return WaitTimeoutForPodRunningInNamespace(ctx, c, podName, namespace, podStartTimeout) } // WaitForPodRunningInNamespaceSlow waits an extended amount of time (slowPodStartTimeout) for the specified pod to become running. // The resourceVersion is used when Watching object changes, it tells since when we care // about changes to the pod. Returns an error if timeout occurs first, or pod goes in to failed state. -func WaitForPodRunningInNamespaceSlow(c clientset.Interface, podName, namespace string) error { - return WaitTimeoutForPodRunningInNamespace(c, podName, namespace, slowPodStartTimeout) +func WaitForPodRunningInNamespaceSlow(ctx context.Context, c clientset.Interface, podName, namespace string) error { + return WaitTimeoutForPodRunningInNamespace(ctx, c, podName, namespace, slowPodStartTimeout) } // WaitTimeoutForPodRunningInNamespace waits the given timeout duration for the specified pod to become running. -func WaitTimeoutForPodRunningInNamespace(c clientset.Interface, podName, namespace string, timeout time.Duration) error { - return WaitForPodCondition(c, namespace, podName, "running", timeout, func(pod *v1.Pod) (bool, error) { - switch pod.Status.Phase { - case v1.PodRunning: - return true, nil - case v1.PodFailed: - return false, errPodFailed - case v1.PodSucceeded: - return false, errPodCompleted - } - return false, nil - }) +// It does not need to exist yet when this function gets called and the pod is not expected to be recreated +// when it succeeds or fails. +func WaitTimeoutForPodRunningInNamespace(ctx context.Context, c clientset.Interface, podName, namespace string, timeout time.Duration) error { + return framework.Gomega().Eventually(ctx, framework.RetryNotFound(framework.GetObject(c.CoreV1().Pods(namespace).Get, podName, metav1.GetOptions{}))). + WithTimeout(timeout). + Should(BeRunningNoRetries()) } // WaitForPodRunningInNamespace waits default amount of time (podStartTimeout) for the specified pod to become running. // Returns an error if timeout occurs first, or pod goes in to failed state. -func WaitForPodRunningInNamespace(c clientset.Interface, pod *v1.Pod) error { +func WaitForPodRunningInNamespace(ctx context.Context, c clientset.Interface, pod *v1.Pod) error { if pod.Status.Phase == v1.PodRunning { return nil } - return WaitTimeoutForPodRunningInNamespace(c, pod.Name, pod.Namespace, podStartTimeout) + return WaitTimeoutForPodRunningInNamespace(ctx, c, pod.Name, pod.Namespace, podStartTimeout) } // WaitTimeoutForPodNoLongerRunningInNamespace waits the given timeout duration for the specified pod to stop. -func WaitTimeoutForPodNoLongerRunningInNamespace(c clientset.Interface, podName, namespace string, timeout time.Duration) error { - return WaitForPodCondition(c, namespace, podName, "completed", timeout, func(pod *v1.Pod) (bool, error) { +func WaitTimeoutForPodNoLongerRunningInNamespace(ctx context.Context, c clientset.Interface, podName, namespace string, timeout time.Duration) error { + return WaitForPodCondition(ctx, c, namespace, podName, "completed", timeout, func(pod *v1.Pod) (bool, error) { switch pod.Status.Phase { case v1.PodFailed, v1.PodSucceeded: return true, nil @@ -554,26 +482,20 @@ func WaitTimeoutForPodNoLongerRunningInNamespace(c clientset.Interface, podName, // WaitForPodNoLongerRunningInNamespace waits default amount of time (defaultPodDeletionTimeout) for the specified pod to stop running. // Returns an error if timeout occurs first. -func WaitForPodNoLongerRunningInNamespace(c clientset.Interface, podName, namespace string) error { - return WaitTimeoutForPodNoLongerRunningInNamespace(c, podName, namespace, defaultPodDeletionTimeout) +func WaitForPodNoLongerRunningInNamespace(ctx context.Context, c clientset.Interface, podName, namespace string) error { + return WaitTimeoutForPodNoLongerRunningInNamespace(ctx, c, podName, namespace, defaultPodDeletionTimeout) } // WaitTimeoutForPodReadyInNamespace waits the given timeout duration for the // specified pod to be ready and running. -func WaitTimeoutForPodReadyInNamespace(c clientset.Interface, podName, namespace string, timeout time.Duration) error { - return WaitForPodCondition(c, namespace, podName, "running and ready", timeout, func(pod *v1.Pod) (bool, error) { +func WaitTimeoutForPodReadyInNamespace(ctx context.Context, c clientset.Interface, podName, namespace string, timeout time.Duration) error { + return WaitForPodCondition(ctx, c, namespace, podName, "running and ready", timeout, func(pod *v1.Pod) (bool, error) { switch pod.Status.Phase { - case v1.PodFailed: - framework.Logf("The phase of Pod %s is %s which is unexpected, pod status: %#v", pod.Name, pod.Status.Phase, pod.Status) - return false, errPodFailed - case v1.PodSucceeded: - framework.Logf("The phase of Pod %s is %s which is unexpected, pod status: %#v", pod.Name, pod.Status.Phase, pod.Status) - return false, errPodCompleted + case v1.PodFailed, v1.PodSucceeded: + return false, gomega.StopTrying(fmt.Sprintf("The phase of Pod %s is %s which is unexpected.", pod.Name, pod.Status.Phase)) case v1.PodRunning: - framework.Logf("The phase of Pod %s is %s (Ready = %v)", pod.Name, pod.Status.Phase, podutils.IsPodReady(pod)) return podutils.IsPodReady(pod), nil } - framework.Logf("The phase of Pod %s is %s, waiting for it to be Running (with Ready = true)", pod.Name, pod.Status.Phase) return false, nil }) } @@ -581,8 +503,8 @@ func WaitTimeoutForPodReadyInNamespace(c clientset.Interface, podName, namespace // WaitForPodNotPending returns an error if it took too long for the pod to go out of pending state. // The resourceVersion is used when Watching object changes, it tells since when we care // about changes to the pod. -func WaitForPodNotPending(c clientset.Interface, ns, podName string) error { - return WaitForPodCondition(c, ns, podName, "not pending", podStartTimeout, func(pod *v1.Pod) (bool, error) { +func WaitForPodNotPending(ctx context.Context, c clientset.Interface, ns, podName string) error { + return WaitForPodCondition(ctx, c, ns, podName, "not pending", podStartTimeout, func(pod *v1.Pod) (bool, error) { switch pod.Status.Phase { case v1.PodPending: return false, nil @@ -593,152 +515,192 @@ func WaitForPodNotPending(c clientset.Interface, ns, podName string) error { } // WaitForPodSuccessInNamespace returns nil if the pod reached state success, or an error if it reached failure or until podStartupTimeout. -func WaitForPodSuccessInNamespace(c clientset.Interface, podName string, namespace string) error { - return WaitForPodSuccessInNamespaceTimeout(c, podName, namespace, podStartTimeout) +func WaitForPodSuccessInNamespace(ctx context.Context, c clientset.Interface, podName string, namespace string) error { + return WaitForPodSuccessInNamespaceTimeout(ctx, c, podName, namespace, podStartTimeout) } // WaitForPodSuccessInNamespaceSlow returns nil if the pod reached state success, or an error if it reached failure or until slowPodStartupTimeout. -func WaitForPodSuccessInNamespaceSlow(c clientset.Interface, podName string, namespace string) error { - return WaitForPodSuccessInNamespaceTimeout(c, podName, namespace, slowPodStartTimeout) +func WaitForPodSuccessInNamespaceSlow(ctx context.Context, c clientset.Interface, podName string, namespace string) error { + return WaitForPodSuccessInNamespaceTimeout(ctx, c, podName, namespace, slowPodStartTimeout) } // WaitForPodNotFoundInNamespace returns an error if it takes too long for the pod to fully terminate. // Unlike `waitForPodTerminatedInNamespace`, the pod's Phase and Reason are ignored. If the pod Get // api returns IsNotFound then the wait stops and nil is returned. If the Get api returns an error other -// than "not found" then that error is returned and the wait stops. -func WaitForPodNotFoundInNamespace(c clientset.Interface, podName, ns string, timeout time.Duration) error { - var lastPod *v1.Pod - err := wait.PollImmediate(poll, timeout, func() (bool, error) { - pod, err := c.CoreV1().Pods(ns).Get(context.TODO(), podName, metav1.GetOptions{}) +// than "not found" and that error is final, that error is returned and the wait stops. +func WaitForPodNotFoundInNamespace(ctx context.Context, c clientset.Interface, podName, ns string, timeout time.Duration) error { + err := framework.Gomega().Eventually(ctx, framework.HandleRetry(func(ctx context.Context) (*v1.Pod, error) { + pod, err := c.CoreV1().Pods(ns).Get(ctx, podName, metav1.GetOptions{}) if apierrors.IsNotFound(err) { - return true, nil // done + return nil, nil } - if err != nil { - return handleWaitingAPIError(err, true, "getting pod %s", podIdentifier(ns, podName)) - } - lastPod = pod - return false, nil - }) - if err == nil { - return nil + return pod, err + })).WithTimeout(timeout).Should(gomega.BeNil()) + if err != nil { + return fmt.Errorf("expected pod to not be found: %w", err) } - if IsTimeout(err) && lastPod != nil { - return TimeoutError(fmt.Sprintf("timed out while waiting for pod %s to be Not Found", podIdentifier(ns, podName)), - lastPod, - ) - } - return maybeTimeoutError(err, "waiting for pod %s not found", podIdentifier(ns, podName)) -} - -// WaitForPodToDisappear waits the given timeout duration for the specified pod to disappear. -func WaitForPodToDisappear(c clientset.Interface, ns, podName string, label labels.Selector, interval, timeout time.Duration) error { - var lastPod *v1.Pod - err := wait.PollImmediate(interval, timeout, func() (bool, error) { - framework.Logf("Waiting for pod %s to disappear", podName) - options := metav1.ListOptions{LabelSelector: label.String()} - pods, err := c.CoreV1().Pods(ns).List(context.TODO(), options) - if err != nil { - return handleWaitingAPIError(err, true, "listing pods") - } - found := false - for i, pod := range pods.Items { - if pod.Name == podName { - framework.Logf("Pod %s still exists", podName) - found = true - lastPod = &(pods.Items[i]) - break - } - } - if !found { - framework.Logf("Pod %s no longer exists", podName) - return true, nil - } - return false, nil - }) - if err == nil { - return nil - } - if IsTimeout(err) { - return TimeoutError(fmt.Sprintf("timed out while waiting for pod %s to disappear", podIdentifier(ns, podName)), - lastPod, - ) - } - return maybeTimeoutError(err, "waiting for pod %s to disappear", podIdentifier(ns, podName)) + return nil } // PodsResponding waits for the pods to response. -func PodsResponding(c clientset.Interface, ns, name string, wantName bool, pods *v1.PodList) error { +func WaitForPodsResponding(ctx context.Context, c clientset.Interface, ns string, controllerName string, wantName bool, timeout time.Duration, pods *v1.PodList) error { + if timeout == 0 { + timeout = podRespondingTimeout + } ginkgo.By("trying to dial each unique pod") - label := labels.SelectorFromSet(labels.Set(map[string]string{"name": name})) - err := wait.PollImmediate(poll, podRespondingTimeout, NewProxyResponseChecker(c, ns, label, name, wantName, pods).CheckAllResponses) - return maybeTimeoutError(err, "waiting for pods to be responsive") + label := labels.SelectorFromSet(labels.Set(map[string]string{"name": controllerName})) + options := metav1.ListOptions{LabelSelector: label.String()} + + type response struct { + podName string + response string + } + + get := func(ctx context.Context) ([]response, error) { + currentPods, err := c.CoreV1().Pods(ns).List(ctx, options) + if err != nil { + return nil, fmt.Errorf("list pods: %w", err) + } + + var responses []response + for _, pod := range pods.Items { + // Check that the replica list remains unchanged, otherwise we have problems. + if !isElementOf(pod.UID, currentPods) { + return nil, gomega.StopTrying(fmt.Sprintf("Pod with UID %s is no longer a member of the replica set. Must have been restarted for some reason.\nCurrent replica set:\n%s", pod.UID, format.Object(currentPods, 1))) + } + + ctxUntil, cancel := context.WithTimeout(ctx, singleCallTimeout) + defer cancel() + + body, err := c.CoreV1().RESTClient().Get(). + Namespace(ns). + Resource("pods"). + SubResource("proxy"). + Name(string(pod.Name)). + Do(ctxUntil). + Raw() + + if err != nil { + // We may encounter errors here because of a race between the pod readiness and apiserver + // proxy. So, we log the error and retry if this occurs. + return nil, fmt.Errorf("Controller %s: failed to Get from replica pod %s:\n%s\nPod status:\n%s", + controllerName, pod.Name, + format.Object(err, 1), format.Object(pod.Status, 1)) + } + responses = append(responses, response{podName: pod.Name, response: string(body)}) + } + return responses, nil + } + + match := func(responses []response) (func() string, error) { + // The response checker expects the pod's name unless !respondName, in + // which case it just checks for a non-empty response. + var unexpected []response + for _, response := range responses { + if wantName { + if response.response != response.podName { + unexpected = append(unexpected, response) + } + } else { + if len(response.response) == 0 { + unexpected = append(unexpected, response) + } + } + } + if len(unexpected) > 0 { + return func() string { + what := "some response" + if wantName { + what = "the pod's own name as response" + } + return fmt.Sprintf("Wanted %s, but the following pods replied with something else:\n%s", what, format.Object(unexpected, 1)) + }, nil + } + return nil, nil + } + + err := framework.Gomega(). + Eventually(ctx, framework.HandleRetry(get)). + WithTimeout(timeout). + Should(framework.MakeMatcher(match)) + if err != nil { + return fmt.Errorf("checking pod responses: %w", err) + } + return nil +} + +func isElementOf(podUID apitypes.UID, pods *v1.PodList) bool { + for _, pod := range pods.Items { + if pod.UID == podUID { + return true + } + } + return false } // WaitForNumberOfPods waits up to timeout to ensure there are exact // `num` pods in namespace `ns`. // It returns the matching Pods or a timeout error. -func WaitForNumberOfPods(c clientset.Interface, ns string, num int, timeout time.Duration) (pods *v1.PodList, err error) { - actualNum := 0 - err = wait.PollImmediate(poll, timeout, func() (bool, error) { - pods, err = c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{}) - if err != nil { - return handleWaitingAPIError(err, false, "listing pods") - } - actualNum = len(pods.Items) - return actualNum == num, nil +func WaitForNumberOfPods(ctx context.Context, c clientset.Interface, ns string, num int, timeout time.Duration) (pods *v1.PodList, err error) { + return WaitForPods(ctx, c, ns, metav1.ListOptions{}, Range{MinMatching: num, MaxMatching: num}, podScheduledBeforeTimeout, "exist", func(pod *v1.Pod) bool { + return true }) - return pods, maybeTimeoutError(err, "waiting for there to be exactly %d pods in namespace (last seen %d)", num, actualNum) } // WaitForPodsWithLabelScheduled waits for all matching pods to become scheduled and at least one // matching pod exists. Return the list of matching pods. -func WaitForPodsWithLabelScheduled(c clientset.Interface, ns string, label labels.Selector) (pods *v1.PodList, err error) { +func WaitForPodsWithLabelScheduled(ctx context.Context, c clientset.Interface, ns string, label labels.Selector) (pods *v1.PodList, err error) { opts := metav1.ListOptions{LabelSelector: label.String()} - return WaitForAllPodsCondition(c, ns, opts, 1, "scheduled", podScheduledBeforeTimeout, func(pod *v1.Pod) (bool, error) { - if pod.Spec.NodeName == "" { - return false, nil - } - return true, nil + return WaitForPods(ctx, c, ns, opts, Range{MinFound: 1, AllMatching: true}, podScheduledBeforeTimeout, "be scheduled", func(pod *v1.Pod) bool { + return pod.Spec.NodeName != "" }) } // WaitForPodsWithLabel waits up to podListTimeout for getting pods with certain label -func WaitForPodsWithLabel(c clientset.Interface, ns string, label labels.Selector) (*v1.PodList, error) { +func WaitForPodsWithLabel(ctx context.Context, c clientset.Interface, ns string, label labels.Selector) (*v1.PodList, error) { opts := metav1.ListOptions{LabelSelector: label.String()} - return WaitForAllPodsCondition(c, ns, opts, 1, "existent", podListTimeout, func(pod *v1.Pod) (bool, error) { - return true, nil + return WaitForPods(ctx, c, ns, opts, Range{MinFound: 1}, podListTimeout, "exist", func(pod *v1.Pod) bool { + return true }) } // WaitForPodsWithLabelRunningReady waits for exact amount of matching pods to become running and ready. // Return the list of matching pods. -func WaitForPodsWithLabelRunningReady(c clientset.Interface, ns string, label labels.Selector, num int, timeout time.Duration) (pods *v1.PodList, err error) { +func WaitForPodsWithLabelRunningReady(ctx context.Context, c clientset.Interface, ns string, label labels.Selector, num int, timeout time.Duration) (pods *v1.PodList, err error) { opts := metav1.ListOptions{LabelSelector: label.String()} - return WaitForAllPodsCondition(c, ns, opts, 1, "running and ready", timeout, testutils.PodRunningReady) + return WaitForPods(ctx, c, ns, opts, Range{MinFound: num, AllMatching: true}, timeout, "be running and ready", RunningReady) } // WaitForNRestartablePods tries to list restarting pods using ps until it finds expect of them, // returning their names if it can do so before timeout. -func WaitForNRestartablePods(ps *testutils.PodStore, expect int, timeout time.Duration) ([]string, error) { +func WaitForNRestartablePods(ctx context.Context, ps *testutils.PodStore, expect int, timeout time.Duration) ([]string, error) { var pods []*v1.Pod - var errLast error - found := wait.Poll(poll, timeout, func() (bool, error) { - allPods := ps.List() + + get := func(ctx context.Context) ([]*v1.Pod, error) { + return ps.List(), nil + } + + match := func(allPods []*v1.Pod) (func() string, error) { pods = FilterNonRestartablePods(allPods) if len(pods) != expect { - errLast = fmt.Errorf("expected to find %d pods but found only %d", expect, len(pods)) - framework.Logf("Error getting pods: %v", errLast) - return false, nil + return func() string { + return fmt.Sprintf("expected to find non-restartable %d pods, but found %d:\n%s", expect, len(pods), format.Object(pods, 1)) + }, nil } - return true, nil - }) == nil + return nil, nil + } + + err := framework.Gomega(). + Eventually(ctx, framework.HandleRetry(get)). + WithTimeout(timeout). + Should(framework.MakeMatcher(match)) + if err != nil { + return nil, err + } + podNames := make([]string, len(pods)) for i, p := range pods { - podNames[i] = p.ObjectMeta.Name - } - if !found { - return podNames, fmt.Errorf("couldn't find %d pods within %v; last error: %v", - expect, timeout, errLast) + podNames[i] = p.Name } return podNames, nil } @@ -746,9 +708,9 @@ func WaitForNRestartablePods(ps *testutils.PodStore, expect int, timeout time.Du // WaitForPodContainerToFail waits for the given Pod container to fail with the given reason, specifically due to // invalid container configuration. In this case, the container will remain in a waiting state with a specific // reason set, which should match the given reason. -func WaitForPodContainerToFail(c clientset.Interface, namespace, podName string, containerIndex int, reason string, timeout time.Duration) error { +func WaitForPodContainerToFail(ctx context.Context, c clientset.Interface, namespace, podName string, containerIndex int, reason string, timeout time.Duration) error { conditionDesc := fmt.Sprintf("container %d failed with reason %s", containerIndex, reason) - return WaitForPodCondition(c, namespace, podName, conditionDesc, timeout, func(pod *v1.Pod) (bool, error) { + return WaitForPodCondition(ctx, c, namespace, podName, conditionDesc, timeout, func(pod *v1.Pod) (bool, error) { switch pod.Status.Phase { case v1.PodPending: if len(pod.Status.ContainerStatuses) == 0 { @@ -766,10 +728,17 @@ func WaitForPodContainerToFail(c clientset.Interface, namespace, podName string, }) } +// WaitForPodScheduled waits for the pod to be schedule, ie. the .spec.nodeName is set +func WaitForPodScheduled(ctx context.Context, c clientset.Interface, namespace, podName string) error { + return WaitForPodCondition(ctx, c, namespace, podName, "pod is scheduled", podScheduledBeforeTimeout, func(pod *v1.Pod) (bool, error) { + return pod.Spec.NodeName != "", nil + }) +} + // WaitForPodContainerStarted waits for the given Pod container to start, after a successful run of the startupProbe. -func WaitForPodContainerStarted(c clientset.Interface, namespace, podName string, containerIndex int, timeout time.Duration) error { +func WaitForPodContainerStarted(ctx context.Context, c clientset.Interface, namespace, podName string, containerIndex int, timeout time.Duration) error { conditionDesc := fmt.Sprintf("container %d started", containerIndex) - return WaitForPodCondition(c, namespace, podName, conditionDesc, timeout, func(pod *v1.Pod) (bool, error) { + return WaitForPodCondition(ctx, c, namespace, podName, conditionDesc, timeout, func(pod *v1.Pod) (bool, error) { if containerIndex > len(pod.Status.ContainerStatuses)-1 { return false, nil } @@ -779,9 +748,9 @@ func WaitForPodContainerStarted(c clientset.Interface, namespace, podName string } // WaitForPodFailedReason wait for pod failed reason in status, for example "SysctlForbidden". -func WaitForPodFailedReason(c clientset.Interface, pod *v1.Pod, reason string, timeout time.Duration) error { +func WaitForPodFailedReason(ctx context.Context, c clientset.Interface, pod *v1.Pod, reason string, timeout time.Duration) error { conditionDesc := fmt.Sprintf("failed with reason %s", reason) - return WaitForPodCondition(c, pod.Namespace, pod.Name, conditionDesc, timeout, func(pod *v1.Pod) (bool, error) { + return WaitForPodCondition(ctx, c, pod.Namespace, pod.Name, conditionDesc, timeout, func(pod *v1.Pod) (bool, error) { switch pod.Status.Phase { case v1.PodSucceeded: return true, errors.New("pod succeeded unexpectedly") @@ -797,9 +766,9 @@ func WaitForPodFailedReason(c clientset.Interface, pod *v1.Pod, reason string, t } // WaitForContainerRunning waits for the given Pod container to have a state of running -func WaitForContainerRunning(c clientset.Interface, namespace, podName, containerName string, timeout time.Duration) error { +func WaitForContainerRunning(ctx context.Context, c clientset.Interface, namespace, podName, containerName string, timeout time.Duration) error { conditionDesc := fmt.Sprintf("container %s running", containerName) - return WaitForPodCondition(c, namespace, podName, conditionDesc, timeout, func(pod *v1.Pod) (bool, error) { + return WaitForPodCondition(ctx, c, namespace, podName, conditionDesc, timeout, func(pod *v1.Pod) (bool, error) { for _, statuses := range [][]v1.ContainerStatus{pod.Status.ContainerStatuses, pod.Status.InitContainerStatuses, pod.Status.EphemeralContainerStatuses} { for _, cs := range statuses { if cs.Name == containerName { @@ -810,38 +779,3 @@ func WaitForContainerRunning(c clientset.Interface, namespace, podName, containe return false, nil }) } - -// handleWaitingAPIErrror handles an error from an API request in the context of a Wait function. -// If the error is retryable, sleep the recommended delay and ignore the error. -// If the error is terminal, return it. -func handleWaitingAPIError(err error, retryNotFound bool, taskFormat string, taskArgs ...interface{}) (bool, error) { - taskDescription := fmt.Sprintf(taskFormat, taskArgs...) - if retryNotFound && apierrors.IsNotFound(err) { - framework.Logf("Ignoring NotFound error while " + taskDescription) - return false, nil - } - if retry, delay := shouldRetry(err); retry { - framework.Logf("Retryable error while %s, retrying after %v: %v", taskDescription, delay, err) - if delay > 0 { - time.Sleep(delay) - } - return false, nil - } - framework.Logf("Encountered non-retryable error while %s: %v", taskDescription, err) - return false, err -} - -// Decide whether to retry an API request. Optionally include a delay to retry after. -func shouldRetry(err error) (retry bool, retryAfter time.Duration) { - // if the error sends the Retry-After header, we respect it as an explicit confirmation we should retry. - if delay, shouldRetry := apierrors.SuggestsClientDelay(err); shouldRetry { - return shouldRetry, time.Duration(delay) * time.Second - } - - // these errors indicate a transient error that should be retried. - if apierrors.IsTimeout(err) || apierrors.IsTooManyRequests(err) { - return true, 0 - } - - return false, 0 -} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/provider.go b/vendor/k8s.io/kubernetes/test/e2e/framework/provider.go index cd98219df..6a463f719 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/provider.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/provider.go @@ -17,6 +17,7 @@ limitations under the License. package framework import ( + "context" "fmt" "os" "sync" @@ -100,12 +101,12 @@ type ProviderInterface interface { CreateShare() (string, string, string, error) DeleteShare(accountName, shareName string) error - CreatePVSource(zone, diskName string) (*v1.PersistentVolumeSource, error) - DeletePVSource(pvSource *v1.PersistentVolumeSource) error + CreatePVSource(ctx context.Context, zone, diskName string) (*v1.PersistentVolumeSource, error) + DeletePVSource(ctx context.Context, pvSource *v1.PersistentVolumeSource) error - CleanupServiceResources(c clientset.Interface, loadBalancerName, region, zone string) + CleanupServiceResources(ctx context.Context, c clientset.Interface, loadBalancerName, region, zone string) - EnsureLoadBalancerResourcesDeleted(ip, portRange string) error + EnsureLoadBalancerResourcesDeleted(ctx context.Context, ip, portRange string) error LoadBalancerSrcRanges() []string EnableAndDisableInternalLB() (enable, disable func(svc *v1.Service)) } @@ -159,21 +160,21 @@ func (n NullProvider) DeletePD(pdName string) error { } // CreatePVSource is a base implementation which creates PV source. -func (n NullProvider) CreatePVSource(zone, diskName string) (*v1.PersistentVolumeSource, error) { +func (n NullProvider) CreatePVSource(ctx context.Context, zone, diskName string) (*v1.PersistentVolumeSource, error) { return nil, fmt.Errorf("Provider not supported") } // DeletePVSource is a base implementation which deletes PV source. -func (n NullProvider) DeletePVSource(pvSource *v1.PersistentVolumeSource) error { +func (n NullProvider) DeletePVSource(ctx context.Context, pvSource *v1.PersistentVolumeSource) error { return fmt.Errorf("Provider not supported") } // CleanupServiceResources is a base implementation which cleans up service resources. -func (n NullProvider) CleanupServiceResources(c clientset.Interface, loadBalancerName, region, zone string) { +func (n NullProvider) CleanupServiceResources(ctx context.Context, c clientset.Interface, loadBalancerName, region, zone string) { } // EnsureLoadBalancerResourcesDeleted is a base implementation which ensures load balancer is deleted. -func (n NullProvider) EnsureLoadBalancerResourcesDeleted(ip, portRange string) error { +func (n NullProvider) EnsureLoadBalancerResourcesDeleted(ctx context.Context, ip, portRange string) error { return nil } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pv/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/pv/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pv/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go index fa0294077..f4bb56707 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pv/pv.go @@ -135,21 +135,21 @@ type PersistentVolumeClaimConfig struct { // PVPVCCleanup cleans up a pv and pvc in a single pv/pvc test case. // Note: delete errors are appended to []error so that we can attempt to delete both the pvc and pv. -func PVPVCCleanup(c clientset.Interface, ns string, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim) []error { +func PVPVCCleanup(ctx context.Context, c clientset.Interface, ns string, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim) []error { var errs []error if pvc != nil { - err := DeletePersistentVolumeClaim(c, pvc.Name, ns) + err := DeletePersistentVolumeClaim(ctx, c, pvc.Name, ns) if err != nil { - errs = append(errs, fmt.Errorf("failed to delete PVC %q: %v", pvc.Name, err)) + errs = append(errs, fmt.Errorf("failed to delete PVC %q: %w", pvc.Name, err)) } } else { framework.Logf("pvc is nil") } if pv != nil { - err := DeletePersistentVolume(c, pv.Name) + err := DeletePersistentVolume(ctx, c, pv.Name) if err != nil { - errs = append(errs, fmt.Errorf("failed to delete PV %q: %v", pv.Name, err)) + errs = append(errs, fmt.Errorf("failed to delete PV %q: %w", pv.Name, err)) } } else { framework.Logf("pv is nil") @@ -160,22 +160,22 @@ func PVPVCCleanup(c clientset.Interface, ns string, pv *v1.PersistentVolume, pvc // PVPVCMapCleanup Cleans up pvs and pvcs in multi-pv-pvc test cases. Entries found in the pv and claim maps are // deleted as long as the Delete api call succeeds. // Note: delete errors are appended to []error so that as many pvcs and pvs as possible are deleted. -func PVPVCMapCleanup(c clientset.Interface, ns string, pvols PVMap, claims PVCMap) []error { +func PVPVCMapCleanup(ctx context.Context, c clientset.Interface, ns string, pvols PVMap, claims PVCMap) []error { var errs []error for pvcKey := range claims { - err := DeletePersistentVolumeClaim(c, pvcKey.Name, ns) + err := DeletePersistentVolumeClaim(ctx, c, pvcKey.Name, ns) if err != nil { - errs = append(errs, fmt.Errorf("failed to delete PVC %q: %v", pvcKey.Name, err)) + errs = append(errs, fmt.Errorf("failed to delete PVC %q: %w", pvcKey.Name, err)) } else { delete(claims, pvcKey) } } for pvKey := range pvols { - err := DeletePersistentVolume(c, pvKey) + err := DeletePersistentVolume(ctx, c, pvKey) if err != nil { - errs = append(errs, fmt.Errorf("failed to delete PV %q: %v", pvKey, err)) + errs = append(errs, fmt.Errorf("failed to delete PV %q: %w", pvKey, err)) } else { delete(pvols, pvKey) } @@ -184,24 +184,24 @@ func PVPVCMapCleanup(c clientset.Interface, ns string, pvols PVMap, claims PVCMa } // DeletePersistentVolume deletes the PV. -func DeletePersistentVolume(c clientset.Interface, pvName string) error { +func DeletePersistentVolume(ctx context.Context, c clientset.Interface, pvName string) error { if c != nil && len(pvName) > 0 { framework.Logf("Deleting PersistentVolume %q", pvName) - err := c.CoreV1().PersistentVolumes().Delete(context.TODO(), pvName, metav1.DeleteOptions{}) + err := c.CoreV1().PersistentVolumes().Delete(ctx, pvName, metav1.DeleteOptions{}) if err != nil && !apierrors.IsNotFound(err) { - return fmt.Errorf("PV Delete API error: %v", err) + return fmt.Errorf("PV Delete API error: %w", err) } } return nil } // DeletePersistentVolumeClaim deletes the Claim. -func DeletePersistentVolumeClaim(c clientset.Interface, pvcName string, ns string) error { +func DeletePersistentVolumeClaim(ctx context.Context, c clientset.Interface, pvcName string, ns string) error { if c != nil && len(pvcName) > 0 { framework.Logf("Deleting PersistentVolumeClaim %q", pvcName) - err := c.CoreV1().PersistentVolumeClaims(ns).Delete(context.TODO(), pvcName, metav1.DeleteOptions{}) + err := c.CoreV1().PersistentVolumeClaims(ns).Delete(ctx, pvcName, metav1.DeleteOptions{}) if err != nil && !apierrors.IsNotFound(err) { - return fmt.Errorf("PVC Delete API error: %v", err) + return fmt.Errorf("PVC Delete API error: %w", err) } } return nil @@ -210,25 +210,25 @@ func DeletePersistentVolumeClaim(c clientset.Interface, pvcName string, ns strin // DeletePVCandValidatePV deletes the PVC and waits for the PV to enter its expected phase. Validate that the PV // has been reclaimed (assumption here about reclaimPolicy). Caller tells this func which // phase value to expect for the pv bound to the to-be-deleted claim. -func DeletePVCandValidatePV(c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvc *v1.PersistentVolumeClaim, pv *v1.PersistentVolume, expectPVPhase v1.PersistentVolumePhase) error { +func DeletePVCandValidatePV(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvc *v1.PersistentVolumeClaim, pv *v1.PersistentVolume, expectPVPhase v1.PersistentVolumePhase) error { pvname := pvc.Spec.VolumeName framework.Logf("Deleting PVC %v to trigger reclamation of PV %v", pvc.Name, pvname) - err := DeletePersistentVolumeClaim(c, pvc.Name, ns) + err := DeletePersistentVolumeClaim(ctx, c, pvc.Name, ns) if err != nil { return err } // Wait for the PV's phase to return to be `expectPVPhase` framework.Logf("Waiting for reclaim process to complete.") - err = WaitForPersistentVolumePhase(expectPVPhase, c, pv.Name, framework.Poll, timeouts.PVReclaim) + err = WaitForPersistentVolumePhase(ctx, expectPVPhase, c, pv.Name, framework.Poll, timeouts.PVReclaim) if err != nil { - return fmt.Errorf("pv %q phase did not become %v: %v", pv.Name, expectPVPhase, err) + return fmt.Errorf("pv %q phase did not become %v: %w", pv.Name, expectPVPhase, err) } // examine the pv's ClaimRef and UID and compare to expected values - pv, err = c.CoreV1().PersistentVolumes().Get(context.TODO(), pv.Name, metav1.GetOptions{}) + pv, err = c.CoreV1().PersistentVolumes().Get(ctx, pv.Name, metav1.GetOptions{}) if err != nil { - return fmt.Errorf("PV Get API error: %v", err) + return fmt.Errorf("PV Get API error: %w", err) } cr := pv.Spec.ClaimRef if expectPVPhase == v1.VolumeAvailable { @@ -254,13 +254,13 @@ func DeletePVCandValidatePV(c clientset.Interface, timeouts *framework.TimeoutCo // Note: if there are more claims than pvs then some of the remaining claims may bind to just made // // available pvs. -func DeletePVCandValidatePVGroup(c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvols PVMap, claims PVCMap, expectPVPhase v1.PersistentVolumePhase) error { +func DeletePVCandValidatePVGroup(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvols PVMap, claims PVCMap, expectPVPhase v1.PersistentVolumePhase) error { var boundPVs, deletedPVCs int for pvName := range pvols { - pv, err := c.CoreV1().PersistentVolumes().Get(context.TODO(), pvName, metav1.GetOptions{}) + pv, err := c.CoreV1().PersistentVolumes().Get(ctx, pvName, metav1.GetOptions{}) if err != nil { - return fmt.Errorf("PV Get API error: %v", err) + return fmt.Errorf("PV Get API error: %w", err) } cr := pv.Spec.ClaimRef // if pv is bound then delete the pvc it is bound to @@ -273,13 +273,13 @@ func DeletePVCandValidatePVGroup(c clientset.Interface, timeouts *framework.Time return fmt.Errorf("internal: claims map is missing pvc %q", pvcKey) } // get the pvc for the delete call below - pvc, err := c.CoreV1().PersistentVolumeClaims(ns).Get(context.TODO(), cr.Name, metav1.GetOptions{}) + pvc, err := c.CoreV1().PersistentVolumeClaims(ns).Get(ctx, cr.Name, metav1.GetOptions{}) if err == nil { - if err = DeletePVCandValidatePV(c, timeouts, ns, pvc, pv, expectPVPhase); err != nil { + if err = DeletePVCandValidatePV(ctx, c, timeouts, ns, pvc, pv, expectPVPhase); err != nil { return err } } else if !apierrors.IsNotFound(err) { - return fmt.Errorf("PVC Get API error: %v", err) + return fmt.Errorf("PVC Get API error: %w", err) } // delete pvckey from map even if apierrors.IsNotFound above is true and thus the // claim was not actually deleted here @@ -294,11 +294,11 @@ func DeletePVCandValidatePVGroup(c clientset.Interface, timeouts *framework.Time } // create the PV resource. Fails test on error. -func createPV(c clientset.Interface, timeouts *framework.TimeoutContext, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { +func createPV(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { var resultPV *v1.PersistentVolume var lastCreateErr error - err := wait.PollImmediate(29*time.Second, timeouts.PVCreate, func() (done bool, err error) { - resultPV, lastCreateErr = c.CoreV1().PersistentVolumes().Create(context.TODO(), pv, metav1.CreateOptions{}) + err := wait.PollImmediateWithContext(ctx, 29*time.Second, timeouts.PVCreate, func(ctx context.Context) (done bool, err error) { + resultPV, lastCreateErr = c.CoreV1().PersistentVolumes().Create(ctx, pv, metav1.CreateOptions{}) if lastCreateErr != nil { // If we hit a quota problem, we are not done and should retry again. This happens to be the quota failure string for GCP. // If quota failure strings are found for other platforms, they can be added to improve reliability when running @@ -316,25 +316,25 @@ func createPV(c clientset.Interface, timeouts *framework.TimeoutContext, pv *v1. }) // if we have an error from creating the PV, use that instead of a timeout error if lastCreateErr != nil { - return nil, fmt.Errorf("PV Create API error: %v", err) + return nil, fmt.Errorf("PV Create API error: %w", err) } if err != nil { - return nil, fmt.Errorf("PV Create API error: %v", err) + return nil, fmt.Errorf("PV Create API error: %w", err) } return resultPV, nil } // CreatePV creates the PV resource. Fails test on error. -func CreatePV(c clientset.Interface, timeouts *framework.TimeoutContext, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { - return createPV(c, timeouts, pv) +func CreatePV(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { + return createPV(ctx, c, timeouts, pv) } // CreatePVC creates the PVC resource. Fails test on error. -func CreatePVC(c clientset.Interface, ns string, pvc *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { - pvc, err := c.CoreV1().PersistentVolumeClaims(ns).Create(context.TODO(), pvc, metav1.CreateOptions{}) +func CreatePVC(ctx context.Context, c clientset.Interface, ns string, pvc *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { + pvc, err := c.CoreV1().PersistentVolumeClaims(ns).Create(ctx, pvc, metav1.CreateOptions{}) if err != nil { - return nil, fmt.Errorf("PVC Create API error: %v", err) + return nil, fmt.Errorf("PVC Create API error: %w", err) } return pvc, nil } @@ -346,7 +346,7 @@ func CreatePVC(c clientset.Interface, ns string, pvc *v1.PersistentVolumeClaim) // // known until after the PVC is instantiated. This is why the pvc is created // before the pv. -func CreatePVCPV(c clientset.Interface, timeouts *framework.TimeoutContext, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig, ns string, preBind bool) (*v1.PersistentVolume, *v1.PersistentVolumeClaim, error) { +func CreatePVCPV(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig, ns string, preBind bool) (*v1.PersistentVolume, *v1.PersistentVolumeClaim, error) { // make the pvc spec pvc := MakePersistentVolumeClaim(pvcConfig, ns) preBindMsg := "" @@ -358,7 +358,7 @@ func CreatePVCPV(c clientset.Interface, timeouts *framework.TimeoutContext, pvCo pv := MakePersistentVolume(pvConfig) ginkgo.By(fmt.Sprintf("Creating a PVC followed by a%s PV", preBindMsg)) - pvc, err := CreatePVC(c, ns, pvc) + pvc, err := CreatePVC(ctx, c, ns, pvc) if err != nil { return nil, nil, err } @@ -367,7 +367,7 @@ func CreatePVCPV(c clientset.Interface, timeouts *framework.TimeoutContext, pvCo if preBind { pv.Spec.ClaimRef.Name = pvc.Name } - pv, err = createPV(c, timeouts, pv) + pv, err = createPV(ctx, c, timeouts, pv) if err != nil { return nil, pvc, err } @@ -382,7 +382,7 @@ func CreatePVCPV(c clientset.Interface, timeouts *framework.TimeoutContext, pvCo // // known until after the PV is instantiated. This is why the pv is created // before the pvc. -func CreatePVPVC(c clientset.Interface, timeouts *framework.TimeoutContext, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig, ns string, preBind bool) (*v1.PersistentVolume, *v1.PersistentVolumeClaim, error) { +func CreatePVPVC(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig, ns string, preBind bool) (*v1.PersistentVolume, *v1.PersistentVolumeClaim, error) { preBindMsg := "" if preBind { preBindMsg = " pre-bound" @@ -394,7 +394,7 @@ func CreatePVPVC(c clientset.Interface, timeouts *framework.TimeoutContext, pvCo pvc := MakePersistentVolumeClaim(pvcConfig, ns) // instantiate the pv - pv, err := createPV(c, timeouts, pv) + pv, err := createPV(ctx, c, timeouts, pv) if err != nil { return nil, nil, err } @@ -402,7 +402,7 @@ func CreatePVPVC(c clientset.Interface, timeouts *framework.TimeoutContext, pvCo if preBind { pvc.Spec.VolumeName = pv.Name } - pvc, err = CreatePVC(c, ns, pvc) + pvc, err = CreatePVC(ctx, c, ns, pvc) if err != nil { return pv, nil, err } @@ -417,7 +417,7 @@ func CreatePVPVC(c clientset.Interface, timeouts *framework.TimeoutContext, pvCo // Note: when the test suite deletes the namespace orphaned pvcs and pods are deleted. However, // // orphaned pvs are not deleted and will remain after the suite completes. -func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig) (PVMap, PVCMap, error) { +func CreatePVsPVCs(ctx context.Context, numpvs, numpvcs int, c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvConfig PersistentVolumeConfig, pvcConfig PersistentVolumeClaimConfig) (PVMap, PVCMap, error) { pvMap := make(PVMap, numpvs) pvcMap := make(PVCMap, numpvcs) extraPVCs := 0 @@ -430,7 +430,7 @@ func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, timeouts *framewo // create pvs and pvcs for i := 0; i < pvsToCreate; i++ { - pv, pvc, err := CreatePVPVC(c, timeouts, pvConfig, pvcConfig, ns, false) + pv, pvc, err := CreatePVPVC(ctx, c, timeouts, pvConfig, pvcConfig, ns, false) if err != nil { return pvMap, pvcMap, err } @@ -441,7 +441,7 @@ func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, timeouts *framewo // create extra pvs or pvcs as needed for i := 0; i < extraPVs; i++ { pv := MakePersistentVolume(pvConfig) - pv, err := createPV(c, timeouts, pv) + pv, err := createPV(ctx, c, timeouts, pv) if err != nil { return pvMap, pvcMap, err } @@ -449,7 +449,7 @@ func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, timeouts *framewo } for i := 0; i < extraPVCs; i++ { pvc := MakePersistentVolumeClaim(pvcConfig, ns) - pvc, err := CreatePVC(c, ns, pvc) + pvc, err := CreatePVC(ctx, c, ns, pvc) if err != nil { return pvMap, pvcMap, err } @@ -459,29 +459,29 @@ func CreatePVsPVCs(numpvs, numpvcs int, c clientset.Interface, timeouts *framewo } // WaitOnPVandPVC waits for the pv and pvc to bind to each other. -func WaitOnPVandPVC(c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim) error { +func WaitOnPVandPVC(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim) error { // Wait for newly created PVC to bind to the PV framework.Logf("Waiting for PV %v to bind to PVC %v", pv.Name, pvc.Name) - err := WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, ns, pvc.Name, framework.Poll, timeouts.ClaimBound) + err := WaitForPersistentVolumeClaimPhase(ctx, v1.ClaimBound, c, ns, pvc.Name, framework.Poll, timeouts.ClaimBound) if err != nil { - return fmt.Errorf("PVC %q did not become Bound: %v", pvc.Name, err) + return fmt.Errorf("PVC %q did not become Bound: %w", pvc.Name, err) } // Wait for PersistentVolume.Status.Phase to be Bound, which it should be // since the PVC is already bound. - err = WaitForPersistentVolumePhase(v1.VolumeBound, c, pv.Name, framework.Poll, timeouts.PVBound) + err = WaitForPersistentVolumePhase(ctx, v1.VolumeBound, c, pv.Name, framework.Poll, timeouts.PVBound) if err != nil { - return fmt.Errorf("PV %q did not become Bound: %v", pv.Name, err) + return fmt.Errorf("PV %q did not become Bound: %w", pv.Name, err) } // Re-get the pv and pvc objects - pv, err = c.CoreV1().PersistentVolumes().Get(context.TODO(), pv.Name, metav1.GetOptions{}) + pv, err = c.CoreV1().PersistentVolumes().Get(ctx, pv.Name, metav1.GetOptions{}) if err != nil { - return fmt.Errorf("PV Get API error: %v", err) + return fmt.Errorf("PV Get API error: %w", err) } - pvc, err = c.CoreV1().PersistentVolumeClaims(ns).Get(context.TODO(), pvc.Name, metav1.GetOptions{}) + pvc, err = c.CoreV1().PersistentVolumeClaims(ns).Get(ctx, pvc.Name, metav1.GetOptions{}) if err != nil { - return fmt.Errorf("PVC Get API error: %v", err) + return fmt.Errorf("PVC Get API error: %w", err) } // The pv and pvc are both bound, but to each other? @@ -508,7 +508,7 @@ func WaitOnPVandPVC(c clientset.Interface, timeouts *framework.TimeoutContext, n // to situations where the maximum wait times are reached several times in succession, // extending test time. Thus, it is recommended to keep the delta between PVs and PVCs // small. -func WaitAndVerifyBinds(c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvols PVMap, claims PVCMap, testExpected bool) error { +func WaitAndVerifyBinds(ctx context.Context, c clientset.Interface, timeouts *framework.TimeoutContext, ns string, pvols PVMap, claims PVCMap, testExpected bool) error { var actualBinds int expectedBinds := len(pvols) if expectedBinds > len(claims) { // want the min of # pvs or #pvcs @@ -516,19 +516,19 @@ func WaitAndVerifyBinds(c clientset.Interface, timeouts *framework.TimeoutContex } for pvName := range pvols { - err := WaitForPersistentVolumePhase(v1.VolumeBound, c, pvName, framework.Poll, timeouts.PVBound) + err := WaitForPersistentVolumePhase(ctx, v1.VolumeBound, c, pvName, framework.Poll, timeouts.PVBound) if err != nil && len(pvols) > len(claims) { framework.Logf("WARN: pv %v is not bound after max wait", pvName) framework.Logf(" This may be ok since there are more pvs than pvcs") continue } if err != nil { - return fmt.Errorf("PV %q did not become Bound: %v", pvName, err) + return fmt.Errorf("PV %q did not become Bound: %w", pvName, err) } - pv, err := c.CoreV1().PersistentVolumes().Get(context.TODO(), pvName, metav1.GetOptions{}) + pv, err := c.CoreV1().PersistentVolumes().Get(ctx, pvName, metav1.GetOptions{}) if err != nil { - return fmt.Errorf("PV Get API error: %v", err) + return fmt.Errorf("PV Get API error: %w", err) } cr := pv.Spec.ClaimRef if cr != nil && len(cr.Name) > 0 { @@ -539,9 +539,9 @@ func WaitAndVerifyBinds(c clientset.Interface, timeouts *framework.TimeoutContex return fmt.Errorf("internal: claims map is missing pvc %q", pvcKey) } - err := WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, ns, cr.Name, framework.Poll, timeouts.ClaimBound) + err := WaitForPersistentVolumeClaimPhase(ctx, v1.ClaimBound, c, ns, cr.Name, framework.Poll, timeouts.ClaimBound) if err != nil { - return fmt.Errorf("PVC %q did not become Bound: %v", cr.Name, err) + return fmt.Errorf("PVC %q did not become Bound: %w", cr.Name, err) } actualBinds++ } @@ -659,10 +659,15 @@ func MakePersistentVolumeClaim(cfg PersistentVolumeClaimConfig, ns string) *v1.P } } -func createPDWithRetry(zone string) (string, error) { +func createPDWithRetry(ctx context.Context, zone string) (string, error) { var err error var newDiskName string - for start := time.Now(); time.Since(start) < pdRetryTimeout; time.Sleep(pdRetryPollTime) { + for start := time.Now(); ; time.Sleep(pdRetryPollTime) { + if time.Since(start) >= pdRetryTimeout || + ctx.Err() != nil { + return "", fmt.Errorf("timed out while trying to create PD in zone %q, last error: %w", zone, err) + } + newDiskName, err = createPD(zone) if err != nil { framework.Logf("Couldn't create a new PD in zone %q, sleeping 5 seconds: %v", zone, err) @@ -671,7 +676,6 @@ func createPDWithRetry(zone string) (string, error) { framework.Logf("Successfully created a new PD in zone %q: %q.", zone, newDiskName) return newDiskName, nil } - return "", err } func CreateShare() (string, string, string, error) { @@ -683,19 +687,23 @@ func DeleteShare(accountName, shareName string) error { } // CreatePDWithRetry creates PD with retry. -func CreatePDWithRetry() (string, error) { - return createPDWithRetry("") +func CreatePDWithRetry(ctx context.Context) (string, error) { + return createPDWithRetry(ctx, "") } // CreatePDWithRetryAndZone creates PD on zone with retry. -func CreatePDWithRetryAndZone(zone string) (string, error) { - return createPDWithRetry(zone) +func CreatePDWithRetryAndZone(ctx context.Context, zone string) (string, error) { + return createPDWithRetry(ctx, zone) } // DeletePDWithRetry deletes PD with retry. -func DeletePDWithRetry(diskName string) error { +func DeletePDWithRetry(ctx context.Context, diskName string) error { var err error - for start := time.Now(); time.Since(start) < pdRetryTimeout; time.Sleep(pdRetryPollTime) { + for start := time.Now(); ; time.Sleep(pdRetryPollTime) { + if time.Since(start) >= pdRetryTimeout || + ctx.Err() != nil { + return fmt.Errorf("timed out while trying to delete PD %q, last error: %w", diskName, err) + } err = deletePD(diskName) if err != nil { framework.Logf("Couldn't delete PD %q, sleeping %v: %v", diskName, pdRetryPollTime, err) @@ -704,7 +712,6 @@ func DeletePDWithRetry(diskName string) error { framework.Logf("Successfully deleted PD %q.", diskName) return nil } - return fmt.Errorf("unable to delete PD %q: %v", diskName, err) } func createPD(zone string) (string, error) { @@ -719,33 +726,33 @@ func deletePD(pdName string) error { } // WaitForPVClaimBoundPhase waits until all pvcs phase set to bound -func WaitForPVClaimBoundPhase(client clientset.Interface, pvclaims []*v1.PersistentVolumeClaim, timeout time.Duration) ([]*v1.PersistentVolume, error) { +func WaitForPVClaimBoundPhase(ctx context.Context, client clientset.Interface, pvclaims []*v1.PersistentVolumeClaim, timeout time.Duration) ([]*v1.PersistentVolume, error) { persistentvolumes := make([]*v1.PersistentVolume, len(pvclaims)) for index, claim := range pvclaims { - err := WaitForPersistentVolumeClaimPhase(v1.ClaimBound, client, claim.Namespace, claim.Name, framework.Poll, timeout) + err := WaitForPersistentVolumeClaimPhase(ctx, v1.ClaimBound, client, claim.Namespace, claim.Name, framework.Poll, timeout) if err != nil { return persistentvolumes, err } // Get new copy of the claim - claim, err = client.CoreV1().PersistentVolumeClaims(claim.Namespace).Get(context.TODO(), claim.Name, metav1.GetOptions{}) + claim, err = client.CoreV1().PersistentVolumeClaims(claim.Namespace).Get(ctx, claim.Name, metav1.GetOptions{}) if err != nil { - return persistentvolumes, fmt.Errorf("PVC Get API error: %v", err) + return persistentvolumes, fmt.Errorf("PVC Get API error: %w", err) } // Get the bounded PV - persistentvolumes[index], err = client.CoreV1().PersistentVolumes().Get(context.TODO(), claim.Spec.VolumeName, metav1.GetOptions{}) + persistentvolumes[index], err = client.CoreV1().PersistentVolumes().Get(ctx, claim.Spec.VolumeName, metav1.GetOptions{}) if err != nil { - return persistentvolumes, fmt.Errorf("PV Get API error: %v", err) + return persistentvolumes, fmt.Errorf("PV Get API error: %w", err) } } return persistentvolumes, nil } // WaitForPersistentVolumePhase waits for a PersistentVolume to be in a specific phase or until timeout occurs, whichever comes first. -func WaitForPersistentVolumePhase(phase v1.PersistentVolumePhase, c clientset.Interface, pvName string, poll, timeout time.Duration) error { +func WaitForPersistentVolumePhase(ctx context.Context, phase v1.PersistentVolumePhase, c clientset.Interface, pvName string, poll, timeout time.Duration) error { framework.Logf("Waiting up to %v for PersistentVolume %s to have phase %s", timeout, pvName, phase) for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) { - pv, err := c.CoreV1().PersistentVolumes().Get(context.TODO(), pvName, metav1.GetOptions{}) + pv, err := c.CoreV1().PersistentVolumes().Get(ctx, pvName, metav1.GetOptions{}) if err != nil { framework.Logf("Get persistent volume %s in failed, ignoring for %v: %v", pvName, poll, err) continue @@ -760,13 +767,13 @@ func WaitForPersistentVolumePhase(phase v1.PersistentVolumePhase, c clientset.In } // WaitForPersistentVolumeClaimPhase waits for a PersistentVolumeClaim to be in a specific phase or until timeout occurs, whichever comes first. -func WaitForPersistentVolumeClaimPhase(phase v1.PersistentVolumeClaimPhase, c clientset.Interface, ns string, pvcName string, poll, timeout time.Duration) error { - return WaitForPersistentVolumeClaimsPhase(phase, c, ns, []string{pvcName}, poll, timeout, true) +func WaitForPersistentVolumeClaimPhase(ctx context.Context, phase v1.PersistentVolumeClaimPhase, c clientset.Interface, ns string, pvcName string, poll, timeout time.Duration) error { + return WaitForPersistentVolumeClaimsPhase(ctx, phase, c, ns, []string{pvcName}, poll, timeout, true) } // WaitForPersistentVolumeClaimsPhase waits for any (if matchAny is true) or all (if matchAny is false) PersistentVolumeClaims // to be in a specific phase or until timeout occurs, whichever comes first. -func WaitForPersistentVolumeClaimsPhase(phase v1.PersistentVolumeClaimPhase, c clientset.Interface, ns string, pvcNames []string, poll, timeout time.Duration, matchAny bool) error { +func WaitForPersistentVolumeClaimsPhase(ctx context.Context, phase v1.PersistentVolumeClaimPhase, c clientset.Interface, ns string, pvcNames []string, poll, timeout time.Duration, matchAny bool) error { if len(pvcNames) == 0 { return fmt.Errorf("Incorrect parameter: Need at least one PVC to track. Found 0") } @@ -774,7 +781,7 @@ func WaitForPersistentVolumeClaimsPhase(phase v1.PersistentVolumeClaimPhase, c c for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) { phaseFoundInAllClaims := true for _, pvcName := range pvcNames { - pvc, err := c.CoreV1().PersistentVolumeClaims(ns).Get(context.TODO(), pvcName, metav1.GetOptions{}) + pvc, err := c.CoreV1().PersistentVolumeClaims(ns).Get(ctx, pvcName, metav1.GetOptions{}) if err != nil { framework.Logf("Failed to get claim %q, retrying in %v. Error: %v", pvcName, poll, err) phaseFoundInAllClaims = false @@ -798,24 +805,24 @@ func WaitForPersistentVolumeClaimsPhase(phase v1.PersistentVolumeClaimPhase, c c } // CreatePVSource creates a PV source. -func CreatePVSource(zone string) (*v1.PersistentVolumeSource, error) { - diskName, err := CreatePDWithRetryAndZone(zone) +func CreatePVSource(ctx context.Context, zone string) (*v1.PersistentVolumeSource, error) { + diskName, err := CreatePDWithRetryAndZone(ctx, zone) if err != nil { return nil, err } - return framework.TestContext.CloudConfig.Provider.CreatePVSource(zone, diskName) + return framework.TestContext.CloudConfig.Provider.CreatePVSource(ctx, zone, diskName) } // DeletePVSource deletes a PV source. -func DeletePVSource(pvSource *v1.PersistentVolumeSource) error { - return framework.TestContext.CloudConfig.Provider.DeletePVSource(pvSource) +func DeletePVSource(ctx context.Context, pvSource *v1.PersistentVolumeSource) error { + return framework.TestContext.CloudConfig.Provider.DeletePVSource(ctx, pvSource) } // GetDefaultStorageClassName returns default storageClass or return error -func GetDefaultStorageClassName(c clientset.Interface) (string, error) { - list, err := c.StorageV1().StorageClasses().List(context.TODO(), metav1.ListOptions{}) +func GetDefaultStorageClassName(ctx context.Context, c clientset.Interface) (string, error) { + list, err := c.StorageV1().StorageClasses().List(ctx, metav1.ListOptions{}) if err != nil { - return "", fmt.Errorf("Error listing storage classes: %v", err) + return "", fmt.Errorf("Error listing storage classes: %w", err) } var scName string for _, sc := range list.Items { @@ -834,18 +841,18 @@ func GetDefaultStorageClassName(c clientset.Interface) (string, error) { } // SkipIfNoDefaultStorageClass skips tests if no default SC can be found. -func SkipIfNoDefaultStorageClass(c clientset.Interface) { - _, err := GetDefaultStorageClassName(c) +func SkipIfNoDefaultStorageClass(ctx context.Context, c clientset.Interface) { + _, err := GetDefaultStorageClassName(ctx, c) if err != nil { e2eskipper.Skipf("error finding default storageClass : %v", err) } } // WaitForPersistentVolumeDeleted waits for a PersistentVolume to get deleted or until timeout occurs, whichever comes first. -func WaitForPersistentVolumeDeleted(c clientset.Interface, pvName string, poll, timeout time.Duration) error { +func WaitForPersistentVolumeDeleted(ctx context.Context, c clientset.Interface, pvName string, poll, timeout time.Duration) error { framework.Logf("Waiting up to %v for PersistentVolume %s to get deleted", timeout, pvName) for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) { - pv, err := c.CoreV1().PersistentVolumes().Get(context.TODO(), pvName, metav1.GetOptions{}) + pv, err := c.CoreV1().PersistentVolumes().Get(ctx, pvName, metav1.GetOptions{}) if err == nil { framework.Logf("PersistentVolume %s found and phase=%s (%v)", pvName, pv.Status.Phase, time.Since(start)) continue diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go index abf6e3387..3c0a2bf78 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/skipper/skipper.go @@ -38,8 +38,6 @@ import ( func skipInternalf(caller int, format string, args ...interface{}) { msg := fmt.Sprintf(format, args...) - // Long term this should get replaced with https://github.com/onsi/ginkgo/issues/1069. - framework.Logf(msg) ginkgo.Skip(msg, caller+1) panic("unreachable") } @@ -103,9 +101,9 @@ func SkipIfFeatureGateEnabled(gate featuregate.Feature) { } // SkipIfMissingResource skips if the gvr resource is missing. -func SkipIfMissingResource(dynamicClient dynamic.Interface, gvr schema.GroupVersionResource, namespace string) { +func SkipIfMissingResource(ctx context.Context, dynamicClient dynamic.Interface, gvr schema.GroupVersionResource, namespace string) { resourceClient := dynamicClient.Resource(gvr).Namespace(namespace) - _, err := resourceClient.List(context.TODO(), metav1.ListOptions{}) + _, err := resourceClient.List(ctx, metav1.ListOptions{}) if err != nil { // not all resources support list, so we ignore those if apierrors.IsMethodNotSupported(err) || apierrors.IsNotFound(err) || apierrors.IsForbidden(err) { @@ -144,8 +142,8 @@ func SkipUnlessProviderIs(supportedProviders ...string) { } // SkipUnlessMultizone skips if the cluster does not have multizone. -func SkipUnlessMultizone(c clientset.Interface) { - zones, err := e2enode.GetClusterZones(c) +func SkipUnlessMultizone(ctx context.Context, c clientset.Interface) { + zones, err := e2enode.GetClusterZones(ctx, c) if err != nil { skipInternalf(1, "Error listing cluster zones") } @@ -155,8 +153,8 @@ func SkipUnlessMultizone(c clientset.Interface) { } // SkipIfMultizone skips if the cluster has multizone. -func SkipIfMultizone(c clientset.Interface) { - zones, err := e2enode.GetClusterZones(c) +func SkipIfMultizone(ctx context.Context, c clientset.Interface) { + zones, err := e2enode.GetClusterZones(ctx, c) if err != nil { skipInternalf(1, "Error listing cluster zones") } @@ -215,11 +213,11 @@ func SkipUnlessSSHKeyPresent() { func serverVersionGTE(v *utilversion.Version, c discovery.ServerVersionInterface) (bool, error) { serverVersion, err := c.ServerVersion() if err != nil { - return false, fmt.Errorf("Unable to get server version: %v", err) + return false, fmt.Errorf("Unable to get server version: %w", err) } sv, err := utilversion.ParseSemantic(serverVersion.GitVersion) if err != nil { - return false, fmt.Errorf("Unable to parse server version %q: %v", serverVersion.GitVersion, err) + return false, fmt.Errorf("Unable to parse server version %q: %w", serverVersion.GitVersion, err) } return sv.AtLeast(v), nil } @@ -243,11 +241,11 @@ func RunIfSystemSpecNameIs(names ...string) { } // SkipUnlessComponentRunsAsPodsAndClientCanDeleteThem run if the component run as pods and client can delete them -func SkipUnlessComponentRunsAsPodsAndClientCanDeleteThem(componentName string, c clientset.Interface, ns string, labelSet labels.Set) { +func SkipUnlessComponentRunsAsPodsAndClientCanDeleteThem(ctx context.Context, componentName string, c clientset.Interface, ns string, labelSet labels.Set) { // verify if component run as pod label := labels.SelectorFromSet(labelSet) listOpts := metav1.ListOptions{LabelSelector: label.String()} - pods, err := c.CoreV1().Pods(ns).List(context.TODO(), listOpts) + pods, err := c.CoreV1().Pods(ns).List(ctx, listOpts) framework.Logf("SkipUnlessComponentRunsAsPodsAndClientCanDeleteThem: %v, %v", pods, err) if err != nil { skipInternalf(1, "Skipped because client failed to get component:%s pod err:%v", componentName, err) @@ -259,7 +257,7 @@ func SkipUnlessComponentRunsAsPodsAndClientCanDeleteThem(componentName string, c // verify if client can delete pod pod := pods.Items[0] - if err := c.CoreV1().Pods(ns).Delete(context.TODO(), pod.Name, metav1.DeleteOptions{DryRun: []string{metav1.DryRunAll}}); err != nil { + if err := c.CoreV1().Pods(ns).Delete(ctx, pod.Name, metav1.DeleteOptions{DryRun: []string{metav1.DryRunAll}}); err != nil { skipInternalf(1, "Skipped because client failed to delete component:%s pod, err:%v", componentName, err) } } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go b/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go index fa9547596..5624b3e4a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/ssh/ssh.go @@ -103,12 +103,12 @@ func GetSigner(provider string) (ssh.Signer, error) { func makePrivateKeySignerFromFile(key string) (ssh.Signer, error) { buffer, err := os.ReadFile(key) if err != nil { - return nil, fmt.Errorf("error reading SSH key %s: '%v'", key, err) + return nil, fmt.Errorf("error reading SSH key %s: %w", key, err) } signer, err := ssh.ParsePrivateKey(buffer) if err != nil { - return nil, fmt.Errorf("error parsing SSH key: '%v'", err) + return nil, fmt.Errorf("error parsing SSH key: %w", err) } return signer, err @@ -119,8 +119,8 @@ func makePrivateKeySignerFromFile(key string) (ssh.Signer, error) { // looking for internal IPs. If it can't find an internal IP for every node it // returns an error, though it still returns all hosts that it found in that // case. -func NodeSSHHosts(c clientset.Interface) ([]string, error) { - nodelist := waitListSchedulableNodesOrDie(c) +func NodeSSHHosts(ctx context.Context, c clientset.Interface) ([]string, error) { + nodelist := waitListSchedulableNodesOrDie(ctx, c) hosts := nodeAddresses(nodelist, v1.NodeExternalIP) // If ExternalIPs aren't available for all nodes, try falling back to the InternalIPs. @@ -188,20 +188,20 @@ type Result struct { // NodeExec execs the given cmd on node via SSH. Note that the nodeName is an sshable name, // eg: the name returned by framework.GetMasterHost(). This is also not guaranteed to work across // cloud providers since it involves ssh. -func NodeExec(nodeName, cmd, provider string) (Result, error) { - return SSH(cmd, net.JoinHostPort(nodeName, SSHPort), provider) +func NodeExec(ctx context.Context, nodeName, cmd, provider string) (Result, error) { + return SSH(ctx, cmd, net.JoinHostPort(nodeName, SSHPort), provider) } // SSH synchronously SSHs to a node running on provider and runs cmd. If there // is no error performing the SSH, the stdout, stderr, and exit code are // returned. -func SSH(cmd, host, provider string) (Result, error) { +func SSH(ctx context.Context, cmd, host, provider string) (Result, error) { result := Result{Host: host, Cmd: cmd} // Get a signer for the provider. signer, err := GetSigner(provider) if err != nil { - return result, fmt.Errorf("error getting signer for provider %s: '%v'", provider, err) + return result, fmt.Errorf("error getting signer for provider %s: %w", provider, err) } // RunSSHCommand will default to Getenv("USER") if user == "", but we're @@ -212,14 +212,14 @@ func SSH(cmd, host, provider string) (Result, error) { } if bastion := os.Getenv(sshBastionEnvKey); len(bastion) > 0 { - stdout, stderr, code, err := runSSHCommandViaBastion(cmd, result.User, bastion, host, signer) + stdout, stderr, code, err := runSSHCommandViaBastion(ctx, cmd, result.User, bastion, host, signer) result.Stdout = stdout result.Stderr = stderr result.Code = code return result, err } - stdout, stderr, code, err := runSSHCommand(cmd, result.User, host, signer) + stdout, stderr, code, err := runSSHCommand(ctx, cmd, result.User, host, signer) result.Stdout = stdout result.Stderr = stderr result.Code = code @@ -229,7 +229,7 @@ func SSH(cmd, host, provider string) (Result, error) { // runSSHCommandViaBastion returns the stdout, stderr, and exit code from running cmd on // host as specific user, along with any SSH-level error. -func runSSHCommand(cmd, user, host string, signer ssh.Signer) (string, string, int, error) { +func runSSHCommand(ctx context.Context, cmd, user, host string, signer ssh.Signer) (string, string, int, error) { if user == "" { user = os.Getenv("USER") } @@ -241,7 +241,7 @@ func runSSHCommand(cmd, user, host string, signer ssh.Signer) (string, string, i } client, err := ssh.Dial("tcp", host, config) if err != nil { - err = wait.Poll(5*time.Second, 20*time.Second, func() (bool, error) { + err = wait.PollWithContext(ctx, 5*time.Second, 20*time.Second, func(ctx context.Context) (bool, error) { fmt.Printf("error dialing %s@%s: '%v', retrying\n", user, host, err) if client, err = ssh.Dial("tcp", host, config); err != nil { return false, nil // retrying, error will be logged above @@ -250,12 +250,12 @@ func runSSHCommand(cmd, user, host string, signer ssh.Signer) (string, string, i }) } if err != nil { - return "", "", 0, fmt.Errorf("error getting SSH client to %s@%s: '%v'", user, host, err) + return "", "", 0, fmt.Errorf("error getting SSH client to %s@%s: %w", user, host, err) } defer client.Close() session, err := client.NewSession() if err != nil { - return "", "", 0, fmt.Errorf("error creating session to %s@%s: '%v'", user, host, err) + return "", "", 0, fmt.Errorf("error creating session to %s@%s: %w", user, host, err) } defer session.Close() @@ -275,7 +275,7 @@ func runSSHCommand(cmd, user, host string, signer ssh.Signer) (string, string, i } else { // Some other kind of error happened (e.g. an IOError); consider the // SSH unsuccessful. - err = fmt.Errorf("failed running `%s` on %s@%s: '%v'", cmd, user, host, err) + err = fmt.Errorf("failed running `%s` on %s@%s: %w", cmd, user, host, err) } } return bout.String(), berr.String(), code, err @@ -285,7 +285,7 @@ func runSSHCommand(cmd, user, host string, signer ssh.Signer) (string, string, i // host as specific user, along with any SSH-level error. It uses an SSH proxy to connect // to bastion, then via that tunnel connects to the remote host. Similar to // sshutil.RunSSHCommand but scoped to the needs of the test infrastructure. -func runSSHCommandViaBastion(cmd, user, bastion, host string, signer ssh.Signer) (string, string, int, error) { +func runSSHCommandViaBastion(ctx context.Context, cmd, user, bastion, host string, signer ssh.Signer) (string, string, int, error) { // Setup the config, dial the server, and open a session. config := &ssh.ClientConfig{ User: user, @@ -295,7 +295,7 @@ func runSSHCommandViaBastion(cmd, user, bastion, host string, signer ssh.Signer) } bastionClient, err := ssh.Dial("tcp", bastion, config) if err != nil { - err = wait.Poll(5*time.Second, 20*time.Second, func() (bool, error) { + err = wait.PollWithContext(ctx, 5*time.Second, 20*time.Second, func(ctx context.Context) (bool, error) { fmt.Printf("error dialing %s@%s: '%v', retrying\n", user, bastion, err) if bastionClient, err = ssh.Dial("tcp", bastion, config); err != nil { return false, err @@ -304,26 +304,26 @@ func runSSHCommandViaBastion(cmd, user, bastion, host string, signer ssh.Signer) }) } if err != nil { - return "", "", 0, fmt.Errorf("error getting SSH client to %s@%s: %v", user, bastion, err) + return "", "", 0, fmt.Errorf("error getting SSH client to %s@%s: %w", user, bastion, err) } defer bastionClient.Close() conn, err := bastionClient.Dial("tcp", host) if err != nil { - return "", "", 0, fmt.Errorf("error dialing %s from bastion: %v", host, err) + return "", "", 0, fmt.Errorf("error dialing %s from bastion: %w", host, err) } defer conn.Close() ncc, chans, reqs, err := ssh.NewClientConn(conn, host, config) if err != nil { - return "", "", 0, fmt.Errorf("error creating forwarding connection %s from bastion: %v", host, err) + return "", "", 0, fmt.Errorf("error creating forwarding connection %s from bastion: %w", host, err) } client := ssh.NewClient(ncc, chans, reqs) defer client.Close() session, err := client.NewSession() if err != nil { - return "", "", 0, fmt.Errorf("error creating session to %s@%s from bastion: '%v'", user, host, err) + return "", "", 0, fmt.Errorf("error creating session to %s@%s from bastion: %w", user, host, err) } defer session.Close() @@ -343,7 +343,7 @@ func runSSHCommandViaBastion(cmd, user, bastion, host string, signer ssh.Signer) } else { // Some other kind of error happened (e.g. an IOError); consider the // SSH unsuccessful. - err = fmt.Errorf("failed running `%s` on %s@%s: '%v'", cmd, user, host, err) + err = fmt.Errorf("failed running `%s` on %s@%s: %w", cmd, user, host, err) } } return bout.String(), berr.String(), code, err @@ -359,7 +359,7 @@ func LogResult(result Result) { } // IssueSSHCommandWithResult tries to execute a SSH command and returns the execution result -func IssueSSHCommandWithResult(cmd, provider string, node *v1.Node) (*Result, error) { +func IssueSSHCommandWithResult(ctx context.Context, cmd, provider string, node *v1.Node) (*Result, error) { framework.Logf("Getting external IP address for %s", node.Name) host := "" for _, a := range node.Status.Addresses { @@ -384,7 +384,7 @@ func IssueSSHCommandWithResult(cmd, provider string, node *v1.Node) (*Result, er } framework.Logf("SSH %q on %s(%s)", cmd, node.Name, host) - result, err := SSH(cmd, host, provider) + result, err := SSH(ctx, cmd, host, provider) LogResult(result) if result.Code != 0 || err != nil { @@ -396,8 +396,8 @@ func IssueSSHCommandWithResult(cmd, provider string, node *v1.Node) (*Result, er } // IssueSSHCommand tries to execute a SSH command -func IssueSSHCommand(cmd, provider string, node *v1.Node) error { - _, err := IssueSSHCommandWithResult(cmd, provider, node) +func IssueSSHCommand(ctx context.Context, cmd, provider string, node *v1.Node) error { + _, err := IssueSSHCommandWithResult(ctx, cmd, provider, node) if err != nil { return err } @@ -419,11 +419,11 @@ func nodeAddresses(nodelist *v1.NodeList, addrType v1.NodeAddressType) []string } // waitListSchedulableNodes is a wrapper around listing nodes supporting retries. -func waitListSchedulableNodes(c clientset.Interface) (*v1.NodeList, error) { +func waitListSchedulableNodes(ctx context.Context, c clientset.Interface) (*v1.NodeList, error) { var nodes *v1.NodeList var err error - if wait.PollImmediate(pollNodeInterval, singleCallTimeout, func() (bool, error) { - nodes, err = c.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{FieldSelector: fields.Set{ + if wait.PollImmediateWithContext(ctx, pollNodeInterval, singleCallTimeout, func(ctx context.Context) (bool, error) { + nodes, err = c.CoreV1().Nodes().List(ctx, metav1.ListOptions{FieldSelector: fields.Set{ "spec.unschedulable": "false", }.AsSelector().String()}) if err != nil { @@ -437,8 +437,8 @@ func waitListSchedulableNodes(c clientset.Interface) (*v1.NodeList, error) { } // waitListSchedulableNodesOrDie is a wrapper around listing nodes supporting retries. -func waitListSchedulableNodesOrDie(c clientset.Interface) *v1.NodeList { - nodes, err := waitListSchedulableNodes(c) +func waitListSchedulableNodesOrDie(ctx context.Context, c clientset.Interface) *v1.NodeList { + nodes, err := waitListSchedulableNodes(ctx, c) if err != nil { expectNoError(err, "Non-retryable failure or timed out while listing nodes for e2e cluster.") } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go b/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go index 6108cddf7..92dc4f683 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go @@ -17,6 +17,7 @@ limitations under the License. package framework import ( + "context" "crypto/rand" "encoding/base64" "errors" @@ -32,6 +33,7 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/onsi/ginkgo/v2/reporters" "github.com/onsi/ginkgo/v2/types" + "github.com/onsi/gomega" gomegaformat "github.com/onsi/gomega/format" restclient "k8s.io/client-go/rest" @@ -40,6 +42,8 @@ import ( "k8s.io/klog/v2" kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" + "k8s.io/kubernetes/test/e2e/framework/internal/junit" + "k8s.io/kubernetes/test/utils/image" "k8s.io/kubernetes/test/utils/kubeconfig" ) @@ -100,15 +104,22 @@ type TestContextType struct { // Tooling is the tooling in use (e.g. kops, gke). Provider is the cloud provider and might not uniquely identify the tooling. Tooling string - CloudConfig CloudConfig - KubectlPath string - OutputDir string - ReportDir string - ReportPrefix string - Prefix string - MinStartupPods int - // Timeout for waiting for system pods to be running - SystemPodsStartupTimeout time.Duration + // timeouts contains user-configurable timeouts for various operations. + // Individual Framework instance also have such timeouts which may be + // different from these here. To avoid confusion, this field is not + // exported. Its values can be accessed through + // NewTimeoutContext. + timeouts TimeoutContext + + CloudConfig CloudConfig + KubectlPath string + OutputDir string + ReportDir string + ReportPrefix string + ReportCompleteGinkgo bool + ReportCompleteJUnit bool + Prefix string + MinStartupPods int EtcdUpgradeStorage string EtcdUpgradeVersion string GCEUpgradeScript string @@ -141,10 +152,6 @@ type TestContextType struct { IncludeClusterAutoscalerMetrics bool // Currently supported values are 'hr' for human-readable and 'json'. It's a comma separated list. OutputPrintType string - // NodeSchedulableTimeout is the timeout for waiting for all nodes to be schedulable. - NodeSchedulableTimeout time.Duration - // SystemDaemonsetStartupTimeout is the timeout for waiting for all system daemonsets to be ready. - SystemDaemonsetStartupTimeout time.Duration // CreateTestingNS is responsible for creating namespace used for executing e2e tests. // It accepts namespace base name, which will be prepended with e2e prefix, kube client // and labels to be applied to a namespace. @@ -182,6 +189,13 @@ type TestContextType struct { // DockerConfigFile is a file that contains credentials which can be used to pull images from certain private registries, needed for a test. DockerConfigFile string + // E2EDockerConfigFile is a docker credentials configuration file used which contains authorization token that can be used to pull images from certain private registries provided by the users. + // For more details refer https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#log-in-to-docker-hub + E2EDockerConfigFile string + + // KubeTestRepoConfigFile is a yaml file used for overriding registries for test images. + KubeTestRepoList string + // SnapshotControllerPodName is the name used for identifying the snapshot controller pod. SnapshotControllerPodName string @@ -214,8 +228,10 @@ type NodeKillerConfig struct { JitterFactor float64 // SimulatedDowntime is a duration between node is killed and recreated. SimulatedDowntime time.Duration - // NodeKillerStopCh is a channel that is used to notify NodeKiller to stop killing nodes. - NodeKillerStopCh chan struct{} + // NodeKillerStopCtx is a context that is used to notify NodeKiller to stop killing nodes. + NodeKillerStopCtx context.Context + // NodeKillerStop is the cancel function for NodeKillerStopCtx. + NodeKillerStop func() } // NodeTestContextType is part of TestContextType, it is shared by all node e2e test. @@ -242,6 +258,8 @@ type NodeTestContextType struct { RestartKubelet bool // ExtraEnvs is a map of environment names to values. ExtraEnvs map[string]string + // StandaloneMode indicates whether the test is running kubelet in a standalone mode. + StandaloneMode bool } // CloudConfig holds the cloud configuration for e2e test suites. @@ -268,7 +286,9 @@ type CloudConfig struct { } // TestContext should be used by all tests to access common context data. -var TestContext TestContextType +var TestContext = TestContextType{ + timeouts: defaultTimeouts, +} // StringArrayValue is used with flag.Var for a comma-separated list of strings placed into a string array. type stringArrayValue struct { @@ -327,7 +347,9 @@ func RegisterCommonFlags(flags *flag.FlagSet) { flags.StringVar(&TestContext.Host, "host", "", fmt.Sprintf("The host, or apiserver, to connect to. Will default to %s if this argument and --kubeconfig are not set.", defaultHost)) flags.StringVar(&TestContext.ReportPrefix, "report-prefix", "", "Optional prefix for JUnit XML reports. Default is empty, which doesn't prepend anything to the default name.") - flags.StringVar(&TestContext.ReportDir, "report-dir", "", "Path to the directory where the JUnit XML reports and other tests results should be saved. Default is empty, which doesn't generate these reports. If ginkgo's -junit-report parameter is used, that parameter instead of -report-dir determines the location of a single JUnit report.") + flags.StringVar(&TestContext.ReportDir, "report-dir", "", "Path to the directory where the simplified JUnit XML reports and other tests results should be saved. Default is empty, which doesn't generate these reports. If ginkgo's -junit-report parameter is used, that parameter instead of -report-dir determines the location of a single JUnit report.") + flags.BoolVar(&TestContext.ReportCompleteGinkgo, "report-complete-ginkgo", false, "Enables writing a complete test report as Ginkgo JSON to /ginkgo/report.json. Ignored if --report-dir is not set.") + flags.BoolVar(&TestContext.ReportCompleteJUnit, "report-complete-junit", false, "Enables writing a complete test report as JUnit XML to /ginkgo/report.json. Ignored if --report-dir is not set.") flags.StringVar(&TestContext.ContainerRuntimeEndpoint, "container-runtime-endpoint", "unix:///var/run/containerd/containerd.sock", "The container runtime endpoint of cluster VM instances.") flags.StringVar(&TestContext.ContainerRuntimeProcessName, "container-runtime-process-name", "dockerd", "The name of the container runtime process.") flags.StringVar(&TestContext.ContainerRuntimePidFile, "container-runtime-pid-file", "/var/run/docker.pid", "The pid file of the container runtime.") @@ -342,12 +364,14 @@ func RegisterCommonFlags(flags *flag.FlagSet) { flags.StringVar(&TestContext.NonblockingTaints, "non-blocking-taints", `node-role.kubernetes.io/control-plane,node-role.kubernetes.io/master`, "Nodes with taints in this comma-delimited list will not block the test framework from starting tests. The default taint 'node-role.kubernetes.io/master' is DEPRECATED and will be removed from the list in a future release.") flags.BoolVar(&TestContext.ListImages, "list-images", false, "If true, will show list of images used for running tests.") - flags.BoolVar(&TestContext.ListConformanceTests, "list-conformance-tests", false, "If true, will show list of conformance tests.") flags.StringVar(&TestContext.KubectlPath, "kubectl-path", "kubectl", "The kubectl binary to use. For development, you might use 'cluster/kubectl.sh' here.") flags.StringVar(&TestContext.ProgressReportURL, "progress-report-url", "", "The URL to POST progress updates to as the suite runs to assist in aiding integrations. If empty, no messages sent.") flags.StringVar(&TestContext.SpecSummaryOutput, "spec-dump", "", "The file to dump all ginkgo.SpecSummary to after tests run. If empty, no objects are saved/printed.") - flags.StringVar(&TestContext.DockerConfigFile, "docker-config-file", "", "A file that contains credentials which can be used to pull images from certain private registries, needed for a test.") + flags.StringVar(&TestContext.DockerConfigFile, "docker-config-file", "", "A docker credential file which contains authorization token that is used to perform image pull tests from an authenticated registry. For more details regarding the content of the file refer https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#log-in-to-docker-hub") + + flags.StringVar(&TestContext.E2EDockerConfigFile, "e2e-docker-config-file", "", "A docker credentials configuration file used which contains authorization token that can be used to pull images from certain private registries provided by the users. For more details refer https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#log-in-to-docker-hub") + flags.StringVar(&TestContext.KubeTestRepoList, "kube-test-repo-list", "", "A yaml file used for overriding registries for test images. Alternatively, the KUBE_TEST_REPO_LIST env variable can be set.") flags.StringVar(&TestContext.SnapshotControllerPodName, "snapshot-controller-pod-name", "", "The pod name to use for identifying the snapshot controller in the kube-system namespace.") flags.IntVar(&TestContext.SnapshotControllerHTTPPort, "snapshot-controller-http-port", 0, "The port to use for snapshot controller HTTP communication.") @@ -358,12 +382,8 @@ func RegisterCommonFlags(flags *flag.FlagSet) { func CreateGinkgoConfig() (types.SuiteConfig, types.ReporterConfig) { // fetch the current config suiteConfig, reporterConfig := ginkgo.GinkgoConfiguration() - // Turn on EmitSpecProgress to get spec progress (especially on interrupt) - suiteConfig.EmitSpecProgress = true // Randomize specs as well as suites suiteConfig.RandomizeAllSpecs = true - // Turn on verbose by default to get spec names - reporterConfig.Verbose = true // Disable skipped tests unless they are explicitly requested. if len(suiteConfig.FocusStrings) == 0 && len(suiteConfig.SkipStrings) == 0 { suiteConfig.SkipStrings = []string{`\[Flaky\]|\[Feature:.+\]`} @@ -415,9 +435,9 @@ func RegisterClusterFlags(flags *flag.FlagSet) { flags.StringVar(&cloudConfig.ClusterTag, "cluster-tag", "", "Tag used to identify resources. Only required if provider is aws.") flags.StringVar(&cloudConfig.ConfigFile, "cloud-config-file", "", "Cloud config file. Only required if provider is azure or vsphere.") flags.IntVar(&TestContext.MinStartupPods, "minStartupPods", 0, "The number of pods which we need to see in 'Running' state with a 'Ready' condition of true, before we try running tests. This is useful in any cluster which needs some base pod-based services running before it can be used. If set to -1, no pods are checked and tests run straight away.") - flags.DurationVar(&TestContext.SystemPodsStartupTimeout, "system-pods-startup-timeout", 10*time.Minute, "Timeout for waiting for all system pods to be running before starting tests.") - flags.DurationVar(&TestContext.NodeSchedulableTimeout, "node-schedulable-timeout", 30*time.Minute, "Timeout for waiting for all nodes to be schedulable.") - flags.DurationVar(&TestContext.SystemDaemonsetStartupTimeout, "system-daemonsets-startup-timeout", 5*time.Minute, "Timeout for waiting for all system daemonsets to be ready.") + flags.DurationVar(&TestContext.timeouts.SystemPodsStartup, "system-pods-startup-timeout", TestContext.timeouts.SystemPodsStartup, "Timeout for waiting for all system pods to be running before starting tests.") + flags.DurationVar(&TestContext.timeouts.NodeSchedulable, "node-schedulable-timeout", TestContext.timeouts.NodeSchedulable, "Timeout for waiting for all nodes to be schedulable.") + flags.DurationVar(&TestContext.timeouts.SystemDaemonsetStartup, "system-daemonsets-startup-timeout", TestContext.timeouts.SystemDaemonsetStartup, "Timeout for waiting for all system daemonsets to be ready.") flags.StringVar(&TestContext.EtcdUpgradeStorage, "etcd-upgrade-storage", "", "The storage version to upgrade to (either 'etcdv2' or 'etcdv3') if doing an etcd upgrade test.") flags.StringVar(&TestContext.EtcdUpgradeVersion, "etcd-upgrade-version", "", "The etcd binary version to upgrade to (e.g., '3.0.14', '2.3.7') if doing an etcd upgrade test.") flags.StringVar(&TestContext.GCEUpgradeScript, "gce-upgrade-script", "", "Script to use to upgrade a GCE cluster.") @@ -455,6 +475,9 @@ func AfterReadingAllFlags(t *TestContextType) { // These flags are not exposed via the normal command line flag set, // therefore we have to use our own private one here. + if t.KubeTestRepoList != "" { + image.Init(t.KubeTestRepoList) + } var fs flag.FlagSet klog.InitFlags(&fs) fs.Set("logtostderr", "false") @@ -463,6 +486,22 @@ func AfterReadingAllFlags(t *TestContextType) { fs.Set("stderrthreshold", "10" /* higher than any of the severities -> none pass the threshold */) klog.SetOutput(ginkgo.GinkgoWriter) + if t.ListImages { + for _, v := range image.GetImageConfigs() { + fmt.Println(v.GetE2EImage()) + } + os.Exit(0) + } + + // Reconfigure gomega defaults. The poll interval should be suitable + // for most tests. The timeouts are more subjective and tests may want + // to override them, but these defaults are still better for E2E than the + // ones from Gomega (1s timeout, 10ms interval). + gomega.SetDefaultEventuallyPollingInterval(t.timeouts.Poll) + gomega.SetDefaultConsistentlyPollingInterval(t.timeouts.Poll) + gomega.SetDefaultEventuallyTimeout(t.timeouts.PodStart) + gomega.SetDefaultConsistentlyDuration(t.timeouts.PodStartShort) + // Only set a default host if one won't be supplied via kubeconfig if len(t.Host) == 0 && len(t.KubeConfig) == 0 { // Check if we can use the in-cluster config @@ -526,72 +565,46 @@ func AfterReadingAllFlags(t *TestContextType) { } if TestContext.ReportDir != "" { - ginkgo.ReportAfterSuite("Kubernetes e2e JUnit report", writeJUnitReport) - } -} - -const ( - // This is the traditional gomega.Format default of 4000 for an object - // dump plus some extra room for the message. - maxFailureMessageSize = 5000 - - truncatedMsg = "\n[... see output for full dump ...]\n" -) - -// writeJUnitReport generates a JUnit file in the e2e report directory that is -// shorter than the one normally written by `ginkgo --junit-report`. This is -// needed because the full report can become too large for tools like Spyglass -// (https://github.com/kubernetes/kubernetes/issues/111510). -// -// Users who want the full report can use `--junit-report`. -func writeJUnitReport(report ginkgo.Report) { - trimmedReport := report - trimmedReport.SpecReports = nil - for _, specReport := range report.SpecReports { - // Remove details for any spec that hasn't failed. In Prow, - // the test output captured in build-log.txt has all of this - // information, so we don't need it in the XML. - if specReport.State != types.SpecStateFailed { - specReport.CapturedGinkgoWriterOutput = "" - specReport.CapturedStdOutErr = "" - } else { - // Truncate the failure message if it is too large. - msgLen := len(specReport.Failure.Message) - if msgLen > maxFailureMessageSize { - // Insert full message at the beginning where it is easy to find. - specReport.CapturedGinkgoWriterOutput = - "Full failure message:\n" + - specReport.Failure.Message + "\n\n" + - strings.Repeat("=", 70) + "\n\n" + - specReport.CapturedGinkgoWriterOutput - specReport.Failure.Message = specReport.Failure.Message[0:maxFailureMessageSize/2] + truncatedMsg + specReport.Failure.Message[msgLen-maxFailureMessageSize/2:msgLen] + // Create the directory before running the suite. If + // --report-dir is not unusable, we should report + // that as soon as possible. This will be done by each worker + // in parallel, so we will get "exists" error in most of them. + if err := os.MkdirAll(TestContext.ReportDir, 0777); err != nil && !os.IsExist(err) { + klog.Errorf("Create report dir: %v", err) + os.Exit(1) + } + ginkgoDir := path.Join(TestContext.ReportDir, "ginkgo") + if TestContext.ReportCompleteGinkgo || TestContext.ReportCompleteJUnit { + if err := os.MkdirAll(ginkgoDir, 0777); err != nil && !os.IsExist(err) { + klog.Errorf("Create /ginkgo: %v", err) + os.Exit(1) } } - // Remove report entries generated by ginkgo.By("doing - // something") because those are not useful (just have the - // start time) and cause Spyglass to show an additional "open - // stdout" button with a summary of the steps, which usually - // doesn't help. We don't remove all entries because other - // measurements also get reported this way. - // - // Removing the report entries is okay because message text was - // already added to the test output when ginkgo.By was called. - reportEntries := specReport.ReportEntries - specReport.ReportEntries = nil - for _, reportEntry := range reportEntries { - if reportEntry.Name != "By Step" { - specReport.ReportEntries = append(specReport.ReportEntries, reportEntry) - } + if TestContext.ReportCompleteGinkgo { + ginkgo.ReportAfterSuite("Ginkgo JSON report", func(report ginkgo.Report) { + ExpectNoError(reporters.GenerateJSONReport(report, path.Join(ginkgoDir, "report.json"))) + }) + ginkgo.ReportAfterSuite("JUnit XML report", func(report ginkgo.Report) { + ExpectNoError(reporters.GenerateJUnitReport(report, path.Join(ginkgoDir, "report.xml"))) + }) } - trimmedReport.SpecReports = append(trimmedReport.SpecReports, specReport) - } + ginkgo.ReportAfterSuite("Kubernetes e2e JUnit report", func(report ginkgo.Report) { + // With Ginkgo v1, we used to write one file per + // parallel node. Now Ginkgo v2 automatically merges + // all results into a report for us. The 01 suffix is + // kept in case that users expect files to be called + // "junit_.xml". + junitReport := path.Join(TestContext.ReportDir, "junit_"+TestContext.ReportPrefix+"01.xml") - // With Ginkgo v1, we used to write one file per parallel node. Now - // Ginkgo v2 automatically merges all results into a report for us. The - // 01 suffix is kept in case that users expect files to be called - // "junit_.xml". - junitReport := path.Join(TestContext.ReportDir, "junit_"+TestContext.ReportPrefix+"01.xml") - reporters.GenerateJUnitReport(trimmedReport, junitReport) + // writeJUnitReport generates a JUnit file in the e2e + // report directory that is shorter than the one + // normally written by `ginkgo --junit-report`. This is + // needed because the full report can become too large + // for tools like Spyglass + // (https://github.com/kubernetes/kubernetes/issues/111510). + ExpectNoError(junit.WriteJUnitReport(report, junitReport)) + }) + } } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/testfiles.go b/vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/testfiles.go index 26aad3530..74b978ade 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/testfiles.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/testfiles/testfiles.go @@ -73,7 +73,7 @@ func Read(filePath string) ([]byte, error) { for _, filesource := range filesources { data, err := filesource.ReadTestFile(filePath) if err != nil { - return nil, fmt.Errorf("fatal error retrieving test file %s: %s", filePath, err) + return nil, fmt.Errorf("fatal error retrieving test file %s: %w", filePath, err) } if data != nil { return data, nil diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/timeouts.go b/vendor/k8s.io/kubernetes/test/e2e/framework/timeouts.go index ac636ddd7..5cfc29edb 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/timeouts.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/timeouts.go @@ -18,33 +18,41 @@ package framework import "time" -const ( - // Default timeouts to be used in TimeoutContext - podStartTimeout = 5 * time.Minute - podStartShortTimeout = 2 * time.Minute - podStartSlowTimeout = 15 * time.Minute - podDeleteTimeout = 5 * time.Minute - claimProvisionTimeout = 5 * time.Minute - claimProvisionShortTimeout = 1 * time.Minute - dataSourceProvisionTimeout = 5 * time.Minute - claimBoundTimeout = 3 * time.Minute - pvReclaimTimeout = 3 * time.Minute - pvBoundTimeout = 3 * time.Minute - pvCreateTimeout = 3 * time.Minute - pvDeleteTimeout = 5 * time.Minute - pvDeleteSlowTimeout = 20 * time.Minute - snapshotCreateTimeout = 5 * time.Minute - snapshotDeleteTimeout = 5 * time.Minute - snapshotControllerMetricsTimeout = 5 * time.Minute -) +var defaultTimeouts = TimeoutContext{ + Poll: 2 * time.Second, // from the former e2e/framework/pod poll interval + PodStart: 5 * time.Minute, + PodStartShort: 2 * time.Minute, + PodStartSlow: 15 * time.Minute, + PodDelete: 5 * time.Minute, + ClaimProvision: 5 * time.Minute, + ClaimProvisionShort: 1 * time.Minute, + DataSourceProvision: 5 * time.Minute, + ClaimBound: 3 * time.Minute, + PVReclaim: 3 * time.Minute, + PVBound: 3 * time.Minute, + PVCreate: 3 * time.Minute, + PVDelete: 5 * time.Minute, + PVDeleteSlow: 20 * time.Minute, + SnapshotCreate: 5 * time.Minute, + SnapshotDelete: 5 * time.Minute, + SnapshotControllerMetrics: 5 * time.Minute, + SystemPodsStartup: 10 * time.Minute, + NodeSchedulable: 30 * time.Minute, + SystemDaemonsetStartup: 5 * time.Minute, +} // TimeoutContext contains timeout settings for several actions. type TimeoutContext struct { + // Poll is how long to wait between API calls when waiting for some condition. + Poll time.Duration + // PodStart is how long to wait for the pod to be started. + // This value is the default for gomega.Eventually. PodStart time.Duration // PodStartShort is same as `PodStart`, but shorter. // Use it in a case-by-case basis, mostly when you are sure pod start will not be delayed. + // This value is the default for gomega.Consistently. PodStartShort time.Duration // PodStartSlow is same as `PodStart`, but longer. @@ -89,26 +97,31 @@ type TimeoutContext struct { // SnapshotControllerMetrics is how long to wait for snapshot controller metrics. SnapshotControllerMetrics time.Duration + + // SystemPodsStartup is how long to wait for system pods to be running. + SystemPodsStartup time.Duration + + // NodeSchedulable is how long to wait for all nodes to be schedulable. + NodeSchedulable time.Duration + + // SystemDaemonsetStartup is how long to wait for all system daemonsets to be ready. + SystemDaemonsetStartup time.Duration } -// NewTimeoutContextWithDefaults returns a TimeoutContext with default values. -func NewTimeoutContextWithDefaults() *TimeoutContext { - return &TimeoutContext{ - PodStart: podStartTimeout, - PodStartShort: podStartShortTimeout, - PodStartSlow: podStartSlowTimeout, - PodDelete: podDeleteTimeout, - ClaimProvision: claimProvisionTimeout, - ClaimProvisionShort: claimProvisionShortTimeout, - DataSourceProvision: dataSourceProvisionTimeout, - ClaimBound: claimBoundTimeout, - PVReclaim: pvReclaimTimeout, - PVBound: pvBoundTimeout, - PVCreate: pvCreateTimeout, - PVDelete: pvDeleteTimeout, - PVDeleteSlow: pvDeleteSlowTimeout, - SnapshotCreate: snapshotCreateTimeout, - SnapshotDelete: snapshotDeleteTimeout, - SnapshotControllerMetrics: snapshotControllerMetricsTimeout, - } +// NewTimeoutContext returns a TimeoutContext with all values set either to +// hard-coded defaults or a value that was configured when running the E2E +// suite. Should be called after command line parsing. +func NewTimeoutContext() *TimeoutContext { + // Make a copy, otherwise the caller would have the ability to modify + // the original values. + copy := TestContext.timeouts + return © +} + +// PollInterval defines how long to wait between API server queries while +// waiting for some condition. +// +// This value is the default for gomega.Eventually and gomega.Consistently. +func PollInterval() time.Duration { + return TestContext.timeouts.Poll } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/util.go b/vendor/k8s.io/kubernetes/test/e2e/framework/util.go index 011cf6713..7213c313b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/util.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/util.go @@ -146,7 +146,7 @@ var ( var RunID = uuid.NewUUID() // CreateTestingNSFn is a func that is responsible for creating namespace used for executing e2e tests. -type CreateTestingNSFn func(baseName string, c clientset.Interface, labels map[string]string) (*v1.Namespace, error) +type CreateTestingNSFn func(ctx context.Context, baseName string, c clientset.Interface, labels map[string]string) (*v1.Namespace, error) // APIAddress returns a address of an instance. func APIAddress() string { @@ -198,9 +198,9 @@ func NodeOSArchIs(supportedNodeOsArchs ...string) bool { // DeleteNamespaces deletes all namespaces that match the given delete and skip filters. // Filter is by simple strings.Contains; first skip filter, then delete filter. // Returns the list of deleted namespaces or an error. -func DeleteNamespaces(c clientset.Interface, deleteFilter, skipFilter []string) ([]string, error) { +func DeleteNamespaces(ctx context.Context, c clientset.Interface, deleteFilter, skipFilter []string) ([]string, error) { ginkgo.By("Deleting namespaces") - nsList, err := c.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + nsList, err := c.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) ExpectNoError(err, "Failed to get namespace list") var deleted []string var wg sync.WaitGroup @@ -228,7 +228,7 @@ OUTER: go func(nsName string) { defer wg.Done() defer ginkgo.GinkgoRecover() - gomega.Expect(c.CoreV1().Namespaces().Delete(context.TODO(), nsName, metav1.DeleteOptions{})).To(gomega.Succeed()) + gomega.Expect(c.CoreV1().Namespaces().Delete(ctx, nsName, metav1.DeleteOptions{})).To(gomega.Succeed()) Logf("namespace : %v api call to delete is complete ", nsName) }(item.Name) } @@ -237,16 +237,16 @@ OUTER: } // WaitForNamespacesDeleted waits for the namespaces to be deleted. -func WaitForNamespacesDeleted(c clientset.Interface, namespaces []string, timeout time.Duration) error { +func WaitForNamespacesDeleted(ctx context.Context, c clientset.Interface, namespaces []string, timeout time.Duration) error { ginkgo.By(fmt.Sprintf("Waiting for namespaces %+v to vanish", namespaces)) nsMap := map[string]bool{} for _, ns := range namespaces { nsMap[ns] = true } //Now POLL until all namespaces have been eradicated. - return wait.Poll(2*time.Second, timeout, - func() (bool, error) { - nsList, err := c.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + return wait.PollWithContext(ctx, 2*time.Second, timeout, + func(ctx context.Context) (bool, error) { + nsList, err := c.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) if err != nil { return false, err } @@ -259,20 +259,20 @@ func WaitForNamespacesDeleted(c clientset.Interface, namespaces []string, timeou }) } -func waitForConfigMapInNamespace(c clientset.Interface, ns, name string, timeout time.Duration) error { +func waitForConfigMapInNamespace(ctx context.Context, c clientset.Interface, ns, name string, timeout time.Duration) error { fieldSelector := fields.OneTermEqualSelector("metadata.name", name).String() + ctx, cancel := watchtools.ContextWithOptionalTimeout(ctx, timeout) + defer cancel() lw := &cache.ListWatch{ ListFunc: func(options metav1.ListOptions) (object runtime.Object, e error) { options.FieldSelector = fieldSelector - return c.CoreV1().ConfigMaps(ns).List(context.TODO(), options) + return c.CoreV1().ConfigMaps(ns).List(ctx, options) }, WatchFunc: func(options metav1.ListOptions) (i watch.Interface, e error) { options.FieldSelector = fieldSelector - return c.CoreV1().ConfigMaps(ns).Watch(context.TODO(), options) + return c.CoreV1().ConfigMaps(ns).Watch(ctx, options) }, } - ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout) - defer cancel() _, err := watchtools.UntilWithSync(ctx, lw, &v1.ConfigMap{}, nil, func(event watch.Event) (bool, error) { switch event.Type { case watch.Deleted: @@ -285,20 +285,20 @@ func waitForConfigMapInNamespace(c clientset.Interface, ns, name string, timeout return err } -func waitForServiceAccountInNamespace(c clientset.Interface, ns, serviceAccountName string, timeout time.Duration) error { +func waitForServiceAccountInNamespace(ctx context.Context, c clientset.Interface, ns, serviceAccountName string, timeout time.Duration) error { fieldSelector := fields.OneTermEqualSelector("metadata.name", serviceAccountName).String() + ctx, cancel := watchtools.ContextWithOptionalTimeout(ctx, timeout) + defer cancel() lw := &cache.ListWatch{ ListFunc: func(options metav1.ListOptions) (object runtime.Object, e error) { options.FieldSelector = fieldSelector - return c.CoreV1().ServiceAccounts(ns).List(context.TODO(), options) + return c.CoreV1().ServiceAccounts(ns).List(ctx, options) }, WatchFunc: func(options metav1.ListOptions) (i watch.Interface, e error) { options.FieldSelector = fieldSelector - return c.CoreV1().ServiceAccounts(ns).Watch(context.TODO(), options) + return c.CoreV1().ServiceAccounts(ns).Watch(ctx, options) }, } - ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout) - defer cancel() _, err := watchtools.UntilWithSync(ctx, lw, &v1.ServiceAccount{}, nil, func(event watch.Event) (bool, error) { switch event.Type { case watch.Deleted: @@ -317,20 +317,20 @@ func waitForServiceAccountInNamespace(c clientset.Interface, ns, serviceAccountN // WaitForDefaultServiceAccountInNamespace waits for the default service account to be provisioned // the default service account is what is associated with pods when they do not specify a service account // as a result, pods are not able to be provisioned in a namespace until the service account is provisioned -func WaitForDefaultServiceAccountInNamespace(c clientset.Interface, namespace string) error { - return waitForServiceAccountInNamespace(c, namespace, "default", ServiceAccountProvisionTimeout) +func WaitForDefaultServiceAccountInNamespace(ctx context.Context, c clientset.Interface, namespace string) error { + return waitForServiceAccountInNamespace(ctx, c, namespace, defaultServiceAccountName, ServiceAccountProvisionTimeout) } // WaitForKubeRootCAInNamespace waits for the configmap kube-root-ca.crt containing the service account // CA trust bundle to be provisioned in the specified namespace so that pods do not have to retry mounting // the config map (which creates noise that hides other issues in the Kubelet). -func WaitForKubeRootCAInNamespace(c clientset.Interface, namespace string) error { - return waitForConfigMapInNamespace(c, namespace, "kube-root-ca.crt", ServiceAccountProvisionTimeout) +func WaitForKubeRootCAInNamespace(ctx context.Context, c clientset.Interface, namespace string) error { + return waitForConfigMapInNamespace(ctx, c, namespace, "kube-root-ca.crt", ServiceAccountProvisionTimeout) } // CreateTestingNS should be used by every test, note that we append a common prefix to the provided test name. // Please see NewFramework instead of using this directly. -func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]string) (*v1.Namespace, error) { +func CreateTestingNS(ctx context.Context, baseName string, c clientset.Interface, labels map[string]string) (*v1.Namespace, error) { if labels == nil { labels = map[string]string{} } @@ -351,9 +351,9 @@ func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]s } // Be robust about making the namespace creation call. var got *v1.Namespace - if err := wait.PollImmediate(Poll, 30*time.Second, func() (bool, error) { + if err := wait.PollImmediateWithContext(ctx, Poll, 30*time.Second, func(ctx context.Context) (bool, error) { var err error - got, err = c.CoreV1().Namespaces().Create(context.TODO(), namespaceObj, metav1.CreateOptions{}) + got, err = c.CoreV1().Namespaces().Create(ctx, namespaceObj, metav1.CreateOptions{}) if err != nil { if apierrors.IsAlreadyExists(err) { // regenerate on conflict @@ -370,7 +370,7 @@ func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]s } if TestContext.VerifyServiceAccount { - if err := WaitForDefaultServiceAccountInNamespace(c, got.Name); err != nil { + if err := WaitForDefaultServiceAccountInNamespace(ctx, c, got.Name); err != nil { // Even if we fail to create serviceAccount in the namespace, // we have successfully create a namespace. // So, return the created namespace. @@ -382,7 +382,7 @@ func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]s // CheckTestingNSDeletedExcept checks whether all e2e based existing namespaces are in the Terminating state // and waits until they are finally deleted. It ignores namespace skip. -func CheckTestingNSDeletedExcept(c clientset.Interface, skip string) error { +func CheckTestingNSDeletedExcept(ctx context.Context, c clientset.Interface, skip string) error { // TODO: Since we don't have support for bulk resource deletion in the API, // while deleting a namespace we are deleting all objects from that namespace // one by one (one deletion == one API call). This basically exposes us to @@ -398,7 +398,7 @@ func CheckTestingNSDeletedExcept(c clientset.Interface, skip string) error { Logf("Waiting for terminating namespaces to be deleted...") for start := time.Now(); time.Since(start) < timeout; time.Sleep(15 * time.Second) { - namespaces, err := c.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + namespaces, err := c.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) if err != nil { Logf("Listing namespaces failed: %v", err) continue @@ -420,10 +420,10 @@ func CheckTestingNSDeletedExcept(c clientset.Interface, skip string) error { } // WaitForServiceEndpointsNum waits until the amount of endpoints that implement service to expectNum. -func WaitForServiceEndpointsNum(c clientset.Interface, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error { - return wait.Poll(interval, timeout, func() (bool, error) { +func WaitForServiceEndpointsNum(ctx context.Context, c clientset.Interface, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error { + return wait.PollWithContext(ctx, interval, timeout, func(ctx context.Context) (bool, error) { Logf("Waiting for amount of service:%s endpoints to be %d", serviceName, expectNum) - list, err := c.CoreV1().Endpoints(namespace).List(context.TODO(), metav1.ListOptions{}) + list, err := c.CoreV1().Endpoints(namespace).List(ctx, metav1.ListOptions{}) if err != nil { return false, err } @@ -547,8 +547,8 @@ func TryKill(cmd *exec.Cmd) { // EnsureLoadBalancerResourcesDeleted ensures that cloud load balancer resources that were created // are actually cleaned up. Currently only implemented for GCE/GKE. -func EnsureLoadBalancerResourcesDeleted(ip, portRange string) error { - return TestContext.CloudConfig.Provider.EnsureLoadBalancerResourcesDeleted(ip, portRange) +func EnsureLoadBalancerResourcesDeleted(ctx context.Context, ip, portRange string) error { + return TestContext.CloudConfig.Provider.EnsureLoadBalancerResourcesDeleted(ctx, ip, portRange) } // CoreDump SSHs to the master and all nodes and dumps their logs into dir. @@ -613,11 +613,11 @@ func RunCmdEnv(env []string, command string, args ...string) (string, string, er // getControlPlaneAddresses returns the externalIP, internalIP and hostname fields of control plane nodes. // If any of these is unavailable, empty slices are returned. -func getControlPlaneAddresses(c clientset.Interface) ([]string, []string, []string) { +func getControlPlaneAddresses(ctx context.Context, c clientset.Interface) ([]string, []string, []string) { var externalIPs, internalIPs, hostnames []string // Populate the internal IPs. - eps, err := c.CoreV1().Endpoints(metav1.NamespaceDefault).Get(context.TODO(), "kubernetes", metav1.GetOptions{}) + eps, err := c.CoreV1().Endpoints(metav1.NamespaceDefault).Get(ctx, "kubernetes", metav1.GetOptions{}) if err != nil { Failf("Failed to get kubernetes endpoints: %v", err) } @@ -647,8 +647,8 @@ func getControlPlaneAddresses(c clientset.Interface) ([]string, []string, []stri // It may return internal and external IPs, even if we expect for // e.g. internal IPs to be used (issue #56787), so that we can be // sure to block the control plane fully during tests. -func GetControlPlaneAddresses(c clientset.Interface) []string { - externalIPs, internalIPs, _ := getControlPlaneAddresses(c) +func GetControlPlaneAddresses(ctx context.Context, c clientset.Interface) []string { + externalIPs, internalIPs, _ := getControlPlaneAddresses(ctx, c) ips := sets.NewString() switch TestContext.Provider { @@ -685,7 +685,7 @@ func PrettyPrintJSON(metrics interface{}) string { // WatchEventSequenceVerifier ... // manages a watch for a given resource, ensures that events take place in a given order, retries the test on failure // -// testContext cancellation signal across API boundaries, e.g: context.TODO() +// ctx cancellation signal across API boundaries, e.g: context from Ginkgo // dc sets up a client to the API // resourceType specify the type of resource // namespace select a namespace diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/volume/.import-restrictions b/vendor/k8s.io/kubernetes/test/e2e/framework/volume/.import-restrictions new file mode 100644 index 000000000..fdd90e600 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/volume/.import-restrictions @@ -0,0 +1,9 @@ +# This E2E framework sub-package is currently allowed to use arbitrary +# dependencies, therefore we need to override the restrictions from +# the parent .import-restrictions file. +# +# At some point it may become useful to also check this package's +# dependencies more careful. +rules: + - selectorRegexp: "" + allowedPrefixes: [ "" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go b/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go index 1249c5086..031a187ab 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/volume/fixtures.go @@ -51,7 +51,6 @@ import ( v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" clientexec "k8s.io/client-go/util/exec" @@ -149,7 +148,11 @@ type Test struct { } // NewNFSServer is a NFS-specific wrapper for CreateStorageServer. -func NewNFSServer(cs clientset.Interface, namespace string, args []string) (config TestConfig, pod *v1.Pod, host string) { +func NewNFSServer(ctx context.Context, cs clientset.Interface, namespace string, args []string) (config TestConfig, pod *v1.Pod, host string) { + return NewNFSServerWithNodeName(ctx, cs, namespace, args, "") +} + +func NewNFSServerWithNodeName(ctx context.Context, cs clientset.Interface, namespace string, args []string, nodeName string) (config TestConfig, pod *v1.Pod, host string) { config = TestConfig{ Namespace: namespace, Prefix: "nfs", @@ -158,10 +161,14 @@ func NewNFSServer(cs clientset.Interface, namespace string, args []string) (conf ServerVolumes: map[string]string{"": "/exports"}, ServerReadyMessage: "NFS started", } + if nodeName != "" { + config.ClientNodeSelection = e2epod.NodeSelection{Name: nodeName} + } + if len(args) > 0 { config.ServerArgs = args } - pod, host = CreateStorageServer(cs, config) + pod, host = CreateStorageServer(ctx, cs, config) if strings.Contains(host, ":") { host = "[" + host + "]" } @@ -171,18 +178,18 @@ func NewNFSServer(cs clientset.Interface, namespace string, args []string) (conf // CreateStorageServer is a wrapper for startVolumeServer(). A storage server config is passed in, and a pod pointer // and ip address string are returned. // Note: Expect() is called so no error is returned. -func CreateStorageServer(cs clientset.Interface, config TestConfig) (pod *v1.Pod, ip string) { - pod = startVolumeServer(cs, config) +func CreateStorageServer(ctx context.Context, cs clientset.Interface, config TestConfig) (pod *v1.Pod, ip string) { + pod = startVolumeServer(ctx, cs, config) gomega.Expect(pod).NotTo(gomega.BeNil(), "storage server pod should not be nil") ip = pod.Status.PodIP - gomega.Expect(len(ip)).NotTo(gomega.BeZero(), fmt.Sprintf("pod %s's IP should not be empty", pod.Name)) + gomega.Expect(ip).NotTo(gomega.BeEmpty(), fmt.Sprintf("pod %s's IP should not be empty", pod.Name)) framework.Logf("%s server pod IP address: %s", config.Prefix, ip) return pod, ip } // GetVolumeAttachmentName returns the hash value of the provisioner, the config ClientNodeSelection name, // and the VolumeAttachment name of the PV that is bound to the PVC with the passed in claimName and claimNamespace. -func GetVolumeAttachmentName(cs clientset.Interface, config TestConfig, provisioner string, claimName string, claimNamespace string) string { +func GetVolumeAttachmentName(ctx context.Context, cs clientset.Interface, config TestConfig, provisioner string, claimName string, claimNamespace string) string { var nodeName string // For provisioning tests, ClientNodeSelection is not set so we do not know the NodeName of the VolumeAttachment of the PV that is // bound to the PVC with the passed in claimName and claimNamespace. We need this NodeName because it is used to generate the @@ -190,9 +197,9 @@ func GetVolumeAttachmentName(cs clientset.Interface, config TestConfig, provisio // To get the nodeName of the VolumeAttachment, we get all the VolumeAttachments, look for the VolumeAttachment with a // PersistentVolumeName equal to the PV that is bound to the passed in PVC, and then we get the NodeName from that VolumeAttachment. if config.ClientNodeSelection.Name == "" { - claim, _ := cs.CoreV1().PersistentVolumeClaims(claimNamespace).Get(context.TODO(), claimName, metav1.GetOptions{}) + claim, _ := cs.CoreV1().PersistentVolumeClaims(claimNamespace).Get(ctx, claimName, metav1.GetOptions{}) pvName := claim.Spec.VolumeName - volumeAttachments, _ := cs.StorageV1().VolumeAttachments().List(context.TODO(), metav1.ListOptions{}) + volumeAttachments, _ := cs.StorageV1().VolumeAttachments().List(ctx, metav1.ListOptions{}) for _, volumeAttachment := range volumeAttachments.Items { if *volumeAttachment.Spec.Source.PersistentVolumeName == pvName { nodeName = volumeAttachment.Spec.NodeName @@ -202,21 +209,21 @@ func GetVolumeAttachmentName(cs clientset.Interface, config TestConfig, provisio } else { nodeName = config.ClientNodeSelection.Name } - handle := getVolumeHandle(cs, claimName, claimNamespace) + handle := getVolumeHandle(ctx, cs, claimName, claimNamespace) attachmentHash := sha256.Sum256([]byte(fmt.Sprintf("%s%s%s", handle, provisioner, nodeName))) return fmt.Sprintf("csi-%x", attachmentHash) } // getVolumeHandle returns the VolumeHandle of the PV that is bound to the PVC with the passed in claimName and claimNamespace. -func getVolumeHandle(cs clientset.Interface, claimName string, claimNamespace string) string { +func getVolumeHandle(ctx context.Context, cs clientset.Interface, claimName string, claimNamespace string) string { // re-get the claim to the latest state with bound volume - claim, err := cs.CoreV1().PersistentVolumeClaims(claimNamespace).Get(context.TODO(), claimName, metav1.GetOptions{}) + claim, err := cs.CoreV1().PersistentVolumeClaims(claimNamespace).Get(ctx, claimName, metav1.GetOptions{}) if err != nil { framework.ExpectNoError(err, "Cannot get PVC") return "" } pvName := claim.Spec.VolumeName - pv, err := cs.CoreV1().PersistentVolumes().Get(context.TODO(), pvName, metav1.GetOptions{}) + pv, err := cs.CoreV1().PersistentVolumes().Get(ctx, pvName, metav1.GetOptions{}) if err != nil { framework.ExpectNoError(err, "Cannot get PV") return "" @@ -229,9 +236,9 @@ func getVolumeHandle(cs clientset.Interface, claimName string, claimNamespace st } // WaitForVolumeAttachmentTerminated waits for the VolumeAttachment with the passed in attachmentName to be terminated. -func WaitForVolumeAttachmentTerminated(attachmentName string, cs clientset.Interface, timeout time.Duration) error { - waitErr := wait.PollImmediate(10*time.Second, timeout, func() (bool, error) { - _, err := cs.StorageV1().VolumeAttachments().Get(context.TODO(), attachmentName, metav1.GetOptions{}) +func WaitForVolumeAttachmentTerminated(ctx context.Context, attachmentName string, cs clientset.Interface, timeout time.Duration) error { + waitErr := wait.PollImmediateWithContext(ctx, 10*time.Second, timeout, func(ctx context.Context) (bool, error) { + _, err := cs.StorageV1().VolumeAttachments().Get(ctx, attachmentName, metav1.GetOptions{}) if err != nil { // if the volumeattachment object is not found, it means it has been terminated. if apierrors.IsNotFound(err) { @@ -250,7 +257,7 @@ func WaitForVolumeAttachmentTerminated(attachmentName string, cs clientset.Inter // startVolumeServer starts a container specified by config.serverImage and exports all // config.serverPorts from it. The returned pod should be used to get the server // IP address and create appropriate VolumeSource. -func startVolumeServer(client clientset.Interface, config TestConfig) *v1.Pod { +func startVolumeServer(ctx context.Context, client clientset.Interface, config TestConfig) *v1.Pod { podClient := client.CoreV1().Pods(config.Namespace) portCount := len(config.ServerPorts) @@ -330,14 +337,18 @@ func startVolumeServer(client clientset.Interface, config TestConfig) *v1.Pod { }, } + if config.ClientNodeSelection.Name != "" { + serverPod.Spec.NodeName = config.ClientNodeSelection.Name + } + var pod *v1.Pod - serverPod, err := podClient.Create(context.TODO(), serverPod, metav1.CreateOptions{}) + serverPod, err := podClient.Create(ctx, serverPod, metav1.CreateOptions{}) // ok if the server pod already exists. TODO: make this controllable by callers if err != nil { if apierrors.IsAlreadyExists(err) { framework.Logf("Ignore \"already-exists\" error, re-get pod...") ginkgo.By(fmt.Sprintf("re-getting the %q server pod", serverPodName)) - serverPod, err = podClient.Get(context.TODO(), serverPodName, metav1.GetOptions{}) + serverPod, err = podClient.Get(ctx, serverPodName, metav1.GetOptions{}) framework.ExpectNoError(err, "Cannot re-get the server pod %q: %v", serverPodName, err) pod = serverPod } else { @@ -345,25 +356,25 @@ func startVolumeServer(client clientset.Interface, config TestConfig) *v1.Pod { } } if config.WaitForCompletion { - framework.ExpectNoError(e2epod.WaitForPodSuccessInNamespace(client, serverPod.Name, serverPod.Namespace)) - framework.ExpectNoError(podClient.Delete(context.TODO(), serverPod.Name, metav1.DeleteOptions{})) + framework.ExpectNoError(e2epod.WaitForPodSuccessInNamespace(ctx, client, serverPod.Name, serverPod.Namespace)) + framework.ExpectNoError(podClient.Delete(ctx, serverPod.Name, metav1.DeleteOptions{})) } else { - framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(client, serverPod)) + framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, client, serverPod)) if pod == nil { ginkgo.By(fmt.Sprintf("locating the %q server pod", serverPodName)) - pod, err = podClient.Get(context.TODO(), serverPodName, metav1.GetOptions{}) + pod, err = podClient.Get(ctx, serverPodName, metav1.GetOptions{}) framework.ExpectNoError(err, "Cannot locate the server pod %q: %v", serverPodName, err) } } if config.ServerReadyMessage != "" { - _, err := e2epodoutput.LookForStringInLog(pod.Namespace, pod.Name, serverPodName, config.ServerReadyMessage, VolumeServerPodStartupTimeout) + _, err := e2epodoutput.LookForStringInLogWithoutKubectl(ctx, client, pod.Namespace, pod.Name, serverPodName, config.ServerReadyMessage, VolumeServerPodStartupTimeout) framework.ExpectNoError(err, "Failed to find %q in pod logs: %s", config.ServerReadyMessage, err) } return pod } // TestServerCleanup cleans server pod. -func TestServerCleanup(f *framework.Framework, config TestConfig) { +func TestServerCleanup(ctx context.Context, f *framework.Framework, config TestConfig) { ginkgo.By(fmt.Sprint("cleaning the environment after ", config.Prefix)) defer ginkgo.GinkgoRecover() @@ -371,11 +382,11 @@ func TestServerCleanup(f *framework.Framework, config TestConfig) { return } - err := e2epod.DeletePodWithWaitByName(f.ClientSet, config.Prefix+"-server", config.Namespace) - gomega.Expect(err).To(gomega.BeNil(), "Failed to delete pod %v in namespace %v", config.Prefix+"-server", config.Namespace) + err := e2epod.DeletePodWithWaitByName(ctx, f.ClientSet, config.Prefix+"-server", config.Namespace) + framework.ExpectNoError(err, "delete pod %v in namespace %v", config.Prefix+"-server", config.Namespace) } -func runVolumeTesterPod(client clientset.Interface, timeouts *framework.TimeoutContext, config TestConfig, podSuffix string, privileged bool, fsGroup *int64, tests []Test, slow bool) (*v1.Pod, error) { +func runVolumeTesterPod(ctx context.Context, client clientset.Interface, timeouts *framework.TimeoutContext, config TestConfig, podSuffix string, privileged bool, fsGroup *int64, tests []Test, slow bool) (*v1.Pod, error) { ginkgo.By(fmt.Sprint("starting ", config.Prefix, "-", podSuffix)) var gracePeriod int64 = 1 var command string @@ -453,18 +464,18 @@ func runVolumeTesterPod(client clientset.Interface, timeouts *framework.TimeoutC }) } podsNamespacer := client.CoreV1().Pods(config.Namespace) - clientPod, err := podsNamespacer.Create(context.TODO(), clientPod, metav1.CreateOptions{}) + clientPod, err := podsNamespacer.Create(ctx, clientPod, metav1.CreateOptions{}) if err != nil { return nil, err } if slow { - err = e2epod.WaitTimeoutForPodRunningInNamespace(client, clientPod.Name, clientPod.Namespace, timeouts.PodStartSlow) + err = e2epod.WaitTimeoutForPodRunningInNamespace(ctx, client, clientPod.Name, clientPod.Namespace, timeouts.PodStartSlow) } else { - err = e2epod.WaitTimeoutForPodRunningInNamespace(client, clientPod.Name, clientPod.Namespace, timeouts.PodStart) + err = e2epod.WaitTimeoutForPodRunningInNamespace(ctx, client, clientPod.Name, clientPod.Namespace, timeouts.PodStart) } if err != nil { - e2epod.DeletePodOrFail(client, clientPod.Namespace, clientPod.Name) - e2epod.WaitForPodToDisappear(client, clientPod.Namespace, clientPod.Name, labels.Everything(), framework.Poll, timeouts.PodDelete) + e2epod.DeletePodOrFail(ctx, client, clientPod.Namespace, clientPod.Name) + _ = e2epod.WaitForPodNotFoundInNamespace(ctx, client, clientPod.Name, clientPod.Namespace, timeouts.PodDelete) return nil, err } return clientPod, nil @@ -519,8 +530,8 @@ func testVolumeContent(f *framework.Framework, pod *v1.Pod, containerName string // Timeout for dynamic provisioning (if "WaitForFirstConsumer" is set && provided PVC is not bound yet), // pod creation, scheduling and complete pod startup (incl. volume attach & mount) is pod.podStartTimeout. // It should be used for cases where "regular" dynamic provisioning of an empty volume is requested. -func TestVolumeClient(f *framework.Framework, config TestConfig, fsGroup *int64, fsType string, tests []Test) { - testVolumeClient(f, config, fsGroup, fsType, tests, false) +func TestVolumeClient(ctx context.Context, f *framework.Framework, config TestConfig, fsGroup *int64, fsType string, tests []Test) { + testVolumeClient(ctx, f, config, fsGroup, fsType, tests, false) } // TestVolumeClientSlow is the same as TestVolumeClient except for its timeout. @@ -528,19 +539,21 @@ func TestVolumeClient(f *framework.Framework, config TestConfig, fsGroup *int64, // pod creation, scheduling and complete pod startup (incl. volume attach & mount) is pod.slowPodStartTimeout. // It should be used for cases where "special" dynamic provisioning is requested, such as volume cloning // or snapshot restore. -func TestVolumeClientSlow(f *framework.Framework, config TestConfig, fsGroup *int64, fsType string, tests []Test) { - testVolumeClient(f, config, fsGroup, fsType, tests, true) +func TestVolumeClientSlow(ctx context.Context, f *framework.Framework, config TestConfig, fsGroup *int64, fsType string, tests []Test) { + testVolumeClient(ctx, f, config, fsGroup, fsType, tests, true) } -func testVolumeClient(f *framework.Framework, config TestConfig, fsGroup *int64, fsType string, tests []Test, slow bool) { +func testVolumeClient(ctx context.Context, f *framework.Framework, config TestConfig, fsGroup *int64, fsType string, tests []Test, slow bool) { timeouts := f.Timeouts - clientPod, err := runVolumeTesterPod(f.ClientSet, timeouts, config, "client", false, fsGroup, tests, slow) + clientPod, err := runVolumeTesterPod(ctx, f.ClientSet, timeouts, config, "client", false, fsGroup, tests, slow) if err != nil { framework.Failf("Failed to create client pod: %v", err) } defer func() { - e2epod.DeletePodOrFail(f.ClientSet, clientPod.Namespace, clientPod.Name) - e2epod.WaitForPodToDisappear(f.ClientSet, clientPod.Namespace, clientPod.Name, labels.Everything(), framework.Poll, timeouts.PodDelete) + // testVolumeClient might get used more than once per test, therefore + // we have to clean up before returning. + e2epod.DeletePodOrFail(ctx, f.ClientSet, clientPod.Namespace, clientPod.Name) + framework.ExpectNoError(e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, clientPod.Name, clientPod.Namespace, timeouts.PodDelete)) }() testVolumeContent(f, clientPod, "", fsGroup, fsType, tests) @@ -551,7 +564,7 @@ func testVolumeClient(f *framework.Framework, config TestConfig, fsGroup *int64, } ec.Resources = v1.ResourceRequirements{} ec.Name = "volume-ephemeral-container" - err = e2epod.NewPodClient(f).AddEphemeralContainerSync(clientPod, ec, timeouts.PodStart) + err = e2epod.NewPodClient(f).AddEphemeralContainerSync(ctx, clientPod, ec, timeouts.PodStart) // The API server will return NotFound for the subresource when the feature is disabled framework.ExpectNoError(err, "failed to add ephemeral container for re-test") testVolumeContent(f, clientPod, ec.Name, fsGroup, fsType, tests) @@ -560,20 +573,22 @@ func testVolumeClient(f *framework.Framework, config TestConfig, fsGroup *int64, // InjectContent inserts index.html with given content into given volume. It does so by // starting and auxiliary pod which writes the file there. // The volume must be writable. -func InjectContent(f *framework.Framework, config TestConfig, fsGroup *int64, fsType string, tests []Test) { +func InjectContent(ctx context.Context, f *framework.Framework, config TestConfig, fsGroup *int64, fsType string, tests []Test) { privileged := true timeouts := f.Timeouts if framework.NodeOSDistroIs("windows") { privileged = false } - injectorPod, err := runVolumeTesterPod(f.ClientSet, timeouts, config, "injector", privileged, fsGroup, tests, false /*slow*/) + injectorPod, err := runVolumeTesterPod(ctx, f.ClientSet, timeouts, config, "injector", privileged, fsGroup, tests, false /*slow*/) if err != nil { framework.Failf("Failed to create injector pod: %v", err) return } defer func() { - e2epod.DeletePodOrFail(f.ClientSet, injectorPod.Namespace, injectorPod.Name) - e2epod.WaitForPodToDisappear(f.ClientSet, injectorPod.Namespace, injectorPod.Name, labels.Everything(), framework.Poll, timeouts.PodDelete) + // This pod must get deleted before the function returns becaue the test relies on + // the volume not being in use. + e2epod.DeletePodOrFail(ctx, f.ClientSet, injectorPod.Namespace, injectorPod.Name) + framework.ExpectNoError(e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, injectorPod.Name, injectorPod.Namespace, timeouts.PodDelete)) }() ginkgo.By("Writing text file contents in the container.") diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go index d8424cb62..c3fb6b369 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go @@ -23,12 +23,13 @@ import ( "errors" "fmt" + "github.com/onsi/ginkgo/v2" + appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" storagev1 "k8s.io/api/storage/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -49,7 +50,7 @@ import ( // // LoadFromManifests has some limitations: // - aliases are not supported (i.e. use serviceAccountName instead of the deprecated serviceAccount, -// https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#podspec-v1-core) +// https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1) // and silently ignored // - the latest stable API version for each item is used, regardless of what // is specified in the manifest files @@ -140,21 +141,7 @@ func PatchItems(f *framework.Framework, driverNamespace *v1.Namespace, items ... // PatchItems has the some limitations as LoadFromManifests: // - only some common items are supported, unknown ones trigger an error // - only the latest stable API version for each item is supported -func CreateItems(f *framework.Framework, ns *v1.Namespace, items ...interface{}) (func(), error) { - var destructors []func() error - cleanup := func() { - // TODO (?): use same logic as framework.go for determining - // whether we are expected to clean up? This would change the - // meaning of the -delete-namespace and -delete-namespace-on-failure - // command line flags, because they would also start to apply - // to non-namespaced items. - for _, destructor := range destructors { - if err := destructor(); err != nil && !apierrors.IsNotFound(err) { - framework.Logf("deleting failed: %s", err) - } - } - } - +func CreateItems(ctx context.Context, f *framework.Framework, ns *v1.Namespace, items ...interface{}) error { var result error for _, item := range items { // Each factory knows which item(s) it supports, so try each one. @@ -164,12 +151,9 @@ func CreateItems(f *framework.Framework, ns *v1.Namespace, items ...interface{}) // description = fmt.Sprintf("%s:\n%s", description, PrettyPrint(item)) framework.Logf("creating %s", description) for _, factory := range factories { - destructor, err := factory.Create(f, ns, item) + destructor, err := factory.Create(ctx, f, ns, item) if destructor != nil { - destructors = append(destructors, func() error { - framework.Logf("deleting %s", description) - return destructor() - }) + ginkgo.DeferCleanup(framework.IgnoreNotFound(destructor), framework.AnnotatedLocation(fmt.Sprintf("deleting %s", description))) } if err == nil { done = true @@ -185,33 +169,28 @@ func CreateItems(f *framework.Framework, ns *v1.Namespace, items ...interface{}) } } - if result != nil { - cleanup() - return nil, result - } - - return cleanup, nil + return result } // CreateFromManifests is a combination of LoadFromManifests, // PatchItems, patching with an optional custom function, // and CreateItems. -func CreateFromManifests(f *framework.Framework, driverNamespace *v1.Namespace, patch func(item interface{}) error, files ...string) (func(), error) { +func CreateFromManifests(ctx context.Context, f *framework.Framework, driverNamespace *v1.Namespace, patch func(item interface{}) error, files ...string) error { items, err := LoadFromManifests(files...) if err != nil { - return nil, fmt.Errorf("CreateFromManifests: %w", err) + return fmt.Errorf("CreateFromManifests: %w", err) } if err := PatchItems(f, driverNamespace, items...); err != nil { - return nil, err + return err } if patch != nil { for _, item := range items { if err := patch(item); err != nil { - return nil, err + return err } } } - return CreateItems(f, driverNamespace, items...) + return CreateItems(ctx, f, driverNamespace, items...) } // What is a subset of metav1.TypeMeta which (in contrast to @@ -251,7 +230,7 @@ type ItemFactory interface { // error or a cleanup function for the created item. // If the item is of an unsupported type, it must return // an error that has errorItemNotSupported as cause. - Create(f *framework.Framework, ns *v1.Namespace, item interface{}) (func() error, error) + Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, item interface{}) (func(ctx context.Context) error, error) } // describeItem always returns a string that describes the item, @@ -410,17 +389,17 @@ func (f *serviceAccountFactory) New() runtime.Object { return &v1.ServiceAccount{} } -func (*serviceAccountFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*serviceAccountFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*v1.ServiceAccount) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.CoreV1().ServiceAccounts(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create ServiceAccount: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -430,7 +409,7 @@ func (f *clusterRoleFactory) New() runtime.Object { return &rbacv1.ClusterRole{} } -func (*clusterRoleFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*clusterRoleFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*rbacv1.ClusterRole) if !ok { return nil, errorItemNotSupported @@ -438,11 +417,11 @@ func (*clusterRoleFactory) Create(f *framework.Framework, ns *v1.Namespace, i in framework.Logf("Define cluster role %v", item.GetName()) client := f.ClientSet.RbacV1().ClusterRoles() - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create ClusterRole: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -452,18 +431,18 @@ func (f *clusterRoleBindingFactory) New() runtime.Object { return &rbacv1.ClusterRoleBinding{} } -func (*clusterRoleBindingFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*clusterRoleBindingFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*rbacv1.ClusterRoleBinding) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.RbacV1().ClusterRoleBindings() - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create ClusterRoleBinding: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -473,18 +452,18 @@ func (f *roleFactory) New() runtime.Object { return &rbacv1.Role{} } -func (*roleFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*roleFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*rbacv1.Role) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.RbacV1().Roles(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create Role: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -494,18 +473,18 @@ func (f *roleBindingFactory) New() runtime.Object { return &rbacv1.RoleBinding{} } -func (*roleBindingFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*roleBindingFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*rbacv1.RoleBinding) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.RbacV1().RoleBindings(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create RoleBinding: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -515,18 +494,18 @@ func (f *serviceFactory) New() runtime.Object { return &v1.Service{} } -func (*serviceFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*serviceFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*v1.Service) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.CoreV1().Services(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create Service: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -536,18 +515,18 @@ func (f *statefulSetFactory) New() runtime.Object { return &appsv1.StatefulSet{} } -func (*statefulSetFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*statefulSetFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*appsv1.StatefulSet) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.AppsV1().StatefulSets(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create StatefulSet: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -557,18 +536,18 @@ func (f *deploymentFactory) New() runtime.Object { return &appsv1.Deployment{} } -func (*deploymentFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*deploymentFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*appsv1.Deployment) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.AppsV1().Deployments(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create Deployment: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -578,18 +557,18 @@ func (f *daemonSetFactory) New() runtime.Object { return &appsv1.DaemonSet{} } -func (*daemonSetFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*daemonSetFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*appsv1.DaemonSet) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.AppsV1().DaemonSets(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create DaemonSet: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -599,18 +578,18 @@ func (f *replicaSetFactory) New() runtime.Object { return &appsv1.ReplicaSet{} } -func (*replicaSetFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*replicaSetFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*appsv1.ReplicaSet) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.AppsV1().ReplicaSets(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create ReplicaSet: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -620,18 +599,18 @@ func (f *storageClassFactory) New() runtime.Object { return &storagev1.StorageClass{} } -func (*storageClassFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*storageClassFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*storagev1.StorageClass) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.StorageV1().StorageClasses() - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create StorageClass: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -641,18 +620,18 @@ func (f *csiDriverFactory) New() runtime.Object { return &storagev1.CSIDriver{} } -func (*csiDriverFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*csiDriverFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*storagev1.CSIDriver) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.StorageV1().CSIDrivers() - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create CSIDriver: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -662,18 +641,18 @@ func (f *secretFactory) New() runtime.Object { return &v1.Secret{} } -func (*secretFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*secretFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { item, ok := i.(*v1.Secret) if !ok { return nil, errorItemNotSupported } client := f.ClientSet.CoreV1().Secrets(ns.Name) - if _, err := client.Create(context.TODO(), item, metav1.CreateOptions{}); err != nil { + if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create Secret: %w", err) } - return func() error { - return client.Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return client.Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } @@ -683,7 +662,7 @@ func (f *customResourceDefinitionFactory) New() runtime.Object { return &apiextensionsv1.CustomResourceDefinition{} } -func (*customResourceDefinitionFactory) Create(f *framework.Framework, ns *v1.Namespace, i interface{}) (func() error, error) { +func (*customResourceDefinitionFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { var err error unstructCRD := &unstructured.Unstructured{} gvr := schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"} @@ -698,11 +677,11 @@ func (*customResourceDefinitionFactory) Create(f *framework.Framework, ns *v1.Na return nil, err } - if _, err = f.DynamicClient.Resource(gvr).Create(context.TODO(), unstructCRD, metav1.CreateOptions{}); err != nil { + if _, err = f.DynamicClient.Resource(gvr).Create(ctx, unstructCRD, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create CustomResourceDefinition: %w", err) } - return func() error { - return f.DynamicClient.Resource(gvr).Delete(context.TODO(), item.GetName(), metav1.DeleteOptions{}) + return func(ctx context.Context) error { + return f.DynamicClient.Resource(gvr).Delete(ctx, item.GetName(), metav1.DeleteOptions{}) }, nil } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/deployment.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/deployment.go index 6e03e4070..f36905cf5 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/deployment.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/deployment.go @@ -17,6 +17,7 @@ limitations under the License. package utils import ( + "fmt" "path" "strings" @@ -94,6 +95,11 @@ func PatchCSIDeployment(f *e2eframework.Framework, o PatchCSIOptions, object int container.VolumeMounts[e].MountPath = substKubeletRootDir(container.VolumeMounts[e].MountPath) } + if len(o.Features) > 0 && len(o.Features[container.Name]) > 0 { + featuregateString := strings.Join(o.Features[container.Name], ",") + container.Args = append(container.Args, fmt.Sprintf("--feature-gates=%s", featuregateString)) + } + // Overwrite driver name resp. provider name // by appending a parameter with the right // value. @@ -218,4 +224,10 @@ type PatchCSIOptions struct { // field *if* the driver deploys a CSIDriver object. Ignored // otherwise. SELinuxMount *bool + // If not nil, the values will be used for setting feature arguments to + // specific sidecar. + // Feature is a map - where key is sidecar name such as: + // -- key: resizer + // -- value: []string{feature-gates} + Features map[string][]string } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/ebs.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/ebs.go deleted file mode 100644 index 39e223f36..000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/ebs.go +++ /dev/null @@ -1,263 +0,0 @@ -/* -Copyright 2020 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 utils - -import ( - "fmt" - "strings" - "time" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ec2" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/klog/v2" -) - -const ( - volumeAttachmentStatusPollDelay = 2 * time.Second - volumeAttachmentStatusFactor = 2 - volumeAttachmentStatusSteps = 6 - - // represents expected attachment status of a volume after attach - volumeAttachedStatus = "attached" - - // represents expected attachment status of a volume after detach - volumeDetachedStatus = "detached" -) - -// EBSUtil provides functions to interact with EBS volumes -type EBSUtil struct { - client *ec2.EC2 - validDevices []string -} - -// NewEBSUtil returns an instance of EBSUtil which can be used to -// to interact with EBS volumes -func NewEBSUtil(client *ec2.EC2) *EBSUtil { - ebsUtil := &EBSUtil{client: client} - validDevices := []string{} - for _, firstChar := range []rune{'b', 'c'} { - for i := 'a'; i <= 'z'; i++ { - dev := string([]rune{firstChar, i}) - validDevices = append(validDevices, dev) - } - } - ebsUtil.validDevices = validDevices - return ebsUtil -} - -// AttachDisk attaches an EBS volume to a node. -func (ebs *EBSUtil) AttachDisk(volumeID string, nodeName string) error { - instance, err := findInstanceByNodeName(nodeName, ebs.client) - if err != nil { - return fmt.Errorf("error finding node %s: %v", nodeName, err) - } - err = ebs.waitForAvailable(volumeID) - if err != nil { - return fmt.Errorf("error waiting volume %s to be available: %v", volumeID, err) - } - - device, err := ebs.findFreeDevice(instance) - if err != nil { - return fmt.Errorf("error finding free device on node %s: %v", nodeName, err) - } - hostDevice := "/dev/xvd" + string(device) - attachInput := &ec2.AttachVolumeInput{ - VolumeId: &volumeID, - InstanceId: instance.InstanceId, - Device: &hostDevice, - } - _, err = ebs.client.AttachVolume(attachInput) - if err != nil { - return fmt.Errorf("error attaching volume %s to node %s: %v", volumeID, nodeName, err) - } - return ebs.waitForAttach(volumeID) -} - -func (ebs *EBSUtil) findFreeDevice(instance *ec2.Instance) (string, error) { - deviceMappings := map[string]string{} - - for _, blockDevice := range instance.BlockDeviceMappings { - name := aws.StringValue(blockDevice.DeviceName) - name = strings.TrimPrefix(name, "/dev/sd") - name = strings.TrimPrefix(name, "/dev/xvd") - if len(name) < 1 || len(name) > 2 { - klog.Warningf("Unexpected EBS DeviceName: %q", aws.StringValue(blockDevice.DeviceName)) - } - - deviceMappings[name] = aws.StringValue(blockDevice.Ebs.VolumeId) - } - - for _, device := range ebs.validDevices { - if _, found := deviceMappings[device]; !found { - return device, nil - } - } - return "", fmt.Errorf("no available device") -} - -func (ebs *EBSUtil) waitForAttach(volumeID string) error { - backoff := wait.Backoff{ - Duration: volumeAttachmentStatusPollDelay, - Factor: volumeAttachmentStatusFactor, - Steps: volumeAttachmentStatusSteps, - } - time.Sleep(volumeAttachmentStatusPollDelay) - err := wait.ExponentialBackoff(backoff, func() (bool, error) { - info, err := ebs.describeVolume(volumeID) - if err != nil { - return false, err - } - - if len(info.Attachments) > 1 { - // Shouldn't happen; log so we know if it is - klog.Warningf("Found multiple attachments for volume %q: %v", volumeID, info) - } - attachmentStatus := "" - for _, a := range info.Attachments { - if attachmentStatus != "" { - // Shouldn't happen; log so we know if it is - klog.Warningf("Found multiple attachments for volume %q: %v", volumeID, info) - } - if a.State != nil { - attachmentStatus = *a.State - } else { - // Shouldn't happen; log so we know if it is - klog.Warningf("Ignoring nil attachment state for volume %q: %v", volumeID, a) - } - } - if attachmentStatus == "" { - attachmentStatus = volumeDetachedStatus - } - if attachmentStatus == volumeAttachedStatus { - // Attachment is in requested state, finish waiting - return true, nil - } - return false, nil - }) - return err -} - -func (ebs *EBSUtil) waitForAvailable(volumeID string) error { - backoff := wait.Backoff{ - Duration: volumeAttachmentStatusPollDelay, - Factor: volumeAttachmentStatusFactor, - Steps: volumeAttachmentStatusSteps, - } - time.Sleep(volumeAttachmentStatusPollDelay) - err := wait.ExponentialBackoff(backoff, func() (bool, error) { - info, err := ebs.describeVolume(volumeID) - if err != nil { - return false, err - } - volumeState := aws.StringValue(info.State) - if volumeState != ec2.VolumeStateAvailable { - return false, nil - } - return true, nil - }) - return err -} - -// Gets the full information about this volume from the EC2 API -func (ebs *EBSUtil) describeVolume(volumeID string) (*ec2.Volume, error) { - request := &ec2.DescribeVolumesInput{ - VolumeIds: []*string{&volumeID}, - } - - results := []*ec2.Volume{} - var nextToken *string - for { - response, err := ebs.client.DescribeVolumes(request) - if err != nil { - return nil, err - } - - results = append(results, response.Volumes...) - - nextToken = response.NextToken - if aws.StringValue(nextToken) == "" { - break - } - request.NextToken = nextToken - } - - if len(results) == 0 { - return nil, fmt.Errorf("no volumes found") - } - if len(results) > 1 { - return nil, fmt.Errorf("multiple volumes found") - } - return results[0], nil -} - -func newEc2Filter(name string, value string) *ec2.Filter { - filter := &ec2.Filter{ - Name: aws.String(name), - Values: []*string{ - aws.String(value), - }, - } - return filter -} - -func findInstanceByNodeName(nodeName string, cloud *ec2.EC2) (*ec2.Instance, error) { - filters := []*ec2.Filter{ - newEc2Filter("private-dns-name", nodeName), - } - - request := &ec2.DescribeInstancesInput{ - Filters: filters, - } - - instances, err := describeInstances(request, cloud) - if err != nil { - return nil, err - } - if len(instances) == 0 { - return nil, nil - } - if len(instances) > 1 { - return nil, fmt.Errorf("multiple instances found for name: %s", nodeName) - } - return instances[0], nil -} - -func describeInstances(request *ec2.DescribeInstancesInput, cloud *ec2.EC2) ([]*ec2.Instance, error) { - // Instances are paged - results := []*ec2.Instance{} - var nextToken *string - - for { - response, err := cloud.DescribeInstances(request) - if err != nil { - return nil, fmt.Errorf("error listing AWS instances: %v", err) - } - - for _, reservation := range response.Reservations { - results = append(results, reservation.Instances...) - } - - nextToken = response.NextToken - if nextToken == nil || len(*nextToken) == 0 { - break - } - request.NextToken = nextToken - } - - return results, nil -} diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/host_exec.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/host_exec.go index edefee588..202377323 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/host_exec.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/host_exec.go @@ -47,10 +47,10 @@ func LogResult(result Result) { // HostExec represents interface we require to execute commands on remote host. type HostExec interface { - Execute(cmd string, node *v1.Node) (Result, error) - IssueCommandWithResult(cmd string, node *v1.Node) (string, error) - IssueCommand(cmd string, node *v1.Node) error - Cleanup() + Execute(ctx context.Context, cmd string, node *v1.Node) (Result, error) + IssueCommandWithResult(ctx context.Context, cmd string, node *v1.Node) (string, error) + IssueCommand(ctx context.Context, cmd string, node *v1.Node) error + Cleanup(ctx context.Context) } // hostExecutor implements HostExec @@ -69,18 +69,25 @@ func NewHostExec(framework *framework.Framework) HostExec { // launchNodeExecPod launches a hostexec pod for local PV and waits // until it's Running. -func (h *hostExecutor) launchNodeExecPod(node string) *v1.Pod { +func (h *hostExecutor) launchNodeExecPod(ctx context.Context, node string) *v1.Pod { f := h.Framework cs := f.ClientSet ns := f.Namespace hostExecPod := e2epod.NewExecPodSpec(ns.Name, "", true) hostExecPod.GenerateName = fmt.Sprintf("hostexec-%s-", node) - // Use NodeAffinity instead of NodeName so that pods will not - // be immediately Failed by kubelet if it's out of space. Instead - // Pods will be pending in the scheduler until there is space freed - // up. - e2epod.SetNodeAffinity(&hostExecPod.Spec, node) + + if framework.TestContext.NodeE2E { + // E2E node tests do not run a scheduler, so set the node name directly + hostExecPod.Spec.NodeName = node + } else { + // Use NodeAffinity instead of NodeName so that pods will not + // be immediately Failed by kubelet if it's out of space. Instead + // Pods will be pending in the scheduler until there is space freed + // up. + e2epod.SetNodeAffinity(&hostExecPod.Spec, node) + + } hostExecPod.Spec.Volumes = []v1.Volume{ { // Required to enter into host mount namespace via nsenter. @@ -104,9 +111,9 @@ func (h *hostExecutor) launchNodeExecPod(node string) *v1.Pod { return &privileged }(true), } - pod, err := cs.CoreV1().Pods(ns.Name).Create(context.TODO(), hostExecPod, metav1.CreateOptions{}) + pod, err := cs.CoreV1().Pods(ns.Name).Create(ctx, hostExecPod, metav1.CreateOptions{}) framework.ExpectNoError(err) - err = e2epod.WaitTimeoutForPodRunningInNamespace(cs, pod.Name, pod.Namespace, f.Timeouts.PodStart) + err = e2epod.WaitTimeoutForPodRunningInNamespace(ctx, cs, pod.Name, pod.Namespace, f.Timeouts.PodStart) framework.ExpectNoError(err) return pod } @@ -115,8 +122,8 @@ func (h *hostExecutor) launchNodeExecPod(node string) *v1.Pod { // performing the remote command execution, the stdout, stderr and exit code // are returned. // This works like ssh.SSH(...) utility. -func (h *hostExecutor) Execute(cmd string, node *v1.Node) (Result, error) { - result, err := h.exec(cmd, node) +func (h *hostExecutor) Execute(ctx context.Context, cmd string, node *v1.Node) (Result, error) { + result, err := h.exec(ctx, cmd, node) if codeExitErr, ok := err.(exec.CodeExitError); ok { // extract the exit code of remote command and silence the command // non-zero exit code error @@ -126,14 +133,14 @@ func (h *hostExecutor) Execute(cmd string, node *v1.Node) (Result, error) { return result, err } -func (h *hostExecutor) exec(cmd string, node *v1.Node) (Result, error) { +func (h *hostExecutor) exec(ctx context.Context, cmd string, node *v1.Node) (Result, error) { result := Result{ Host: node.Name, Cmd: cmd, } pod, ok := h.nodeExecPods[node.Name] if !ok { - pod = h.launchNodeExecPod(node.Name) + pod = h.launchNodeExecPod(ctx, node.Name) if pod == nil { return result, fmt.Errorf("failed to create hostexec pod for node %q", node) } @@ -165,8 +172,8 @@ func (h *hostExecutor) exec(cmd string, node *v1.Node) (Result, error) { // IssueCommandWithResult issues command on the given node and returns stdout as // result. It returns error if there are some issues executing the command or // the command exits non-zero. -func (h *hostExecutor) IssueCommandWithResult(cmd string, node *v1.Node) (string, error) { - result, err := h.exec(cmd, node) +func (h *hostExecutor) IssueCommandWithResult(ctx context.Context, cmd string, node *v1.Node) (string, error) { + result, err := h.exec(ctx, cmd, node) if err != nil { LogResult(result) } @@ -174,17 +181,17 @@ func (h *hostExecutor) IssueCommandWithResult(cmd string, node *v1.Node) (string } // IssueCommand works like IssueCommandWithResult, but discards result. -func (h *hostExecutor) IssueCommand(cmd string, node *v1.Node) error { - _, err := h.IssueCommandWithResult(cmd, node) +func (h *hostExecutor) IssueCommand(ctx context.Context, cmd string, node *v1.Node) error { + _, err := h.IssueCommandWithResult(ctx, cmd, node) return err } // Cleanup cleanup resources it created during test. // Note that in most cases it is not necessary to call this because we create // pods under test namespace which will be destroyed in teardown phase. -func (h *hostExecutor) Cleanup() { +func (h *hostExecutor) Cleanup(ctx context.Context) { for _, pod := range h.nodeExecPods { - e2epod.DeletePodOrFail(h.Framework.ClientSet, pod.Namespace, pod.Name) + e2epod.DeletePodOrFail(ctx, h.Framework.ClientSet, pod.Namespace, pod.Name) } h.nodeExecPods = make(map[string]*v1.Pod) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/local.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/local.go index ef3e81888..df96eac12 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/local.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/local.go @@ -21,6 +21,7 @@ package utils */ import ( + "context" "fmt" "path/filepath" "strings" @@ -69,9 +70,9 @@ type LocalTestResource struct { // LocalTestResourceManager represents interface to create/destroy local test resources on node type LocalTestResourceManager interface { - Create(node *v1.Node, volumeType LocalVolumeType, parameters map[string]string) *LocalTestResource - ExpandBlockDevice(ltr *LocalTestResource, mbToAdd int) error - Remove(ltr *LocalTestResource) + Create(ctx context.Context, node *v1.Node, volumeType LocalVolumeType, parameters map[string]string) *LocalTestResource + ExpandBlockDevice(ctx context.Context, ltr *LocalTestResource, mbToAdd int) error + Remove(ctx context.Context, ltr *LocalTestResource) } // ltrMgr implements LocalTestResourceManager @@ -98,10 +99,10 @@ func (l *ltrMgr) getTestDir() string { return filepath.Join(l.hostBase, testDirName) } -func (l *ltrMgr) setupLocalVolumeTmpfs(node *v1.Node, parameters map[string]string) *LocalTestResource { +func (l *ltrMgr) setupLocalVolumeTmpfs(ctx context.Context, node *v1.Node, parameters map[string]string) *LocalTestResource { hostDir := l.getTestDir() ginkgo.By(fmt.Sprintf("Creating tmpfs mount point on node %q at path %q", node.Name, hostDir)) - err := l.hostExec.IssueCommand(fmt.Sprintf("mkdir -p %q && mount -t tmpfs -o size=10m tmpfs-%q %q", hostDir, hostDir, hostDir), node) + err := l.hostExec.IssueCommand(ctx, fmt.Sprintf("mkdir -p %q && mount -t tmpfs -o size=10m tmpfs-%q %q", hostDir, hostDir, hostDir), node) framework.ExpectNoError(err) return &LocalTestResource{ Node: node, @@ -109,18 +110,18 @@ func (l *ltrMgr) setupLocalVolumeTmpfs(node *v1.Node, parameters map[string]stri } } -func (l *ltrMgr) cleanupLocalVolumeTmpfs(ltr *LocalTestResource) { +func (l *ltrMgr) cleanupLocalVolumeTmpfs(ctx context.Context, ltr *LocalTestResource) { ginkgo.By(fmt.Sprintf("Unmount tmpfs mount point on node %q at path %q", ltr.Node.Name, ltr.Path)) - err := l.hostExec.IssueCommand(fmt.Sprintf("umount %q", ltr.Path), ltr.Node) + err := l.hostExec.IssueCommand(ctx, fmt.Sprintf("umount %q", ltr.Path), ltr.Node) framework.ExpectNoError(err) ginkgo.By("Removing the test directory") - err = l.hostExec.IssueCommand(fmt.Sprintf("rm -r %s", ltr.Path), ltr.Node) + err = l.hostExec.IssueCommand(ctx, fmt.Sprintf("rm -r %s", ltr.Path), ltr.Node) framework.ExpectNoError(err) } // createAndSetupLoopDevice creates an empty file and associates a loop devie with it. -func (l *ltrMgr) createAndSetupLoopDevice(dir string, node *v1.Node, size int) { +func (l *ltrMgr) createAndSetupLoopDevice(ctx context.Context, dir string, node *v1.Node, size int) { ginkgo.By(fmt.Sprintf("Creating block device on node %q using path %q", node.Name, dir)) mkdirCmd := fmt.Sprintf("mkdir -p %s", dir) count := size / 4096 @@ -130,22 +131,22 @@ func (l *ltrMgr) createAndSetupLoopDevice(dir string, node *v1.Node, size int) { } ddCmd := fmt.Sprintf("dd if=/dev/zero of=%s/file bs=4096 count=%d", dir, count) losetupCmd := fmt.Sprintf("losetup -f %s/file", dir) - err := l.hostExec.IssueCommand(fmt.Sprintf("%s && %s && %s", mkdirCmd, ddCmd, losetupCmd), node) + err := l.hostExec.IssueCommand(ctx, fmt.Sprintf("%s && %s && %s", mkdirCmd, ddCmd, losetupCmd), node) framework.ExpectNoError(err) } // findLoopDevice finds loop device path by its associated storage directory. -func (l *ltrMgr) findLoopDevice(dir string, node *v1.Node) string { +func (l *ltrMgr) findLoopDevice(ctx context.Context, dir string, node *v1.Node) string { cmd := fmt.Sprintf("E2E_LOOP_DEV=$(losetup | grep %s/file | awk '{ print $1 }') 2>&1 > /dev/null && echo ${E2E_LOOP_DEV}", dir) - loopDevResult, err := l.hostExec.IssueCommandWithResult(cmd, node) + loopDevResult, err := l.hostExec.IssueCommandWithResult(ctx, cmd, node) framework.ExpectNoError(err) return strings.TrimSpace(loopDevResult) } -func (l *ltrMgr) setupLocalVolumeBlock(node *v1.Node, parameters map[string]string) *LocalTestResource { +func (l *ltrMgr) setupLocalVolumeBlock(ctx context.Context, node *v1.Node, parameters map[string]string) *LocalTestResource { loopDir := l.getTestDir() - l.createAndSetupLoopDevice(loopDir, node, 20*1024*1024) - loopDev := l.findLoopDevice(loopDir, node) + l.createAndSetupLoopDevice(ctx, loopDir, node, 20*1024*1024) + loopDev := l.findLoopDevice(ctx, loopDir, node) return &LocalTestResource{ Node: node, Path: loopDev, @@ -154,30 +155,30 @@ func (l *ltrMgr) setupLocalVolumeBlock(node *v1.Node, parameters map[string]stri } // teardownLoopDevice tears down loop device by its associated storage directory. -func (l *ltrMgr) teardownLoopDevice(dir string, node *v1.Node) { - loopDev := l.findLoopDevice(dir, node) +func (l *ltrMgr) teardownLoopDevice(ctx context.Context, dir string, node *v1.Node) { + loopDev := l.findLoopDevice(ctx, dir, node) ginkgo.By(fmt.Sprintf("Tear down block device %q on node %q at path %s/file", loopDev, node.Name, dir)) losetupDeleteCmd := fmt.Sprintf("losetup -d %s", loopDev) - err := l.hostExec.IssueCommand(losetupDeleteCmd, node) + err := l.hostExec.IssueCommand(ctx, losetupDeleteCmd, node) framework.ExpectNoError(err) return } -func (l *ltrMgr) cleanupLocalVolumeBlock(ltr *LocalTestResource) { - l.teardownLoopDevice(ltr.loopDir, ltr.Node) +func (l *ltrMgr) cleanupLocalVolumeBlock(ctx context.Context, ltr *LocalTestResource) { + l.teardownLoopDevice(ctx, ltr.loopDir, ltr.Node) ginkgo.By(fmt.Sprintf("Removing the test directory %s", ltr.loopDir)) removeCmd := fmt.Sprintf("rm -r %s", ltr.loopDir) - err := l.hostExec.IssueCommand(removeCmd, ltr.Node) + err := l.hostExec.IssueCommand(ctx, removeCmd, ltr.Node) framework.ExpectNoError(err) } -func (l *ltrMgr) setupLocalVolumeBlockFS(node *v1.Node, parameters map[string]string) *LocalTestResource { - ltr := l.setupLocalVolumeBlock(node, parameters) +func (l *ltrMgr) setupLocalVolumeBlockFS(ctx context.Context, node *v1.Node, parameters map[string]string) *LocalTestResource { + ltr := l.setupLocalVolumeBlock(ctx, node, parameters) loopDev := ltr.Path loopDir := ltr.loopDir // Format and mount at loopDir and give others rwx for read/write testing cmd := fmt.Sprintf("mkfs -t ext4 %s && mount -t ext4 %s %s && chmod o+rwx %s", loopDev, loopDev, loopDir, loopDir) - err := l.hostExec.IssueCommand(cmd, node) + err := l.hostExec.IssueCommand(ctx, cmd, node) framework.ExpectNoError(err) return &LocalTestResource{ Node: node, @@ -186,17 +187,17 @@ func (l *ltrMgr) setupLocalVolumeBlockFS(node *v1.Node, parameters map[string]st } } -func (l *ltrMgr) cleanupLocalVolumeBlockFS(ltr *LocalTestResource) { +func (l *ltrMgr) cleanupLocalVolumeBlockFS(ctx context.Context, ltr *LocalTestResource) { umountCmd := fmt.Sprintf("umount %s", ltr.Path) - err := l.hostExec.IssueCommand(umountCmd, ltr.Node) + err := l.hostExec.IssueCommand(ctx, umountCmd, ltr.Node) framework.ExpectNoError(err) - l.cleanupLocalVolumeBlock(ltr) + l.cleanupLocalVolumeBlock(ctx, ltr) } -func (l *ltrMgr) setupLocalVolumeDirectory(node *v1.Node, parameters map[string]string) *LocalTestResource { +func (l *ltrMgr) setupLocalVolumeDirectory(ctx context.Context, node *v1.Node, parameters map[string]string) *LocalTestResource { hostDir := l.getTestDir() mkdirCmd := fmt.Sprintf("mkdir -p %s", hostDir) - err := l.hostExec.IssueCommand(mkdirCmd, node) + err := l.hostExec.IssueCommand(ctx, mkdirCmd, node) framework.ExpectNoError(err) return &LocalTestResource{ Node: node, @@ -204,18 +205,18 @@ func (l *ltrMgr) setupLocalVolumeDirectory(node *v1.Node, parameters map[string] } } -func (l *ltrMgr) cleanupLocalVolumeDirectory(ltr *LocalTestResource) { +func (l *ltrMgr) cleanupLocalVolumeDirectory(ctx context.Context, ltr *LocalTestResource) { ginkgo.By("Removing the test directory") removeCmd := fmt.Sprintf("rm -r %s", ltr.Path) - err := l.hostExec.IssueCommand(removeCmd, ltr.Node) + err := l.hostExec.IssueCommand(ctx, removeCmd, ltr.Node) framework.ExpectNoError(err) } -func (l *ltrMgr) setupLocalVolumeDirectoryLink(node *v1.Node, parameters map[string]string) *LocalTestResource { +func (l *ltrMgr) setupLocalVolumeDirectoryLink(ctx context.Context, node *v1.Node, parameters map[string]string) *LocalTestResource { hostDir := l.getTestDir() hostDirBackend := hostDir + "-backend" cmd := fmt.Sprintf("mkdir %s && ln -s %s %s", hostDirBackend, hostDirBackend, hostDir) - err := l.hostExec.IssueCommand(cmd, node) + err := l.hostExec.IssueCommand(ctx, cmd, node) framework.ExpectNoError(err) return &LocalTestResource{ Node: node, @@ -223,19 +224,19 @@ func (l *ltrMgr) setupLocalVolumeDirectoryLink(node *v1.Node, parameters map[str } } -func (l *ltrMgr) cleanupLocalVolumeDirectoryLink(ltr *LocalTestResource) { +func (l *ltrMgr) cleanupLocalVolumeDirectoryLink(ctx context.Context, ltr *LocalTestResource) { ginkgo.By("Removing the test directory") hostDir := ltr.Path hostDirBackend := hostDir + "-backend" removeCmd := fmt.Sprintf("rm -r %s && rm -r %s", hostDir, hostDirBackend) - err := l.hostExec.IssueCommand(removeCmd, ltr.Node) + err := l.hostExec.IssueCommand(ctx, removeCmd, ltr.Node) framework.ExpectNoError(err) } -func (l *ltrMgr) setupLocalVolumeDirectoryBindMounted(node *v1.Node, parameters map[string]string) *LocalTestResource { +func (l *ltrMgr) setupLocalVolumeDirectoryBindMounted(ctx context.Context, node *v1.Node, parameters map[string]string) *LocalTestResource { hostDir := l.getTestDir() cmd := fmt.Sprintf("mkdir %s && mount --bind %s %s", hostDir, hostDir, hostDir) - err := l.hostExec.IssueCommand(cmd, node) + err := l.hostExec.IssueCommand(ctx, cmd, node) framework.ExpectNoError(err) return &LocalTestResource{ Node: node, @@ -243,19 +244,19 @@ func (l *ltrMgr) setupLocalVolumeDirectoryBindMounted(node *v1.Node, parameters } } -func (l *ltrMgr) cleanupLocalVolumeDirectoryBindMounted(ltr *LocalTestResource) { +func (l *ltrMgr) cleanupLocalVolumeDirectoryBindMounted(ctx context.Context, ltr *LocalTestResource) { ginkgo.By("Removing the test directory") hostDir := ltr.Path removeCmd := fmt.Sprintf("umount %s && rm -r %s", hostDir, hostDir) - err := l.hostExec.IssueCommand(removeCmd, ltr.Node) + err := l.hostExec.IssueCommand(ctx, removeCmd, ltr.Node) framework.ExpectNoError(err) } -func (l *ltrMgr) setupLocalVolumeDirectoryLinkBindMounted(node *v1.Node, parameters map[string]string) *LocalTestResource { +func (l *ltrMgr) setupLocalVolumeDirectoryLinkBindMounted(ctx context.Context, node *v1.Node, parameters map[string]string) *LocalTestResource { hostDir := l.getTestDir() hostDirBackend := hostDir + "-backend" cmd := fmt.Sprintf("mkdir %s && mount --bind %s %s && ln -s %s %s", hostDirBackend, hostDirBackend, hostDirBackend, hostDirBackend, hostDir) - err := l.hostExec.IssueCommand(cmd, node) + err := l.hostExec.IssueCommand(ctx, cmd, node) framework.ExpectNoError(err) return &LocalTestResource{ Node: node, @@ -263,17 +264,17 @@ func (l *ltrMgr) setupLocalVolumeDirectoryLinkBindMounted(node *v1.Node, paramet } } -func (l *ltrMgr) cleanupLocalVolumeDirectoryLinkBindMounted(ltr *LocalTestResource) { +func (l *ltrMgr) cleanupLocalVolumeDirectoryLinkBindMounted(ctx context.Context, ltr *LocalTestResource) { ginkgo.By("Removing the test directory") hostDir := ltr.Path hostDirBackend := hostDir + "-backend" removeCmd := fmt.Sprintf("rm %s && umount %s && rm -r %s", hostDir, hostDirBackend, hostDirBackend) - err := l.hostExec.IssueCommand(removeCmd, ltr.Node) + err := l.hostExec.IssueCommand(ctx, removeCmd, ltr.Node) framework.ExpectNoError(err) } -func (l *ltrMgr) setupLocalVolumeGCELocalSSD(node *v1.Node, parameters map[string]string) *LocalTestResource { - res, err := l.hostExec.IssueCommandWithResult("ls /mnt/disks/by-uuid/google-local-ssds-scsi-fs/", node) +func (l *ltrMgr) setupLocalVolumeGCELocalSSD(ctx context.Context, node *v1.Node, parameters map[string]string) *LocalTestResource { + res, err := l.hostExec.IssueCommandWithResult(ctx, "ls /mnt/disks/by-uuid/google-local-ssds-scsi-fs/", node) framework.ExpectNoError(err) dirName := strings.Fields(res)[0] hostDir := "/mnt/disks/by-uuid/google-local-ssds-scsi-fs/" + dirName @@ -283,47 +284,47 @@ func (l *ltrMgr) setupLocalVolumeGCELocalSSD(node *v1.Node, parameters map[strin } } -func (l *ltrMgr) cleanupLocalVolumeGCELocalSSD(ltr *LocalTestResource) { +func (l *ltrMgr) cleanupLocalVolumeGCELocalSSD(ctx context.Context, ltr *LocalTestResource) { // This filesystem is attached in cluster initialization, we clean all files to make it reusable. removeCmd := fmt.Sprintf("find '%s' -mindepth 1 -maxdepth 1 -print0 | xargs -r -0 rm -rf", ltr.Path) - err := l.hostExec.IssueCommand(removeCmd, ltr.Node) + err := l.hostExec.IssueCommand(ctx, removeCmd, ltr.Node) framework.ExpectNoError(err) } -func (l *ltrMgr) expandLocalVolumeBlockFS(ltr *LocalTestResource, mbToAdd int) error { +func (l *ltrMgr) expandLocalVolumeBlockFS(ctx context.Context, ltr *LocalTestResource, mbToAdd int) error { ddCmd := fmt.Sprintf("dd if=/dev/zero of=%s/file conv=notrunc oflag=append bs=1M count=%d", ltr.loopDir, mbToAdd) - loopDev := l.findLoopDevice(ltr.loopDir, ltr.Node) + loopDev := l.findLoopDevice(ctx, ltr.loopDir, ltr.Node) losetupCmd := fmt.Sprintf("losetup -c %s", loopDev) - return l.hostExec.IssueCommand(fmt.Sprintf("%s && %s", ddCmd, losetupCmd), ltr.Node) + return l.hostExec.IssueCommand(ctx, fmt.Sprintf("%s && %s", ddCmd, losetupCmd), ltr.Node) } -func (l *ltrMgr) ExpandBlockDevice(ltr *LocalTestResource, mbtoAdd int) error { +func (l *ltrMgr) ExpandBlockDevice(ctx context.Context, ltr *LocalTestResource, mbtoAdd int) error { switch ltr.VolumeType { case LocalVolumeBlockFS: - return l.expandLocalVolumeBlockFS(ltr, mbtoAdd) + return l.expandLocalVolumeBlockFS(ctx, ltr, mbtoAdd) } return fmt.Errorf("Failed to expand local test resource, unsupported volume type: %s", ltr.VolumeType) } -func (l *ltrMgr) Create(node *v1.Node, volumeType LocalVolumeType, parameters map[string]string) *LocalTestResource { +func (l *ltrMgr) Create(ctx context.Context, node *v1.Node, volumeType LocalVolumeType, parameters map[string]string) *LocalTestResource { var ltr *LocalTestResource switch volumeType { case LocalVolumeDirectory: - ltr = l.setupLocalVolumeDirectory(node, parameters) + ltr = l.setupLocalVolumeDirectory(ctx, node, parameters) case LocalVolumeDirectoryLink: - ltr = l.setupLocalVolumeDirectoryLink(node, parameters) + ltr = l.setupLocalVolumeDirectoryLink(ctx, node, parameters) case LocalVolumeDirectoryBindMounted: - ltr = l.setupLocalVolumeDirectoryBindMounted(node, parameters) + ltr = l.setupLocalVolumeDirectoryBindMounted(ctx, node, parameters) case LocalVolumeDirectoryLinkBindMounted: - ltr = l.setupLocalVolumeDirectoryLinkBindMounted(node, parameters) + ltr = l.setupLocalVolumeDirectoryLinkBindMounted(ctx, node, parameters) case LocalVolumeTmpfs: - ltr = l.setupLocalVolumeTmpfs(node, parameters) + ltr = l.setupLocalVolumeTmpfs(ctx, node, parameters) case LocalVolumeBlock: - ltr = l.setupLocalVolumeBlock(node, parameters) + ltr = l.setupLocalVolumeBlock(ctx, node, parameters) case LocalVolumeBlockFS: - ltr = l.setupLocalVolumeBlockFS(node, parameters) + ltr = l.setupLocalVolumeBlockFS(ctx, node, parameters) case LocalVolumeGCELocalSSD: - ltr = l.setupLocalVolumeGCELocalSSD(node, parameters) + ltr = l.setupLocalVolumeGCELocalSSD(ctx, node, parameters) default: framework.Failf("Failed to create local test resource on node %q, unsupported volume type: %v is specified", node.Name, volumeType) return nil @@ -335,24 +336,24 @@ func (l *ltrMgr) Create(node *v1.Node, volumeType LocalVolumeType, parameters ma return ltr } -func (l *ltrMgr) Remove(ltr *LocalTestResource) { +func (l *ltrMgr) Remove(ctx context.Context, ltr *LocalTestResource) { switch ltr.VolumeType { case LocalVolumeDirectory: - l.cleanupLocalVolumeDirectory(ltr) + l.cleanupLocalVolumeDirectory(ctx, ltr) case LocalVolumeDirectoryLink: - l.cleanupLocalVolumeDirectoryLink(ltr) + l.cleanupLocalVolumeDirectoryLink(ctx, ltr) case LocalVolumeDirectoryBindMounted: - l.cleanupLocalVolumeDirectoryBindMounted(ltr) + l.cleanupLocalVolumeDirectoryBindMounted(ctx, ltr) case LocalVolumeDirectoryLinkBindMounted: - l.cleanupLocalVolumeDirectoryLinkBindMounted(ltr) + l.cleanupLocalVolumeDirectoryLinkBindMounted(ctx, ltr) case LocalVolumeTmpfs: - l.cleanupLocalVolumeTmpfs(ltr) + l.cleanupLocalVolumeTmpfs(ctx, ltr) case LocalVolumeBlock: - l.cleanupLocalVolumeBlock(ltr) + l.cleanupLocalVolumeBlock(ctx, ltr) case LocalVolumeBlockFS: - l.cleanupLocalVolumeBlockFS(ltr) + l.cleanupLocalVolumeBlockFS(ctx, ltr) case LocalVolumeGCELocalSSD: - l.cleanupLocalVolumeGCELocalSSD(ltr) + l.cleanupLocalVolumeGCELocalSSD(ctx, ltr) default: framework.Failf("Failed to remove local test resource, unsupported volume type: %v is specified", ltr.VolumeType) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go index 0c9307d27..b971bd152 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go @@ -43,8 +43,8 @@ import ( // // The output goes to log files (when using --report-dir, as in the // CI) or the output stream (otherwise). -func StartPodLogs(f *framework.Framework, driverNamespace *v1.Namespace) func() { - ctx, cancel := context.WithCancel(context.Background()) +func StartPodLogs(ctx context.Context, f *framework.Framework, driverNamespace *v1.Namespace) func() { + ctx, cancel := context.WithCancel(ctx) cs := f.ClientSet ns := driverNamespace.Name @@ -103,17 +103,17 @@ func StartPodLogs(f *framework.Framework, driverNamespace *v1.Namespace) func() // - If `systemctl` returns stderr "command not found, issues the command via `service` // - If `service` also returns stderr "command not found", the test is aborted. // Allowed kubeletOps are `KStart`, `KStop`, and `KRestart` -func KubeletCommand(kOp KubeletOpt, c clientset.Interface, pod *v1.Pod) { +func KubeletCommand(ctx context.Context, kOp KubeletOpt, c clientset.Interface, pod *v1.Pod) { command := "" systemctlPresent := false kubeletPid := "" - nodeIP, err := getHostAddress(c, pod) + nodeIP, err := getHostAddress(ctx, c, pod) framework.ExpectNoError(err) nodeIP = nodeIP + ":22" framework.Logf("Checking if systemctl command is present") - sshResult, err := e2essh.SSH("systemctl --version", nodeIP, framework.TestContext.Provider) + sshResult, err := e2essh.SSH(ctx, "systemctl --version", nodeIP, framework.TestContext.Provider) framework.ExpectNoError(err, fmt.Sprintf("SSH to Node %q errored.", pod.Spec.NodeName)) if !strings.Contains(sshResult.Stderr, "command not found") { command = fmt.Sprintf("systemctl %s kubelet", string(kOp)) @@ -122,23 +122,23 @@ func KubeletCommand(kOp KubeletOpt, c clientset.Interface, pod *v1.Pod) { command = fmt.Sprintf("service kubelet %s", string(kOp)) } - sudoPresent := isSudoPresent(nodeIP, framework.TestContext.Provider) + sudoPresent := isSudoPresent(ctx, nodeIP, framework.TestContext.Provider) if sudoPresent { command = fmt.Sprintf("sudo %s", command) } if kOp == KRestart { - kubeletPid = getKubeletMainPid(nodeIP, sudoPresent, systemctlPresent) + kubeletPid = getKubeletMainPid(ctx, nodeIP, sudoPresent, systemctlPresent) } framework.Logf("Attempting `%s`", command) - sshResult, err = e2essh.SSH(command, nodeIP, framework.TestContext.Provider) + sshResult, err = e2essh.SSH(ctx, command, nodeIP, framework.TestContext.Provider) framework.ExpectNoError(err, fmt.Sprintf("SSH to Node %q errored.", pod.Spec.NodeName)) e2essh.LogResult(sshResult) gomega.Expect(sshResult.Code).To(gomega.BeZero(), "Failed to [%s] kubelet:\n%#v", string(kOp), sshResult) if kOp == KStop { - if ok := e2enode.WaitForNodeToBeNotReady(c, pod.Spec.NodeName, NodeStateTimeout); !ok { + if ok := e2enode.WaitForNodeToBeNotReady(ctx, c, pod.Spec.NodeName, NodeStateTimeout); !ok { framework.Failf("Node %s failed to enter NotReady state", pod.Spec.NodeName) } } @@ -146,7 +146,10 @@ func KubeletCommand(kOp KubeletOpt, c clientset.Interface, pod *v1.Pod) { // Wait for a minute to check if kubelet Pid is getting changed isPidChanged := false for start := time.Now(); time.Since(start) < 1*time.Minute; time.Sleep(2 * time.Second) { - kubeletPidAfterRestart := getKubeletMainPid(nodeIP, sudoPresent, systemctlPresent) + if ctx.Err() != nil { + framework.Fail("timed out waiting for Kubelet POD change") + } + kubeletPidAfterRestart := getKubeletMainPid(ctx, nodeIP, sudoPresent, systemctlPresent) if kubeletPid != kubeletPidAfterRestart { isPidChanged = true break @@ -161,7 +164,7 @@ func KubeletCommand(kOp KubeletOpt, c clientset.Interface, pod *v1.Pod) { } if kOp == KStart || kOp == KRestart { // For kubelet start and restart operations, Wait until Node becomes Ready - if ok := e2enode.WaitForNodeToBeReady(c, pod.Spec.NodeName, NodeStateTimeout); !ok { + if ok := e2enode.WaitForNodeToBeReady(ctx, c, pod.Spec.NodeName, NodeStateTimeout); !ok { framework.Failf("Node %s failed to enter Ready state", pod.Spec.NodeName) } } @@ -170,8 +173,8 @@ func KubeletCommand(kOp KubeletOpt, c clientset.Interface, pod *v1.Pod) { // getHostAddress gets the node for a pod and returns the first // address. Returns an error if the node the pod is on doesn't have an // address. -func getHostAddress(client clientset.Interface, p *v1.Pod) (string, error) { - node, err := client.CoreV1().Nodes().Get(context.TODO(), p.Spec.NodeName, metav1.GetOptions{}) +func getHostAddress(ctx context.Context, client clientset.Interface, p *v1.Pod) (string, error) { + node, err := client.CoreV1().Nodes().Get(ctx, p.Spec.NodeName, metav1.GetOptions{}) if err != nil { return "", err } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot.go index aff9e20ef..a721bd1dc 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/snapshot.go @@ -48,11 +48,11 @@ var ( ) // WaitForSnapshotReady waits for a VolumeSnapshot to be ready to use or until timeout occurs, whichever comes first. -func WaitForSnapshotReady(c dynamic.Interface, ns string, snapshotName string, poll, timeout time.Duration) error { +func WaitForSnapshotReady(ctx context.Context, c dynamic.Interface, ns string, snapshotName string, poll, timeout time.Duration) error { framework.Logf("Waiting up to %v for VolumeSnapshot %s to become ready", timeout, snapshotName) if successful := WaitUntil(poll, timeout, func() bool { - snapshot, err := c.Resource(SnapshotGVR).Namespace(ns).Get(context.TODO(), snapshotName, metav1.GetOptions{}) + snapshot, err := c.Resource(SnapshotGVR).Namespace(ns).Get(ctx, snapshotName, metav1.GetOptions{}) if err != nil { framework.Logf("Failed to get snapshot %q, retrying in %v. Error: %v", snapshotName, poll, err) return false @@ -80,12 +80,12 @@ func WaitForSnapshotReady(c dynamic.Interface, ns string, snapshotName string, p // GetSnapshotContentFromSnapshot returns the VolumeSnapshotContent object Bound to a // given VolumeSnapshot -func GetSnapshotContentFromSnapshot(dc dynamic.Interface, snapshot *unstructured.Unstructured, timeout time.Duration) *unstructured.Unstructured { +func GetSnapshotContentFromSnapshot(ctx context.Context, dc dynamic.Interface, snapshot *unstructured.Unstructured, timeout time.Duration) *unstructured.Unstructured { defer ginkgo.GinkgoRecover() - err := WaitForSnapshotReady(dc, snapshot.GetNamespace(), snapshot.GetName(), framework.Poll, timeout) + err := WaitForSnapshotReady(ctx, dc, snapshot.GetNamespace(), snapshot.GetName(), framework.Poll, timeout) framework.ExpectNoError(err) - vs, err := dc.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Get(context.TODO(), snapshot.GetName(), metav1.GetOptions{}) + vs, err := dc.Resource(SnapshotGVR).Namespace(snapshot.GetNamespace()).Get(ctx, snapshot.GetName(), metav1.GetOptions{}) snapshotStatus := vs.Object["status"].(map[string]interface{}) snapshotContentName := snapshotStatus["boundVolumeSnapshotContentName"].(string) @@ -93,7 +93,7 @@ func GetSnapshotContentFromSnapshot(dc dynamic.Interface, snapshot *unstructured framework.Logf("snapshotContentName %s", snapshotContentName) framework.ExpectNoError(err) - vscontent, err := dc.Resource(SnapshotContentGVR).Get(context.TODO(), snapshotContentName, metav1.GetOptions{}) + vscontent, err := dc.Resource(SnapshotContentGVR).Get(ctx, snapshotContentName, metav1.GetOptions{}) framework.ExpectNoError(err) return vscontent @@ -101,9 +101,9 @@ func GetSnapshotContentFromSnapshot(dc dynamic.Interface, snapshot *unstructured } // DeleteSnapshotWithoutWaiting deletes a VolumeSnapshot and return directly without waiting -func DeleteSnapshotWithoutWaiting(dc dynamic.Interface, ns string, snapshotName string) error { +func DeleteSnapshotWithoutWaiting(ctx context.Context, dc dynamic.Interface, ns string, snapshotName string) error { ginkgo.By("deleting the snapshot") - err := dc.Resource(SnapshotGVR).Namespace(ns).Delete(context.TODO(), snapshotName, metav1.DeleteOptions{}) + err := dc.Resource(SnapshotGVR).Namespace(ns).Delete(ctx, snapshotName, metav1.DeleteOptions{}) if err != nil && !apierrors.IsNotFound(err) { return err } @@ -111,15 +111,15 @@ func DeleteSnapshotWithoutWaiting(dc dynamic.Interface, ns string, snapshotName } // DeleteAndWaitSnapshot deletes a VolumeSnapshot and waits for it to be deleted or until timeout occurs, whichever comes first -func DeleteAndWaitSnapshot(dc dynamic.Interface, ns string, snapshotName string, poll, timeout time.Duration) error { +func DeleteAndWaitSnapshot(ctx context.Context, dc dynamic.Interface, ns string, snapshotName string, poll, timeout time.Duration) error { var err error - err = DeleteSnapshotWithoutWaiting(dc, ns, snapshotName) + err = DeleteSnapshotWithoutWaiting(ctx, dc, ns, snapshotName) if err != nil { return err } ginkgo.By("checking the Snapshot has been deleted") - err = WaitForNamespacedGVRDeletion(dc, SnapshotGVR, ns, snapshotName, poll, timeout) + err = WaitForNamespacedGVRDeletion(ctx, dc, SnapshotGVR, ns, snapshotName, poll, timeout) return err } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go index c6ca07fa9..2c4fc261f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/utils.go @@ -75,7 +75,7 @@ func VerifyFSGroupInPod(f *framework.Framework, filePath, expectedFSGroup string } // getKubeletMainPid return the Main PID of the Kubelet Process -func getKubeletMainPid(nodeIP string, sudoPresent bool, systemctlPresent bool) string { +func getKubeletMainPid(ctx context.Context, nodeIP string, sudoPresent bool, systemctlPresent bool) string { command := "" if systemctlPresent { command = "systemctl status kubelet | grep 'Main PID'" @@ -86,7 +86,7 @@ func getKubeletMainPid(nodeIP string, sudoPresent bool, systemctlPresent bool) s command = fmt.Sprintf("sudo %s", command) } framework.Logf("Attempting `%s`", command) - sshResult, err := e2essh.SSH(command, nodeIP, framework.TestContext.Provider) + sshResult, err := e2essh.SSH(ctx, command, nodeIP, framework.TestContext.Provider) framework.ExpectNoError(err, fmt.Sprintf("SSH to Node %q errored.", nodeIP)) e2essh.LogResult(sshResult) gomega.Expect(sshResult.Code).To(gomega.BeZero(), "Failed to get kubelet PID") @@ -95,7 +95,7 @@ func getKubeletMainPid(nodeIP string, sudoPresent bool, systemctlPresent bool) s } // TestKubeletRestartsAndRestoresMount tests that a volume mounted to a pod remains mounted after a kubelet restarts -func TestKubeletRestartsAndRestoresMount(c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, volumePath string) { +func TestKubeletRestartsAndRestoresMount(ctx context.Context, c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, volumePath string) { byteLen := 64 seed := time.Now().UTC().UnixNano() @@ -103,7 +103,7 @@ func TestKubeletRestartsAndRestoresMount(c clientset.Interface, f *framework.Fra CheckWriteToPath(f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) ginkgo.By("Restarting kubelet") - KubeletCommand(KRestart, c, clientPod) + KubeletCommand(ctx, KRestart, c, clientPod) ginkgo.By("Testing that written file is accessible.") CheckReadFromPath(f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) @@ -112,7 +112,7 @@ func TestKubeletRestartsAndRestoresMount(c clientset.Interface, f *framework.Fra } // TestKubeletRestartsAndRestoresMap tests that a volume mapped to a pod remains mapped after a kubelet restarts -func TestKubeletRestartsAndRestoresMap(c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, volumePath string) { +func TestKubeletRestartsAndRestoresMap(ctx context.Context, c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, volumePath string) { byteLen := 64 seed := time.Now().UTC().UnixNano() @@ -120,7 +120,7 @@ func TestKubeletRestartsAndRestoresMap(c clientset.Interface, f *framework.Frame CheckWriteToPath(f, clientPod, v1.PersistentVolumeBlock, false, volumePath, byteLen, seed) ginkgo.By("Restarting kubelet") - KubeletCommand(KRestart, c, clientPod) + KubeletCommand(ctx, KRestart, c, clientPod) ginkgo.By("Testing that written pv is accessible.") CheckReadFromPath(f, clientPod, v1.PersistentVolumeBlock, false, volumePath, byteLen, seed) @@ -132,20 +132,20 @@ func TestKubeletRestartsAndRestoresMap(c clientset.Interface, f *framework.Frame // forceDelete is true indicating whether the pod is forcefully deleted. // checkSubpath is true indicating whether the subpath should be checked. // If secondPod is set, it is started when kubelet is down to check that the volume is usable while the old pod is being deleted and the new pod is starting. -func TestVolumeUnmountsFromDeletedPodWithForceOption(c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, forceDelete bool, checkSubpath bool, secondPod *v1.Pod, volumePath string) { - nodeIP, err := getHostAddress(c, clientPod) +func TestVolumeUnmountsFromDeletedPodWithForceOption(ctx context.Context, c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, forceDelete bool, checkSubpath bool, secondPod *v1.Pod, volumePath string) { + nodeIP, err := getHostAddress(ctx, c, clientPod) framework.ExpectNoError(err) nodeIP = nodeIP + ":22" ginkgo.By("Expecting the volume mount to be found.") - result, err := e2essh.SSH(fmt.Sprintf("mount | grep %s | grep -v volume-subpaths", clientPod.UID), nodeIP, framework.TestContext.Provider) + result, err := e2essh.SSH(ctx, fmt.Sprintf("mount | grep %s | grep -v volume-subpaths", clientPod.UID), nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error.") framework.ExpectEqual(result.Code, 0, fmt.Sprintf("Expected grep exit code of 0, got %d", result.Code)) if checkSubpath { ginkgo.By("Expecting the volume subpath mount to be found.") - result, err := e2essh.SSH(fmt.Sprintf("cat /proc/self/mountinfo | grep %s | grep volume-subpaths", clientPod.UID), nodeIP, framework.TestContext.Provider) + result, err := e2essh.SSH(ctx, fmt.Sprintf("cat /proc/self/mountinfo | grep %s | grep volume-subpaths", clientPod.UID), nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error.") framework.ExpectEqual(result.Code, 0, fmt.Sprintf("Expected grep exit code of 0, got %d", result.Code)) @@ -157,11 +157,9 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(c clientset.Interface, f *f CheckWriteToPath(f, clientPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) // This command is to make sure kubelet is started after test finishes no matter it fails or not. - defer func() { - KubeletCommand(KStart, c, clientPod) - }() + ginkgo.DeferCleanup(KubeletCommand, KStart, c, clientPod) ginkgo.By("Stopping the kubelet.") - KubeletCommand(KStop, c, clientPod) + KubeletCommand(ctx, KStop, c, clientPod) if secondPod != nil { ginkgo.By("Starting the second pod") @@ -171,15 +169,15 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(c clientset.Interface, f *f ginkgo.By(fmt.Sprintf("Deleting Pod %q", clientPod.Name)) if forceDelete { - err = c.CoreV1().Pods(clientPod.Namespace).Delete(context.TODO(), clientPod.Name, *metav1.NewDeleteOptions(0)) + err = c.CoreV1().Pods(clientPod.Namespace).Delete(ctx, clientPod.Name, *metav1.NewDeleteOptions(0)) } else { - err = c.CoreV1().Pods(clientPod.Namespace).Delete(context.TODO(), clientPod.Name, metav1.DeleteOptions{}) + err = c.CoreV1().Pods(clientPod.Namespace).Delete(ctx, clientPod.Name, metav1.DeleteOptions{}) } framework.ExpectNoError(err) ginkgo.By("Starting the kubelet and waiting for pod to delete.") - KubeletCommand(KStart, c, clientPod) - err = e2epod.WaitForPodNotFoundInNamespace(f.ClientSet, clientPod.Name, f.Namespace.Name, f.Timeouts.PodDelete) + KubeletCommand(ctx, KStart, c, clientPod) + err = e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, clientPod.Name, f.Namespace.Name, f.Timeouts.PodDelete) if err != nil { framework.ExpectNoError(err, "Expected pod to be not found.") } @@ -192,7 +190,7 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(c clientset.Interface, f *f if secondPod != nil { ginkgo.By("Waiting for the second pod.") - err = e2epod.WaitForPodRunningInNamespace(c, secondPod) + err = e2epod.WaitForPodRunningInNamespace(ctx, c, secondPod) framework.ExpectNoError(err, "while waiting for the second pod Running") ginkgo.By("Getting the second pod uuid.") @@ -200,7 +198,7 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(c clientset.Interface, f *f framework.ExpectNoError(err, "getting the second UID") ginkgo.By("Expecting the volume mount to be found in the second pod.") - result, err := e2essh.SSH(fmt.Sprintf("mount | grep %s | grep -v volume-subpaths", secondPod.UID), nodeIP, framework.TestContext.Provider) + result, err := e2essh.SSH(ctx, fmt.Sprintf("mount | grep %s | grep -v volume-subpaths", secondPod.UID), nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error when checking the second pod.") framework.ExpectEqual(result.Code, 0, fmt.Sprintf("Expected grep exit code of 0, got %d", result.Code)) @@ -209,12 +207,12 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(c clientset.Interface, f *f CheckReadFromPath(f, secondPod, v1.PersistentVolumeFilesystem, false, volumePath, byteLen, seed) err = c.CoreV1().Pods(secondPod.Namespace).Delete(context.TODO(), secondPod.Name, metav1.DeleteOptions{}) framework.ExpectNoError(err, "when deleting the second pod") - err = e2epod.WaitForPodNotFoundInNamespace(f.ClientSet, secondPod.Name, f.Namespace.Name, f.Timeouts.PodDelete) + err = e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, secondPod.Name, f.Namespace.Name, f.Timeouts.PodDelete) framework.ExpectNoError(err, "when waiting for the second pod to disappear") } ginkgo.By("Expecting the volume mount not to be found.") - result, err = e2essh.SSH(fmt.Sprintf("mount | grep %s | grep -v volume-subpaths", clientPod.UID), nodeIP, framework.TestContext.Provider) + result, err = e2essh.SSH(ctx, fmt.Sprintf("mount | grep %s | grep -v volume-subpaths", clientPod.UID), nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error.") gomega.Expect(result.Stdout).To(gomega.BeEmpty(), "Expected grep stdout to be empty (i.e. no mount found).") @@ -222,7 +220,7 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(c clientset.Interface, f *f if checkSubpath { ginkgo.By("Expecting the volume subpath mount not to be found.") - result, err = e2essh.SSH(fmt.Sprintf("cat /proc/self/mountinfo | grep %s | grep volume-subpaths", clientPod.UID), nodeIP, framework.TestContext.Provider) + result, err = e2essh.SSH(ctx, fmt.Sprintf("cat /proc/self/mountinfo | grep %s | grep volume-subpaths", clientPod.UID), nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error.") gomega.Expect(result.Stdout).To(gomega.BeEmpty(), "Expected grep stdout to be empty (i.e. no subpath mount found).") @@ -232,64 +230,62 @@ func TestVolumeUnmountsFromDeletedPodWithForceOption(c clientset.Interface, f *f } // TestVolumeUnmountsFromDeletedPod tests that a volume unmounts if the client pod was deleted while the kubelet was down. -func TestVolumeUnmountsFromDeletedPod(c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, volumePath string) { - TestVolumeUnmountsFromDeletedPodWithForceOption(c, f, clientPod, false, false, nil, volumePath) +func TestVolumeUnmountsFromDeletedPod(ctx context.Context, c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, volumePath string) { + TestVolumeUnmountsFromDeletedPodWithForceOption(ctx, c, f, clientPod, false, false, nil, volumePath) } // TestVolumeUnmountsFromForceDeletedPod tests that a volume unmounts if the client pod was forcefully deleted while the kubelet was down. -func TestVolumeUnmountsFromForceDeletedPod(c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, volumePath string) { - TestVolumeUnmountsFromDeletedPodWithForceOption(c, f, clientPod, true, false, nil, volumePath) +func TestVolumeUnmountsFromForceDeletedPod(ctx context.Context, c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, volumePath string) { + TestVolumeUnmountsFromDeletedPodWithForceOption(ctx, c, f, clientPod, true, false, nil, volumePath) } // TestVolumeUnmapsFromDeletedPodWithForceOption tests that a volume unmaps if the client pod was deleted while the kubelet was down. // forceDelete is true indicating whether the pod is forcefully deleted. -func TestVolumeUnmapsFromDeletedPodWithForceOption(c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, forceDelete bool, devicePath string) { - nodeIP, err := getHostAddress(c, clientPod) +func TestVolumeUnmapsFromDeletedPodWithForceOption(ctx context.Context, c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, forceDelete bool, devicePath string) { + nodeIP, err := getHostAddress(ctx, c, clientPod) framework.ExpectNoError(err, "Failed to get nodeIP.") nodeIP = nodeIP + ":22" // Creating command to check whether path exists podDirectoryCmd := fmt.Sprintf("ls /var/lib/kubelet/pods/%s/volumeDevices/*/ | grep '.'", clientPod.UID) - if isSudoPresent(nodeIP, framework.TestContext.Provider) { + if isSudoPresent(ctx, nodeIP, framework.TestContext.Provider) { podDirectoryCmd = fmt.Sprintf("sudo sh -c \"%s\"", podDirectoryCmd) } // Directories in the global directory have unpredictable names, however, device symlinks // have the same name as pod.UID. So just find anything with pod.UID name. globalBlockDirectoryCmd := fmt.Sprintf("find /var/lib/kubelet/plugins -name %s", clientPod.UID) - if isSudoPresent(nodeIP, framework.TestContext.Provider) { + if isSudoPresent(ctx, nodeIP, framework.TestContext.Provider) { globalBlockDirectoryCmd = fmt.Sprintf("sudo sh -c \"%s\"", globalBlockDirectoryCmd) } ginkgo.By("Expecting the symlinks from PodDeviceMapPath to be found.") - result, err := e2essh.SSH(podDirectoryCmd, nodeIP, framework.TestContext.Provider) + result, err := e2essh.SSH(ctx, podDirectoryCmd, nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error.") framework.ExpectEqual(result.Code, 0, fmt.Sprintf("Expected grep exit code of 0, got %d", result.Code)) ginkgo.By("Expecting the symlinks from global map path to be found.") - result, err = e2essh.SSH(globalBlockDirectoryCmd, nodeIP, framework.TestContext.Provider) + result, err = e2essh.SSH(ctx, globalBlockDirectoryCmd, nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error.") framework.ExpectEqual(result.Code, 0, fmt.Sprintf("Expected find exit code of 0, got %d", result.Code)) // This command is to make sure kubelet is started after test finishes no matter it fails or not. - defer func() { - KubeletCommand(KStart, c, clientPod) - }() + ginkgo.DeferCleanup(KubeletCommand, KStart, c, clientPod) ginkgo.By("Stopping the kubelet.") - KubeletCommand(KStop, c, clientPod) + KubeletCommand(ctx, KStop, c, clientPod) ginkgo.By(fmt.Sprintf("Deleting Pod %q", clientPod.Name)) if forceDelete { - err = c.CoreV1().Pods(clientPod.Namespace).Delete(context.TODO(), clientPod.Name, *metav1.NewDeleteOptions(0)) + err = c.CoreV1().Pods(clientPod.Namespace).Delete(ctx, clientPod.Name, *metav1.NewDeleteOptions(0)) } else { - err = c.CoreV1().Pods(clientPod.Namespace).Delete(context.TODO(), clientPod.Name, metav1.DeleteOptions{}) + err = c.CoreV1().Pods(clientPod.Namespace).Delete(ctx, clientPod.Name, metav1.DeleteOptions{}) } framework.ExpectNoError(err, "Failed to delete pod.") ginkgo.By("Starting the kubelet and waiting for pod to delete.") - KubeletCommand(KStart, c, clientPod) - err = e2epod.WaitForPodNotFoundInNamespace(f.ClientSet, clientPod.Name, f.Namespace.Name, f.Timeouts.PodDelete) + KubeletCommand(ctx, KStart, c, clientPod) + err = e2epod.WaitForPodNotFoundInNamespace(ctx, f.ClientSet, clientPod.Name, f.Namespace.Name, f.Timeouts.PodDelete) framework.ExpectNoError(err, "Expected pod to be not found.") if forceDelete { @@ -299,13 +295,13 @@ func TestVolumeUnmapsFromDeletedPodWithForceOption(c clientset.Interface, f *fra } ginkgo.By("Expecting the symlink from PodDeviceMapPath not to be found.") - result, err = e2essh.SSH(podDirectoryCmd, nodeIP, framework.TestContext.Provider) + result, err = e2essh.SSH(ctx, podDirectoryCmd, nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error.") gomega.Expect(result.Stdout).To(gomega.BeEmpty(), "Expected grep stdout to be empty.") ginkgo.By("Expecting the symlinks from global map path not to be found.") - result, err = e2essh.SSH(globalBlockDirectoryCmd, nodeIP, framework.TestContext.Provider) + result, err = e2essh.SSH(ctx, globalBlockDirectoryCmd, nodeIP, framework.TestContext.Provider) e2essh.LogResult(result) framework.ExpectNoError(err, "Encountered SSH error.") gomega.Expect(result.Stdout).To(gomega.BeEmpty(), "Expected find stdout to be empty.") @@ -314,17 +310,17 @@ func TestVolumeUnmapsFromDeletedPodWithForceOption(c clientset.Interface, f *fra } // TestVolumeUnmapsFromDeletedPod tests that a volume unmaps if the client pod was deleted while the kubelet was down. -func TestVolumeUnmapsFromDeletedPod(c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, devicePath string) { - TestVolumeUnmapsFromDeletedPodWithForceOption(c, f, clientPod, false, devicePath) +func TestVolumeUnmapsFromDeletedPod(ctx context.Context, c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, devicePath string) { + TestVolumeUnmapsFromDeletedPodWithForceOption(ctx, c, f, clientPod, false, devicePath) } // TestVolumeUnmapsFromForceDeletedPod tests that a volume unmaps if the client pod was forcefully deleted while the kubelet was down. -func TestVolumeUnmapsFromForceDeletedPod(c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, devicePath string) { - TestVolumeUnmapsFromDeletedPodWithForceOption(c, f, clientPod, true, devicePath) +func TestVolumeUnmapsFromForceDeletedPod(ctx context.Context, c clientset.Interface, f *framework.Framework, clientPod *v1.Pod, devicePath string) { + TestVolumeUnmapsFromDeletedPodWithForceOption(ctx, c, f, clientPod, true, devicePath) } // RunInPodWithVolume runs a command in a pod with given claim mounted to /mnt directory. -func RunInPodWithVolume(c clientset.Interface, t *framework.TimeoutContext, ns, claimName, command string) { +func RunInPodWithVolume(ctx context.Context, c clientset.Interface, t *framework.TimeoutContext, ns, claimName, command string) { pod := &v1.Pod{ TypeMeta: metav1.TypeMeta{ Kind: "Pod", @@ -362,16 +358,14 @@ func RunInPodWithVolume(c clientset.Interface, t *framework.TimeoutContext, ns, }, }, } - pod, err := c.CoreV1().Pods(ns).Create(context.TODO(), pod, metav1.CreateOptions{}) + pod, err := c.CoreV1().Pods(ns).Create(ctx, pod, metav1.CreateOptions{}) framework.ExpectNoError(err, "Failed to create pod: %v", err) - defer func() { - e2epod.DeletePodOrFail(c, ns, pod.Name) - }() - framework.ExpectNoError(e2epod.WaitForPodSuccessInNamespaceTimeout(c, pod.Name, pod.Namespace, t.PodStartSlow)) + ginkgo.DeferCleanup(e2epod.DeletePodOrFail, c, ns, pod.Name) + framework.ExpectNoError(e2epod.WaitForPodSuccessInNamespaceTimeout(ctx, c, pod.Name, pod.Namespace, t.PodStartSlow)) } // StartExternalProvisioner create external provisioner pod -func StartExternalProvisioner(c clientset.Interface, ns string, externalPluginName string) *v1.Pod { +func StartExternalProvisioner(ctx context.Context, c clientset.Interface, ns string, externalPluginName string) *v1.Pod { podClient := c.CoreV1().Pods(ns) provisionerPod := &v1.Pod{ @@ -432,21 +426,21 @@ func StartExternalProvisioner(c clientset.Interface, ns string, externalPluginNa }, }, } - provisionerPod, err := podClient.Create(context.TODO(), provisionerPod, metav1.CreateOptions{}) + provisionerPod, err := podClient.Create(ctx, provisionerPod, metav1.CreateOptions{}) framework.ExpectNoError(err, "Failed to create %s pod: %v", provisionerPod.Name, err) - framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(c, provisionerPod)) + framework.ExpectNoError(e2epod.WaitForPodRunningInNamespace(ctx, c, provisionerPod)) ginkgo.By("locating the provisioner pod") - pod, err := podClient.Get(context.TODO(), provisionerPod.Name, metav1.GetOptions{}) + pod, err := podClient.Get(ctx, provisionerPod.Name, metav1.GetOptions{}) framework.ExpectNoError(err, "Cannot locate the provisioner pod %v: %v", provisionerPod.Name, err) return pod } -func isSudoPresent(nodeIP string, provider string) bool { +func isSudoPresent(ctx context.Context, nodeIP string, provider string) bool { framework.Logf("Checking if sudo command is present") - sshResult, err := e2essh.SSH("sudo --version", nodeIP, provider) + sshResult, err := e2essh.SSH(ctx, "sudo --version", nodeIP, provider) framework.ExpectNoError(err, "SSH to %q errored.", nodeIP) if !strings.Contains(sshResult.Stderr, "command not found") { return true @@ -562,8 +556,8 @@ func GetSectorSize(f *framework.Framework, pod *v1.Pod, device string) int { } // findMountPoints returns all mount points on given node under specified directory. -func findMountPoints(hostExec HostExec, node *v1.Node, dir string) []string { - result, err := hostExec.IssueCommandWithResult(fmt.Sprintf(`find %s -type d -exec mountpoint {} \; | grep 'is a mountpoint$' || true`, dir), node) +func findMountPoints(ctx context.Context, hostExec HostExec, node *v1.Node, dir string) []string { + result, err := hostExec.IssueCommandWithResult(ctx, fmt.Sprintf(`find %s -type d -exec mountpoint {} \; | grep 'is a mountpoint$' || true`, dir), node) framework.ExpectNoError(err, "Encountered HostExec error.") var mountPoints []string if err != nil { @@ -578,16 +572,16 @@ func findMountPoints(hostExec HostExec, node *v1.Node, dir string) []string { } // FindVolumeGlobalMountPoints returns all volume global mount points on the node of given pod. -func FindVolumeGlobalMountPoints(hostExec HostExec, node *v1.Node) sets.String { - return sets.NewString(findMountPoints(hostExec, node, "/var/lib/kubelet/plugins")...) +func FindVolumeGlobalMountPoints(ctx context.Context, hostExec HostExec, node *v1.Node) sets.String { + return sets.NewString(findMountPoints(ctx, hostExec, node, "/var/lib/kubelet/plugins")...) } // CreateDriverNamespace creates a namespace for CSI driver installation. // The namespace is still tracked and ensured that gets deleted when test terminates. -func CreateDriverNamespace(f *framework.Framework) *v1.Namespace { +func CreateDriverNamespace(ctx context.Context, f *framework.Framework) *v1.Namespace { ginkgo.By(fmt.Sprintf("Building a driver namespace object, basename %s", f.Namespace.Name)) // The driver namespace will be bound to the test namespace in the prefix - namespace, err := f.CreateNamespace(f.Namespace.Name, map[string]string{ + namespace, err := f.CreateNamespace(ctx, f.Namespace.Name, map[string]string{ "e2e-framework": f.BaseName, "e2e-test-namespace": f.Namespace.Name, }) @@ -595,7 +589,7 @@ func CreateDriverNamespace(f *framework.Framework) *v1.Namespace { if framework.TestContext.VerifyServiceAccount { ginkgo.By("Waiting for a default service account to be provisioned in namespace") - err = framework.WaitForDefaultServiceAccountInNamespace(f.ClientSet, namespace.Name) + err = framework.WaitForDefaultServiceAccountInNamespace(ctx, f.ClientSet, namespace.Name) framework.ExpectNoError(err) } else { framework.Logf("Skipping waiting for service account") @@ -604,11 +598,11 @@ func CreateDriverNamespace(f *framework.Framework) *v1.Namespace { } // WaitForGVRDeletion waits until a non-namespaced object has been deleted -func WaitForGVRDeletion(c dynamic.Interface, gvr schema.GroupVersionResource, objectName string, poll, timeout time.Duration) error { +func WaitForGVRDeletion(ctx context.Context, c dynamic.Interface, gvr schema.GroupVersionResource, objectName string, poll, timeout time.Duration) error { framework.Logf("Waiting up to %v for %s %s to be deleted", timeout, gvr.Resource, objectName) if successful := WaitUntil(poll, timeout, func() bool { - _, err := c.Resource(gvr).Get(context.TODO(), objectName, metav1.GetOptions{}) + _, err := c.Resource(gvr).Get(ctx, objectName, metav1.GetOptions{}) if err != nil && apierrors.IsNotFound(err) { framework.Logf("%s %v is not found and has been deleted", gvr.Resource, objectName) return true @@ -627,11 +621,11 @@ func WaitForGVRDeletion(c dynamic.Interface, gvr schema.GroupVersionResource, ob } // WaitForNamespacedGVRDeletion waits until a namespaced object has been deleted -func WaitForNamespacedGVRDeletion(c dynamic.Interface, gvr schema.GroupVersionResource, ns, objectName string, poll, timeout time.Duration) error { +func WaitForNamespacedGVRDeletion(ctx context.Context, c dynamic.Interface, gvr schema.GroupVersionResource, ns, objectName string, poll, timeout time.Duration) error { framework.Logf("Waiting up to %v for %s %s to be deleted", timeout, gvr.Resource, objectName) if successful := WaitUntil(poll, timeout, func() bool { - _, err := c.Resource(gvr).Namespace(ns).Get(context.TODO(), objectName, metav1.GetOptions{}) + _, err := c.Resource(gvr).Namespace(ns).Get(ctx, objectName, metav1.GetOptions{}) if err != nil && apierrors.IsNotFound(err) { framework.Logf("%s %s is not found in namespace %s and has been deleted", gvr.Resource, objectName, ns) return true @@ -651,6 +645,7 @@ func WaitForNamespacedGVRDeletion(c dynamic.Interface, gvr schema.GroupVersionRe // WaitUntil runs checkDone until a timeout is reached func WaitUntil(poll, timeout time.Duration, checkDone func() bool) bool { + // TODO (pohly): replace with gomega.Eventually for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) { if checkDone() { framework.Logf("WaitUntil finished successfully after %v", time.Since(start)) @@ -716,8 +711,8 @@ func ChangeFilePathGidInPod(f *framework.Framework, filePath, targetGid string, } // DeleteStorageClass deletes the passed in StorageClass and catches errors other than "Not Found" -func DeleteStorageClass(cs clientset.Interface, className string) error { - err := cs.StorageV1().StorageClasses().Delete(context.TODO(), className, metav1.DeleteOptions{}) +func DeleteStorageClass(ctx context.Context, cs clientset.Interface, className string) error { + err := cs.StorageV1().StorageClasses().Delete(ctx, className, metav1.DeleteOptions{}) if err != nil && !apierrors.IsNotFound(err) { return err } diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/embed.go b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/embed.go index a763b2fc8..bc0e9070f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/embed.go +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/embed.go @@ -22,7 +22,7 @@ import ( e2etestfiles "k8s.io/kubernetes/test/e2e/framework/testfiles" ) -//go:embed cluster-dns flexvolume guestbook kubectl sample-device-plugin.yaml scheduling/nvidia-driver-installer.yaml statefulset storage-csi +//go:embed cluster-dns flexvolume guestbook kubectl sample-device-plugin scheduling/nvidia-driver-installer.yaml statefulset storage-csi var e2eTestingManifestsFS embed.FS func GetE2ETestingManifestsFS() e2etestfiles.EmbeddedFileSource { diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/sample-device-plugin/sample-device-plugin-control-registration.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/sample-device-plugin/sample-device-plugin-control-registration.yaml new file mode 100644 index 000000000..54cf07c46 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/sample-device-plugin/sample-device-plugin-control-registration.yaml @@ -0,0 +1,52 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: sample-device-plugin-beta + namespace: kube-system + labels: + k8s-app: sample-device-plugin +spec: + selector: + matchLabels: + k8s-app: sample-device-plugin + template: + metadata: + labels: + k8s-app: sample-device-plugin + annotations: + spec: + priorityClassName: system-node-critical + tolerations: + - operator: "Exists" + effect: "NoExecute" + - operator: "Exists" + effect: "NoSchedule" + volumes: + - name: device-plugin + hostPath: + path: /var/lib/kubelet/device-plugins + - name: plugins-registry-probe-mode + hostPath: + path: /var/lib/kubelet/plugins_registry + - name: dev + hostPath: + path: /dev + containers: + - image: registry.k8s.io/e2e-test-images/sample-device-plugin:1.5 + name: sample-device-plugin + env: + - name: PLUGIN_SOCK_DIR + value: "/var/lib/kubelet/device-plugins" + - name: REGISTER_CONTROL_FILE + value: "/var/lib/kubelet/device-plugins/sample/registration" + securityContext: + privileged: true + volumeMounts: + - name: device-plugin + mountPath: /var/lib/kubelet/device-plugins + - name: plugins-registry-probe-mode + mountPath: /var/lib/kubelet/plugins_registry + - name: dev + mountPath: /dev + updateStrategy: + type: RollingUpdate diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/sample-device-plugin.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/sample-device-plugin/sample-device-plugin.yaml similarity index 100% rename from vendor/k8s.io/kubernetes/test/e2e/testing-manifests/sample-device-plugin.yaml rename to vendor/k8s.io/kubernetes/test/e2e/testing-manifests/sample-device-plugin/sample-device-plugin.yaml diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml index 0ca5a187f..e6be99ae5 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml @@ -39,7 +39,7 @@ spec: - name: socket-dir mountPath: /csi - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v3.3.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v3.4.0 args: - "--v=5" - "--csi-address=/csi/csi.sock" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml index afca3241f..6a41a0239 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml @@ -218,7 +218,7 @@ spec: serviceAccountName: csi-hostpathplugin-sa containers: - name: hostpath - image: registry.k8s.io/sig-storage/hostpathplugin:v1.9.0 + image: registry.k8s.io/sig-storage/hostpathplugin:v1.11.0 args: - "--drivername=hostpath.csi.k8s.io" - "--v=5" @@ -323,7 +323,7 @@ spec: name: socket-dir - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v3.3.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v3.4.0 args: - -v=5 - --csi-address=/csi/csi.sock diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver.yaml index 29570e39f..4493deccc 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: csi-mock containers: - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v3.3.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v3.4.0 args: - "--csi-address=$(ADDRESS)" # Topology support is needed for the pod rescheduling test diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-proxy.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-proxy.yaml index ba27f9367..d1aa8ece8 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-proxy.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-proxy.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: csi-mock containers: - name: csi-provisioner - image: registry.k8s.io/sig-storage/csi-provisioner:v3.3.0 + image: registry.k8s.io/sig-storage/csi-provisioner:v3.4.0 args: - "--csi-address=$(ADDRESS)" # Topology support is needed for the pod rescheduling test diff --git a/vendor/k8s.io/kubernetes/test/utils/audit.go b/vendor/k8s.io/kubernetes/test/utils/audit.go index 0156303f6..73abf4501 100644 --- a/vendor/k8s.io/kubernetes/test/utils/audit.go +++ b/vendor/k8s.io/kubernetes/test/utils/audit.go @@ -53,8 +53,13 @@ type AuditEvent struct { // not reference these maps after calling the Check functions. AdmissionWebhookMutationAnnotations map[string]string AdmissionWebhookPatchAnnotations map[string]string + + // Only populated when a filter is provided to testEventFromInternalFiltered + CustomAuditAnnotations map[string]string } +type AuditAnnotationsFilter func(key, val string) bool + // MissingEventsReport provides an analysis if any events are missing type MissingEventsReport struct { FirstEventChecked *auditinternal.Event @@ -78,6 +83,13 @@ func (m *MissingEventsReport) String() string { // CheckAuditLines searches the audit log for the expected audit lines. func CheckAuditLines(stream io.Reader, expected []AuditEvent, version schema.GroupVersion) (missingReport *MissingEventsReport, err error) { + return CheckAuditLinesFiltered(stream, expected, version, nil) +} + +// CheckAuditLinesFiltered searches the audit log for the expected audit lines, customAnnotationsFilter +// controls which audit annotations are added to AuditEvent.CustomAuditAnnotations. +// If the customAnnotationsFilter is nil, AuditEvent.CustomAuditAnnotations will be empty. +func CheckAuditLinesFiltered(stream io.Reader, expected []AuditEvent, version schema.GroupVersion, customAnnotationsFilter AuditAnnotationsFilter) (missingReport *MissingEventsReport, err error) { expectations := newAuditEventTracker(expected) scanner := bufio.NewScanner(stream) @@ -100,7 +112,7 @@ func CheckAuditLines(stream io.Reader, expected []AuditEvent, version schema.Gro } missingReport.LastEventChecked = e - event, err := testEventFromInternal(e) + event, err := testEventFromInternalFiltered(e, customAnnotationsFilter) if err != nil { return missingReport, err } @@ -162,6 +174,13 @@ func CheckForDuplicates(el auditinternal.EventList) (auditinternal.EventList, er // testEventFromInternal takes an internal audit event and returns a test event func testEventFromInternal(e *auditinternal.Event) (AuditEvent, error) { + return testEventFromInternalFiltered(e, nil) +} + +// testEventFromInternalFiltered takes an internal audit event and returns a test event, customAnnotationsFilter +// controls which audit annotations are added to AuditEvent.CustomAuditAnnotations. +// If the customAnnotationsFilter is nil, AuditEvent.CustomAuditAnnotations will be empty. +func testEventFromInternalFiltered(e *auditinternal.Event, customAnnotationsFilter AuditAnnotationsFilter) (AuditEvent, error) { event := AuditEvent{ Level: e.Level, Stage: e.Stage, @@ -199,6 +218,11 @@ func testEventFromInternal(e *auditinternal.Event) (AuditEvent, error) { event.AdmissionWebhookMutationAnnotations = map[string]string{} } event.AdmissionWebhookMutationAnnotations[k] = v + } else if customAnnotationsFilter != nil && customAnnotationsFilter(k, v) { + if event.CustomAuditAnnotations == nil { + event.CustomAuditAnnotations = map[string]string{} + } + event.CustomAuditAnnotations[k] = v } } return event, nil diff --git a/vendor/k8s.io/kubernetes/test/utils/format/format.go b/vendor/k8s.io/kubernetes/test/utils/format/format.go new file mode 100644 index 000000000..a77f697ad --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/utils/format/format.go @@ -0,0 +1,80 @@ +/* +Copyright 2022 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 format is an extension of Gomega's format package which +// improves printing of objects that can be serialized well as YAML, +// like the structs in the Kubernetes API. +// +// Just importing it is enough to activate this special YAML support +// in Gomega. +package format + +import ( + "reflect" + "strings" + + "github.com/onsi/gomega/format" + + "sigs.k8s.io/yaml" +) + +func init() { + format.RegisterCustomFormatter(handleYAML) +} + +// Object makes Gomega's [format.Object] available without having to import that +// package. +func Object(object interface{}, indentation uint) string { + return format.Object(object, indentation) +} + +// handleYAML formats all values as YAML where the result +// is likely to look better as YAML: +// - pointer to struct or struct where all fields +// have `json` tags +// - slices containing such a value +// - maps where the key or value are such a value +func handleYAML(object interface{}) (string, bool) { + value := reflect.ValueOf(object) + if !useYAML(value.Type()) { + return "", false + } + y, err := yaml.Marshal(object) + if err != nil { + return "", false + } + return "\n" + strings.TrimSpace(string(y)), true +} + +func useYAML(t reflect.Type) bool { + switch t.Kind() { + case reflect.Pointer, reflect.Slice, reflect.Array: + return useYAML(t.Elem()) + case reflect.Map: + return useYAML(t.Key()) || useYAML(t.Elem()) + case reflect.Struct: + // All fields must have a `json` tag. + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if _, ok := field.Tag.Lookup("json"); !ok { + return false + } + } + return true + default: + return false + } +} diff --git a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go index 974c21af8..eae32ff5a 100644 --- a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go +++ b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go @@ -68,12 +68,16 @@ func (i *Config) SetVersion(version string) { i.version = version } -func initReg() RegistryList { +func Init(repoList string) { + registry, imageConfigs, originalImageConfigs = readRepoList(repoList) +} + +func readRepoList(repoList string) (RegistryList, map[ImageID]Config, map[ImageID]Config) { registry := initRegistry - repoList := os.Getenv("KUBE_TEST_REPO_LIST") if repoList == "" { - return registry + imageConfigs, originalImageConfigs := initImageConfigs(registry) + return registry, imageConfigs, originalImageConfigs } var fileContent []byte @@ -94,9 +98,13 @@ func initReg() RegistryList { err = yaml.Unmarshal(fileContent, ®istry) if err != nil { - panic(fmt.Errorf("Error unmarshalling '%v' YAML file: %v", repoList, err)) + panic(fmt.Errorf("error unmarshalling '%v' YAML file: %v", repoList, err)) } - return registry + + imageConfigs, originalImageConfigs := initImageConfigs(registry) + + return registry, imageConfigs, originalImageConfigs + } // Essentially curl url | writer @@ -135,10 +143,7 @@ var ( CloudProviderGcpRegistry: "registry.k8s.io/cloud-provider-gcp", } - registry = initReg() - - // Preconfigured image configs - imageConfigs, originalImageConfigs = initImageConfigs(registry) + registry, imageConfigs, originalImageConfigs = readRepoList(os.Getenv("KUBE_TEST_REPO_LIST")) ) type ImageID int @@ -240,8 +245,8 @@ func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.29-4"} configs[CudaVectorAdd] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "1.0"} configs[CudaVectorAdd2] = Config{list.PromoterE2eRegistry, "cuda-vector-add", "2.2"} - configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.1.2"} - configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.6-0"} + configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.2.3"} + configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.7-0"} configs[GlusterDynamicProvisioner] = Config{list.PromoterE2eRegistry, "glusterdynamic-provisioner", "v1.3"} configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-4"} configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-4"} diff --git a/vendor/k8s.io/kubernetes/test/utils/runners.go b/vendor/k8s.io/kubernetes/test/utils/runners.go index 344e7fc54..6e18e8b9c 100644 --- a/vendor/k8s.io/kubernetes/test/utils/runners.go +++ b/vendor/k8s.io/kubernetes/test/utils/runners.go @@ -49,6 +49,7 @@ import ( batchinternal "k8s.io/kubernetes/pkg/apis/batch" api "k8s.io/kubernetes/pkg/apis/core" extensionsinternal "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/utils/pointer" "k8s.io/klog/v2" ) @@ -65,17 +66,17 @@ func removePtr(replicas *int32) int32 { return *replicas } -func WaitUntilPodIsScheduled(c clientset.Interface, name, namespace string, timeout time.Duration) (*v1.Pod, error) { +func WaitUntilPodIsScheduled(ctx context.Context, c clientset.Interface, name, namespace string, timeout time.Duration) (*v1.Pod, error) { // Wait until it's scheduled - p, err := c.CoreV1().Pods(namespace).Get(context.TODO(), name, metav1.GetOptions{ResourceVersion: "0"}) + p, err := c.CoreV1().Pods(namespace).Get(ctx, name, metav1.GetOptions{ResourceVersion: "0"}) if err == nil && p.Spec.NodeName != "" { return p, nil } pollingPeriod := 200 * time.Millisecond startTime := time.Now() - for startTime.Add(timeout).After(time.Now()) { + for startTime.Add(timeout).After(time.Now()) && ctx.Err() == nil { time.Sleep(pollingPeriod) - p, err := c.CoreV1().Pods(namespace).Get(context.TODO(), name, metav1.GetOptions{ResourceVersion: "0"}) + p, err := c.CoreV1().Pods(namespace).Get(ctx, name, metav1.GetOptions{ResourceVersion: "0"}) if err == nil && p.Spec.NodeName != "" { return p, nil } @@ -83,13 +84,13 @@ func WaitUntilPodIsScheduled(c clientset.Interface, name, namespace string, time return nil, fmt.Errorf("timed out after %v when waiting for pod %v/%v to start", timeout, namespace, name) } -func RunPodAndGetNodeName(c clientset.Interface, pod *v1.Pod, timeout time.Duration) (string, error) { +func RunPodAndGetNodeName(ctx context.Context, c clientset.Interface, pod *v1.Pod, timeout time.Duration) (string, error) { name := pod.Name namespace := pod.Namespace if err := CreatePodWithRetries(c, namespace, pod); err != nil { return "", err } - p, err := WaitUntilPodIsScheduled(c, name, namespace, timeout) + p, err := WaitUntilPodIsScheduled(ctx, c, name, namespace, timeout) if err != nil { return "", err } @@ -173,8 +174,8 @@ type RCConfig struct { LogFunc func(fmt string, args ...interface{}) // If set those functions will be used to gather data from Nodes - in integration tests where no // kubelets are running those variables should be nil. - NodeDumpFunc func(c clientset.Interface, nodeNames []string, logFunc func(fmt string, args ...interface{})) - ContainerDumpFunc func(c clientset.Interface, ns string, logFunc func(ftm string, args ...interface{})) + NodeDumpFunc func(ctx context.Context, c clientset.Interface, nodeNames []string, logFunc func(fmt string, args ...interface{})) + ContainerDumpFunc func(ctx context.Context, c clientset.Interface, ns string, logFunc func(ftm string, args ...interface{})) // Names of the secrets and configmaps to mount. SecretNames []string @@ -288,16 +289,16 @@ func Diff(oldPods []*v1.Pod, curPods []*v1.Pod) PodDiff { // and will wait for all pods it spawns to become "Running". // It's the caller's responsibility to clean up externally (i.e. use the // namespace lifecycle for handling Cleanup). -func RunDeployment(config DeploymentConfig) error { +func RunDeployment(ctx context.Context, config DeploymentConfig) error { err := config.create() if err != nil { return err } - return config.start() + return config.start(ctx) } -func (config *DeploymentConfig) Run() error { - return RunDeployment(*config) +func (config *DeploymentConfig) Run(ctx context.Context) error { + return RunDeployment(ctx, *config) } func (config *DeploymentConfig) GetKind() schema.GroupKind { @@ -318,7 +319,7 @@ func (config *DeploymentConfig) create() error { Name: config.Name, }, Spec: apps.DeploymentSpec{ - Replicas: func(i int) *int32 { x := int32(i); return &x }(config.Replicas), + Replicas: pointer.Int32(int32(config.Replicas)), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "name": config.Name, @@ -374,16 +375,16 @@ func (config *DeploymentConfig) create() error { // and waits until all the pods it launches to reach the "Running" state. // It's the caller's responsibility to clean up externally (i.e. use the // namespace lifecycle for handling Cleanup). -func RunReplicaSet(config ReplicaSetConfig) error { +func RunReplicaSet(ctx context.Context, config ReplicaSetConfig) error { err := config.create() if err != nil { return err } - return config.start() + return config.start(ctx) } -func (config *ReplicaSetConfig) Run() error { - return RunReplicaSet(*config) +func (config *ReplicaSetConfig) Run(ctx context.Context) error { + return RunReplicaSet(ctx, *config) } func (config *ReplicaSetConfig) GetKind() schema.GroupKind { @@ -404,7 +405,7 @@ func (config *ReplicaSetConfig) create() error { Name: config.Name, }, Spec: apps.ReplicaSetSpec{ - Replicas: func(i int) *int32 { x := int32(i); return &x }(config.Replicas), + Replicas: pointer.Int32(int32(config.Replicas)), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "name": config.Name, @@ -456,16 +457,16 @@ func (config *ReplicaSetConfig) create() error { // and will wait for all pods it spawns to become "Running". // It's the caller's responsibility to clean up externally (i.e. use the // namespace lifecycle for handling Cleanup). -func RunJob(config JobConfig) error { +func RunJob(ctx context.Context, config JobConfig) error { err := config.create() if err != nil { return err } - return config.start() + return config.start(ctx) } -func (config *JobConfig) Run() error { - return RunJob(*config) +func (config *JobConfig) Run(ctx context.Context) error { + return RunJob(ctx, *config) } func (config *JobConfig) GetKind() schema.GroupKind { @@ -486,8 +487,8 @@ func (config *JobConfig) create() error { Name: config.Name, }, Spec: batch.JobSpec{ - Parallelism: func(i int) *int32 { x := int32(i); return &x }(config.Replicas), - Completions: func(i int) *int32 { x := int32(i); return &x }(config.Replicas), + Parallelism: pointer.Int32(int32(config.Replicas)), + Completions: pointer.Int32(int32(config.Replicas)), Template: v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{"name": config.Name}, @@ -530,16 +531,16 @@ func (config *JobConfig) create() error { // and will wait for all pods it spawns to become "Running". // It's the caller's responsibility to clean up externally (i.e. use the // namespace lifecycle for handling Cleanup). -func RunRC(config RCConfig) error { +func RunRC(ctx context.Context, config RCConfig) error { err := config.create() if err != nil { return err } - return config.start() + return config.start(ctx) } -func (config *RCConfig) Run() error { - return RunRC(*config) +func (config *RCConfig) Run(ctx context.Context) error { + return RunRC(ctx, *config) } func (config *RCConfig) GetName() string { @@ -598,7 +599,7 @@ func (config *RCConfig) create() error { Name: config.Name, }, Spec: v1.ReplicationControllerSpec{ - Replicas: func(i int) *int32 { x := int32(i); return &x }(config.Replicas), + Replicas: pointer.Int32(int32(config.Replicas)), Selector: map[string]string{ "name": config.Name, }, @@ -776,7 +777,7 @@ func ComputeRCStartupStatus(pods []*v1.Pod, expected int) RCStartupStatus { return startupStatus } -func (config *RCConfig) start() error { +func (config *RCConfig) start(ctx context.Context) error { // Don't force tests to fail if they don't care about containers restarting. var maxContainerFailures int if config.MaxContainerFailures == nil { @@ -824,11 +825,11 @@ func (config *RCConfig) start() error { if startupStatus.FailedContainers > maxContainerFailures { if config.NodeDumpFunc != nil { - config.NodeDumpFunc(config.Client, startupStatus.ContainerRestartNodes.List(), config.RCConfigLog) + config.NodeDumpFunc(ctx, config.Client, startupStatus.ContainerRestartNodes.List(), config.RCConfigLog) } if config.ContainerDumpFunc != nil { // Get the logs from the failed containers to help diagnose what caused them to fail - config.ContainerDumpFunc(config.Client, config.Namespace, config.RCConfigLog) + config.ContainerDumpFunc(ctx, config.Client, config.Namespace, config.RCConfigLog) } return fmt.Errorf("%d containers failed which is more than allowed %d", startupStatus.FailedContainers, maxContainerFailures) } @@ -858,7 +859,7 @@ func (config *RCConfig) start() error { if oldRunning != config.Replicas { // List only pods from a given replication controller. options := metav1.ListOptions{LabelSelector: label.String()} - if pods, err := config.Client.CoreV1().Pods(config.Namespace).List(context.TODO(), options); err == nil { + if pods, err := config.Client.CoreV1().Pods(config.Namespace).List(ctx, options); err == nil { for _, pod := range pods.Items { config.RCConfigLog("Pod %s\t%s\t%s\t%s", pod.Name, pod.Spec.NodeName, pod.Status.Phase, pod.DeletionTimestamp) } @@ -946,8 +947,8 @@ type CountToStrategy struct { } type TestNodePreparer interface { - PrepareNodes(nextNodeIndex int) error - CleanupNodes() error + PrepareNodes(ctx context.Context, nextNodeIndex int) error + CleanupNodes(ctx context.Context) error } type PrepareNodeStrategy interface { @@ -955,12 +956,12 @@ type PrepareNodeStrategy interface { PreparePatch(node *v1.Node) []byte // Create or modify any objects that depend on the node before the test starts. // Caller will re-try when http.StatusConflict error is returned. - PrepareDependentObjects(node *v1.Node, client clientset.Interface) error + PrepareDependentObjects(ctx context.Context, node *v1.Node, client clientset.Interface) error // Clean up any node modifications after the test finishes. - CleanupNode(node *v1.Node) *v1.Node + CleanupNode(ctx context.Context, node *v1.Node) *v1.Node // Clean up any objects that depend on the node after the test finishes. // Caller will re-try when http.StatusConflict error is returned. - CleanupDependentObjects(nodeName string, client clientset.Interface) error + CleanupDependentObjects(ctx context.Context, nodeName string, client clientset.Interface) error } type TrivialNodePrepareStrategy struct{} @@ -971,16 +972,16 @@ func (*TrivialNodePrepareStrategy) PreparePatch(*v1.Node) []byte { return []byte{} } -func (*TrivialNodePrepareStrategy) CleanupNode(node *v1.Node) *v1.Node { +func (*TrivialNodePrepareStrategy) CleanupNode(ctx context.Context, node *v1.Node) *v1.Node { nodeCopy := *node return &nodeCopy } -func (*TrivialNodePrepareStrategy) PrepareDependentObjects(node *v1.Node, client clientset.Interface) error { +func (*TrivialNodePrepareStrategy) PrepareDependentObjects(ctx context.Context, node *v1.Node, client clientset.Interface) error { return nil } -func (*TrivialNodePrepareStrategy) CleanupDependentObjects(nodeName string, client clientset.Interface) error { +func (*TrivialNodePrepareStrategy) CleanupDependentObjects(ctx context.Context, nodeName string, client clientset.Interface) error { return nil } @@ -1009,7 +1010,7 @@ func (s *LabelNodePrepareStrategy) PreparePatch(*v1.Node) []byte { return []byte(patch) } -func (s *LabelNodePrepareStrategy) CleanupNode(node *v1.Node) *v1.Node { +func (s *LabelNodePrepareStrategy) CleanupNode(ctx context.Context, node *v1.Node) *v1.Node { nodeCopy := node.DeepCopy() if node.Labels != nil && len(node.Labels[s.LabelKey]) != 0 { delete(nodeCopy.Labels, s.LabelKey) @@ -1017,11 +1018,11 @@ func (s *LabelNodePrepareStrategy) CleanupNode(node *v1.Node) *v1.Node { return nodeCopy } -func (*LabelNodePrepareStrategy) PrepareDependentObjects(node *v1.Node, client clientset.Interface) error { +func (*LabelNodePrepareStrategy) PrepareDependentObjects(ctx context.Context, node *v1.Node, client clientset.Interface) error { return nil } -func (*LabelNodePrepareStrategy) CleanupDependentObjects(nodeName string, client clientset.Interface) error { +func (*LabelNodePrepareStrategy) CleanupDependentObjects(ctx context.Context, nodeName string, client clientset.Interface) error { return nil } @@ -1069,7 +1070,7 @@ func (s *NodeAllocatableStrategy) PreparePatch(node *v1.Node) []byte { return patch } -func (s *NodeAllocatableStrategy) CleanupNode(node *v1.Node) *v1.Node { +func (s *NodeAllocatableStrategy) CleanupNode(ctx context.Context, node *v1.Node) *v1.Node { nodeCopy := node.DeepCopy() for name := range s.NodeAllocatable { delete(nodeCopy.Status.Allocatable, name) @@ -1077,7 +1078,7 @@ func (s *NodeAllocatableStrategy) CleanupNode(node *v1.Node) *v1.Node { return nodeCopy } -func (s *NodeAllocatableStrategy) createCSINode(nodeName string, client clientset.Interface) error { +func (s *NodeAllocatableStrategy) createCSINode(ctx context.Context, nodeName string, client clientset.Interface) error { csiNode := &storagev1.CSINode{ ObjectMeta: metav1.ObjectMeta{ Name: nodeName, @@ -1099,7 +1100,7 @@ func (s *NodeAllocatableStrategy) createCSINode(nodeName string, client clientse csiNode.Spec.Drivers = append(csiNode.Spec.Drivers, d) } - _, err := client.StorageV1().CSINodes().Create(context.TODO(), csiNode, metav1.CreateOptions{}) + _, err := client.StorageV1().CSINodes().Create(ctx, csiNode, metav1.CreateOptions{}) if apierrors.IsAlreadyExists(err) { // Something created CSINode instance after we checked it did not exist. // Make the caller to re-try PrepareDependentObjects by returning Conflict error @@ -1108,7 +1109,7 @@ func (s *NodeAllocatableStrategy) createCSINode(nodeName string, client clientse return err } -func (s *NodeAllocatableStrategy) updateCSINode(csiNode *storagev1.CSINode, client clientset.Interface) error { +func (s *NodeAllocatableStrategy) updateCSINode(ctx context.Context, csiNode *storagev1.CSINode, client clientset.Interface) error { for driverName, allocatable := range s.CsiNodeAllocatable { found := false for i, driver := range csiNode.Spec.Drivers { @@ -1129,23 +1130,23 @@ func (s *NodeAllocatableStrategy) updateCSINode(csiNode *storagev1.CSINode, clie } csiNode.Annotations[v1.MigratedPluginsAnnotationKey] = strings.Join(s.MigratedPlugins, ",") - _, err := client.StorageV1().CSINodes().Update(context.TODO(), csiNode, metav1.UpdateOptions{}) + _, err := client.StorageV1().CSINodes().Update(ctx, csiNode, metav1.UpdateOptions{}) return err } -func (s *NodeAllocatableStrategy) PrepareDependentObjects(node *v1.Node, client clientset.Interface) error { - csiNode, err := client.StorageV1().CSINodes().Get(context.TODO(), node.Name, metav1.GetOptions{}) +func (s *NodeAllocatableStrategy) PrepareDependentObjects(ctx context.Context, node *v1.Node, client clientset.Interface) error { + csiNode, err := client.StorageV1().CSINodes().Get(ctx, node.Name, metav1.GetOptions{}) if err != nil { if apierrors.IsNotFound(err) { - return s.createCSINode(node.Name, client) + return s.createCSINode(ctx, node.Name, client) } return err } - return s.updateCSINode(csiNode, client) + return s.updateCSINode(ctx, csiNode, client) } -func (s *NodeAllocatableStrategy) CleanupDependentObjects(nodeName string, client clientset.Interface) error { - csiNode, err := client.StorageV1().CSINodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) +func (s *NodeAllocatableStrategy) CleanupDependentObjects(ctx context.Context, nodeName string, client clientset.Interface) error { + csiNode, err := client.StorageV1().CSINodes().Get(ctx, nodeName, metav1.GetOptions{}) if err != nil { if apierrors.IsNotFound(err) { return nil @@ -1160,7 +1161,7 @@ func (s *NodeAllocatableStrategy) CleanupDependentObjects(nodeName string, clien } } } - return s.updateCSINode(csiNode, client) + return s.updateCSINode(ctx, csiNode, client) } // UniqueNodeLabelStrategy sets a unique label for each node. @@ -1182,7 +1183,7 @@ func (s *UniqueNodeLabelStrategy) PreparePatch(*v1.Node) []byte { return []byte(patch) } -func (s *UniqueNodeLabelStrategy) CleanupNode(node *v1.Node) *v1.Node { +func (s *UniqueNodeLabelStrategy) CleanupNode(ctx context.Context, node *v1.Node) *v1.Node { nodeCopy := node.DeepCopy() if node.Labels != nil && len(node.Labels[s.LabelKey]) != 0 { delete(nodeCopy.Labels, s.LabelKey) @@ -1190,22 +1191,22 @@ func (s *UniqueNodeLabelStrategy) CleanupNode(node *v1.Node) *v1.Node { return nodeCopy } -func (*UniqueNodeLabelStrategy) PrepareDependentObjects(node *v1.Node, client clientset.Interface) error { +func (*UniqueNodeLabelStrategy) PrepareDependentObjects(ctx context.Context, node *v1.Node, client clientset.Interface) error { return nil } -func (*UniqueNodeLabelStrategy) CleanupDependentObjects(nodeName string, client clientset.Interface) error { +func (*UniqueNodeLabelStrategy) CleanupDependentObjects(ctx context.Context, nodeName string, client clientset.Interface) error { return nil } -func DoPrepareNode(client clientset.Interface, node *v1.Node, strategy PrepareNodeStrategy) error { +func DoPrepareNode(ctx context.Context, client clientset.Interface, node *v1.Node, strategy PrepareNodeStrategy) error { var err error patch := strategy.PreparePatch(node) if len(patch) == 0 { return nil } for attempt := 0; attempt < retries; attempt++ { - if _, err = client.CoreV1().Nodes().Patch(context.TODO(), node.Name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}); err == nil { + if _, err = client.CoreV1().Nodes().Patch(ctx, node.Name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}); err == nil { break } if !apierrors.IsConflict(err) { @@ -1218,7 +1219,7 @@ func DoPrepareNode(client clientset.Interface, node *v1.Node, strategy PrepareNo } for attempt := 0; attempt < retries; attempt++ { - if err = strategy.PrepareDependentObjects(node, client); err == nil { + if err = strategy.PrepareDependentObjects(ctx, node, client); err == nil { break } if !apierrors.IsConflict(err) { @@ -1232,19 +1233,19 @@ func DoPrepareNode(client clientset.Interface, node *v1.Node, strategy PrepareNo return nil } -func DoCleanupNode(client clientset.Interface, nodeName string, strategy PrepareNodeStrategy) error { +func DoCleanupNode(ctx context.Context, client clientset.Interface, nodeName string, strategy PrepareNodeStrategy) error { var err error for attempt := 0; attempt < retries; attempt++ { var node *v1.Node - node, err = client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) + node, err = client.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{}) if err != nil { return fmt.Errorf("skipping cleanup of Node: failed to get Node %v: %v", nodeName, err) } - updatedNode := strategy.CleanupNode(node) + updatedNode := strategy.CleanupNode(ctx, node) if apiequality.Semantic.DeepEqual(node, updatedNode) { return nil } - if _, err = client.CoreV1().Nodes().Update(context.TODO(), updatedNode, metav1.UpdateOptions{}); err == nil { + if _, err = client.CoreV1().Nodes().Update(ctx, updatedNode, metav1.UpdateOptions{}); err == nil { break } if !apierrors.IsConflict(err) { @@ -1257,7 +1258,7 @@ func DoCleanupNode(client clientset.Interface, nodeName string, strategy Prepare } for attempt := 0; attempt < retries; attempt++ { - err = strategy.CleanupDependentObjects(nodeName, client) + err = strategy.CleanupDependentObjects(ctx, nodeName, client) if err == nil { break } @@ -1272,7 +1273,7 @@ func DoCleanupNode(client clientset.Interface, nodeName string, strategy Prepare return nil } -type TestPodCreateStrategy func(client clientset.Interface, namespace string, podCount int) error +type TestPodCreateStrategy func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error type CountToPodStrategy struct { Count int @@ -1304,10 +1305,10 @@ func NewTestPodCreator(client clientset.Interface, config *TestPodCreatorConfig) } } -func (c *TestPodCreator) CreatePods() error { +func (c *TestPodCreator) CreatePods(ctx context.Context) error { for ns, v := range *(c.Config) { for _, countToStrategy := range v { - if err := countToStrategy.Strategy(c.Client, ns, countToStrategy.Count); err != nil { + if err := countToStrategy.Strategy(ctx, c.Client, ns, countToStrategy.Count); err != nil { return err } } @@ -1342,11 +1343,14 @@ func makeCreatePod(client clientset.Interface, namespace string, podTemplate *v1 return nil } -func CreatePod(client clientset.Interface, namespace string, podCount int, podTemplate *v1.Pod) error { +func CreatePod(ctx context.Context, client clientset.Interface, namespace string, podCount int, podTemplate *v1.Pod) error { var createError error lock := sync.Mutex{} createPodFunc := func(i int) { - if err := makeCreatePod(client, namespace, podTemplate); err != nil { + // client-go writes into the object that is passed to Create, + // causing a data race unless we create a new copy for each + // parallel call. + if err := makeCreatePod(client, namespace, podTemplate.DeepCopy()); err != nil { lock.Lock() defer lock.Unlock() createError = err @@ -1354,14 +1358,14 @@ func CreatePod(client clientset.Interface, namespace string, podCount int, podTe } if podCount < 30 { - workqueue.ParallelizeUntil(context.TODO(), podCount, podCount, createPodFunc) + workqueue.ParallelizeUntil(ctx, podCount, podCount, createPodFunc) } else { - workqueue.ParallelizeUntil(context.TODO(), 30, podCount, createPodFunc) + workqueue.ParallelizeUntil(ctx, 30, podCount, createPodFunc) } return createError } -func CreatePodWithPersistentVolume(client clientset.Interface, namespace string, claimTemplate *v1.PersistentVolumeClaim, factory volumeFactory, podTemplate *v1.Pod, count int, bindVolume bool) error { +func CreatePodWithPersistentVolume(ctx context.Context, client clientset.Interface, namespace string, claimTemplate *v1.PersistentVolumeClaim, factory volumeFactory, podTemplate *v1.Pod, count int, bindVolume bool) error { var createError error lock := sync.Mutex{} createPodFunc := func(i int) { @@ -1400,7 +1404,7 @@ func CreatePodWithPersistentVolume(client clientset.Interface, namespace string, } // We need to update statuses separately, as creating pv/pvc resets status to the default one. - if _, err := client.CoreV1().PersistentVolumeClaims(namespace).UpdateStatus(context.TODO(), pvc, metav1.UpdateOptions{}); err != nil { + if _, err := client.CoreV1().PersistentVolumeClaims(namespace).UpdateStatus(ctx, pvc, metav1.UpdateOptions{}); err != nil { lock.Lock() defer lock.Unlock() createError = fmt.Errorf("error updating PVC status: %s", err) @@ -1414,7 +1418,7 @@ func CreatePodWithPersistentVolume(client clientset.Interface, namespace string, return } // We need to update statuses separately, as creating pv/pvc resets status to the default one. - if _, err := client.CoreV1().PersistentVolumes().UpdateStatus(context.TODO(), pv, metav1.UpdateOptions{}); err != nil { + if _, err := client.CoreV1().PersistentVolumes().UpdateStatus(ctx, pv, metav1.UpdateOptions{}); err != nil { lock.Lock() defer lock.Unlock() createError = fmt.Errorf("error updating PV status: %s", err) @@ -1442,9 +1446,9 @@ func CreatePodWithPersistentVolume(client clientset.Interface, namespace string, } if count < 30 { - workqueue.ParallelizeUntil(context.TODO(), count, count, createPodFunc) + workqueue.ParallelizeUntil(ctx, count, count, createPodFunc) } else { - workqueue.ParallelizeUntil(context.TODO(), 30, count, createPodFunc) + workqueue.ParallelizeUntil(ctx, 30, count, createPodFunc) } return createError } @@ -1455,7 +1459,7 @@ func createController(client clientset.Interface, controllerName, namespace stri Name: controllerName, }, Spec: v1.ReplicationControllerSpec{ - Replicas: func(i int) *int32 { x := int32(i); return &x }(podCount), + Replicas: pointer.Int32(int32(podCount)), Selector: map[string]string{"name": controllerName}, Template: &v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -1472,8 +1476,8 @@ func createController(client clientset.Interface, controllerName, namespace stri } func NewCustomCreatePodStrategy(podTemplate *v1.Pod) TestPodCreateStrategy { - return func(client clientset.Interface, namespace string, podCount int) error { - return CreatePod(client, namespace, podCount, podTemplate) + return func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error { + return CreatePod(ctx, client, namespace, podCount, podTemplate) } } @@ -1481,8 +1485,8 @@ func NewCustomCreatePodStrategy(podTemplate *v1.Pod) TestPodCreateStrategy { type volumeFactory func(uniqueID int) *v1.PersistentVolume func NewCreatePodWithPersistentVolumeStrategy(claimTemplate *v1.PersistentVolumeClaim, factory volumeFactory, podTemplate *v1.Pod) TestPodCreateStrategy { - return func(client clientset.Interface, namespace string, podCount int) error { - return CreatePodWithPersistentVolume(client, namespace, claimTemplate, factory, podTemplate, podCount, true /* bindVolume */) + return func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error { + return CreatePodWithPersistentVolume(ctx, client, namespace, claimTemplate, factory, podTemplate, podCount, true /* bindVolume */) } } @@ -1501,7 +1505,7 @@ func makeUnboundPersistentVolumeClaim(storageClass string) *v1.PersistentVolumeC } func NewCreatePodWithPersistentVolumeWithFirstConsumerStrategy(factory volumeFactory, podTemplate *v1.Pod) TestPodCreateStrategy { - return func(client clientset.Interface, namespace string, podCount int) error { + return func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error { volumeBindingMode := storagev1.VolumeBindingWaitForFirstConsumer storageClass := &storagev1.StorageClass{ ObjectMeta: metav1.ObjectMeta{ @@ -1522,7 +1526,7 @@ func NewCreatePodWithPersistentVolumeWithFirstConsumerStrategy(factory volumeFac return pv } - return CreatePodWithPersistentVolume(client, namespace, claimTemplate, factoryWithStorageClass, podTemplate, podCount, false /* bindVolume */) + return CreatePodWithPersistentVolume(ctx, client, namespace, claimTemplate, factoryWithStorageClass, podTemplate, podCount, false /* bindVolume */) } } @@ -1537,7 +1541,7 @@ func NewSimpleCreatePodStrategy() TestPodCreateStrategy { } func NewSimpleWithControllerCreatePodStrategy(controllerName string) TestPodCreateStrategy { - return func(client clientset.Interface, namespace string, podCount int) error { + return func(ctx context.Context, client clientset.Interface, namespace string, podCount int) error { basePod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ GenerateName: controllerName + "-pod-", @@ -1548,7 +1552,7 @@ func NewSimpleWithControllerCreatePodStrategy(controllerName string) TestPodCrea if err := createController(client, controllerName, namespace, podCount, basePod); err != nil { return err } - return CreatePod(client, namespace, podCount, basePod) + return CreatePod(ctx, client, namespace, podCount, basePod) } } @@ -1739,7 +1743,7 @@ type DaemonConfig struct { Timeout time.Duration } -func (config *DaemonConfig) Run() error { +func (config *DaemonConfig) Run(ctx context.Context) error { if config.Image == "" { config.Image = "registry.k8s.io/pause:3.9" } @@ -1775,7 +1779,7 @@ func (config *DaemonConfig) Run() error { var err error for i := 0; i < retries; i++ { // Wait for all daemons to be running - nodes, err = config.Client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{ResourceVersion: "0"}) + nodes, err = config.Client.CoreV1().Nodes().List(ctx, metav1.ListOptions{ResourceVersion: "0"}) if err == nil { break } else if i+1 == retries { diff --git a/vendor/k8s.io/utils/lru/lru.go b/vendor/k8s.io/utils/lru/lru.go index 5d0077abf..47f135281 100644 --- a/vendor/k8s.io/utils/lru/lru.go +++ b/vendor/k8s.io/utils/lru/lru.go @@ -5,7 +5,7 @@ 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 + 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, @@ -22,6 +22,7 @@ import ( ) type Key = groupcache.Key +type EvictionFunc = func(key Key, value interface{}) // Cache is a thread-safe fixed size LRU cache. type Cache struct { @@ -36,6 +37,13 @@ func New(size int) *Cache { } } +// NewWithEvictionFunc creates an LRU of the given size with the given eviction func. +func NewWithEvictionFunc(size int, f EvictionFunc) *Cache { + c := New(size) + c.cache.OnEvicted = f + return c +} + // Add adds a value to the cache. func (c *Cache) Add(key Key, value interface{}) { c.lock.Lock() diff --git a/vendor/modules.txt b/vendor/modules.txt index 4e33ff920..6dac92a32 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2,12 +2,18 @@ ## explicit; go 1.15 github.com/IBM/keyprotect-go-client github.com/IBM/keyprotect-go-client/iam +# github.com/NYTimes/gziphandler v1.1.1 +## explicit; go 1.11 +github.com/NYTimes/gziphandler # github.com/ansel1/merry v1.6.2 ## explicit; go 1.12 github.com/ansel1/merry # github.com/ansel1/merry/v2 v2.0.1 ## explicit; go 1.12 github.com/ansel1/merry/v2 +# github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 +## explicit; go 1.16 +github.com/antlr/antlr4/runtime/Go/antlr # github.com/armon/go-metrics v0.3.10 ## explicit; go 1.12 github.com/armon/go-metrics @@ -42,7 +48,6 @@ github.com/aws/aws-sdk-go/internal/shareddefaults github.com/aws/aws-sdk-go/internal/strings github.com/aws/aws-sdk-go/internal/sync/singleflight github.com/aws/aws-sdk-go/private/protocol -github.com/aws/aws-sdk-go/private/protocol/ec2query github.com/aws/aws-sdk-go/private/protocol/json/jsonutil github.com/aws/aws-sdk-go/private/protocol/jsonrpc github.com/aws/aws-sdk-go/private/protocol/query @@ -50,7 +55,6 @@ github.com/aws/aws-sdk-go/private/protocol/query/queryutil github.com/aws/aws-sdk-go/private/protocol/rest github.com/aws/aws-sdk-go/private/protocol/restjson github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil -github.com/aws/aws-sdk-go/service/ec2 github.com/aws/aws-sdk-go/service/kms github.com/aws/aws-sdk-go/service/sso github.com/aws/aws-sdk-go/service/sso/ssoiface @@ -145,6 +149,13 @@ github.com/cespare/xxhash/v2 # github.com/container-storage-interface/spec v1.8.0 ## explicit; go 1.18 github.com/container-storage-interface/spec/lib/go/csi +# github.com/coreos/go-semver v0.3.0 +## explicit +github.com/coreos/go-semver/semver +# github.com/coreos/go-systemd/v22 v22.4.0 +## explicit; go 1.12 +github.com/coreos/go-systemd/v22/daemon +github.com/coreos/go-systemd/v22/journal # github.com/csi-addons/replication-lib-utils v0.2.0 ## explicit; go 1.15 github.com/csi-addons/replication-lib-utils/protosanitizer @@ -207,10 +218,10 @@ github.com/go-logr/logr/funcr # github.com/go-logr/stdr v1.2.2 ## explicit; go 1.16 github.com/go-logr/stdr -# github.com/go-openapi/jsonpointer v0.19.5 +# github.com/go-openapi/jsonpointer v0.19.6 ## explicit; go 1.13 github.com/go-openapi/jsonpointer -# github.com/go-openapi/jsonreference v0.20.0 +# github.com/go-openapi/jsonreference v0.20.1 ## explicit; go 1.13 github.com/go-openapi/jsonreference github.com/go-openapi/jsonreference/internal @@ -219,7 +230,9 @@ github.com/go-openapi/jsonreference/internal github.com/go-openapi/swag # github.com/gogo/protobuf v1.3.2 ## explicit; go 1.15 +github.com/gogo/protobuf/gogoproto github.com/gogo/protobuf/proto +github.com/gogo/protobuf/protoc-gen-gogo/descriptor github.com/gogo/protobuf/sortkeys # github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da ## explicit @@ -238,6 +251,26 @@ github.com/golang/protobuf/ptypes/wrappers # github.com/golang/snappy v0.0.4 ## explicit github.com/golang/snappy +# github.com/google/cel-go v0.12.6 +## explicit; go 1.17 +github.com/google/cel-go/cel +github.com/google/cel-go/checker +github.com/google/cel-go/checker/decls +github.com/google/cel-go/common +github.com/google/cel-go/common/containers +github.com/google/cel-go/common/debug +github.com/google/cel-go/common/operators +github.com/google/cel-go/common/overloads +github.com/google/cel-go/common/runes +github.com/google/cel-go/common/types +github.com/google/cel-go/common/types/pb +github.com/google/cel-go/common/types/ref +github.com/google/cel-go/common/types/traits +github.com/google/cel-go/ext +github.com/google/cel-go/interpreter +github.com/google/cel-go/interpreter/functions +github.com/google/cel-go/parser +github.com/google/cel-go/parser/gen # github.com/google/fscrypt v0.3.4 ## explicit; go 1.16 github.com/google/fscrypt/actions @@ -420,6 +453,7 @@ github.com/onsi/ginkgo/v2/types ## explicit; go 1.18 github.com/onsi/gomega github.com/onsi/gomega/format +github.com/onsi/gomega/gcustom github.com/onsi/gomega/internal github.com/onsi/gomega/internal/gutil github.com/onsi/gomega/matchers @@ -485,11 +519,40 @@ github.com/spf13/cobra # github.com/spf13/pflag v1.0.5 ## explicit; go 1.12 github.com/spf13/pflag +# github.com/stoewer/go-strcase v1.2.0 +## explicit; go 1.11 +github.com/stoewer/go-strcase # github.com/stretchr/testify v1.8.3 ## explicit; go 1.20 github.com/stretchr/testify/assert github.com/stretchr/testify/require -# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0 +# go.etcd.io/etcd/api/v3 v3.5.7 +## explicit; go 1.17 +go.etcd.io/etcd/api/v3/authpb +go.etcd.io/etcd/api/v3/etcdserverpb +go.etcd.io/etcd/api/v3/membershippb +go.etcd.io/etcd/api/v3/mvccpb +go.etcd.io/etcd/api/v3/v3rpc/rpctypes +go.etcd.io/etcd/api/v3/version +# go.etcd.io/etcd/client/pkg/v3 v3.5.7 +## explicit; go 1.17 +go.etcd.io/etcd/client/pkg/v3/fileutil +go.etcd.io/etcd/client/pkg/v3/logutil +go.etcd.io/etcd/client/pkg/v3/systemd +go.etcd.io/etcd/client/pkg/v3/tlsutil +go.etcd.io/etcd/client/pkg/v3/transport +go.etcd.io/etcd/client/pkg/v3/types +# go.etcd.io/etcd/client/v3 v3.5.7 +## explicit; go 1.17 +go.etcd.io/etcd/client/v3 +go.etcd.io/etcd/client/v3/credentials +go.etcd.io/etcd/client/v3/internal/endpoint +go.etcd.io/etcd/client/v3/internal/resolver +# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 +## explicit; go 1.17 +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal +# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.1 ## explicit; go 1.17 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp # go.opentelemetry.io/otel v1.10.0 @@ -559,19 +622,24 @@ go.uber.org/zap/internal/bufferpool go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore +go.uber.org/zap/zapgrpc # golang.org/x/crypto v0.9.0 ## explicit; go 1.17 golang.org/x/crypto/argon2 golang.org/x/crypto/blake2b golang.org/x/crypto/blowfish golang.org/x/crypto/chacha20 +golang.org/x/crypto/cryptobyte +golang.org/x/crypto/cryptobyte/asn1 golang.org/x/crypto/curve25519 golang.org/x/crypto/curve25519/internal/field golang.org/x/crypto/ed25519 golang.org/x/crypto/hkdf golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 +golang.org/x/crypto/nacl/secretbox golang.org/x/crypto/pbkdf2 +golang.org/x/crypto/salsa20/salsa golang.org/x/crypto/scrypt golang.org/x/crypto/ssh golang.org/x/crypto/ssh/internal/bcrypt_pbkdf @@ -589,10 +657,14 @@ golang.org/x/net/internal/socks golang.org/x/net/internal/timeseries golang.org/x/net/proxy golang.org/x/net/trace +golang.org/x/net/websocket # golang.org/x/oauth2 v0.6.0 ## explicit; go 1.17 golang.org/x/oauth2 golang.org/x/oauth2/internal +# golang.org/x/sync v0.1.0 +## explicit +golang.org/x/sync/singleflight # golang.org/x/sys v0.8.0 ## explicit; go 1.17 golang.org/x/sys/cpu @@ -628,6 +700,7 @@ golang.org/x/text/secure/bidirule golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm +golang.org/x/text/width # golang.org/x/time v0.3.0 ## explicit golang.org/x/time/rate @@ -647,6 +720,9 @@ google.golang.org/appengine/internal/urlfetch google.golang.org/appengine/urlfetch # google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 ## explicit; go 1.19 +google.golang.org/genproto/googleapis/api +google.golang.org/genproto/googleapis/api/annotations +google.golang.org/genproto/googleapis/api/expr/v1alpha1 google.golang.org/genproto/googleapis/api/httpbody google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status @@ -699,6 +775,7 @@ google.golang.org/grpc/keepalive google.golang.org/grpc/metadata google.golang.org/grpc/peer google.golang.org/grpc/resolver +google.golang.org/grpc/resolver/manual google.golang.org/grpc/serviceconfig google.golang.org/grpc/stats google.golang.org/grpc/status @@ -734,8 +811,10 @@ google.golang.org/protobuf/reflect/protoregistry google.golang.org/protobuf/runtime/protoiface google.golang.org/protobuf/runtime/protoimpl google.golang.org/protobuf/types/descriptorpb +google.golang.org/protobuf/types/dynamicpb google.golang.org/protobuf/types/known/anypb google.golang.org/protobuf/types/known/durationpb +google.golang.org/protobuf/types/known/emptypb google.golang.org/protobuf/types/known/fieldmaskpb google.golang.org/protobuf/types/known/structpb google.golang.org/protobuf/types/known/timestamppb @@ -743,6 +822,9 @@ google.golang.org/protobuf/types/known/wrapperspb # gopkg.in/inf.v0 v0.9.1 ## explicit gopkg.in/inf.v0 +# gopkg.in/natefinch/lumberjack.v2 v2.0.0 +## explicit +gopkg.in/natefinch/lumberjack.v2 # gopkg.in/yaml.v2 v2.4.0 ## explicit; go 1.15 gopkg.in/yaml.v2 @@ -818,10 +900,12 @@ k8s.io/apimachinery/pkg/api/validation k8s.io/apimachinery/pkg/api/validation/path k8s.io/apimachinery/pkg/apis/meta/internalversion k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme +k8s.io/apimachinery/pkg/apis/meta/internalversion/validation k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/apimachinery/pkg/apis/meta/v1/unstructured k8s.io/apimachinery/pkg/apis/meta/v1/validation k8s.io/apimachinery/pkg/apis/meta/v1beta1 +k8s.io/apimachinery/pkg/apis/meta/v1beta1/validation k8s.io/apimachinery/pkg/conversion k8s.io/apimachinery/pkg/conversion/queryparams k8s.io/apimachinery/pkg/fields @@ -858,6 +942,7 @@ k8s.io/apimachinery/pkg/util/validation k8s.io/apimachinery/pkg/util/validation/field k8s.io/apimachinery/pkg/util/version k8s.io/apimachinery/pkg/util/wait +k8s.io/apimachinery/pkg/util/waitgroup k8s.io/apimachinery/pkg/util/yaml k8s.io/apimachinery/pkg/version k8s.io/apimachinery/pkg/watch @@ -867,9 +952,14 @@ k8s.io/apimachinery/third_party/forked/golang/reflect # k8s.io/apiserver v0.26.2 => k8s.io/apiserver v0.26.2 ## explicit; go 1.19 k8s.io/apiserver/pkg/admission +k8s.io/apiserver/pkg/admission/cel k8s.io/apiserver/pkg/admission/configuration k8s.io/apiserver/pkg/admission/initializer k8s.io/apiserver/pkg/admission/metrics +k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle +k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy +k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic +k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching k8s.io/apiserver/pkg/admission/plugin/webhook k8s.io/apiserver/pkg/admission/plugin/webhook/config k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission @@ -882,26 +972,122 @@ k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules k8s.io/apiserver/pkg/admission/plugin/webhook/request +k8s.io/apiserver/pkg/admission/plugin/webhook/validating k8s.io/apiserver/pkg/apis/apiserver k8s.io/apiserver/pkg/apis/apiserver/install k8s.io/apiserver/pkg/apis/apiserver/v1 k8s.io/apiserver/pkg/apis/apiserver/v1alpha1 k8s.io/apiserver/pkg/apis/apiserver/v1beta1 k8s.io/apiserver/pkg/apis/audit +k8s.io/apiserver/pkg/apis/audit/install k8s.io/apiserver/pkg/apis/audit/v1 +k8s.io/apiserver/pkg/apis/audit/validation +k8s.io/apiserver/pkg/apis/config +k8s.io/apiserver/pkg/apis/config/v1 +k8s.io/apiserver/pkg/apis/config/validation +k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap k8s.io/apiserver/pkg/audit +k8s.io/apiserver/pkg/audit/policy +k8s.io/apiserver/pkg/authentication/authenticator +k8s.io/apiserver/pkg/authentication/authenticatorfactory +k8s.io/apiserver/pkg/authentication/group +k8s.io/apiserver/pkg/authentication/request/anonymous +k8s.io/apiserver/pkg/authentication/request/bearertoken +k8s.io/apiserver/pkg/authentication/request/headerrequest +k8s.io/apiserver/pkg/authentication/request/union +k8s.io/apiserver/pkg/authentication/request/websocket +k8s.io/apiserver/pkg/authentication/request/x509 +k8s.io/apiserver/pkg/authentication/serviceaccount +k8s.io/apiserver/pkg/authentication/token/cache +k8s.io/apiserver/pkg/authentication/token/tokenfile k8s.io/apiserver/pkg/authentication/user k8s.io/apiserver/pkg/authorization/authorizer +k8s.io/apiserver/pkg/authorization/authorizerfactory +k8s.io/apiserver/pkg/authorization/path +k8s.io/apiserver/pkg/authorization/union +k8s.io/apiserver/pkg/cel +k8s.io/apiserver/pkg/cel/library +k8s.io/apiserver/pkg/endpoints +k8s.io/apiserver/pkg/endpoints/deprecation +k8s.io/apiserver/pkg/endpoints/discovery +k8s.io/apiserver/pkg/endpoints/discovery/aggregated +k8s.io/apiserver/pkg/endpoints/filterlatency +k8s.io/apiserver/pkg/endpoints/filters +k8s.io/apiserver/pkg/endpoints/handlers +k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager +k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal +k8s.io/apiserver/pkg/endpoints/handlers/finisher +k8s.io/apiserver/pkg/endpoints/handlers/metrics +k8s.io/apiserver/pkg/endpoints/handlers/negotiation +k8s.io/apiserver/pkg/endpoints/handlers/responsewriters +k8s.io/apiserver/pkg/endpoints/metrics +k8s.io/apiserver/pkg/endpoints/openapi k8s.io/apiserver/pkg/endpoints/request +k8s.io/apiserver/pkg/endpoints/responsewriter +k8s.io/apiserver/pkg/endpoints/warning k8s.io/apiserver/pkg/features k8s.io/apiserver/pkg/quota/v1 +k8s.io/apiserver/pkg/registry/generic +k8s.io/apiserver/pkg/registry/generic/registry +k8s.io/apiserver/pkg/registry/rest +k8s.io/apiserver/pkg/server +k8s.io/apiserver/pkg/server/dynamiccertificates k8s.io/apiserver/pkg/server/egressselector k8s.io/apiserver/pkg/server/egressselector/metrics +k8s.io/apiserver/pkg/server/filters +k8s.io/apiserver/pkg/server/healthz +k8s.io/apiserver/pkg/server/httplog +k8s.io/apiserver/pkg/server/mux +k8s.io/apiserver/pkg/server/options +k8s.io/apiserver/pkg/server/options/encryptionconfig +k8s.io/apiserver/pkg/server/options/encryptionconfig/controller +k8s.io/apiserver/pkg/server/resourceconfig +k8s.io/apiserver/pkg/server/routes +k8s.io/apiserver/pkg/server/storage +k8s.io/apiserver/pkg/storage +k8s.io/apiserver/pkg/storage/cacher +k8s.io/apiserver/pkg/storage/cacher/metrics +k8s.io/apiserver/pkg/storage/errors +k8s.io/apiserver/pkg/storage/etcd3 +k8s.io/apiserver/pkg/storage/etcd3/metrics k8s.io/apiserver/pkg/storage/names +k8s.io/apiserver/pkg/storage/storagebackend +k8s.io/apiserver/pkg/storage/storagebackend/factory +k8s.io/apiserver/pkg/storage/value +k8s.io/apiserver/pkg/storage/value/encrypt/aes +k8s.io/apiserver/pkg/storage/value/encrypt/envelope +k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2 +k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1 +k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics +k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util +k8s.io/apiserver/pkg/storage/value/encrypt/identity +k8s.io/apiserver/pkg/storage/value/encrypt/secretbox +k8s.io/apiserver/pkg/storageversion +k8s.io/apiserver/pkg/util/apihelpers +k8s.io/apiserver/pkg/util/dryrun k8s.io/apiserver/pkg/util/feature +k8s.io/apiserver/pkg/util/flowcontrol +k8s.io/apiserver/pkg/util/flowcontrol/debug +k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing +k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/eventclock +k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/promise +k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset +k8s.io/apiserver/pkg/util/flowcontrol/format +k8s.io/apiserver/pkg/util/flowcontrol/metrics +k8s.io/apiserver/pkg/util/flowcontrol/request +k8s.io/apiserver/pkg/util/flushwriter +k8s.io/apiserver/pkg/util/openapi +k8s.io/apiserver/pkg/util/shufflesharding k8s.io/apiserver/pkg/util/webhook +k8s.io/apiserver/pkg/util/wsstream k8s.io/apiserver/pkg/util/x509metrics k8s.io/apiserver/pkg/warning +k8s.io/apiserver/plugin/pkg/audit/buffered +k8s.io/apiserver/plugin/pkg/audit/log +k8s.io/apiserver/plugin/pkg/audit/truncate +k8s.io/apiserver/plugin/pkg/audit/webhook +k8s.io/apiserver/plugin/pkg/authenticator/token/webhook +k8s.io/apiserver/plugin/pkg/authorizer/webhook # k8s.io/client-go v12.0.0+incompatible => k8s.io/client-go v0.26.2 ## explicit; go 1.19 k8s.io/client-go/applyconfigurations/admissionregistration/v1 @@ -954,6 +1140,8 @@ k8s.io/client-go/applyconfigurations/storage/v1beta1 k8s.io/client-go/discovery k8s.io/client-go/discovery/cached/memory k8s.io/client-go/dynamic +k8s.io/client-go/dynamic/dynamicinformer +k8s.io/client-go/dynamic/dynamiclister k8s.io/client-go/informers k8s.io/client-go/informers/admissionregistration k8s.io/client-go/informers/admissionregistration/v1 @@ -1167,19 +1355,31 @@ k8s.io/client-go/util/workqueue # k8s.io/cloud-provider v0.26.2 => k8s.io/cloud-provider v0.26.2 ## explicit; go 1.19 k8s.io/cloud-provider +k8s.io/cloud-provider/app/config +k8s.io/cloud-provider/config +k8s.io/cloud-provider/config/install +k8s.io/cloud-provider/config/v1alpha1 +k8s.io/cloud-provider/controllers/service/config +k8s.io/cloud-provider/controllers/service/config/v1alpha1 +k8s.io/cloud-provider/options k8s.io/cloud-provider/volume k8s.io/cloud-provider/volume/helpers # k8s.io/component-base v0.26.2 => k8s.io/component-base v0.26.2 ## explicit; go 1.19 k8s.io/component-base/cli/flag k8s.io/component-base/config +k8s.io/component-base/config/options k8s.io/component-base/config/v1alpha1 k8s.io/component-base/featuregate +k8s.io/component-base/logs k8s.io/component-base/logs/api/v1 k8s.io/component-base/logs/klogflags k8s.io/component-base/metrics +k8s.io/component-base/metrics/features k8s.io/component-base/metrics/legacyregistry k8s.io/component-base/metrics/prometheus/feature +k8s.io/component-base/metrics/prometheus/slis +k8s.io/component-base/metrics/prometheus/workqueue k8s.io/component-base/metrics/prometheusextension k8s.io/component-base/metrics/testutil k8s.io/component-base/tracing @@ -1191,6 +1391,19 @@ k8s.io/component-helpers/node/util/sysctl k8s.io/component-helpers/scheduling/corev1 k8s.io/component-helpers/scheduling/corev1/nodeaffinity k8s.io/component-helpers/storage/volume +# k8s.io/controller-manager v0.26.2 => k8s.io/controller-manager v0.26.2 +## explicit; go 1.19 +k8s.io/controller-manager/config +k8s.io/controller-manager/config/v1 +k8s.io/controller-manager/config/v1alpha1 +k8s.io/controller-manager/config/v1beta1 +k8s.io/controller-manager/options +k8s.io/controller-manager/pkg/clientbuilder +k8s.io/controller-manager/pkg/features +k8s.io/controller-manager/pkg/features/register +k8s.io/controller-manager/pkg/leadermigration +k8s.io/controller-manager/pkg/leadermigration/config +k8s.io/controller-manager/pkg/leadermigration/options # k8s.io/klog/v2 v2.100.1 ## explicit; go 1.13 k8s.io/klog/v2 @@ -1199,18 +1412,27 @@ k8s.io/klog/v2/internal/clock k8s.io/klog/v2/internal/dbg k8s.io/klog/v2/internal/serialize k8s.io/klog/v2/internal/severity -# k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 -## explicit; go 1.18 +# k8s.io/kms v0.26.2 +## explicit; go 1.19 +k8s.io/kms/apis/v1beta1 +k8s.io/kms/apis/v2alpha1 +# k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f +## explicit; go 1.19 +k8s.io/kube-openapi/pkg/builder +k8s.io/kube-openapi/pkg/builder3 k8s.io/kube-openapi/pkg/builder3/util +k8s.io/kube-openapi/pkg/cached k8s.io/kube-openapi/pkg/common +k8s.io/kube-openapi/pkg/common/restfuladapter +k8s.io/kube-openapi/pkg/handler k8s.io/kube-openapi/pkg/handler3 k8s.io/kube-openapi/pkg/internal -k8s.io/kube-openapi/pkg/internal/handler k8s.io/kube-openapi/pkg/internal/third_party/go-json-experiment/json k8s.io/kube-openapi/pkg/openapiconv k8s.io/kube-openapi/pkg/schemaconv k8s.io/kube-openapi/pkg/schemamutation k8s.io/kube-openapi/pkg/spec3 +k8s.io/kube-openapi/pkg/util k8s.io/kube-openapi/pkg/util/proto k8s.io/kube-openapi/pkg/validation/spec # k8s.io/kubectl v0.0.0 => k8s.io/kubectl v0.26.2 @@ -1219,9 +1441,10 @@ k8s.io/kubectl/pkg/scale k8s.io/kubectl/pkg/util/podutils # k8s.io/kubelet v0.0.0 => k8s.io/kubelet v0.26.2 ## explicit; go 1.19 +k8s.io/kubelet/pkg/apis k8s.io/kubelet/pkg/apis/stats/v1alpha1 -# k8s.io/kubernetes v1.26.2 -## explicit; go 1.19 +# k8s.io/kubernetes v1.27.2 +## explicit; go 1.20 k8s.io/kubernetes/pkg/api/legacyscheme k8s.io/kubernetes/pkg/api/service k8s.io/kubernetes/pkg/api/v1/pod @@ -1230,6 +1453,7 @@ k8s.io/kubernetes/pkg/apis/autoscaling k8s.io/kubernetes/pkg/apis/batch k8s.io/kubernetes/pkg/apis/core k8s.io/kubernetes/pkg/apis/core/helper +k8s.io/kubernetes/pkg/apis/core/helper/qos k8s.io/kubernetes/pkg/apis/core/install k8s.io/kubernetes/pkg/apis/core/pods k8s.io/kubernetes/pkg/apis/core/v1 @@ -1237,7 +1461,6 @@ k8s.io/kubernetes/pkg/apis/core/v1/helper k8s.io/kubernetes/pkg/apis/core/validation k8s.io/kubernetes/pkg/apis/extensions k8s.io/kubernetes/pkg/apis/networking -k8s.io/kubernetes/pkg/apis/policy k8s.io/kubernetes/pkg/capabilities k8s.io/kubernetes/pkg/client/conditions k8s.io/kubernetes/pkg/cluster/ports @@ -1268,6 +1491,7 @@ k8s.io/kubernetes/pkg/volume/util/volumepathhandler k8s.io/kubernetes/test/e2e/framework k8s.io/kubernetes/test/e2e/framework/config k8s.io/kubernetes/test/e2e/framework/debug +k8s.io/kubernetes/test/e2e/framework/internal/junit k8s.io/kubernetes/test/e2e/framework/kubectl k8s.io/kubernetes/test/e2e/framework/metrics k8s.io/kubernetes/test/e2e/framework/node @@ -1283,6 +1507,7 @@ k8s.io/kubernetes/test/e2e/storage/podlogs k8s.io/kubernetes/test/e2e/storage/utils k8s.io/kubernetes/test/e2e/testing-manifests k8s.io/kubernetes/test/utils +k8s.io/kubernetes/test/utils/format k8s.io/kubernetes/test/utils/image k8s.io/kubernetes/test/utils/kubeconfig # k8s.io/mount-utils v0.26.2 => k8s.io/mount-utils v0.26.2 @@ -1292,7 +1517,7 @@ k8s.io/mount-utils ## explicit; go 1.19 k8s.io/pod-security-admission/api k8s.io/pod-security-admission/policy -# k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 +# k8s.io/utils v0.0.0-20230209194617-a36077c30491 ## explicit; go 1.18 k8s.io/utils/buffer k8s.io/utils/clock @@ -1311,7 +1536,7 @@ k8s.io/utils/pointer k8s.io/utils/strings k8s.io/utils/strings/slices k8s.io/utils/trace -# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 +# sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 ## explicit; go 1.17 sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics @@ -1356,13 +1581,14 @@ sigs.k8s.io/controller-runtime/pkg/source/internal sigs.k8s.io/controller-runtime/pkg/webhook sigs.k8s.io/controller-runtime/pkg/webhook/admission sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics -# sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 +# sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd ## explicit; go 1.18 sigs.k8s.io/json sigs.k8s.io/json/internal/golang/encoding/json # sigs.k8s.io/structured-merge-diff/v4 v4.2.3 ## explicit; go 1.13 sigs.k8s.io/structured-merge-diff/v4/fieldpath +sigs.k8s.io/structured-merge-diff/v4/merge sigs.k8s.io/structured-merge-diff/v4/schema sigs.k8s.io/structured-merge-diff/v4/typed sigs.k8s.io/structured-merge-diff/v4/value diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go index cb186cefc..541e6a5aa 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/client.go @@ -118,6 +118,8 @@ func (cm *connectionManager) closeAll() { // grpcTunnel implements Tunnel type grpcTunnel struct { stream client.ProxyService_ProxyClient + sendLock sync.Mutex + recvLock sync.Mutex clientConn clientConn pendingDial pendingDialManager conns connectionManager @@ -130,6 +132,11 @@ type grpcTunnel struct { // serving. done chan struct{} + // started is an atomic bool represented as a 0 or 1, and set to true when a single-use tunnel has been started (dialed). + // started should only be accessed through atomic methods. + // TODO: switch this to an atomic.Bool once the client is exclusively buit with go1.19+ + started uint32 + // closing is an atomic bool represented as a 0 or 1, and set to true when the tunnel is being closed. // closing should only be accessed through atomic methods. // TODO: switch this to an atomic.Bool once the client is exclusively buit with go1.19+ @@ -195,6 +202,7 @@ func newUnstartedTunnel(stream client.ProxyService_ProxyClient, c clientConn) *g conns: connectionManager{conns: make(map[int64]*conn)}, readTimeoutSeconds: 10, done: make(chan struct{}), + started: 0, } s := metrics.ClientConnectionStatusCreated t.prevStatus.Store(s) @@ -243,20 +251,17 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { }() for { - pkt, err := t.stream.Recv() + pkt, err := t.Recv() if err == io.EOF { return } - const segment = commonmetrics.SegmentToClient isClosing := t.isClosing() if err != nil || pkt == nil { if !isClosing { klog.ErrorS(err, "stream read failure") } - metrics.Metrics.ObserveStreamErrorNoPacket(segment, err) return } - metrics.Metrics.ObservePacket(segment, pkt.Type) if isClosing { return } @@ -335,11 +340,23 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { case client.PacketType_DATA: resp := pkt.GetData() + if resp.ConnectID == 0 { + klog.ErrorS(nil, "Received packet missing ConnectID", "packetType", "DATA") + continue + } // TODO: flow control conn, ok := t.conns.get(resp.ConnectID) if !ok { - klog.V(1).InfoS("Connection not recognized", "connectionID", resp.ConnectID) + klog.ErrorS(nil, "Connection not recognized", "connectionID", resp.ConnectID, "packetType", "DATA") + t.Send(&client.Packet{ + Type: client.PacketType_CLOSE_REQ, + Payload: &client.Packet_CloseRequest{ + CloseRequest: &client.CloseRequest{ + ConnectID: resp.ConnectID, + }, + }, + }) continue } timer := time.NewTimer((time.Duration)(t.readTimeoutSeconds) * time.Second) @@ -358,7 +375,7 @@ func (t *grpcTunnel) serve(tunnelCtx context.Context) { conn, ok := t.conns.get(resp.ConnectID) if !ok { - klog.V(1).InfoS("Connection not recognized", "connectionID", resp.ConnectID) + klog.V(1).InfoS("Connection not recognized", "connectionID", resp.ConnectID, "packetType", "CLOSE_RSP") continue } close(conn.readCh) @@ -382,6 +399,11 @@ func (t *grpcTunnel) DialContext(requestCtx context.Context, protocol, address s } func (t *grpcTunnel) dialContext(requestCtx context.Context, protocol, address string) (net.Conn, error) { + prevStarted := atomic.SwapUint32(&t.started, 1) + if prevStarted != 0 { + return nil, &dialFailure{"single-use dialer already dialed", metrics.DialFailureAlreadyStarted} + } + select { case <-t.done: return nil, errors.New("tunnel is closed") @@ -418,18 +440,15 @@ func (t *grpcTunnel) dialContext(requestCtx context.Context, protocol, address s } klog.V(5).InfoS("[tracing] send packet", "type", req.Type) - const segment = commonmetrics.SegmentFromClient - metrics.Metrics.ObservePacket(segment, req.Type) - err := t.stream.Send(req) + err := t.Send(req) if err != nil { - metrics.Metrics.ObserveStreamError(segment, err, req.Type) return nil, err } klog.V(5).Infoln("DIAL_REQ sent to proxy server") c := &conn{ - stream: t.stream, + tunnel: t, random: random, closeTunnel: t.closeTunnel, } @@ -473,10 +492,7 @@ func (t *grpcTunnel) closeDial(dialID int64) { }, }, } - const segment = commonmetrics.SegmentFromClient - metrics.Metrics.ObservePacket(segment, req.Type) - if err := t.stream.Send(req); err != nil { - metrics.Metrics.ObserveStreamError(segment, err, req.Type) + if err := t.Send(req); err != nil { klog.V(5).InfoS("Failed to send DIAL_CLS", "err", err, "dialID", dialID) } t.closeTunnel() @@ -491,6 +507,35 @@ func (t *grpcTunnel) isClosing() bool { return atomic.LoadUint32(&t.closing) != 0 } +func (t *grpcTunnel) Send(pkt *client.Packet) error { + t.sendLock.Lock() + defer t.sendLock.Unlock() + + const segment = commonmetrics.SegmentFromClient + metrics.Metrics.ObservePacket(segment, pkt.Type) + err := t.stream.Send(pkt) + if err != nil && err != io.EOF { + metrics.Metrics.ObserveStreamError(segment, err, pkt.Type) + } + return err +} + +func (t *grpcTunnel) Recv() (*client.Packet, error) { + t.recvLock.Lock() + defer t.recvLock.Unlock() + + const segment = commonmetrics.SegmentToClient + pkt, err := t.stream.Recv() + if err != nil { + if err != io.EOF { + metrics.Metrics.ObserveStreamErrorNoPacket(segment, err) + } + return nil, err + } + metrics.Metrics.ObservePacket(segment, pkt.Type) + return pkt, nil +} + func GetDialFailureReason(err error) (isDialFailure bool, reason metrics.DialFailureReason) { var df *dialFailure if errors.As(err, &df) { diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go index 14384a62c..f4d3f7886 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/conn.go @@ -24,8 +24,6 @@ import ( "k8s.io/klog/v2" - "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics" - commonmetrics "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics" "sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client" ) @@ -38,7 +36,7 @@ var errConnCloseTimeout = errors.New("close timeout") // conn is an implementation of net.Conn, where the data is transported // over an established tunnel defined by a gRPC service ProxyService. type conn struct { - stream client.ProxyService_ProxyClient + tunnel *grpcTunnel connID int64 random int64 readCh chan []byte @@ -65,11 +63,8 @@ func (c *conn) Write(data []byte) (n int, err error) { klog.V(5).InfoS("[tracing] send req", "type", req.Type) - const segment = commonmetrics.SegmentFromClient - metrics.Metrics.ObservePacket(segment, req.Type) - err = c.stream.Send(req) + err = c.tunnel.Send(req) if err != nil { - metrics.Metrics.ObserveStreamError(segment, err, req.Type) return 0, err } return len(data), err @@ -153,10 +148,7 @@ func (c *conn) Close() error { klog.V(5).InfoS("[tracing] send req", "type", req.Type) - const segment = commonmetrics.SegmentFromClient - metrics.Metrics.ObservePacket(segment, req.Type) - if err := c.stream.Send(req); err != nil { - metrics.Metrics.ObserveStreamError(segment, err, req.Type) + if err := c.tunnel.Send(req); err != nil { return err } diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics/metrics.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics/metrics.go index 03e9d94da..ce942e3eb 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics/metrics.go +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics/metrics.go @@ -62,6 +62,8 @@ const ( // DialFailureTunnelClosed indicates that the client connection was closed before the dial could // complete. DialFailureTunnelClosed DialFailureReason = "tunnelclosed" + // DialFailureAlreadyStarted indicates that a single-use tunnel dialer was already used once. + DialFailureAlreadyStarted DialFailureReason = "tunnelstarted" ) type ClientConnectionStatus string diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go index 59a797df4..6af92b448 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.pb.go @@ -1,43 +1,38 @@ -/* -Copyright The Kubernetes Authors. +// Copyright 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. -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.27.1 +// protoc v3.12.4 // source: konnectivity-client/proto/client/client.proto package client import ( - context "context" - fmt "fmt" - proto "github.com/golang/protobuf/proto" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +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) +) type PacketType int32 @@ -50,101 +45,158 @@ const ( PacketType_DIAL_CLS PacketType = 5 ) -var PacketType_name = map[int32]string{ - 0: "DIAL_REQ", - 1: "DIAL_RSP", - 2: "CLOSE_REQ", - 3: "CLOSE_RSP", - 4: "DATA", - 5: "DIAL_CLS", -} +// Enum value maps for PacketType. +var ( + PacketType_name = map[int32]string{ + 0: "DIAL_REQ", + 1: "DIAL_RSP", + 2: "CLOSE_REQ", + 3: "CLOSE_RSP", + 4: "DATA", + 5: "DIAL_CLS", + } + PacketType_value = map[string]int32{ + "DIAL_REQ": 0, + "DIAL_RSP": 1, + "CLOSE_REQ": 2, + "CLOSE_RSP": 3, + "DATA": 4, + "DIAL_CLS": 5, + } +) -var PacketType_value = map[string]int32{ - "DIAL_REQ": 0, - "DIAL_RSP": 1, - "CLOSE_REQ": 2, - "CLOSE_RSP": 3, - "DATA": 4, - "DIAL_CLS": 5, +func (x PacketType) Enum() *PacketType { + p := new(PacketType) + *p = x + return p } func (x PacketType) String() string { - return proto.EnumName(PacketType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } +func (PacketType) Descriptor() protoreflect.EnumDescriptor { + return file_konnectivity_client_proto_client_client_proto_enumTypes[0].Descriptor() +} + +func (PacketType) Type() protoreflect.EnumType { + return &file_konnectivity_client_proto_client_client_proto_enumTypes[0] +} + +func (x PacketType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PacketType.Descriptor instead. func (PacketType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{0} -} - -type Error int32 - -const ( - Error_EOF Error = 0 -) - -var Error_name = map[int32]string{ - 0: "EOF", -} - -var Error_value = map[string]int32{ - "EOF": 0, -} - -func (x Error) String() string { - return proto.EnumName(Error_name, int32(x)) -} - -func (Error) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{1} + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{0} } type Packet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + Type PacketType `protobuf:"varint,1,opt,name=type,proto3,enum=PacketType" json:"type,omitempty"` - // Types that are valid to be assigned to Payload: + // Types that are assignable to Payload: + // // *Packet_DialRequest // *Packet_DialResponse // *Packet_Data // *Packet_CloseRequest // *Packet_CloseResponse // *Packet_CloseDial - Payload isPacket_Payload `protobuf_oneof:"payload"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Payload isPacket_Payload `protobuf_oneof:"payload"` } -func (m *Packet) Reset() { *m = Packet{} } -func (m *Packet) String() string { return proto.CompactTextString(m) } -func (*Packet) ProtoMessage() {} +func (x *Packet) Reset() { + *x = Packet{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Packet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Packet) ProtoMessage() {} + +func (x *Packet) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Packet.ProtoReflect.Descriptor instead. func (*Packet) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{0} + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{0} } -func (m *Packet) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Packet.Unmarshal(m, b) -} -func (m *Packet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Packet.Marshal(b, m, deterministic) -} -func (m *Packet) XXX_Merge(src proto.Message) { - xxx_messageInfo_Packet.Merge(m, src) -} -func (m *Packet) XXX_Size() int { - return xxx_messageInfo_Packet.Size(m) -} -func (m *Packet) XXX_DiscardUnknown() { - xxx_messageInfo_Packet.DiscardUnknown(m) -} - -var xxx_messageInfo_Packet proto.InternalMessageInfo - -func (m *Packet) GetType() PacketType { - if m != nil { - return m.Type +func (x *Packet) GetType() PacketType { + if x != nil { + return x.Type } return PacketType_DIAL_REQ } +func (m *Packet) GetPayload() isPacket_Payload { + if m != nil { + return m.Payload + } + return nil +} + +func (x *Packet) GetDialRequest() *DialRequest { + if x, ok := x.GetPayload().(*Packet_DialRequest); ok { + return x.DialRequest + } + return nil +} + +func (x *Packet) GetDialResponse() *DialResponse { + if x, ok := x.GetPayload().(*Packet_DialResponse); ok { + return x.DialResponse + } + return nil +} + +func (x *Packet) GetData() *Data { + if x, ok := x.GetPayload().(*Packet_Data); ok { + return x.Data + } + return nil +} + +func (x *Packet) GetCloseRequest() *CloseRequest { + if x, ok := x.GetPayload().(*Packet_CloseRequest); ok { + return x.CloseRequest + } + return nil +} + +func (x *Packet) GetCloseResponse() *CloseResponse { + if x, ok := x.GetPayload().(*Packet_CloseResponse); ok { + return x.CloseResponse + } + return nil +} + +func (x *Packet) GetCloseDial() *CloseDial { + if x, ok := x.GetPayload().(*Packet_CloseDial); ok { + return x.CloseDial + } + return nil +} + type isPacket_Payload interface { isPacket_Payload() } @@ -185,58 +237,560 @@ func (*Packet_CloseResponse) isPacket_Payload() {} func (*Packet_CloseDial) isPacket_Payload() {} -func (m *Packet) GetPayload() isPacket_Payload { - if m != nil { - return m.Payload - } - return nil +type DialRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // tcp or udp? + Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty"` + // node:port + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` + // random id for client, maybe should be longer + Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` } -func (m *Packet) GetDialRequest() *DialRequest { - if x, ok := m.GetPayload().(*Packet_DialRequest); ok { - return x.DialRequest +func (x *DialRequest) Reset() { + *x = DialRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return nil } -func (m *Packet) GetDialResponse() *DialResponse { - if x, ok := m.GetPayload().(*Packet_DialResponse); ok { - return x.DialResponse - } - return nil +func (x *DialRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *Packet) GetData() *Data { - if x, ok := m.GetPayload().(*Packet_Data); ok { +func (*DialRequest) ProtoMessage() {} + +func (x *DialRequest) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DialRequest.ProtoReflect.Descriptor instead. +func (*DialRequest) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{1} +} + +func (x *DialRequest) GetProtocol() string { + if x != nil { + return x.Protocol + } + return "" +} + +func (x *DialRequest) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *DialRequest) GetRandom() int64 { + if x != nil { + return x.Random + } + return 0 +} + +type DialResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // error failed reason; enum? + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + // connectID indicates the identifier of the connection + ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` + // random copied from DialRequest + Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` +} + +func (x *DialResponse) Reset() { + *x = DialResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DialResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DialResponse) ProtoMessage() {} + +func (x *DialResponse) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DialResponse.ProtoReflect.Descriptor instead. +func (*DialResponse) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{2} +} + +func (x *DialResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *DialResponse) GetConnectID() int64 { + if x != nil { + return x.ConnectID + } + return 0 +} + +func (x *DialResponse) GetRandom() int64 { + if x != nil { + return x.Random + } + return 0 +} + +type CloseRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // connectID of the stream to close + ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` +} + +func (x *CloseRequest) Reset() { + *x = CloseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CloseRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CloseRequest) ProtoMessage() {} + +func (x *CloseRequest) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CloseRequest.ProtoReflect.Descriptor instead. +func (*CloseRequest) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{3} +} + +func (x *CloseRequest) GetConnectID() int64 { + if x != nil { + return x.ConnectID + } + return 0 +} + +type CloseResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // error message + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + // connectID indicates the identifier of the connection + ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` +} + +func (x *CloseResponse) Reset() { + *x = CloseResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CloseResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CloseResponse) ProtoMessage() {} + +func (x *CloseResponse) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CloseResponse.ProtoReflect.Descriptor instead. +func (*CloseResponse) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{4} +} + +func (x *CloseResponse) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *CloseResponse) GetConnectID() int64 { + if x != nil { + return x.ConnectID + } + return 0 +} + +type CloseDial struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // random id of the DialRequest + Random int64 `protobuf:"varint,1,opt,name=random,proto3" json:"random,omitempty"` +} + +func (x *CloseDial) Reset() { + *x = CloseDial{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CloseDial) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CloseDial) ProtoMessage() {} + +func (x *CloseDial) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CloseDial.ProtoReflect.Descriptor instead. +func (*CloseDial) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{5} +} + +func (x *CloseDial) GetRandom() int64 { + if x != nil { + return x.Random + } + return 0 +} + +type Data struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // connectID to connect to + ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` + // error message if error happens + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + // stream data + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *Data) Reset() { + *x = Data{} + if protoimpl.UnsafeEnabled { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Data) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Data) ProtoMessage() {} + +func (x *Data) ProtoReflect() protoreflect.Message { + mi := &file_konnectivity_client_proto_client_client_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Data.ProtoReflect.Descriptor instead. +func (*Data) Descriptor() ([]byte, []int) { + return file_konnectivity_client_proto_client_client_proto_rawDescGZIP(), []int{6} +} + +func (x *Data) GetConnectID() int64 { + if x != nil { + return x.ConnectID + } + return 0 +} + +func (x *Data) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *Data) GetData() []byte { + if x != nil { return x.Data } return nil } -func (m *Packet) GetCloseRequest() *CloseRequest { - if x, ok := m.GetPayload().(*Packet_CloseRequest); ok { - return x.CloseRequest - } - return nil +var File_konnectivity_client_proto_client_client_proto protoreflect.FileDescriptor + +var file_konnectivity_client_proto_client_client_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x6b, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2d, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xd1, 0x02, 0x0a, 0x06, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x64, + 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, + 0x52, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, + 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x05, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x33, 0x0a, 0x0c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x0d, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x09, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x69, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0a, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x69, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x09, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x69, 0x61, 0x6c, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x22, 0x5b, 0x0a, 0x0b, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, + 0x22, 0x5a, 0x0a, 0x0c, 0x44, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0x2c, 0x0a, 0x0c, + 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x22, 0x43, 0x0a, 0x0d, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x22, + 0x23, 0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x44, 0x69, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x72, 0x61, + 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0x4e, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x2a, 0x5e, 0x0a, 0x0a, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x00, + 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x52, 0x53, 0x50, 0x10, 0x01, 0x12, 0x0d, + 0x0a, 0x09, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x51, 0x10, 0x02, 0x12, 0x0d, 0x0a, + 0x09, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x52, 0x53, 0x50, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, + 0x44, 0x41, 0x54, 0x41, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x41, 0x4c, 0x5f, 0x43, + 0x4c, 0x53, 0x10, 0x05, 0x32, 0x2f, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x07, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x1a, 0x07, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x22, + 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x46, 0x5a, 0x44, 0x73, 0x69, 0x67, 0x73, 0x2e, 0x6b, 0x38, + 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x6b, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } -func (m *Packet) GetCloseResponse() *CloseResponse { - if x, ok := m.GetPayload().(*Packet_CloseResponse); ok { - return x.CloseResponse - } - return nil +var ( + file_konnectivity_client_proto_client_client_proto_rawDescOnce sync.Once + file_konnectivity_client_proto_client_client_proto_rawDescData = file_konnectivity_client_proto_client_client_proto_rawDesc +) + +func file_konnectivity_client_proto_client_client_proto_rawDescGZIP() []byte { + file_konnectivity_client_proto_client_client_proto_rawDescOnce.Do(func() { + file_konnectivity_client_proto_client_client_proto_rawDescData = protoimpl.X.CompressGZIP(file_konnectivity_client_proto_client_client_proto_rawDescData) + }) + return file_konnectivity_client_proto_client_client_proto_rawDescData } -func (m *Packet) GetCloseDial() *CloseDial { - if x, ok := m.GetPayload().(*Packet_CloseDial); ok { - return x.CloseDial - } - return nil +var file_konnectivity_client_proto_client_client_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_konnectivity_client_proto_client_client_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_konnectivity_client_proto_client_client_proto_goTypes = []interface{}{ + (PacketType)(0), // 0: PacketType + (*Packet)(nil), // 1: Packet + (*DialRequest)(nil), // 2: DialRequest + (*DialResponse)(nil), // 3: DialResponse + (*CloseRequest)(nil), // 4: CloseRequest + (*CloseResponse)(nil), // 5: CloseResponse + (*CloseDial)(nil), // 6: CloseDial + (*Data)(nil), // 7: Data +} +var file_konnectivity_client_proto_client_client_proto_depIdxs = []int32{ + 0, // 0: Packet.type:type_name -> PacketType + 2, // 1: Packet.dialRequest:type_name -> DialRequest + 3, // 2: Packet.dialResponse:type_name -> DialResponse + 7, // 3: Packet.data:type_name -> Data + 4, // 4: Packet.closeRequest:type_name -> CloseRequest + 5, // 5: Packet.closeResponse:type_name -> CloseResponse + 6, // 6: Packet.closeDial:type_name -> CloseDial + 1, // 7: ProxyService.Proxy:input_type -> Packet + 1, // 8: ProxyService.Proxy:output_type -> Packet + 8, // [8:9] is the sub-list for method output_type + 7, // [7:8] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } -// XXX_OneofWrappers is for the internal use of the proto package. -func (*Packet) XXX_OneofWrappers() []interface{} { - return []interface{}{ +func init() { file_konnectivity_client_proto_client_client_proto_init() } +func file_konnectivity_client_proto_client_client_proto_init() { + if File_konnectivity_client_proto_client_client_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_konnectivity_client_proto_client_client_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Packet); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DialRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DialResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CloseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CloseResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CloseDial); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Data); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_konnectivity_client_proto_client_client_proto_msgTypes[0].OneofWrappers = []interface{}{ (*Packet_DialRequest)(nil), (*Packet_DialResponse)(nil), (*Packet_Data)(nil), @@ -244,471 +798,23 @@ func (*Packet) XXX_OneofWrappers() []interface{} { (*Packet_CloseResponse)(nil), (*Packet_CloseDial)(nil), } -} - -type DialRequest struct { - // tcp or udp? - Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty"` - // node:port - Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - // random id for client, maybe should be longer - Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DialRequest) Reset() { *m = DialRequest{} } -func (m *DialRequest) String() string { return proto.CompactTextString(m) } -func (*DialRequest) ProtoMessage() {} -func (*DialRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{1} -} - -func (m *DialRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DialRequest.Unmarshal(m, b) -} -func (m *DialRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DialRequest.Marshal(b, m, deterministic) -} -func (m *DialRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_DialRequest.Merge(m, src) -} -func (m *DialRequest) XXX_Size() int { - return xxx_messageInfo_DialRequest.Size(m) -} -func (m *DialRequest) XXX_DiscardUnknown() { - xxx_messageInfo_DialRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_DialRequest proto.InternalMessageInfo - -func (m *DialRequest) GetProtocol() string { - if m != nil { - return m.Protocol - } - return "" -} - -func (m *DialRequest) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -func (m *DialRequest) GetRandom() int64 { - if m != nil { - return m.Random - } - return 0 -} - -type DialResponse struct { - // error failed reason; enum? - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` - // connectID indicates the identifier of the connection - ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` - // random copied from DialRequest - Random int64 `protobuf:"varint,3,opt,name=random,proto3" json:"random,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DialResponse) Reset() { *m = DialResponse{} } -func (m *DialResponse) String() string { return proto.CompactTextString(m) } -func (*DialResponse) ProtoMessage() {} -func (*DialResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{2} -} - -func (m *DialResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DialResponse.Unmarshal(m, b) -} -func (m *DialResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DialResponse.Marshal(b, m, deterministic) -} -func (m *DialResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_DialResponse.Merge(m, src) -} -func (m *DialResponse) XXX_Size() int { - return xxx_messageInfo_DialResponse.Size(m) -} -func (m *DialResponse) XXX_DiscardUnknown() { - xxx_messageInfo_DialResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_DialResponse proto.InternalMessageInfo - -func (m *DialResponse) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -func (m *DialResponse) GetConnectID() int64 { - if m != nil { - return m.ConnectID - } - return 0 -} - -func (m *DialResponse) GetRandom() int64 { - if m != nil { - return m.Random - } - return 0 -} - -type CloseRequest struct { - // connectID of the stream to close - ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CloseRequest) Reset() { *m = CloseRequest{} } -func (m *CloseRequest) String() string { return proto.CompactTextString(m) } -func (*CloseRequest) ProtoMessage() {} -func (*CloseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{3} -} - -func (m *CloseRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CloseRequest.Unmarshal(m, b) -} -func (m *CloseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CloseRequest.Marshal(b, m, deterministic) -} -func (m *CloseRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CloseRequest.Merge(m, src) -} -func (m *CloseRequest) XXX_Size() int { - return xxx_messageInfo_CloseRequest.Size(m) -} -func (m *CloseRequest) XXX_DiscardUnknown() { - xxx_messageInfo_CloseRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_CloseRequest proto.InternalMessageInfo - -func (m *CloseRequest) GetConnectID() int64 { - if m != nil { - return m.ConnectID - } - return 0 -} - -type CloseResponse struct { - // error message - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` - // connectID indicates the identifier of the connection - ConnectID int64 `protobuf:"varint,2,opt,name=connectID,proto3" json:"connectID,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CloseResponse) Reset() { *m = CloseResponse{} } -func (m *CloseResponse) String() string { return proto.CompactTextString(m) } -func (*CloseResponse) ProtoMessage() {} -func (*CloseResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{4} -} - -func (m *CloseResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CloseResponse.Unmarshal(m, b) -} -func (m *CloseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CloseResponse.Marshal(b, m, deterministic) -} -func (m *CloseResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CloseResponse.Merge(m, src) -} -func (m *CloseResponse) XXX_Size() int { - return xxx_messageInfo_CloseResponse.Size(m) -} -func (m *CloseResponse) XXX_DiscardUnknown() { - xxx_messageInfo_CloseResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_CloseResponse proto.InternalMessageInfo - -func (m *CloseResponse) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -func (m *CloseResponse) GetConnectID() int64 { - if m != nil { - return m.ConnectID - } - return 0 -} - -type CloseDial struct { - // random id of the DialRequest - Random int64 `protobuf:"varint,1,opt,name=random,proto3" json:"random,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CloseDial) Reset() { *m = CloseDial{} } -func (m *CloseDial) String() string { return proto.CompactTextString(m) } -func (*CloseDial) ProtoMessage() {} -func (*CloseDial) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{5} -} - -func (m *CloseDial) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CloseDial.Unmarshal(m, b) -} -func (m *CloseDial) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CloseDial.Marshal(b, m, deterministic) -} -func (m *CloseDial) XXX_Merge(src proto.Message) { - xxx_messageInfo_CloseDial.Merge(m, src) -} -func (m *CloseDial) XXX_Size() int { - return xxx_messageInfo_CloseDial.Size(m) -} -func (m *CloseDial) XXX_DiscardUnknown() { - xxx_messageInfo_CloseDial.DiscardUnknown(m) -} - -var xxx_messageInfo_CloseDial proto.InternalMessageInfo - -func (m *CloseDial) GetRandom() int64 { - if m != nil { - return m.Random - } - return 0 -} - -type Data struct { - // connectID to connect to - ConnectID int64 `protobuf:"varint,1,opt,name=connectID,proto3" json:"connectID,omitempty"` - // error message if error happens - Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` - // stream data - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Data) Reset() { *m = Data{} } -func (m *Data) String() string { return proto.CompactTextString(m) } -func (*Data) ProtoMessage() {} -func (*Data) Descriptor() ([]byte, []int) { - return fileDescriptor_fec4258d9ecd175d, []int{6} -} - -func (m *Data) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Data.Unmarshal(m, b) -} -func (m *Data) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Data.Marshal(b, m, deterministic) -} -func (m *Data) XXX_Merge(src proto.Message) { - xxx_messageInfo_Data.Merge(m, src) -} -func (m *Data) XXX_Size() int { - return xxx_messageInfo_Data.Size(m) -} -func (m *Data) XXX_DiscardUnknown() { - xxx_messageInfo_Data.DiscardUnknown(m) -} - -var xxx_messageInfo_Data proto.InternalMessageInfo - -func (m *Data) GetConnectID() int64 { - if m != nil { - return m.ConnectID - } - return 0 -} - -func (m *Data) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -func (m *Data) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -func init() { - proto.RegisterEnum("PacketType", PacketType_name, PacketType_value) - proto.RegisterEnum("Error", Error_name, Error_value) - proto.RegisterType((*Packet)(nil), "Packet") - proto.RegisterType((*DialRequest)(nil), "DialRequest") - proto.RegisterType((*DialResponse)(nil), "DialResponse") - proto.RegisterType((*CloseRequest)(nil), "CloseRequest") - proto.RegisterType((*CloseResponse)(nil), "CloseResponse") - proto.RegisterType((*CloseDial)(nil), "CloseDial") - proto.RegisterType((*Data)(nil), "Data") -} - -func init() { - proto.RegisterFile("konnectivity-client/proto/client/client.proto", fileDescriptor_fec4258d9ecd175d) -} - -var fileDescriptor_fec4258d9ecd175d = []byte{ - // 505 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x51, 0x8b, 0xd3, 0x40, - 0x18, 0x4c, 0xda, 0xa4, 0x6d, 0xbe, 0xa6, 0x47, 0x58, 0x44, 0xc2, 0x29, 0xdc, 0x11, 0x5f, 0x4a, - 0xb1, 0xe9, 0xd1, 0x03, 0xf1, 0xb5, 0xd7, 0xf4, 0xe8, 0x41, 0xf1, 0xea, 0xf6, 0x9e, 0x4e, 0x50, - 0xd6, 0x64, 0x91, 0xd0, 0x98, 0x8d, 0xbb, 0x6b, 0x35, 0x3f, 0xd3, 0x7f, 0x24, 0xd9, 0xa4, 0x4d, - 0x22, 0xa8, 0x70, 0x4f, 0xed, 0xcc, 0x7e, 0x33, 0x3b, 0x19, 0xbe, 0x85, 0xe9, 0x9e, 0xa5, 0x29, - 0x0d, 0x65, 0x7c, 0x88, 0x65, 0x3e, 0x0d, 0x93, 0x98, 0xa6, 0x72, 0x96, 0x71, 0x26, 0xd9, 0xac, - 0x02, 0xe5, 0x8f, 0xaf, 0x38, 0xef, 0x57, 0x07, 0x7a, 0x5b, 0x12, 0xee, 0xa9, 0x44, 0x17, 0x60, - 0xc8, 0x3c, 0xa3, 0xae, 0x7e, 0xa9, 0x8f, 0xcf, 0xe6, 0x43, 0xbf, 0xa4, 0x1f, 0xf2, 0x8c, 0x62, - 0x75, 0x80, 0xae, 0x60, 0x18, 0xc5, 0x24, 0xc1, 0xf4, 0xdb, 0x77, 0x2a, 0xa4, 0xdb, 0xb9, 0xd4, - 0xc7, 0xc3, 0xb9, 0xed, 0x07, 0x35, 0xb7, 0xd6, 0x70, 0x73, 0x04, 0x5d, 0x83, 0x5d, 0x42, 0x91, - 0xb1, 0x54, 0x50, 0xb7, 0xab, 0x24, 0xa3, 0x4a, 0x52, 0x92, 0x6b, 0x0d, 0xb7, 0x86, 0xd0, 0x0b, - 0x30, 0x22, 0x22, 0x89, 0x6b, 0xa8, 0x61, 0xd3, 0x0f, 0x88, 0x24, 0x6b, 0x0d, 0x2b, 0xb2, 0x70, - 0x0c, 0x13, 0x26, 0xe8, 0x31, 0x84, 0x59, 0x39, 0x2e, 0x1b, 0x64, 0xe1, 0xd8, 0x1c, 0x42, 0x6f, - 0x60, 0x54, 0xe1, 0x2a, 0x47, 0x4f, 0xa9, 0xce, 0x8e, 0xaa, 0x53, 0x90, 0xf6, 0x18, 0x9a, 0x80, - 0xa5, 0x88, 0x22, 0xae, 0xdb, 0x57, 0x1a, 0x28, 0x35, 0x05, 0xb3, 0xd6, 0x70, 0x7d, 0x7c, 0x63, - 0x41, 0x3f, 0x23, 0x79, 0xc2, 0x48, 0xe4, 0x7d, 0x80, 0x61, 0xa3, 0x13, 0x74, 0x0e, 0x03, 0xd5, - 0x75, 0xc8, 0x12, 0xd5, 0xad, 0x85, 0x4f, 0x18, 0xb9, 0xd0, 0x27, 0x51, 0xc4, 0xa9, 0x10, 0xaa, - 0x4e, 0x0b, 0x1f, 0x21, 0x7a, 0x0e, 0x3d, 0x4e, 0xd2, 0x88, 0x7d, 0x55, 0xa5, 0x75, 0x71, 0x85, - 0xbc, 0x47, 0xb0, 0x9b, 0xed, 0xa1, 0x67, 0x60, 0x52, 0xce, 0x19, 0xaf, 0xac, 0x4b, 0x80, 0x5e, - 0x82, 0x15, 0x96, 0x7b, 0x70, 0x17, 0x28, 0xe7, 0x2e, 0xae, 0x89, 0xbf, 0x7a, 0xbf, 0x06, 0xbb, - 0xd9, 0x63, 0xdb, 0x45, 0xff, 0xc3, 0xc5, 0x5b, 0xc2, 0xa8, 0xd5, 0xdf, 0x53, 0xa2, 0x78, 0xaf, - 0xc0, 0x3a, 0x15, 0xda, 0xc8, 0xa5, 0xb7, 0x72, 0xbd, 0x03, 0xa3, 0x58, 0x82, 0x7f, 0xe7, 0xa9, - 0xaf, 0xef, 0x34, 0xaf, 0x47, 0xd5, 0x36, 0x15, 0x5f, 0x6a, 0x97, 0x4b, 0x34, 0xf9, 0x08, 0x50, - 0x2f, 0x37, 0xb2, 0x61, 0x10, 0xdc, 0x2d, 0x36, 0x9f, 0xf0, 0xea, 0xbd, 0xa3, 0xd5, 0x68, 0xb7, - 0x75, 0x74, 0x34, 0x02, 0x6b, 0xb9, 0xb9, 0xdf, 0xad, 0xd4, 0x61, 0xa7, 0x01, 0x77, 0x5b, 0xa7, - 0x8b, 0x06, 0x60, 0x04, 0x8b, 0x87, 0x85, 0x63, 0x9c, 0x54, 0xcb, 0xcd, 0xce, 0x31, 0x27, 0x0e, - 0x98, 0x2b, 0x75, 0x79, 0x1f, 0xba, 0xab, 0xfb, 0x5b, 0x47, 0x9b, 0xcf, 0xc0, 0xde, 0x72, 0xf6, - 0x33, 0xdf, 0x51, 0x7e, 0x88, 0x43, 0x8a, 0x2e, 0xc0, 0x54, 0x18, 0xf5, 0xab, 0x67, 0x76, 0x7e, - 0xfc, 0xe3, 0x69, 0x63, 0xfd, 0x4a, 0xbf, 0xb9, 0x7d, 0x0c, 0x44, 0xfc, 0x45, 0xf8, 0xfb, 0xb7, - 0xc2, 0x8f, 0xd9, 0x8c, 0x64, 0xb1, 0xa0, 0xfc, 0x40, 0xf9, 0x34, 0xa5, 0xf2, 0x07, 0xe3, 0xfb, - 0x69, 0x56, 0xc8, 0x67, 0xff, 0x7b, 0xec, 0x9f, 0x7b, 0x0a, 0x5d, 0xff, 0x0e, 0x00, 0x00, 0xff, - 0xff, 0x38, 0x1b, 0xf6, 0x4f, 0x17, 0x04, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// ProxyServiceClient is the client API for ProxyService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type ProxyServiceClient interface { - Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) -} - -type proxyServiceClient struct { - cc *grpc.ClientConn -} - -func NewProxyServiceClient(cc *grpc.ClientConn) ProxyServiceClient { - return &proxyServiceClient{cc} -} - -func (c *proxyServiceClient) Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) { - stream, err := c.cc.NewStream(ctx, &_ProxyService_serviceDesc.Streams[0], "/ProxyService/Proxy", opts...) - if err != nil { - return nil, err - } - x := &proxyServiceProxyClient{stream} - return x, nil -} - -type ProxyService_ProxyClient interface { - Send(*Packet) error - Recv() (*Packet, error) - grpc.ClientStream -} - -type proxyServiceProxyClient struct { - grpc.ClientStream -} - -func (x *proxyServiceProxyClient) Send(m *Packet) error { - return x.ClientStream.SendMsg(m) -} - -func (x *proxyServiceProxyClient) Recv() (*Packet, error) { - m := new(Packet) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// ProxyServiceServer is the server API for ProxyService service. -type ProxyServiceServer interface { - Proxy(ProxyService_ProxyServer) error -} - -// UnimplementedProxyServiceServer can be embedded to have forward compatible implementations. -type UnimplementedProxyServiceServer struct { -} - -func (*UnimplementedProxyServiceServer) Proxy(srv ProxyService_ProxyServer) error { - return status.Errorf(codes.Unimplemented, "method Proxy not implemented") -} - -func RegisterProxyServiceServer(s *grpc.Server, srv ProxyServiceServer) { - s.RegisterService(&_ProxyService_serviceDesc, srv) -} - -func _ProxyService_Proxy_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ProxyServiceServer).Proxy(&proxyServiceProxyServer{stream}) -} - -type ProxyService_ProxyServer interface { - Send(*Packet) error - Recv() (*Packet, error) - grpc.ServerStream -} - -type proxyServiceProxyServer struct { - grpc.ServerStream -} - -func (x *proxyServiceProxyServer) Send(m *Packet) error { - return x.ServerStream.SendMsg(m) -} - -func (x *proxyServiceProxyServer) Recv() (*Packet, error) { - m := new(Packet) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -var _ProxyService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "ProxyService", - HandlerType: (*ProxyServiceServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "Proxy", - Handler: _ProxyService_Proxy_Handler, - ServerStreams: true, - ClientStreams: true, + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_konnectivity_client_proto_client_client_proto_rawDesc, + NumEnums: 1, + NumMessages: 7, + NumExtensions: 0, + NumServices: 1, }, - }, - Metadata: "konnectivity-client/proto/client/client.proto", + GoTypes: file_konnectivity_client_proto_client_client_proto_goTypes, + DependencyIndexes: file_konnectivity_client_proto_client_client_proto_depIdxs, + EnumInfos: file_konnectivity_client_proto_client_client_proto_enumTypes, + MessageInfos: file_konnectivity_client_proto_client_client_proto_msgTypes, + }.Build() + File_konnectivity_client_proto_client_client_proto = out.File + file_konnectivity_client_proto_client_client_proto_rawDesc = nil + file_konnectivity_client_proto_client_client_proto_goTypes = nil + file_konnectivity_client_proto_client_client_proto_depIdxs = nil } diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto index 0c4cff8cd..811278e62 100644 --- a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client.proto @@ -32,11 +32,6 @@ enum PacketType { DIAL_CLS = 5; } -enum Error { - EOF = 0; - // ... -} - message Packet { PacketType type = 1; diff --git a/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client_grpc.pb.go b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client_grpc.pb.go new file mode 100644 index 000000000..b8d07fe55 --- /dev/null +++ b/vendor/sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client/client_grpc.pb.go @@ -0,0 +1,150 @@ +/* +Copyright 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. +*/ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.12.4 +// source: konnectivity-client/proto/client/client.proto + +package client + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ProxyServiceClient is the client API for ProxyService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ProxyServiceClient interface { + Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) +} + +type proxyServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewProxyServiceClient(cc grpc.ClientConnInterface) ProxyServiceClient { + return &proxyServiceClient{cc} +} + +func (c *proxyServiceClient) Proxy(ctx context.Context, opts ...grpc.CallOption) (ProxyService_ProxyClient, error) { + stream, err := c.cc.NewStream(ctx, &ProxyService_ServiceDesc.Streams[0], "/ProxyService/Proxy", opts...) + if err != nil { + return nil, err + } + x := &proxyServiceProxyClient{stream} + return x, nil +} + +type ProxyService_ProxyClient interface { + Send(*Packet) error + Recv() (*Packet, error) + grpc.ClientStream +} + +type proxyServiceProxyClient struct { + grpc.ClientStream +} + +func (x *proxyServiceProxyClient) Send(m *Packet) error { + return x.ClientStream.SendMsg(m) +} + +func (x *proxyServiceProxyClient) Recv() (*Packet, error) { + m := new(Packet) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ProxyServiceServer is the server API for ProxyService service. +// All implementations should embed UnimplementedProxyServiceServer +// for forward compatibility +type ProxyServiceServer interface { + Proxy(ProxyService_ProxyServer) error +} + +// UnimplementedProxyServiceServer should be embedded to have forward compatible implementations. +type UnimplementedProxyServiceServer struct { +} + +func (UnimplementedProxyServiceServer) Proxy(ProxyService_ProxyServer) error { + return status.Errorf(codes.Unimplemented, "method Proxy not implemented") +} + +// UnsafeProxyServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ProxyServiceServer will +// result in compilation errors. +type UnsafeProxyServiceServer interface { + mustEmbedUnimplementedProxyServiceServer() +} + +func RegisterProxyServiceServer(s grpc.ServiceRegistrar, srv ProxyServiceServer) { + s.RegisterService(&ProxyService_ServiceDesc, srv) +} + +func _ProxyService_Proxy_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ProxyServiceServer).Proxy(&proxyServiceProxyServer{stream}) +} + +type ProxyService_ProxyServer interface { + Send(*Packet) error + Recv() (*Packet, error) + grpc.ServerStream +} + +type proxyServiceProxyServer struct { + grpc.ServerStream +} + +func (x *proxyServiceProxyServer) Send(m *Packet) error { + return x.ServerStream.SendMsg(m) +} + +func (x *proxyServiceProxyServer) Recv() (*Packet, error) { + m := new(Packet) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ProxyService_ServiceDesc is the grpc.ServiceDesc for ProxyService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ProxyService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ProxyService", + HandlerType: (*ProxyServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Proxy", + Handler: _ProxyService_Proxy_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "konnectivity-client/proto/client/client.proto", +} diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go index a6c419365..6a13cf2df 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/decode.go @@ -75,6 +75,8 @@ import ( // either be any string type, an integer, implement json.Unmarshaler, or // implement encoding.TextUnmarshaler. // +// If the JSON-encoded data contain a syntax error, Unmarshal returns a SyntaxError. +// // If a JSON value is not appropriate for a given target type, // or if a JSON number overflows the target type, Unmarshal // skips that field and completes the unmarshaling as best it can. @@ -85,14 +87,13 @@ import ( // // The JSON null value unmarshals into an interface, map, pointer, or slice // by setting that Go value to nil. Because null is often used in JSON to mean -// ``not present,'' unmarshaling a JSON null into any other Go type has no effect +// “not present,” unmarshaling a JSON null into any other Go type has no effect // on the value and produces no error. // // When unmarshaling quoted strings, invalid UTF-8 or // invalid UTF-16 surrogate pairs are not treated as an error. // Instead, they are replaced by the Unicode replacement // character U+FFFD. -// func Unmarshal(data []byte, v any, opts ...UnmarshalOpt) error { // Check for well-formedness. // Avoids filling out half a data structure diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go index 1f5e3e446..5b67251fb 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/encode.go @@ -77,31 +77,31 @@ import ( // // Examples of struct field tags and their meanings: // -// // Field appears in JSON as key "myName". -// Field int `json:"myName"` +// // Field appears in JSON as key "myName". +// Field int `json:"myName"` // -// // Field appears in JSON as key "myName" and -// // the field is omitted from the object if its value is empty, -// // as defined above. -// Field int `json:"myName,omitempty"` +// // Field appears in JSON as key "myName" and +// // the field is omitted from the object if its value is empty, +// // as defined above. +// Field int `json:"myName,omitempty"` // -// // Field appears in JSON as key "Field" (the default), but -// // the field is skipped if empty. -// // Note the leading comma. -// Field int `json:",omitempty"` +// // Field appears in JSON as key "Field" (the default), but +// // the field is skipped if empty. +// // Note the leading comma. +// Field int `json:",omitempty"` // -// // Field is ignored by this package. -// Field int `json:"-"` +// // Field is ignored by this package. +// Field int `json:"-"` // -// // Field appears in JSON as key "-". -// Field int `json:"-,"` +// // Field appears in JSON as key "-". +// Field int `json:"-,"` // // The "string" option signals that a field is stored as JSON inside a // JSON-encoded string. It applies only to fields of string, floating point, // integer, or boolean types. This extra level of encoding is sometimes used // when communicating with JavaScript programs: // -// Int64String int64 `json:",string"` +// Int64String int64 `json:",string"` // // The key name will be used if it's a non-empty string consisting of // only Unicode letters, digits, and ASCII punctuation except quotation @@ -154,7 +154,6 @@ import ( // JSON cannot represent cyclic data structures and Marshal does not // handle them. Passing cyclic structures to Marshal will result in // an error. -// func Marshal(v any) ([]byte, error) { e := newEncodeState() @@ -784,7 +783,7 @@ func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter { // We're a large number of nested ptrEncoder.encode calls deep; // start checking if we've run into a pointer cycle. - ptr := v.Pointer() + ptr := v.UnsafePointer() if _, ok := e.ptrSeen[ptr]; ok { e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) } @@ -877,9 +876,9 @@ func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { // Here we use a struct to memorize the pointer to the first element of the slice // and its length. ptr := struct { - ptr uintptr + ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe len int - }{v.Pointer(), v.Len()} + }{v.UnsafePointer(), v.Len()} if _, ok := e.ptrSeen[ptr]; ok { e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) } diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go index 9e170127d..ab249b2bb 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/fold.go @@ -24,8 +24,9 @@ const ( // 4) simpleLetterEqualFold, no specials, no non-letters. // // The letters S and K are special because they map to 3 runes, not just 2: -// * S maps to s and to U+017F 'ſ' Latin small letter long s -// * k maps to K and to U+212A 'K' Kelvin sign +// - S maps to s and to U+017F 'ſ' Latin small letter long s +// - k maps to K and to U+212A 'K' Kelvin sign +// // See https://play.golang.org/p/tTxjOc0OGo // // The returned function is specialized for matching against s and diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go index dbaa821be..22fc6922d 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/scanner.go @@ -27,6 +27,7 @@ func Valid(data []byte) bool { // checkValid verifies that data is valid JSON-encoded data. // scan is passed in for use by checkValid to avoid an allocation. +// checkValid returns nil or a SyntaxError. func checkValid(data []byte, scan *scanner) error { scan.reset() for _, c := range data { @@ -42,6 +43,7 @@ func checkValid(data []byte, scan *scanner) error { } // A SyntaxError is a description of a JSON syntax error. +// Unmarshal will return a SyntaxError if the JSON can't be parsed. type SyntaxError struct { msg string // description of error Offset int64 // error occurred after reading Offset bytes diff --git a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go index 6775b4cf8..1967755ac 100644 --- a/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go +++ b/vendor/sigs.k8s.io/json/internal/golang/encoding/json/stream.go @@ -289,7 +289,6 @@ var _ Unmarshaler = (*RawMessage)(nil) // Number, for JSON numbers // string, for JSON string literals // nil, for JSON null -// type Token any */ diff --git a/vendor/sigs.k8s.io/json/json.go b/vendor/sigs.k8s.io/json/json.go index d3a42b426..e8f31b16c 100644 --- a/vendor/sigs.k8s.io/json/json.go +++ b/vendor/sigs.k8s.io/json/json.go @@ -34,13 +34,13 @@ type Decoder interface { } // NewDecoderCaseSensitivePreserveInts returns a decoder that matches the behavior of encoding/json#NewDecoder, with the following changes: -// - When unmarshaling into a struct, JSON keys must case-sensitively match `json` tag names (for tagged struct fields) -// or struct field names (for untagged struct fields), or they are treated as unknown fields and discarded. -// - When unmarshaling a number into an interface value, it is unmarshaled as an int64 if -// the JSON data does not contain a "." character and parses as an integer successfully and -// does not overflow int64. Otherwise, the number is unmarshaled as a float64. -// - If a syntax error is returned, it will not be of type encoding/json#SyntaxError, -// but will be recognizeable by this package's IsSyntaxError() function. +// - When unmarshaling into a struct, JSON keys must case-sensitively match `json` tag names (for tagged struct fields) +// or struct field names (for untagged struct fields), or they are treated as unknown fields and discarded. +// - When unmarshaling a number into an interface value, it is unmarshaled as an int64 if +// the JSON data does not contain a "." character and parses as an integer successfully and +// does not overflow int64. Otherwise, the number is unmarshaled as a float64. +// - If a syntax error is returned, it will not be of type encoding/json#SyntaxError, +// but will be recognizeable by this package's IsSyntaxError() function. func NewDecoderCaseSensitivePreserveInts(r io.Reader) Decoder { d := internaljson.NewDecoder(r) d.CaseSensitive() @@ -51,13 +51,13 @@ func NewDecoderCaseSensitivePreserveInts(r io.Reader) Decoder { // UnmarshalCaseSensitivePreserveInts parses the JSON-encoded data and stores the result in the value pointed to by v. // // UnmarshalCaseSensitivePreserveInts matches the behavior of encoding/json#Unmarshal, with the following changes: -// - When unmarshaling into a struct, JSON keys must case-sensitively match `json` tag names (for tagged struct fields) -// or struct field names (for untagged struct fields), or they are treated as unknown fields and discarded. -// - When unmarshaling a number into an interface value, it is unmarshaled as an int64 if -// the JSON data does not contain a "." character and parses as an integer successfully and -// does not overflow int64. Otherwise, the number is unmarshaled as a float64. -// - If a syntax error is returned, it will not be of type encoding/json#SyntaxError, -// but will be recognizeable by this package's IsSyntaxError() function. +// - When unmarshaling into a struct, JSON keys must case-sensitively match `json` tag names (for tagged struct fields) +// or struct field names (for untagged struct fields), or they are treated as unknown fields and discarded. +// - When unmarshaling a number into an interface value, it is unmarshaled as an int64 if +// the JSON data does not contain a "." character and parses as an integer successfully and +// does not overflow int64. Otherwise, the number is unmarshaled as a float64. +// - If a syntax error is returned, it will not be of type encoding/json#SyntaxError, +// but will be recognizeable by this package's IsSyntaxError() function. func UnmarshalCaseSensitivePreserveInts(data []byte, v interface{}) error { return internaljson.Unmarshal( data, diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go new file mode 100644 index 000000000..75a492d8e --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/conflict.go @@ -0,0 +1,121 @@ +/* +Copyright 2018 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 merge + +import ( + "fmt" + "sort" + "strings" + + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +// Conflict is a conflict on a specific field with the current manager of +// that field. It does implement the error interface so that it can be +// used as an error. +type Conflict struct { + Manager string + Path fieldpath.Path +} + +// Conflict is an error. +var _ error = Conflict{} + +// Error formats the conflict as an error. +func (c Conflict) Error() string { + return fmt.Sprintf("conflict with %q: %v", c.Manager, c.Path) +} + +// Equals returns true if c == c2 +func (c Conflict) Equals(c2 Conflict) bool { + if c.Manager != c2.Manager { + return false + } + return c.Path.Equals(c2.Path) +} + +// Conflicts accumulates multiple conflicts and aggregates them by managers. +type Conflicts []Conflict + +var _ error = Conflicts{} + +// Error prints the list of conflicts, grouped by sorted managers. +func (conflicts Conflicts) Error() string { + if len(conflicts) == 1 { + return conflicts[0].Error() + } + + m := map[string][]fieldpath.Path{} + for _, conflict := range conflicts { + m[conflict.Manager] = append(m[conflict.Manager], conflict.Path) + } + + managers := []string{} + for manager := range m { + managers = append(managers, manager) + } + + // Print conflicts by sorted managers. + sort.Strings(managers) + + messages := []string{} + for _, manager := range managers { + messages = append(messages, fmt.Sprintf("conflicts with %q:", manager)) + for _, path := range m[manager] { + messages = append(messages, fmt.Sprintf("- %v", path)) + } + } + return strings.Join(messages, "\n") +} + +// Equals returns true if the lists of conflicts are the same. +func (c Conflicts) Equals(c2 Conflicts) bool { + if len(c) != len(c2) { + return false + } + for i := range c { + if !c[i].Equals(c2[i]) { + return false + } + } + return true +} + +// ToSet aggregates conflicts for all managers into a single Set. +func (c Conflicts) ToSet() *fieldpath.Set { + set := fieldpath.NewSet() + for _, conflict := range []Conflict(c) { + set.Insert(conflict.Path) + } + return set +} + +// ConflictsFromManagers creates a list of conflicts given Managers sets. +func ConflictsFromManagers(sets fieldpath.ManagedFields) Conflicts { + conflicts := []Conflict{} + + for manager, set := range sets { + set.Set().Iterate(func(p fieldpath.Path) { + conflicts = append(conflicts, Conflict{ + Manager: manager, + Path: p, + }) + }) + } + + return conflicts +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go new file mode 100644 index 000000000..1b23dcbd5 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go @@ -0,0 +1,356 @@ +/* +Copyright 2018 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 merge + +import ( + "fmt" + + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" + "sigs.k8s.io/structured-merge-diff/v4/typed" +) + +// Converter is an interface to the conversion logic. The converter +// needs to be able to convert objects from one version to another. +type Converter interface { + Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) + IsMissingVersionError(error) bool +} + +// Updater is the object used to compute updated FieldSets and also +// merge the object on Apply. +type Updater struct { + Converter Converter + IgnoredFields map[fieldpath.APIVersion]*fieldpath.Set + + enableUnions bool +} + +// EnableUnionFeature turns on union handling. It is disabled by default until the +// feature is complete. +func (s *Updater) EnableUnionFeature() { + s.enableUnions = true +} + +func (s *Updater) update(oldObject, newObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, workflow string, force bool) (fieldpath.ManagedFields, *typed.Comparison, error) { + conflicts := fieldpath.ManagedFields{} + removed := fieldpath.ManagedFields{} + compare, err := oldObject.Compare(newObject) + if err != nil { + return nil, nil, fmt.Errorf("failed to compare objects: %v", err) + } + + versions := map[fieldpath.APIVersion]*typed.Comparison{ + version: compare.ExcludeFields(s.IgnoredFields[version]), + } + + for manager, managerSet := range managers { + if manager == workflow { + continue + } + compare, ok := versions[managerSet.APIVersion()] + if !ok { + var err error + versionedOldObject, err := s.Converter.Convert(oldObject, managerSet.APIVersion()) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + delete(managers, manager) + continue + } + return nil, nil, fmt.Errorf("failed to convert old object: %v", err) + } + versionedNewObject, err := s.Converter.Convert(newObject, managerSet.APIVersion()) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + delete(managers, manager) + continue + } + return nil, nil, fmt.Errorf("failed to convert new object: %v", err) + } + compare, err = versionedOldObject.Compare(versionedNewObject) + if err != nil { + return nil, nil, fmt.Errorf("failed to compare objects: %v", err) + } + versions[managerSet.APIVersion()] = compare.ExcludeFields(s.IgnoredFields[managerSet.APIVersion()]) + } + + conflictSet := managerSet.Set().Intersection(compare.Modified.Union(compare.Added)) + if !conflictSet.Empty() { + conflicts[manager] = fieldpath.NewVersionedSet(conflictSet, managerSet.APIVersion(), false) + } + + if !compare.Removed.Empty() { + removed[manager] = fieldpath.NewVersionedSet(compare.Removed, managerSet.APIVersion(), false) + } + } + + if !force && len(conflicts) != 0 { + return nil, nil, ConflictsFromManagers(conflicts) + } + + for manager, conflictSet := range conflicts { + managers[manager] = fieldpath.NewVersionedSet(managers[manager].Set().Difference(conflictSet.Set()), managers[manager].APIVersion(), managers[manager].Applied()) + } + + for manager, removedSet := range removed { + managers[manager] = fieldpath.NewVersionedSet(managers[manager].Set().Difference(removedSet.Set()), managers[manager].APIVersion(), managers[manager].Applied()) + } + + for manager := range managers { + if managers[manager].Set().Empty() { + delete(managers, manager) + } + } + + return managers, compare, nil +} + +// Update is the method you should call once you've merged your final +// object on CREATE/UPDATE/PATCH verbs. newObject must be the object +// that you intend to persist (after applying the patch if this is for a +// PATCH call), and liveObject must be the original object (empty if +// this is a CREATE call). +func (s *Updater) Update(liveObject, newObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, manager string) (*typed.TypedValue, fieldpath.ManagedFields, error) { + var err error + managers, err = s.reconcileManagedFieldsWithSchemaChanges(liveObject, managers) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + if s.enableUnions { + newObject, err = liveObject.NormalizeUnions(newObject) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + } + managers, compare, err := s.update(liveObject, newObject, version, managers, manager, true) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + if _, ok := managers[manager]; !ok { + managers[manager] = fieldpath.NewVersionedSet(fieldpath.NewSet(), version, false) + } + + ignored := s.IgnoredFields[version] + if ignored == nil { + ignored = fieldpath.NewSet() + } + managers[manager] = fieldpath.NewVersionedSet( + managers[manager].Set().Union(compare.Modified).Union(compare.Added).Difference(compare.Removed).RecursiveDifference(ignored), + version, + false, + ) + if managers[manager].Set().Empty() { + delete(managers, manager) + } + return newObject, managers, nil +} + +// Apply should be called when Apply is run, given the current object as +// well as the configuration that is applied. This will merge the object +// and return it. If the object hasn't changed, nil is returned (the +// managers can still have changed though). +func (s *Updater) Apply(liveObject, configObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, manager string, force bool) (*typed.TypedValue, fieldpath.ManagedFields, error) { + var err error + managers, err = s.reconcileManagedFieldsWithSchemaChanges(liveObject, managers) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + if s.enableUnions { + configObject, err = configObject.NormalizeUnionsApply(configObject) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + } + newObject, err := liveObject.Merge(configObject) + if err != nil { + return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to merge config: %v", err) + } + if s.enableUnions { + newObject, err = configObject.NormalizeUnionsApply(newObject) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + } + lastSet := managers[manager] + set, err := configObject.ToFieldSet() + if err != nil { + return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to get field set: %v", err) + } + + ignored := s.IgnoredFields[version] + if ignored != nil { + set = set.RecursiveDifference(ignored) + // TODO: is this correct. If we don't remove from lastSet pruning might remove the fields? + if lastSet != nil { + lastSet.Set().RecursiveDifference(ignored) + } + } + managers[manager] = fieldpath.NewVersionedSet(set, version, true) + newObject, err = s.prune(newObject, managers, manager, lastSet) + if err != nil { + return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to prune fields: %v", err) + } + managers, compare, err := s.update(liveObject, newObject, version, managers, manager, force) + if err != nil { + return nil, fieldpath.ManagedFields{}, err + } + if compare.IsSame() { + newObject = nil + } + return newObject, managers, nil +} + +// prune will remove a field, list or map item, iff: +// * applyingManager applied it last time +// * applyingManager didn't apply it this time +// * no other applier claims to manage it +func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFields, applyingManager string, lastSet fieldpath.VersionedSet) (*typed.TypedValue, error) { + if lastSet == nil || lastSet.Set().Empty() { + return merged, nil + } + convertedMerged, err := s.Converter.Convert(merged, lastSet.APIVersion()) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + return merged, nil + } + return nil, fmt.Errorf("failed to convert merged object to last applied version: %v", err) + } + + sc, tr := convertedMerged.Schema(), convertedMerged.TypeRef() + pruned := convertedMerged.RemoveItems(lastSet.Set().EnsureNamedFieldsAreMembers(sc, tr)) + pruned, err = s.addBackOwnedItems(convertedMerged, pruned, managers, applyingManager) + if err != nil { + return nil, fmt.Errorf("failed add back owned items: %v", err) + } + pruned, err = s.addBackDanglingItems(convertedMerged, pruned, lastSet) + if err != nil { + return nil, fmt.Errorf("failed add back dangling items: %v", err) + } + return s.Converter.Convert(pruned, managers[applyingManager].APIVersion()) +} + +// addBackOwnedItems adds back any fields, list and map items that were removed by prune, +// but other appliers or updaters (or the current applier's new config) claim to own. +func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFields fieldpath.ManagedFields, applyingManager string) (*typed.TypedValue, error) { + var err error + managedAtVersion := map[fieldpath.APIVersion]*fieldpath.Set{} + for _, managerSet := range managedFields { + if _, ok := managedAtVersion[managerSet.APIVersion()]; !ok { + managedAtVersion[managerSet.APIVersion()] = fieldpath.NewSet() + } + managedAtVersion[managerSet.APIVersion()] = managedAtVersion[managerSet.APIVersion()].Union(managerSet.Set()) + } + // Add back owned items at pruned version first to avoid conversion failure + // caused by pruned fields which are required for conversion. + prunedVersion := fieldpath.APIVersion(*pruned.TypeRef().NamedType) + if managed, ok := managedAtVersion[prunedVersion]; ok { + merged, pruned, err = s.addBackOwnedItemsForVersion(merged, pruned, prunedVersion, managed) + if err != nil { + return nil, err + } + delete(managedAtVersion, prunedVersion) + } + for version, managed := range managedAtVersion { + merged, pruned, err = s.addBackOwnedItemsForVersion(merged, pruned, version, managed) + if err != nil { + return nil, err + } + } + return pruned, nil +} + +// addBackOwnedItemsForVersion adds back any fields, list and map items that were removed by prune with specific managed field path at a version. +// It is an extracted sub-function from addBackOwnedItems for code reuse. +func (s *Updater) addBackOwnedItemsForVersion(merged, pruned *typed.TypedValue, version fieldpath.APIVersion, managed *fieldpath.Set) (*typed.TypedValue, *typed.TypedValue, error) { + var err error + merged, err = s.Converter.Convert(merged, version) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + return merged, pruned, nil + } + return nil, nil, fmt.Errorf("failed to convert merged object at version %v: %v", version, err) + } + pruned, err = s.Converter.Convert(pruned, version) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + return merged, pruned, nil + } + return nil, nil, fmt.Errorf("failed to convert pruned object at version %v: %v", version, err) + } + mergedSet, err := merged.ToFieldSet() + if err != nil { + return nil, nil, fmt.Errorf("failed to create field set from merged object at version %v: %v", version, err) + } + prunedSet, err := pruned.ToFieldSet() + if err != nil { + return nil, nil, fmt.Errorf("failed to create field set from pruned object at version %v: %v", version, err) + } + sc, tr := merged.Schema(), merged.TypeRef() + pruned = merged.RemoveItems(mergedSet.EnsureNamedFieldsAreMembers(sc, tr).Difference(prunedSet.EnsureNamedFieldsAreMembers(sc, tr).Union(managed.EnsureNamedFieldsAreMembers(sc, tr)))) + return merged, pruned, nil +} + +// addBackDanglingItems makes sure that the fields list and map items removed by prune were +// previously owned by the currently applying manager. This will add back fields list and map items +// that are unowned or that are owned by Updaters and shouldn't be removed. +func (s *Updater) addBackDanglingItems(merged, pruned *typed.TypedValue, lastSet fieldpath.VersionedSet) (*typed.TypedValue, error) { + convertedPruned, err := s.Converter.Convert(pruned, lastSet.APIVersion()) + if err != nil { + if s.Converter.IsMissingVersionError(err) { + return merged, nil + } + return nil, fmt.Errorf("failed to convert pruned object to last applied version: %v", err) + } + prunedSet, err := convertedPruned.ToFieldSet() + if err != nil { + return nil, fmt.Errorf("failed to create field set from pruned object in last applied version: %v", err) + } + mergedSet, err := merged.ToFieldSet() + if err != nil { + return nil, fmt.Errorf("failed to create field set from merged object in last applied version: %v", err) + } + sc, tr := merged.Schema(), merged.TypeRef() + prunedSet = prunedSet.EnsureNamedFieldsAreMembers(sc, tr) + mergedSet = mergedSet.EnsureNamedFieldsAreMembers(sc, tr) + last := lastSet.Set().EnsureNamedFieldsAreMembers(sc, tr) + return merged.RemoveItems(mergedSet.Difference(prunedSet).Intersection(last)), nil +} + +// reconcileManagedFieldsWithSchemaChanges reconciles the managed fields with any changes to the +// object's schema since the managed fields were written. +// +// Supports: +// - changing types from atomic to granular +// - changing types from granular to atomic +func (s *Updater) reconcileManagedFieldsWithSchemaChanges(liveObject *typed.TypedValue, managers fieldpath.ManagedFields) (fieldpath.ManagedFields, error) { + result := fieldpath.ManagedFields{} + for manager, versionedSet := range managers { + tv, err := s.Converter.Convert(liveObject, versionedSet.APIVersion()) + if s.Converter.IsMissingVersionError(err) { // okay to skip, obsolete versions will be deleted automatically anyway + continue + } + if err != nil { + return nil, err + } + reconciled, err := typed.ReconcileFieldSetWithSchema(versionedSet.Set(), tv) + if err != nil { + return nil, err + } + if reconciled != nil { + result[manager] = fieldpath.NewVersionedSet(reconciled, versionedSet.APIVersion(), versionedSet.Applied()) + } else { + result[manager] = versionedSet + } + } + return result, nil +} From 2551a0b05fc67b01bfdcdedbb918bc922dbf58b8 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Thu, 1 Jun 2023 18:58:10 +0200 Subject: [PATCH 133/165] rebase: update all k8s packages to 0.27.2 Signed-off-by: Niels de Vos --- go.mod | 74 +- go.sum | 134 +- .../asaskevich/govalidator/.travis.yml | 14 + .../asaskevich/govalidator/CONTRIBUTING.md | 63 + .../github.com/asaskevich/govalidator/LICENSE | 21 + .../asaskevich/govalidator/README.md | 507 ++ .../asaskevich/govalidator/arrays.go | 58 + .../asaskevich/govalidator/converter.go | 64 + .../asaskevich/govalidator/error.go | 43 + .../asaskevich/govalidator/numerics.go | 97 + .../asaskevich/govalidator/patterns.go | 101 + .../asaskevich/govalidator/types.go | 636 ++ .../asaskevich/govalidator/utils.go | 270 + .../asaskevich/govalidator/validator.go | 1278 +++ .../asaskevich/govalidator/wercker.yml | 15 + .../v1/types_swagger_doc_generated.go | 2 +- .../v1beta1/types_swagger_doc_generated.go | 2 +- .../admissionregistration/v1/generated.pb.go | 484 +- .../admissionregistration/v1/generated.proto | 73 + .../api/admissionregistration/v1/types.go | 73 + .../v1/types_swagger_doc_generated.go | 14 +- .../v1/zz_generated.deepcopy.go | 26 + .../v1alpha1/generated.pb.go | 1469 +++- .../v1alpha1/generated.proto | 228 +- .../admissionregistration/v1alpha1/types.go | 217 +- .../v1alpha1/types_swagger_doc_generated.go | 67 +- .../v1alpha1/zz_generated.deepcopy.go | 113 + .../v1beta1/generated.pb.go | 465 +- .../v1beta1/generated.proto | 73 + .../admissionregistration/v1beta1/types.go | 73 + .../v1beta1/types_swagger_doc_generated.go | 14 +- .../v1beta1/zz_generated.deepcopy.go | 26 + .../v1alpha1/types_swagger_doc_generated.go | 2 +- vendor/k8s.io/api/apps/v1/generated.proto | 5 +- vendor/k8s.io/api/apps/v1/types.go | 5 +- .../apps/v1/types_swagger_doc_generated.go | 10 +- .../k8s.io/api/apps/v1beta1/generated.proto | 57 +- vendor/k8s.io/api/apps/v1beta1/types.go | 57 +- .../v1beta1/types_swagger_doc_generated.go | 60 +- .../k8s.io/api/apps/v1beta2/generated.proto | 7 +- vendor/k8s.io/api/apps/v1beta2/types.go | 7 +- .../v1beta2/types_swagger_doc_generated.go | 12 +- .../v1/types_swagger_doc_generated.go | 2 +- .../authentication/v1alpha1/generated.proto | 3 +- .../api/authentication/v1alpha1/types.go | 5 +- .../v1alpha1/types_swagger_doc_generated.go | 4 +- .../zz_generated.prerelease-lifecycle.go | 6 +- .../authentication/v1beta1/generated.pb.go | 476 +- .../authentication/v1beta1/generated.proto | 21 + .../api/authentication/v1beta1/register.go | 1 + .../api/authentication/v1beta1/types.go | 27 + .../v1beta1/types_swagger_doc_generated.go | 21 +- .../v1beta1/zz_generated.deepcopy.go | 44 + .../zz_generated.prerelease-lifecycle.go | 18 + .../v1/types_swagger_doc_generated.go | 2 +- .../v1beta1/types_swagger_doc_generated.go | 2 +- .../k8s.io/api/autoscaling/v1/generated.proto | 42 +- vendor/k8s.io/api/autoscaling/v1/types.go | 79 +- .../v1/types_swagger_doc_generated.go | 42 +- .../k8s.io/api/autoscaling/v2/generated.proto | 20 +- vendor/k8s.io/api/autoscaling/v2/types.go | 61 +- .../v2/types_swagger_doc_generated.go | 22 +- .../api/autoscaling/v2beta1/generated.proto | 2 +- .../k8s.io/api/autoscaling/v2beta1/types.go | 2 +- .../v2beta1/types_swagger_doc_generated.go | 4 +- .../api/autoscaling/v2beta2/generated.proto | 24 +- .../k8s.io/api/autoscaling/v2beta2/types.go | 62 +- .../v2beta2/types_swagger_doc_generated.go | 26 +- vendor/k8s.io/api/batch/v1/generated.proto | 32 +- vendor/k8s.io/api/batch/v1/types.go | 46 +- .../batch/v1/types_swagger_doc_generated.go | 30 +- .../k8s.io/api/batch/v1beta1/generated.pb.go | 317 +- .../k8s.io/api/batch/v1beta1/generated.proto | 15 +- vendor/k8s.io/api/batch/v1beta1/register.go | 1 - vendor/k8s.io/api/batch/v1beta1/types.go | 20 +- .../v1beta1/types_swagger_doc_generated.go | 16 +- .../batch/v1beta1/zz_generated.deepcopy.go | 27 - .../zz_generated.prerelease-lifecycle.go | 18 - vendor/k8s.io/api/certificates/v1/types.go | 3 +- .../v1/types_swagger_doc_generated.go | 2 +- .../k8s.io/api/certificates/v1alpha1/doc.go | 24 + .../api/certificates/v1alpha1/generated.pb.go | 831 ++ .../api/certificates/v1alpha1/generated.proto | 103 + .../api/certificates/v1alpha1/register.go | 61 + .../k8s.io/api/certificates/v1alpha1/types.go | 106 + .../v1alpha1/types_swagger_doc_generated.go | 60 + .../v1alpha1/zz_generated.deepcopy.go | 102 + .../zz_generated.prerelease-lifecycle.go | 58 + .../api/certificates/v1beta1/generated.proto | 6 +- .../k8s.io/api/certificates/v1beta1/types.go | 9 +- .../v1beta1/types_swagger_doc_generated.go | 4 +- .../api/coordination/v1/generated.proto | 6 +- vendor/k8s.io/api/coordination/v1/types.go | 6 +- .../v1/types_swagger_doc_generated.go | 8 +- .../api/coordination/v1beta1/generated.proto | 6 +- .../k8s.io/api/coordination/v1beta1/types.go | 6 +- .../v1beta1/types_swagger_doc_generated.go | 8 +- .../api/core/v1/annotation_key_constants.go | 21 +- vendor/k8s.io/api/core/v1/generated.pb.go | 2800 ++++--- vendor/k8s.io/api/core/v1/generated.proto | 148 +- vendor/k8s.io/api/core/v1/toleration.go | 14 +- vendor/k8s.io/api/core/v1/types.go | 229 +- .../core/v1/types_swagger_doc_generated.go | 67 +- .../api/core/v1/zz_generated.deepcopy.go | 40 +- .../k8s.io/api/discovery/v1/generated.proto | 26 +- vendor/k8s.io/api/discovery/v1/types.go | 42 +- .../v1/types_swagger_doc_generated.go | 14 +- .../api/discovery/v1beta1/generated.proto | 13 +- vendor/k8s.io/api/discovery/v1beta1/types.go | 30 +- .../v1beta1/types_swagger_doc_generated.go | 12 +- .../events/v1/types_swagger_doc_generated.go | 2 +- .../v1beta1/types_swagger_doc_generated.go | 2 +- .../api/extensions/v1beta1/generated.pb.go | 4334 +--------- .../api/extensions/v1beta1/generated.proto | 289 +- .../k8s.io/api/extensions/v1beta1/register.go | 2 - vendor/k8s.io/api/extensions/v1beta1/types.go | 385 +- .../v1beta1/types_swagger_doc_generated.go | 164 +- .../v1beta1/zz_generated.deepcopy.go | 366 - .../zz_generated.prerelease-lifecycle.go | 48 - .../v1alpha1/types_swagger_doc_generated.go | 2 +- .../v1beta1/types_swagger_doc_generated.go | 2 +- .../v1beta2/types_swagger_doc_generated.go | 2 +- .../v1beta3/types_swagger_doc_generated.go | 2 +- .../k8s.io/api/networking/v1/generated.proto | 176 +- vendor/k8s.io/api/networking/v1/types.go | 188 +- .../v1/types_swagger_doc_generated.go | 120 +- .../api/networking/v1alpha1/generated.pb.go | 1011 ++- .../api/networking/v1alpha1/generated.proto | 79 +- .../api/networking/v1alpha1/register.go | 12 +- .../k8s.io/api/networking/v1alpha1/types.go | 86 +- .../v1alpha1/types_swagger_doc_generated.go | 56 +- .../networking/v1alpha1/well_known_labels.go | 33 + .../v1alpha1/zz_generated.deepcopy.go | 97 + .../zz_generated.prerelease-lifecycle.go | 36 + .../api/networking/v1beta1/generated.proto | 78 +- vendor/k8s.io/api/networking/v1beta1/types.go | 87 +- .../v1beta1/types_swagger_doc_generated.go | 72 +- vendor/k8s.io/api/node/v1/generated.proto | 10 +- vendor/k8s.io/api/node/v1/types.go | 12 +- .../node/v1/types_swagger_doc_generated.go | 12 +- .../k8s.io/api/node/v1alpha1/generated.proto | 14 +- vendor/k8s.io/api/node/v1alpha1/types.go | 16 +- .../v1alpha1/types_swagger_doc_generated.go | 14 +- .../k8s.io/api/node/v1beta1/generated.proto | 12 +- vendor/k8s.io/api/node/v1beta1/types.go | 14 +- .../v1beta1/types_swagger_doc_generated.go | 12 +- vendor/k8s.io/api/policy/v1/generated.proto | 4 +- vendor/k8s.io/api/policy/v1/types.go | 4 +- .../policy/v1/types_swagger_doc_generated.go | 4 +- .../k8s.io/api/policy/v1beta1/generated.proto | 4 +- vendor/k8s.io/api/policy/v1beta1/types.go | 4 +- .../v1beta1/types_swagger_doc_generated.go | 4 +- .../rbac/v1/types_swagger_doc_generated.go | 2 +- .../v1alpha1/types_swagger_doc_generated.go | 2 +- .../v1beta1/types_swagger_doc_generated.go | 2 +- .../resource/{v1alpha1 => v1alpha2}/doc.go | 4 +- .../{v1alpha1 => v1alpha2}/generated.pb.go | 654 +- .../{v1alpha1 => v1alpha2}/generated.proto | 84 +- .../{v1alpha1 => v1alpha2}/register.go | 8 +- .../resource/{v1alpha1 => v1alpha2}/types.go | 92 +- .../types_swagger_doc_generated.go | 56 +- .../zz_generated.deepcopy.go | 61 +- .../k8s.io/api/scheduling/v1/generated.proto | 4 +- vendor/k8s.io/api/scheduling/v1/types.go | 4 +- .../v1/types_swagger_doc_generated.go | 6 +- .../api/scheduling/v1alpha1/generated.proto | 4 +- .../k8s.io/api/scheduling/v1alpha1/types.go | 4 +- .../v1alpha1/types_swagger_doc_generated.go | 6 +- .../api/scheduling/v1beta1/generated.proto | 4 +- vendor/k8s.io/api/scheduling/v1beta1/types.go | 4 +- .../v1beta1/types_swagger_doc_generated.go | 6 +- vendor/k8s.io/api/storage/v1/generated.proto | 126 +- vendor/k8s.io/api/storage/v1/types.go | 132 +- .../storage/v1/types_swagger_doc_generated.go | 82 +- .../api/storage/v1alpha1/generated.proto | 38 +- vendor/k8s.io/api/storage/v1alpha1/types.go | 41 +- .../v1alpha1/types_swagger_doc_generated.go | 38 +- .../api/storage/v1beta1/generated.proto | 112 +- vendor/k8s.io/api/storage/v1beta1/types.go | 119 +- .../v1beta1/types_swagger_doc_generated.go | 78 +- .../apis/apiextensions/types_jsonschema.go | 12 + .../pkg/apis/apiextensions/v1/generated.pb.go | 401 +- .../pkg/apis/apiextensions/v1/generated.proto | 19 +- .../pkg/apis/apiextensions/v1/types.go | 6 +- .../apis/apiextensions/v1/types_jsonschema.go | 14 +- .../v1/zz_generated.conversion.go | 2 + .../k8s.io/apimachinery/pkg/api/meta/help.go | 3 +- .../pkg/apis/meta/internalversion/defaults.go | 38 + .../pkg/apis/meta/internalversion/types.go | 25 + .../internalversion/validation/validation.go | 38 +- .../zz_generated.conversion.go | 2 + .../internalversion/zz_generated.deepcopy.go | 5 + .../pkg/apis/meta/v1/generated.pb.go | 385 +- .../pkg/apis/meta/v1/generated.proto | 69 +- .../apimachinery/pkg/apis/meta/v1/types.go | 69 +- .../meta/v1/types_swagger_doc_generated.go | 25 +- .../apis/meta/v1/zz_generated.conversion.go | 7 + .../pkg/apis/meta/v1/zz_generated.deepcopy.go | 5 + .../v1beta1/types_swagger_doc_generated.go | 2 +- .../k8s.io/apimachinery/pkg/labels/labels.go | 2 + .../apimachinery/pkg/labels/selector.go | 131 +- .../pkg/runtime/schema/group_version.go | 6 +- .../k8s.io/apimachinery/pkg/runtime/scheme.go | 3 +- .../pkg/runtime/serializer/codec_factory.go | 3 +- .../serializer/versioning/versioning.go | 2 +- .../k8s.io/apimachinery/pkg/runtime/types.go | 2 +- .../apimachinery/pkg/types/namespacedname.go | 11 + .../apimachinery/pkg/util/errors/errors.go | 2 +- .../apimachinery/pkg/util/framer/framer.go | 2 +- .../pkg/util/managedfields/endpoints.yaml | 7018 +++++++++++++++++ .../pkg/util/managedfields/fieldmanager.go | 57 + .../managedfields}/internal/atmostevery.go | 0 .../internal}/buildmanagerinfo.go | 5 +- .../managedfields/internal}/capmanagers.go | 5 +- .../util/managedfields}/internal/conflict.go | 0 .../managedfields/internal}/fieldmanager.go | 84 +- .../util/managedfields}/internal/fields.go | 0 .../managedfields/internal/lastapplied.go | 50 + .../internal}/lastappliedmanager.go | 5 +- .../internal}/lastappliedupdater.go | 27 +- .../managedfields}/internal/managedfields.go | 0 .../internal}/managedfieldsupdater.go | 5 +- .../util/managedfields/internal/manager.go | 52 + .../managedfields}/internal/pathelement.go | 0 .../managedfields/internal}/skipnonapplied.go | 2 +- .../util/managedfields/internal}/stripmeta.go | 2 +- .../internal}/structuredmerge.go | 7 +- .../managedfields/internal/typeconverter.go | 193 + .../internal}/versionconverter.go | 24 +- .../pkg/util/managedfields/node.yaml | 261 + .../pkg/util/managedfields/pod.yaml | 121 + .../pkg/util/managedfields}/scalehandler.go | 10 +- .../pkg/util/managedfields/typeconverter.go | 47 + .../apimachinery/pkg/util/mergepatch/util.go | 3 +- .../k8s.io/apimachinery/pkg/util/sets/set.go | 14 + .../pkg/util/strategicpatch/OWNERS | 1 + .../pkg/util/strategicpatch/patch.go | 2 +- .../pkg/util/validation/validation.go | 8 +- .../apimachinery/pkg/util/wait/backoff.go | 502 ++ .../apimachinery/pkg/util/wait/delay.go | 51 + .../apimachinery/pkg/util/wait/error.go | 96 + .../k8s.io/apimachinery/pkg/util/wait/loop.go | 86 + .../k8s.io/apimachinery/pkg/util/wait/poll.go | 315 + .../apimachinery/pkg/util/wait/timer.go | 121 + .../k8s.io/apimachinery/pkg/util/wait/wait.go | 650 +- .../util/waitgroup/ratelimited_waitgroup.go | 134 + .../apiserver/pkg/admission/cel/metrics.go | 12 + .../configuration/mutating_webhook_manager.go | 72 +- .../validating_webhook_manager.go | 73 +- .../webhook/generic => }/conversion.go | 34 +- .../pkg/admission/initializer/interfaces.go | 8 + .../pkg/admission/metrics/metrics.go | 33 +- .../apiserver/pkg/admission/plugin/cel/OWNERS | 10 + .../compiler.go => cel/compile.go} | 136 +- .../pkg/admission/plugin/cel/filter.go | 296 + .../pkg/admission/plugin/cel/interface.go | 87 + .../validatingadmissionpolicy/admission.go | 20 +- .../validatingadmissionpolicy/controller.go | 386 +- .../controller_reconcile.go | 407 +- .../validatingadmissionpolicy/initializer.go | 1 + .../validatingadmissionpolicy/interface.go | 69 +- .../internal/generic/controller.go | 41 +- .../validatingadmissionpolicy/matcher.go | 78 + .../validatingadmissionpolicy/message.go | 36 + .../policy_decision.go | 53 +- .../validatingadmissionpolicy/typechecking.go | 435 + .../validatingadmissionpolicy/validator.go | 454 +- .../pkg/admission/plugin/webhook/accessors.go | 69 +- .../plugin/webhook/generic/interfaces.go | 30 +- .../plugin/webhook/generic/webhook.go | 33 +- .../webhook/matchconditions/interface.go | 36 + .../plugin/webhook/matchconditions/matcher.go | 139 + .../plugin/webhook/mutating/dispatcher.go | 67 +- .../webhook/predicates/namespace/matcher.go | 2 +- .../plugin/webhook/request/admissionreview.go | 7 +- .../plugin/webhook/validating/dispatcher.go | 41 +- .../apiserver/pkg/apis/apiserver/types.go | 15 +- .../pkg/apis/apiserver/v1alpha1/types.go | 15 +- .../v1alpha1/zz_generated.conversion.go | 6 +- .../v1alpha1/zz_generated.deepcopy.go | 11 +- .../pkg/apis/apiserver/v1beta1/register.go | 7 + .../pkg/apis/apiserver/v1beta1/types.go | 11 + .../v1beta1/zz_generated.conversion.go | 30 + .../v1beta1/zz_generated.deepcopy.go | 26 + .../apis/apiserver/zz_generated.deepcopy.go | 11 +- .../k8s.io/apiserver/pkg/apis/cel/config.go | 45 + .../k8s.io/apiserver/pkg/apis/config/types.go | 54 +- .../apiserver/pkg/apis/config/v1/defaults.go | 9 +- .../apiserver/pkg/apis/config/v1/types.go | 54 +- .../pkg/apis/config/validation/validation.go | 199 +- .../k8s.io/apiserver/pkg/audit/evaluator.go | 16 +- .../apiserver/pkg/audit/policy/checker.go | 32 +- .../request/headerrequest/requestheader.go | 34 +- .../token/cache/cached_token_authenticator.go | 16 +- vendor/k8s.io/apiserver/pkg/cel/OWNERS | 11 + .../apiserver/pkg/cel/common/adaptor.go | 81 + .../apiserver/pkg/cel/common/maplist.go | 177 + .../apiserver/pkg/cel/common/schemas.go | 257 + .../k8s.io/apiserver/pkg/cel/common/values.go | 717 ++ vendor/k8s.io/apiserver/pkg/cel/composited.go | 119 + .../k8s.io/apiserver/pkg/cel/library/authz.go | 580 ++ .../k8s.io/apiserver/pkg/cel/library/cost.go | 17 +- .../apiserver/pkg/cel/library/libraries.go | 1 + .../k8s.io/apiserver/pkg/cel/library/urls.go | 4 +- vendor/k8s.io/apiserver/pkg/cel/limits.go | 4 +- .../apiserver/pkg/cel/openapi/adaptor.go | 147 + .../apiserver/pkg/cel/openapi/extensions.go | 62 + .../pkg/cel/openapi/resolver/definitions.go | 115 + .../pkg/cel/openapi/resolver/discovery.go | 104 + .../pkg/cel/openapi/resolver/refs.go | 100 + .../pkg/cel/openapi/resolver/resolver.go | 39 + vendor/k8s.io/apiserver/pkg/cel/types.go | 23 +- vendor/k8s.io/apiserver/pkg/endpoints/OWNERS | 2 + .../apiserver/pkg/endpoints/discovery/OWNERS | 5 + .../endpoints/discovery/aggregated/etag.go | 5 +- .../endpoints/discovery/aggregated/fake.go | 4 + .../endpoints/discovery/aggregated/handler.go | 229 +- .../discovery/aggregated/metrics.go} | 24 +- .../endpoints/discovery/storageversionhash.go | 3 - .../apiserver/pkg/endpoints/filters/audit.go | 10 +- .../pkg/endpoints/filters/authentication.go | 31 +- .../pkg/endpoints/filters/authorization.go | 2 +- .../pkg/endpoints/filters/impersonation.go | 4 +- .../pkg/endpoints/filters/storageversion.go | 4 +- .../apiserver/pkg/endpoints/groupversion.go | 8 +- .../pkg/endpoints/handlers/create.go | 9 +- .../pkg/endpoints/handlers/delete.go | 5 +- .../handlers/fieldmanager/admission.go | 3 +- .../handlers/fieldmanager/typeconverter.go | 130 - .../apiserver/pkg/endpoints/handlers/get.go | 5 +- .../apiserver/pkg/endpoints/handlers/patch.go | 7 +- .../apiserver/pkg/endpoints/handlers/rest.go | 13 +- .../apiserver/pkg/endpoints/handlers/watch.go | 21 +- .../apiserver/pkg/endpoints/installer.go | 42 +- .../pkg/endpoints/metrics/metrics.go | 59 +- .../pkg/endpoints/request/requestinfo.go | 2 +- .../request/server_shutdown_signal.go | 55 + .../pkg/endpoints/request/webhook_duration.go | 13 + .../apiserver/pkg/features/kube_features.go | 43 +- .../pkg/registry/generic/registry/store.go | 92 +- .../apiserver/pkg/registry/rest/rest.go | 13 + vendor/k8s.io/apiserver/pkg/server/config.go | 156 +- .../apiserver/pkg/server/filters/cors.go | 92 +- .../apiserver/pkg/server/filters/waitgroup.go | 36 +- .../pkg/server/filters/watch_termination.go | 62 + .../apiserver/pkg/server/filters/wrap.go | 2 +- .../apiserver/pkg/server/genericapiserver.go | 171 +- .../apiserver/pkg/server/lifecycle_signals.go | 8 + .../pkg/server/options/authentication.go | 20 + .../pkg/server/options/authorization.go | 5 +- .../server/options/encryptionconfig/config.go | 352 +- .../encryptionconfig/controller/controller.go | 47 +- .../apiserver/pkg/server/options/etcd.go | 27 +- .../apiserver/pkg/server/options/feature.go | 7 +- .../pkg/server/options/server_run_options.go | 123 +- .../apiserver/pkg/server/options/tracing.go | 6 +- .../pkg/server/routes/debugsocket.go | 82 + .../apiserver/pkg/server/routes/openapi.go | 19 +- .../pkg/storage/cacher/cache_watcher.go | 543 ++ .../apiserver/pkg/storage/cacher/cacher.go | 598 +- .../pkg/storage/cacher/metrics/metrics.go | 14 +- .../apiserver/pkg/storage/cacher/ready.go | 125 +- .../pkg/storage/cacher/watch_cache.go | 81 +- .../pkg/storage/etcd3/latency_tracker.go | 3 +- .../pkg/storage/etcd3/metrics/metrics.go | 29 + .../apiserver/pkg/storage/etcd3/store.go | 43 +- .../apiserver/pkg/storage/etcd3/watcher.go | 43 +- .../apiserver/pkg/storage/interfaces.go | 6 + .../pkg/storage/selection_predicate.go | 12 + .../pkg/storage/value/encrypt/aes/aes.go | 176 +- .../value/encrypt/envelope/envelope.go | 10 +- .../value/encrypt/envelope/grpc_service.go | 10 +- .../value/encrypt/envelope/kmsv2/cache.go | 108 + .../value/encrypt/envelope/kmsv2/envelope.go | 367 +- .../encrypt/envelope/kmsv2/grpc_service.go | 38 +- .../envelope/kmsv2/{v2alpha1 => v2}/OWNERS | 0 .../envelope/kmsv2/{v2alpha1 => v2}/api.pb.go | 37 +- .../envelope/kmsv2/{v2alpha1 => v2}/api.proto | 5 +- .../value/encrypt/envelope/kmsv2/v2/v2.go} | 4 +- .../value/encrypt/envelope/metrics/metrics.go | 206 +- .../apiserver/pkg/storage/value/metrics.go | 9 +- .../pkg/storage/value/transformer.go | 8 +- .../pkg/util/flowcontrol/apf_controller.go | 2 +- .../util/flowcontrol/apf_controller_debug.go | 56 +- .../pkg/util/flowcontrol/apf_filter.go | 17 +- .../pkg/util/flowcontrol/conc_alloc.go | 11 +- .../pkg/util/flowcontrol/debug/dump.go | 4 + .../fairqueuing/queueset/queueset.go | 40 + .../metrics/timing_ratio_histogram.go | 1 + .../request/list_work_estimator.go | 5 +- .../pkg/util/flowcontrol/watch_tracker.go | 5 +- .../apiserver/pkg/util/openapi/enablement.go | 83 - .../apiserver/pkg/util/openapi/proto.go | 46 - .../apiserver/pkg/util/webhook/webhook.go | 2 +- .../v1/matchcondition.go | 48 + .../v1/mutatingwebhook.go | 14 + .../v1/validatingwebhook.go | 14 + .../v1alpha1/admissionpolicyspec.go | 75 - .../v1alpha1/auditannotation.go | 48 + .../v1alpha1/expressionwarning.go | 48 + .../{paramsource.go => matchcondition.go} | 30 +- .../admissionregistration/v1alpha1/rule.go | 76 - .../v1alpha1/rulewithoperations.go | 85 - .../v1alpha1/typechecking.go | 44 + .../v1alpha1/validatingadmissionpolicy.go | 11 +- .../validatingadmissionpolicybindingspec.go | 21 +- .../v1alpha1/validatingadmissionpolicyspec.go | 28 + .../validatingadmissionpolicystatus.go | 66 + .../v1alpha1/validation.go | 15 +- .../v1beta1/matchcondition.go | 48 + .../v1beta1/mutatingwebhook.go | 14 + .../admissionregistration/v1beta1/rule.go | 76 - .../v1beta1/rulewithoperations.go | 85 - .../v1beta1/validatingwebhook.go | 14 + .../autoscaling/v2/podresourcemetricsource.go | 52 - .../v1alpha1/clustertrustbundle.go} | 95 +- .../v1alpha1/clustertrustbundlespec.go | 48 + .../applyconfigurations/core/v1/container.go | 58 +- .../core/v1/containerresizepolicy.go | 52 + .../core/v1/containerstatus.go | 40 +- .../core/v1/ephemeralcontainer.go | 13 + .../core/v1/ephemeralcontainercommon.go | 58 +- .../applyconfigurations/core/v1/podstatus.go | 9 + .../core/v1/servicespec.go | 8 +- .../extensions/v1beta1/allowedcsidriver.go | 39 - .../extensions/v1beta1/allowedflexvolume.go | 39 - .../extensions/v1beta1/allowedhostpath.go | 48 - .../v1beta1/fsgroupstrategyoptions.go | 57 - .../extensions/v1beta1/hostportrange.go | 48 - .../extensions/v1beta1/idrange.go | 48 - .../v1beta1/podsecuritypolicyspec.go | 285 - .../v1beta1/runasgroupstrategyoptions.go | 57 - .../v1beta1/runasuserstrategyoptions.go | 57 - .../v1beta1/runtimeclassstrategyoptions.go | 50 - .../v1beta1/selinuxstrategyoptions.go | 53 - .../supplementalgroupsstrategyoptions.go | 57 - .../applyconfigurations/internal/internal.go | 554 +- .../meta/v1/groupversionkind.go | 57 - .../applyconfigurations/meta/v1/listmeta.go | 66 - .../applyconfigurations/meta/v1/status.go | 142 - .../meta/v1/statuscause.go | 61 - .../meta/v1/statusdetails.go | 93 - .../v1alpha1/ipaddress.go} | 86 +- .../networking/v1alpha1/ipaddressspec.go | 39 + .../networking/v1alpha1/parentreference.go | 79 + .../allocationresult.go | 19 +- .../resource/v1alpha2/podschedulingcontext.go | 258 + .../podschedulingcontextspec.go} | 16 +- .../podschedulingcontextstatus.go} | 14 +- .../{v1alpha1 => v1alpha2}/resourceclaim.go | 16 +- .../resourceclaimconsumerreference.go | 2 +- .../resourceclaimparametersreference.go | 2 +- .../resourceclaimschedulingstatus.go | 2 +- .../resourceclaimspec.go | 8 +- .../resourceclaimstatus.go | 2 +- .../resourceclaimtemplate.go | 16 +- .../resourceclaimtemplatespec.go | 2 +- .../{v1alpha1 => v1alpha2}/resourceclass.go | 16 +- .../resourceclassparametersreference.go | 2 +- .../resource/v1alpha2/resourcehandle.go | 48 + .../discovery/aggregated_discovery.go | 102 +- .../discovery/cached/memory/memcache.go | 53 +- .../client-go/discovery/discovery_client.go | 172 +- .../dynamic/dynamicinformer/informer.go | 38 +- .../dynamic/dynamicinformer/interface.go | 19 + .../informers/certificates/interface.go | 8 + .../v1alpha1/clustertrustbundle.go} | 43 +- .../certificates/v1alpha1/interface.go | 45 + vendor/k8s.io/client-go/informers/doc.go | 18 + .../informers/extensions/v1beta1/interface.go | 7 - vendor/k8s.io/client-go/informers/generic.go | 29 +- .../networking/v1alpha1/interface.go | 7 + .../v1alpha1/ipaddress.go} | 44 +- .../client-go/informers/resource/interface.go | 12 +- .../{v1alpha1 => v1alpha2}/interface.go | 12 +- .../resource/v1alpha2/podschedulingcontext.go | 90 + .../{v1alpha1 => v1alpha2}/resourceclaim.go | 20 +- .../resourceclaimtemplate.go | 20 +- .../{v1alpha1 => v1alpha2}/resourceclass.go | 20 +- .../k8s.io/client-go/kubernetes/clientset.go | 29 +- vendor/k8s.io/client-go/kubernetes/doc.go | 7 +- .../client-go/kubernetes/scheme/register.go | 6 +- .../v1alpha1/validatingadmissionpolicy.go | 46 + .../v1beta1/authentication_client.go | 5 + .../v1beta1/generated_expansion.go | 2 + .../v1beta1/selfsubjectreview.go | 64 + .../v1alpha1/certificates_client.go | 107 + .../v1alpha1/clustertrustbundle.go | 197 + .../v1alpha1/doc.go | 0 .../v1alpha1/generated_expansion.go | 21 + .../typed/events/v1beta1/event_expansion.go | 3 +- .../extensions/v1beta1/extensions_client.go | 5 - .../extensions/v1beta1/generated_expansion.go | 2 - .../extensions/v1beta1/podsecuritypolicy.go | 197 - .../v1alpha1/generated_expansion.go | 2 + .../typed/networking/v1alpha1/ipaddress.go | 197 + .../networking/v1alpha1/networking_client.go | 5 + .../typed/resource/v1alpha1/podscheduling.go | 256 - .../kubernetes/typed/resource/v1alpha2/doc.go | 20 + .../generated_expansion.go | 4 +- .../resource/v1alpha2/podschedulingcontext.go | 256 + .../{v1alpha1 => v1alpha2}/resource_client.go | 46 +- .../{v1alpha1 => v1alpha2}/resourceclaim.go | 56 +- .../resourceclaimtemplate.go | 44 +- .../{v1alpha1 => v1alpha2}/resourceclass.go | 44 +- .../v1alpha1/clustertrustbundle.go | 68 + .../v1alpha1/expansion_generated.go | 23 + .../extensions/v1beta1/expansion_generated.go | 4 - .../extensions/v1beta1/podsecuritypolicy.go | 68 - .../v1alpha1/expansion_generated.go | 4 + .../listers/networking/v1alpha1/ipaddress.go | 68 + .../resource/v1alpha1/podscheduling.go | 99 - .../expansion_generated.go | 14 +- .../resource/v1alpha2/podschedulingcontext.go | 99 + .../{v1alpha1 => v1alpha2}/resourceclaim.go | 24 +- .../resourceclaimtemplate.go | 24 +- .../{v1alpha1 => v1alpha2}/resourceclass.go | 18 +- vendor/k8s.io/client-go/openapi/OWNERS | 4 + vendor/k8s.io/client-go/openapi/client.go | 7 +- .../k8s.io/client-go/openapi/groupversion.go | 42 +- vendor/k8s.io/client-go/pkg/version/base.go | 3 +- vendor/k8s.io/client-go/rest/client.go | 3 +- vendor/k8s.io/client-go/rest/request.go | 45 +- vendor/k8s.io/client-go/rest/with_retry.go | 18 +- .../client-go/tools/cache/controller.go | 92 +- .../client-go/tools/cache/delta_fifo.go | 142 +- vendor/k8s.io/client-go/tools/cache/fifo.go | 14 +- .../k8s.io/client-go/tools/cache/reflector.go | 483 +- .../client-go/tools/cache/shared_informer.go | 147 +- .../client-go/tools/cache/synctrack/lazy.go | 83 + .../tools/cache/synctrack/synctrack.go | 120 + .../tools/events/event_broadcaster.go | 34 +- .../client-go/tools/events/event_recorder.go | 2 +- .../tools/leaderelection/leaderelection.go | 15 +- .../leaderelection/resourcelock/interface.go | 2 +- .../leaderelection/resourcelock/leaselock.go | 8 +- .../k8s.io/client-go/tools/metrics/metrics.go | 17 + .../tools/portforward/portforward.go | 4 +- vendor/k8s.io/client-go/tools/record/event.go | 53 +- vendor/k8s.io/client-go/tools/record/fake.go | 25 +- vendor/k8s.io/client-go/tools/watch/until.go | 5 +- vendor/k8s.io/client-go/util/cert/cert.go | 2 +- .../util/workqueue/delaying_queue.go | 61 +- .../client-go/util/workqueue/metrics.go | 9 +- .../k8s.io/client-go/util/workqueue/queue.go | 57 +- .../util/workqueue/rate_limiting_queue.go | 61 +- .../cloud-provider/app/config/config.go | 4 + vendor/k8s.io/cloud-provider/cloud.go | 5 + vendor/k8s.io/cloud-provider/config/types.go | 17 + .../config/v1alpha1/defaults.go | 3 + .../cloud-provider/config/v1alpha1/types.go | 18 + .../v1alpha1/zz_generated.conversion.go | 45 + .../config/v1alpha1/zz_generated.deepcopy.go | 23 + .../config/zz_generated.deepcopy.go | 23 + .../controllers/node/config/types.go | 24 + .../node/config/v1alpha1/conversion.go | 39 + .../node/config/v1alpha1/defaults.go | 23 + .../controllers/node/config/v1alpha1/doc.go | 21 + .../node/config/v1alpha1/register.go | 31 + .../controllers/node/config/v1alpha1/types.go | 24 + .../v1alpha1/zz_generated.conversion.go | 58 + .../config/v1alpha1/zz_generated.deepcopy.go | 38 + .../cloud-provider/options/nodecontroller.go | 62 + .../k8s.io/cloud-provider/options/options.go | 77 +- .../k8s.io/cloud-provider/options/webhook.go | 206 + vendor/k8s.io/cloud-provider/plugins.go | 1 - vendor/k8s.io/component-base/config/types.go | 2 +- .../component-base/config/v1alpha1/types.go | 2 +- .../component-base/logs/api/v1/options.go | 82 +- .../component-base/logs/api/v1/registry.go | 23 +- .../setverbositylevel/setverbositylevel.go | 34 + vendor/k8s.io/component-base/logs/logs.go | 19 +- .../metrics/features/kube_features.go | 2 +- .../k8s.io/component-base/metrics/metric.go | 5 +- .../metrics/testutil/testutil.go | 7 + vendor/k8s.io/component-base/metrics/value.go | 3 +- .../controller-manager/options/debugging.go | 2 +- .../controller-manager/options/generic.go | 6 + .../pkg/features/kube_features.go | 37 +- .../pkg/leadermigration/config/default.go | 3 +- .../pkg/leadermigration/filter.go | 35 - .../pkg/leadermigration/migrator.go | 62 - .../pkg/leadermigration/options/options.go | 4 - .../pkg/leadermigration/util.go | 25 - vendor/k8s.io/kms/apis/v1beta1/api.pb.go | 38 +- vendor/k8s.io/kms/apis/v1beta1/api.proto | 3 +- .../kms/apis/{v2alpha1 => v2}/api.pb.go | 85 +- .../kms/apis/{v2alpha1 => v2}/api.proto | 5 +- .../v2alpha1.go => kms/apis/v2/v2.go} | 4 +- vendor/k8s.io/kms/pkg/service/grpc_service.go | 141 + vendor/k8s.io/kms/pkg/service/interface.go | 50 + .../encrypt/envelope => kms/pkg}/util/util.go | 2 +- .../pkg/validation/errors/.gitignore | 2 + .../pkg/validation/errors/LICENSE | 202 + .../kube-openapi/pkg/validation/errors/api.go | 46 + .../kube-openapi/pkg/validation/errors/doc.go | 26 + .../pkg/validation/errors/headers.go | 44 + .../pkg/validation/errors/schema.go | 573 ++ .../pkg/validation/strfmt/.gitignore | 2 + .../pkg/validation/strfmt/LICENSE | 202 + .../pkg/validation/strfmt/bson.go | 103 + .../pkg/validation/strfmt/bson/objectid.go | 122 + .../pkg/validation/strfmt/date.go | 103 + .../pkg/validation/strfmt/default.go | 1562 ++++ .../kube-openapi/pkg/validation/strfmt/doc.go | 18 + .../pkg/validation/strfmt/duration.go | 180 + .../pkg/validation/strfmt/format.go | 314 + .../pkg/validation/strfmt/time.go | 172 + .../kubectl/pkg/util/podutils/podutils.go | 52 + vendor/k8s.io/mount-utils/fake_mounter.go | 2 +- vendor/k8s.io/mount-utils/mount.go | 35 +- .../k8s.io/mount-utils/mount_helper_common.go | 8 +- vendor/k8s.io/mount-utils/mount_linux.go | 90 +- .../k8s.io/mount-utils/mount_unsupported.go | 4 +- vendor/k8s.io/mount-utils/mount_windows.go | 4 +- vendor/k8s.io/mount-utils/resizefs_linux.go | 33 +- .../policy/check_sysctls.go | 23 +- vendor/modules.txt | 152 +- 618 files changed, 42944 insertions(+), 16168 deletions(-) create mode 100644 vendor/github.com/asaskevich/govalidator/.travis.yml create mode 100644 vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md create mode 100644 vendor/github.com/asaskevich/govalidator/LICENSE create mode 100644 vendor/github.com/asaskevich/govalidator/README.md create mode 100644 vendor/github.com/asaskevich/govalidator/arrays.go create mode 100644 vendor/github.com/asaskevich/govalidator/converter.go create mode 100644 vendor/github.com/asaskevich/govalidator/error.go create mode 100644 vendor/github.com/asaskevich/govalidator/numerics.go create mode 100644 vendor/github.com/asaskevich/govalidator/patterns.go create mode 100644 vendor/github.com/asaskevich/govalidator/types.go create mode 100644 vendor/github.com/asaskevich/govalidator/utils.go create mode 100644 vendor/github.com/asaskevich/govalidator/validator.go create mode 100644 vendor/github.com/asaskevich/govalidator/wercker.yml create mode 100644 vendor/k8s.io/api/certificates/v1alpha1/doc.go create mode 100644 vendor/k8s.io/api/certificates/v1alpha1/generated.pb.go create mode 100644 vendor/k8s.io/api/certificates/v1alpha1/generated.proto create mode 100644 vendor/k8s.io/api/certificates/v1alpha1/register.go create mode 100644 vendor/k8s.io/api/certificates/v1alpha1/types.go create mode 100644 vendor/k8s.io/api/certificates/v1alpha1/types_swagger_doc_generated.go create mode 100644 vendor/k8s.io/api/certificates/v1alpha1/zz_generated.deepcopy.go create mode 100644 vendor/k8s.io/api/certificates/v1alpha1/zz_generated.prerelease-lifecycle.go create mode 100644 vendor/k8s.io/api/networking/v1alpha1/well_known_labels.go rename vendor/k8s.io/api/resource/{v1alpha1 => v1alpha2}/doc.go (84%) rename vendor/k8s.io/api/resource/{v1alpha1 => v1alpha2}/generated.pb.go (83%) rename vendor/k8s.io/api/resource/{v1alpha1 => v1alpha2}/generated.proto (79%) rename vendor/k8s.io/api/resource/{v1alpha1 => v1alpha2}/register.go (95%) rename vendor/k8s.io/api/resource/{v1alpha1 => v1alpha2}/types.go (81%) rename vendor/k8s.io/api/resource/{v1alpha1 => v1alpha2}/types_swagger_doc_generated.go (76%) rename vendor/k8s.io/api/resource/{v1alpha1 => v1alpha2}/zz_generated.deepcopy.go (88%) create mode 100644 vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields}/internal/atmostevery.go (100%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/buildmanagerinfo.go (94%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/capmanagers.go (96%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields}/internal/conflict.go (100%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/fieldmanager.go (62%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields}/internal/fields.go (100%) create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/lastappliedmanager.go (97%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/lastappliedupdater.go (78%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields}/internal/managedfields.go (100%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/managedfieldsupdater.go (95%) create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields}/internal/pathelement.go (100%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/skipnonapplied.go (99%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/stripmeta.go (99%) rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/structuredmerge.go (97%) create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields/internal}/versionconverter.go (87%) create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml rename vendor/k8s.io/{apiserver/pkg/endpoints/handlers/fieldmanager => apimachinery/pkg/util/managedfields}/scalehandler.go (94%) create mode 100644 vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/wait/delay.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/wait/error.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/wait/loop.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/wait/poll.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/wait/timer.go create mode 100644 vendor/k8s.io/apimachinery/pkg/util/waitgroup/ratelimited_waitgroup.go rename vendor/k8s.io/apiserver/pkg/admission/{plugin/webhook/generic => }/conversion.go (73%) create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/cel/OWNERS rename vendor/k8s.io/apiserver/pkg/admission/plugin/{validatingadmissionpolicy/compiler.go => cel/compile.go} (61%) create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matcher.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/message.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/typechecking.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/interface.go create mode 100644 vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/matcher.go create mode 100644 vendor/k8s.io/apiserver/pkg/apis/cel/config.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/OWNERS create mode 100644 vendor/k8s.io/apiserver/pkg/cel/common/adaptor.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/common/maplist.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/common/schemas.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/common/values.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/composited.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/library/authz.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/openapi/extensions.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/definitions.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/discovery.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go create mode 100644 vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/resolver.go create mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/OWNERS create mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/discovery/OWNERS rename vendor/k8s.io/{controller-manager/pkg/leadermigration/feature.go => apiserver/pkg/endpoints/discovery/aggregated/metrics.go} (54%) delete mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter.go create mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/request/server_shutdown_signal.go create mode 100644 vendor/k8s.io/apiserver/pkg/server/filters/watch_termination.go create mode 100644 vendor/k8s.io/apiserver/pkg/server/routes/debugsocket.go create mode 100644 vendor/k8s.io/apiserver/pkg/storage/cacher/cache_watcher.go create mode 100644 vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/cache.go rename vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/{v2alpha1 => v2}/OWNERS (100%) rename vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/{v2alpha1 => v2}/api.pb.go (68%) rename vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/{v2alpha1 => v2}/api.proto (86%) rename vendor/k8s.io/{kms/apis/v2alpha1/v2alpha1.go => apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/v2.go} (86%) delete mode 100644 vendor/k8s.io/apiserver/pkg/util/openapi/enablement.go delete mode 100644 vendor/k8s.io/apiserver/pkg/util/openapi/proto.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/admissionpolicyspec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go rename vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/{paramsource.go => matchcondition.go} (50%) delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rule.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rulewithoperations.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go rename vendor/k8s.io/client-go/applyconfigurations/{resource/v1alpha1/podscheduling.go => certificates/v1alpha1/clustertrustbundle.go} (64%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/meta/v1/groupversionkind.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/meta/v1/listmeta.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/meta/v1/status.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/meta/v1/statuscause.go delete mode 100644 vendor/k8s.io/client-go/applyconfigurations/meta/v1/statusdetails.go rename vendor/k8s.io/client-go/applyconfigurations/{extensions/v1beta1/podsecuritypolicy.go => networking/v1alpha1/ipaddress.go} (66%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go create mode 100644 vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/allocationresult.go (76%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1/podschedulingspec.go => v1alpha2/podschedulingcontextspec.go} (67%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1/podschedulingstatus.go => v1alpha2/podschedulingcontextstatus.go} (64%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclaim.go (96%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclaimconsumerreference.go (99%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclaimparametersreference.go (99%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclaimschedulingstatus.go (99%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclaimspec.go (93%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclaimstatus.go (99%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclaimtemplate.go (96%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclaimtemplatespec.go (99%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclass.go (96%) rename vendor/k8s.io/client-go/applyconfigurations/resource/{v1alpha1 => v1alpha2}/resourceclassparametersreference.go (99%) create mode 100644 vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go rename vendor/k8s.io/client-go/informers/{resource/v1alpha1/podscheduling.go => certificates/v1alpha1/clustertrustbundle.go} (52%) create mode 100644 vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go create mode 100644 vendor/k8s.io/client-go/informers/doc.go rename vendor/k8s.io/client-go/informers/{extensions/v1beta1/podsecuritypolicy.go => networking/v1alpha1/ipaddress.go} (50%) rename vendor/k8s.io/client-go/informers/resource/{v1alpha1 => v1alpha2}/interface.go (84%) create mode 100644 vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go rename vendor/k8s.io/client-go/informers/resource/{v1alpha1 => v1alpha2}/resourceclaim.go (85%) rename vendor/k8s.io/client-go/informers/resource/{v1alpha1 => v1alpha2}/resourceclaimtemplate.go (86%) rename vendor/k8s.io/client-go/informers/resource/{v1alpha1 => v1alpha2}/resourceclass.go (85%) create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go rename vendor/k8s.io/client-go/kubernetes/typed/{resource => certificates}/v1alpha1/doc.go (100%) create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go delete mode 100644 vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/podscheduling.go create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go rename vendor/k8s.io/client-go/kubernetes/typed/resource/{v1alpha1 => v1alpha2}/generated_expansion.go (92%) create mode 100644 vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go rename vendor/k8s.io/client-go/kubernetes/typed/resource/{v1alpha1 => v1alpha2}/resource_client.go (66%) rename vendor/k8s.io/client-go/kubernetes/typed/resource/{v1alpha1 => v1alpha2}/resourceclaim.go (79%) rename vendor/k8s.io/client-go/kubernetes/typed/resource/{v1alpha1 => v1alpha2}/resourceclaimtemplate.go (80%) rename vendor/k8s.io/client-go/kubernetes/typed/resource/{v1alpha1 => v1alpha2}/resourceclass.go (80%) create mode 100644 vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go create mode 100644 vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go delete mode 100644 vendor/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go create mode 100644 vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go delete mode 100644 vendor/k8s.io/client-go/listers/resource/v1alpha1/podscheduling.go rename vendor/k8s.io/client-go/listers/resource/{v1alpha1 => v1alpha2}/expansion_generated.go (79%) create mode 100644 vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go rename vendor/k8s.io/client-go/listers/resource/{v1alpha1 => v1alpha2}/resourceclaim.go (84%) rename vendor/k8s.io/client-go/listers/resource/{v1alpha1 => v1alpha2}/resourceclaimtemplate.go (84%) rename vendor/k8s.io/client-go/listers/resource/{v1alpha1 => v1alpha2}/resourceclass.go (81%) create mode 100644 vendor/k8s.io/client-go/openapi/OWNERS create mode 100644 vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go create mode 100644 vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go create mode 100644 vendor/k8s.io/cloud-provider/controllers/node/config/types.go create mode 100644 vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/conversion.go create mode 100644 vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/defaults.go create mode 100644 vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/doc.go create mode 100644 vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/register.go create mode 100644 vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go create mode 100644 vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go create mode 100644 vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.deepcopy.go create mode 100644 vendor/k8s.io/cloud-provider/options/nodecontroller.go create mode 100644 vendor/k8s.io/cloud-provider/options/webhook.go create mode 100644 vendor/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go delete mode 100644 vendor/k8s.io/controller-manager/pkg/leadermigration/filter.go delete mode 100644 vendor/k8s.io/controller-manager/pkg/leadermigration/migrator.go delete mode 100644 vendor/k8s.io/controller-manager/pkg/leadermigration/util.go rename vendor/k8s.io/kms/apis/{v2alpha1 => v2}/api.pb.go (83%) rename vendor/k8s.io/kms/apis/{v2alpha1 => v2}/api.proto (95%) rename vendor/k8s.io/{apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/v2alpha1.go => kms/apis/v2/v2.go} (86%) create mode 100644 vendor/k8s.io/kms/pkg/service/grpc_service.go create mode 100644 vendor/k8s.io/kms/pkg/service/interface.go rename vendor/k8s.io/{apiserver/pkg/storage/value/encrypt/envelope => kms/pkg}/util/util.go (95%) create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/errors/.gitignore create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/errors/LICENSE create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/errors/api.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/errors/headers.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/errors/schema.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/.gitignore create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/LICENSE create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson/objectid.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/date.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/doc.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/duration.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/format.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/time.go diff --git a/go.mod b/go.mod index 400f6b33a..b424ccb7d 100644 --- a/go.mod +++ b/go.mod @@ -35,13 +35,13 @@ require ( // // when updating k8s.io/kubernetes, make sure to update the replace section too // - k8s.io/api v0.26.3 - k8s.io/apimachinery v0.26.3 + k8s.io/api v0.27.2 + k8s.io/apimachinery v0.27.2 k8s.io/client-go v12.0.0+incompatible - k8s.io/cloud-provider v0.26.2 + k8s.io/cloud-provider v0.27.2 k8s.io/klog/v2 v2.100.1 k8s.io/kubernetes v1.27.2 - k8s.io/mount-utils v0.26.2 + k8s.io/mount-utils v0.27.2 k8s.io/pod-security-admission v0.0.0 k8s.io/utils v0.0.0-20230209194617-a36077c30491 sigs.k8s.io/controller-runtime v0.14.6 @@ -53,6 +53,7 @@ require ( github.com/ansel1/merry/v2 v2.0.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect github.com/armon/go-metrics v0.3.10 // indirect + github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/aws/aws-sdk-go-v2 v1.18.0 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 // indirect @@ -130,7 +131,6 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/spf13/cobra v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -164,12 +164,12 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.26.2 // indirect - k8s.io/apiserver v0.26.2 // indirect - k8s.io/component-base v0.26.2 // indirect - k8s.io/component-helpers v0.26.2 // indirect - k8s.io/controller-manager v0.26.2 // indirect - k8s.io/kms v0.26.2 // indirect + k8s.io/apiextensions-apiserver v0.27.2 // indirect + k8s.io/apiserver v0.27.2 // indirect + k8s.io/component-base v0.27.2 // indirect + k8s.io/component-helpers v0.27.2 // indirect + k8s.io/controller-manager v0.27.2 // indirect + k8s.io/kms v0.27.2 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect k8s.io/kubectl v0.0.0 // indirect k8s.io/kubelet v0.0.0 // indirect @@ -190,32 +190,32 @@ replace ( // // k8s.io/kubernetes depends on these k8s.io packages, but unversioned // - k8s.io/api => k8s.io/api v0.26.3 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.2 - k8s.io/apimachinery => k8s.io/apimachinery v0.26.3 - k8s.io/apiserver => k8s.io/apiserver v0.26.2 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.26.2 - k8s.io/client-go => k8s.io/client-go v0.26.2 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.26.2 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.26.2 - k8s.io/code-generator => k8s.io/code-generator v0.26.2 - k8s.io/component-base => k8s.io/component-base v0.26.2 - k8s.io/component-helpers => k8s.io/component-helpers v0.26.2 - k8s.io/controller-manager => k8s.io/controller-manager v0.26.2 - k8s.io/cri-api => k8s.io/cri-api v0.26.2 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.26.2 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.26.2 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.26.2 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.26.2 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.26.2 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.26.2 - k8s.io/kubectl => k8s.io/kubectl v0.26.2 - k8s.io/kubelet => k8s.io/kubelet v0.26.2 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.26.2 - k8s.io/metrics => k8s.io/metrics v0.26.2 - k8s.io/mount-utils => k8s.io/mount-utils v0.26.2 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.26.2 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.26.2 + k8s.io/api => k8s.io/api v0.27.2 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.27.2 + k8s.io/apimachinery => k8s.io/apimachinery v0.27.2 + k8s.io/apiserver => k8s.io/apiserver v0.27.2 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.27.2 + k8s.io/client-go => k8s.io/client-go v0.27.2 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.27.2 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.27.2 + k8s.io/code-generator => k8s.io/code-generator v0.27.2 + k8s.io/component-base => k8s.io/component-base v0.27.2 + k8s.io/component-helpers => k8s.io/component-helpers v0.27.2 + k8s.io/controller-manager => k8s.io/controller-manager v0.27.2 + k8s.io/cri-api => k8s.io/cri-api v0.27.2 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.27.2 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.27.2 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.27.2 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.27.2 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.27.2 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.27.2 + k8s.io/kubectl => k8s.io/kubectl v0.27.2 + k8s.io/kubelet => k8s.io/kubelet v0.27.2 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.27.2 + k8s.io/metrics => k8s.io/metrics v0.27.2 + k8s.io/mount-utils => k8s.io/mount-utils v0.27.2 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.27.2 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.27.2 // layeh.com seems to be misbehaving layeh.com/radius => github.com/layeh/radius v0.0.0-20190322222518-890bc1058917 ) diff --git a/go.sum b/go.sum index 732da7266..0e4e29b50 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,6 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/SAP/go-hdb v0.14.1/go.mod h1:7fdQLVC2lER3urZLjZCm0AuMQfApof92n3aylBPEkMo= github.com/Sectorbob/mlab-ns2 v0.0.0-20171030222938-d3aa0c295a8a/go.mod h1:D73UAuEPckrDorYZdtlCu2ySOLuPB5W4rhIkmmc/XbI= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -257,6 +255,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/csi-addons/replication-lib-utils v0.2.0 h1:tGs42wfjkObbBo/98a3uxTFWEJ1dq5PIMqPWtdLd040= github.com/csi-addons/replication-lib-utils v0.2.0/go.mod h1:ROQlEsc2EerVtc/K/C+6Hx8pqaQ9MVy9xFFpyKfI9lc= github.com/csi-addons/spec v0.1.0/go.mod h1:Mwq4iLiUV4s+K1bszcWU6aMsR5KPsbIYzzszJ6+56vI= @@ -291,8 +290,6 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8= github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -322,7 +319,6 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.4.0/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= @@ -375,16 +371,10 @@ github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -407,6 +397,7 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= @@ -788,6 +779,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -809,9 +801,6 @@ github.com/libopenstorage/stork v1.3.0-beta1.0.20200630005842-9255e7a98775/go.mo github.com/linode/linodego v0.7.1 h1:4WZmMpSA2NRwlPZcc0+4Gyn7rr99Evk9bnr0B3gXRKE= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= @@ -873,7 +862,7 @@ github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -913,7 +902,7 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= -github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU= github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1034,8 +1023,9 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -1060,6 +1050,7 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= @@ -1113,6 +1104,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= @@ -1142,23 +1134,20 @@ go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.5.0-alpha.5.0.20191023171146-3cf2f69b5738 h1:lWF4f9Nypl1ZqSb4gLeh/DGvBYVaUYHuiB93teOmwgc= go.etcd.io/etcd v0.5.0-alpha.5.0.20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY= go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA= -go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg= go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY= -go.etcd.io/etcd/client/v2 v2.305.5/go.mod h1:zQjKllfqfBVyVStbt4FaosoX2iYd8fV/GRy/PbowgP4= go.etcd.io/etcd/client/v2 v2.305.7 h1:AELPkjNR3/igjbO7CjyF1fPuVPjrblliiKj+Y6xSGOU= -go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c= +go.etcd.io/etcd/client/v2 v2.305.7/go.mod h1:GQGT5Z3TBuAQGvgPfhR7VPySu/SudxmEkRq9BgzFU6s= go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4= go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw= -go.etcd.io/etcd/pkg/v3 v3.5.5/go.mod h1:6ksYFxttiUGzC2uxyqiyOEvhAiD0tuIqSZkX3TyPdaE= go.etcd.io/etcd/pkg/v3 v3.5.7 h1:obOzeVwerFwZ9trMWapU/VjDcYUJb5OfgC1zqEGWO/0= -go.etcd.io/etcd/raft/v3 v3.5.5/go.mod h1:76TA48q03g1y1VpTue92jZLr9lIHKUNcYdZOOGyx8rI= +go.etcd.io/etcd/pkg/v3 v3.5.7/go.mod h1:kcOfWt3Ov9zgYdOiJ/o1Y9zFfLhQjylTgL4Lru8opRo= go.etcd.io/etcd/raft/v3 v3.5.7 h1:aN79qxLmV3SvIq84aNTliYGmjwsW6NqJSnqmI1HLJKc= -go.etcd.io/etcd/server/v3 v3.5.5/go.mod h1:rZ95vDw/jrvsbj9XpTqPrTAB9/kzchVdhRirySPkUBc= +go.etcd.io/etcd/raft/v3 v3.5.7/go.mod h1:TflkAb/8Uy6JFBxcRaH2Fr6Slm9mCPVdI2efzxY96yU= go.etcd.io/etcd/server/v3 v3.5.7 h1:BTBD8IJUV7YFgsczZMHhMTS67XuA4KpRquL0MFOJGRk= +go.etcd.io/etcd/server/v3 v3.5.7/go.mod h1:gxBgT84issUVBRpZ3XkW1T55NjOb4vZZRI4wVvNhf4A= go.mongodb.org/mongo-driver v1.2.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A= go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M= @@ -1174,7 +1163,6 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 h1:xFSRQBbXF6VvYRf2lqMJXxoB72XI1K/azav8TekHHSw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.1 h1:sxoY9kG1s1WpSYNyzm24rlwH4lnRYFXUVVBmKMBfRgw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.1/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU= @@ -1210,7 +1198,9 @@ go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= @@ -1285,6 +1275,9 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1306,7 +1299,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1337,11 +1329,16 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1461,22 +1458,26 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1490,7 +1491,9 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1519,7 +1522,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190718200317-82a3ea8a504c/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1567,15 +1569,18 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU= google.golang.org/api v0.3.0/go.mod h1:IuvZyQh8jgscv8qWfQ4ABd8m7hEudgBFM/EdhA3BnXw= @@ -1727,6 +1732,7 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5 google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -1774,7 +1780,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1798,8 +1803,6 @@ gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1810,26 +1813,26 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.3.0/go.mod h1:vlRD9XErLMGT+mDuofSr0mMMquscM/1nQqtRSsh6m70= -k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU= -k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE= -k8s.io/apiextensions-apiserver v0.26.2 h1:/yTG2B9jGY2Q70iGskMf41qTLhL9XeNN2KhI0uDgwko= -k8s.io/apiextensions-apiserver v0.26.2/go.mod h1:Y7UPgch8nph8mGCuVk0SK83LnS8Esf3n6fUBgew8SH8= -k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k= -k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= -k8s.io/apiserver v0.26.2 h1:Pk8lmX4G14hYqJd1poHGC08G03nIHVqdJMR0SD3IH3o= -k8s.io/apiserver v0.26.2/go.mod h1:GHcozwXgXsPuOJ28EnQ/jXEM9QeG6HT22YxSNmpYNh8= -k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= -k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= -k8s.io/cloud-provider v0.26.2 h1:VlLGDayUV5VBpvMSBFqmpz2HHTjBLUw02wuZzNeEsW0= -k8s.io/cloud-provider v0.26.2/go.mod h1:/Am9R0merLIZgVqPTE4Z1JkBcCrp2uXImHCxnvVARxc= -k8s.io/code-generator v0.26.2/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI= -k8s.io/component-base v0.26.2 h1:IfWgCGUDzrD6wLLgXEstJKYZKAFS2kO+rBRi0p3LqcI= -k8s.io/component-base v0.26.2/go.mod h1:DxbuIe9M3IZPRxPIzhch2m1eT7uFrSBJUBuVCQEBivs= -k8s.io/component-helpers v0.26.2 h1:+JJ1gwyVsqSwZCJVLJotx/IPq2pMpo0kifeAzfo6i3U= -k8s.io/component-helpers v0.26.2/go.mod h1:PRvoduZ5/IeKGGbZRki3J2cTQVwZLD+EUxIEbvvX0W4= -k8s.io/controller-manager v0.26.2 h1:Y4g50VqaXkr02v5FNTWDQ47ZPFNM1ls00F0+FoKKaTM= -k8s.io/controller-manager v0.26.2/go.mod h1:h8yv0MO3jjo9px49uResC9laZekvOmQRmrRLwe9n6Zw= -k8s.io/csi-translation-lib v0.26.2 h1:WWnJjYKBlnoMzwc77ioT9bppJPFYNAZ0uhzert/3QJ4= +k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo= +k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4= +k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo= +k8s.io/apiextensions-apiserver v0.27.2/go.mod h1:Oz9UdvGguL3ULgRdY9QMUzL2RZImotgxvGjdWRq6ZXQ= +k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= +k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/apiserver v0.27.2 h1:p+tjwrcQEZDrEorCZV2/qE8osGTINPuS5ZNqWAvKm5E= +k8s.io/apiserver v0.27.2/go.mod h1:EsOf39d75rMivgvvwjJ3OW/u9n1/BmUMK5otEOJrb1Y= +k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE= +k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ= +k8s.io/cloud-provider v0.27.2 h1:IiQWyFtdzcPOqvrBZE9FCt0CDCx3GUcZhKkykEgKlM4= +k8s.io/cloud-provider v0.27.2/go.mod h1:QnFa2fPMEWntkpU+kOAC9MZ6DKUB9WTQmMGA0MuYoj0= +k8s.io/code-generator v0.27.2/go.mod h1:DPung1sI5vBgn4AGKtlPRQAyagj/ir/4jI55ipZHVww= +k8s.io/component-base v0.27.2 h1:neju+7s/r5O4x4/txeUONNTS9r1HsPbyoPBAtHsDCpo= +k8s.io/component-base v0.27.2/go.mod h1:5UPk7EjfgrfgRIuDBFtsEFAe4DAvP3U+M8RTzoSJkpo= +k8s.io/component-helpers v0.27.2 h1:i9TgWJ6TH8lQ9x4ExHOwhVitrRpBOr7Wn8aZLbBWxkc= +k8s.io/component-helpers v0.27.2/go.mod h1:NwcpSKo1xzXtUtrUjj5NTSVWex84UPua/z0PYDcCzNo= +k8s.io/controller-manager v0.27.2 h1:S7984FVb5ajp8YqMQGAm8zXEUEl0Omw6FJlOiQU2Ne8= +k8s.io/controller-manager v0.27.2/go.mod h1:2HzIhmjKxSH5dJVjYLuJ7/v9HYluNDcHLh6ZyE6rT18= +k8s.io/csi-translation-lib v0.27.2 h1:HbwiOk+M3jIkTC+e5nxUCwmux68OguKV/g9NaHDQhzs= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -1837,39 +1840,36 @@ k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kms v0.26.2 h1:GM1gg3tFK3OUU/QQFi93yGjG3lJT8s8l3Wkn2+VxBLM= -k8s.io/kms v0.26.2/go.mod h1:69qGnf1NsFOQP07fBYqNLZklqEHSJF024JqYCaeVxHg= +k8s.io/kms v0.27.2 h1:wCdmPCa3kubcVd3AssOeaVjLQSu45k5g/vruJ3iqwDU= +k8s.io/kms v0.27.2/go.mod h1:dahSqjI05J55Fo5qipzvHSRbm20d7llrSeQjjl86A7c= k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/kubectl v0.26.2 h1:SMPB4j48eVFxsYluBq3VLyqXtE6b72YnszkbTAtFye4= -k8s.io/kubectl v0.26.2/go.mod h1:KYWOXSwp2BrDn3kPeoU/uKzKtdqvhK1dgZGd0+no4cM= -k8s.io/kubelet v0.26.2 h1:egg7YfhCpH9wvLwQdL2Mzuy4/kC6hO91azY0jgdYPWA= -k8s.io/kubelet v0.26.2/go.mod h1:IXthU5hcJQE6+K33LuaYYO0wUcYO8glhl/ip1Hzux44= +k8s.io/kubectl v0.27.2 h1:sSBM2j94MHBFRWfHIWtEXWCicViQzZsb177rNsKBhZg= +k8s.io/kubectl v0.27.2/go.mod h1:GCOODtxPcrjh+EC611MqREkU8RjYBh10ldQCQ6zpFKw= +k8s.io/kubelet v0.27.2 h1:vpJnBkqQjxItEhehKG0toXoZ+G+tf4UXAOqtMJy6qgc= +k8s.io/kubelet v0.27.2/go.mod h1:1SVrHaLnuw53nQJx8036k9HjE0teDXZtbN51cYC0HSc= k8s.io/kubernetes v1.27.2 h1:g4v9oY6u7vBUDEuq4FvC50Bbw2K7GZuvM00IIESWVf4= k8s.io/kubernetes v1.27.2/go.mod h1:U8ZXeKBAPxeb4J4/HOaxjw1A9K6WfSH+fY2SS7CR6IM= -k8s.io/mount-utils v0.26.2 h1:KoRKqCAAK2l37l71YMvKx6vaLToh52RkNx1RU/dSLGQ= -k8s.io/mount-utils v0.26.2/go.mod h1:95yx9K6N37y8YZ0/lUh9U6ITosMODNaW0/v4wvaa0Xw= -k8s.io/pod-security-admission v0.26.2 h1:R41JH34lRsqThGUCi1XdDFhG+UoRK4ZFzQ89FxgWDP8= -k8s.io/pod-security-admission v0.26.2/go.mod h1:tb7Huh4QpEZZets79N8QQOtbvRBARSU0b8YqGTpTA7I= +k8s.io/mount-utils v0.27.2 h1:fEqtBdAv88xpoPr3nR0MgYs6P+2PjXyUTwd4NmqSBjY= +k8s.io/mount-utils v0.27.2/go.mod h1:vmcjYdi2Vg1VTWY7KkhvwJVY6WDHxb/QQhiQKkR8iNs= +k8s.io/pod-security-admission v0.27.2 h1:dSGK0ftJwJNHSp5fMAwVuFIMMY1MlzW4k82mjar6G8I= +k8s.io/pod-security-admission v0.27.2/go.mod h1:jWVYAoR3AwJxwJ6tTQSVBZBBe4u0tvmFhyhpAWcOlYY= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 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.35/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 h1:trsWhjU5jZrx6UvFu4WzQDrN7Pga4a7Qg+zcfcj64PA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2/go.mod h1:+qG7ISXqCDVVcyO8hLn12AKVYYUjM7ftlqsqmrhMZE0= sigs.k8s.io/controller-runtime v0.2.2/go.mod h1:9dyohw3ZtoXQuV1e766PHUn+cmrRCIcBh6XIMFNMZ+I= sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= diff --git a/vendor/github.com/asaskevich/govalidator/.travis.yml b/vendor/github.com/asaskevich/govalidator/.travis.yml new file mode 100644 index 000000000..e29f8eef5 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/.travis.yml @@ -0,0 +1,14 @@ +language: go + +go: + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - 1.5 + - 1.6 + - tip + +notifications: + email: + - bwatas@gmail.com diff --git a/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md b/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md new file mode 100644 index 000000000..f0f7e3a8a --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/CONTRIBUTING.md @@ -0,0 +1,63 @@ +#### Support +If you do have a contribution to the package, feel free to create a Pull Request or an Issue. + +#### What to contribute +If you don't know what to do, there are some features and functions that need to be done + +- [ ] Refactor code +- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check +- [ ] Create actual list of contributors and projects that currently using this package +- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues) +- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions) +- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new +- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc +- [ ] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224) +- [ ] Implement fuzzing testing +- [ ] Implement some struct/map/array utilities +- [ ] Implement map/array validation +- [ ] Implement benchmarking +- [ ] Implement batch of examples +- [ ] Look at forks for new features and fixes + +#### Advice +Feel free to create what you want, but keep in mind when you implement new features: +- Code must be clear and readable, names of variables/constants clearly describes what they are doing +- Public functions must be documented and described in source file and added to README.md to the list of available functions +- There are must be unit-tests for any new functions and improvements + +## Financial contributions + +We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/govalidator). +Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed. + + +## Credits + + +### Contributors + +Thank you to all the people who have already contributed to govalidator! + + + +### Backers + +Thank you to all our backers! [[Become a backer](https://opencollective.com/govalidator#backer)] + + + + +### Sponsors + +Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/govalidator#sponsor)) + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/github.com/asaskevich/govalidator/LICENSE b/vendor/github.com/asaskevich/govalidator/LICENSE new file mode 100644 index 000000000..2f9a31fad --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Alex Saskevich + +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. \ No newline at end of file diff --git a/vendor/github.com/asaskevich/govalidator/README.md b/vendor/github.com/asaskevich/govalidator/README.md new file mode 100644 index 000000000..40f9a8781 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/README.md @@ -0,0 +1,507 @@ +govalidator +=========== +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/asaskevich/govalidator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![GoDoc](https://godoc.org/github.com/asaskevich/govalidator?status.png)](https://godoc.org/github.com/asaskevich/govalidator) [![Coverage Status](https://img.shields.io/coveralls/asaskevich/govalidator.svg)](https://coveralls.io/r/asaskevich/govalidator?branch=master) [![wercker status](https://app.wercker.com/status/1ec990b09ea86c910d5f08b0e02c6043/s "wercker status")](https://app.wercker.com/project/bykey/1ec990b09ea86c910d5f08b0e02c6043) +[![Build Status](https://travis-ci.org/asaskevich/govalidator.svg?branch=master)](https://travis-ci.org/asaskevich/govalidator) [![Go Report Card](https://goreportcard.com/badge/github.com/asaskevich/govalidator)](https://goreportcard.com/report/github.com/asaskevich/govalidator) [![GoSearch](http://go-search.org/badge?id=github.com%2Fasaskevich%2Fgovalidator)](http://go-search.org/view?id=github.com%2Fasaskevich%2Fgovalidator) [![Backers on Open Collective](https://opencollective.com/govalidator/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/govalidator/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_shield) + +A package of validators and sanitizers for strings, structs and collections. Based on [validator.js](https://github.com/chriso/validator.js). + +#### Installation +Make sure that Go is installed on your computer. +Type the following command in your terminal: + + go get github.com/asaskevich/govalidator + +or you can get specified release of the package with `gopkg.in`: + + go get gopkg.in/asaskevich/govalidator.v4 + +After it the package is ready to use. + + +#### Import package in your project +Add following line in your `*.go` file: +```go +import "github.com/asaskevich/govalidator" +``` +If you are unhappy to use long `govalidator`, you can do something like this: +```go +import ( + valid "github.com/asaskevich/govalidator" +) +``` + +#### Activate behavior to require all fields have a validation tag by default +`SetFieldsRequiredByDefault` causes validation to fail when struct fields do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). A good place to activate this is a package init function or the main() function. + +`SetNilPtrAllowedByRequired` causes validation to pass when struct fields marked by `required` are set to nil. This is disabled by default for consistency, but some packages that need to be able to determine between `nil` and `zero value` state can use this. If disabled, both `nil` and `zero` values cause validation errors. + +```go +import "github.com/asaskevich/govalidator" + +func init() { + govalidator.SetFieldsRequiredByDefault(true) +} +``` + +Here's some code to explain it: +```go +// this struct definition will fail govalidator.ValidateStruct() (and the field values do not matter): +type exampleStruct struct { + Name string `` + Email string `valid:"email"` +} + +// this, however, will only fail when Email is empty or an invalid email address: +type exampleStruct2 struct { + Name string `valid:"-"` + Email string `valid:"email"` +} + +// lastly, this will only fail when Email is an invalid email address but not when it's empty: +type exampleStruct2 struct { + Name string `valid:"-"` + Email string `valid:"email,optional"` +} +``` + +#### Recent breaking changes (see [#123](https://github.com/asaskevich/govalidator/pull/123)) +##### Custom validator function signature +A context was added as the second parameter, for structs this is the object being validated – this makes dependent validation possible. +```go +import "github.com/asaskevich/govalidator" + +// old signature +func(i interface{}) bool + +// new signature +func(i interface{}, o interface{}) bool +``` + +##### Adding a custom validator +This was changed to prevent data races when accessing custom validators. +```go +import "github.com/asaskevich/govalidator" + +// before +govalidator.CustomTypeTagMap["customByteArrayValidator"] = CustomTypeValidator(func(i interface{}, o interface{}) bool { + // ... +}) + +// after +govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool { + // ... +})) +``` + +#### List of functions: +```go +func Abs(value float64) float64 +func BlackList(str, chars string) string +func ByteLength(str string, params ...string) bool +func CamelCaseToUnderscore(str string) string +func Contains(str, substring string) bool +func Count(array []interface{}, iterator ConditionIterator) int +func Each(array []interface{}, iterator Iterator) +func ErrorByField(e error, field string) string +func ErrorsByField(e error) map[string]string +func Filter(array []interface{}, iterator ConditionIterator) []interface{} +func Find(array []interface{}, iterator ConditionIterator) interface{} +func GetLine(s string, index int) (string, error) +func GetLines(s string) []string +func InRange(value, left, right float64) bool +func IsASCII(str string) bool +func IsAlpha(str string) bool +func IsAlphanumeric(str string) bool +func IsBase64(str string) bool +func IsByteLength(str string, min, max int) bool +func IsCIDR(str string) bool +func IsCreditCard(str string) bool +func IsDNSName(str string) bool +func IsDataURI(str string) bool +func IsDialString(str string) bool +func IsDivisibleBy(str, num string) bool +func IsEmail(str string) bool +func IsFilePath(str string) (bool, int) +func IsFloat(str string) bool +func IsFullWidth(str string) bool +func IsHalfWidth(str string) bool +func IsHexadecimal(str string) bool +func IsHexcolor(str string) bool +func IsHost(str string) bool +func IsIP(str string) bool +func IsIPv4(str string) bool +func IsIPv6(str string) bool +func IsISBN(str string, version int) bool +func IsISBN10(str string) bool +func IsISBN13(str string) bool +func IsISO3166Alpha2(str string) bool +func IsISO3166Alpha3(str string) bool +func IsISO693Alpha2(str string) bool +func IsISO693Alpha3b(str string) bool +func IsISO4217(str string) bool +func IsIn(str string, params ...string) bool +func IsInt(str string) bool +func IsJSON(str string) bool +func IsLatitude(str string) bool +func IsLongitude(str string) bool +func IsLowerCase(str string) bool +func IsMAC(str string) bool +func IsMongoID(str string) bool +func IsMultibyte(str string) bool +func IsNatural(value float64) bool +func IsNegative(value float64) bool +func IsNonNegative(value float64) bool +func IsNonPositive(value float64) bool +func IsNull(str string) bool +func IsNumeric(str string) bool +func IsPort(str string) bool +func IsPositive(value float64) bool +func IsPrintableASCII(str string) bool +func IsRFC3339(str string) bool +func IsRFC3339WithoutZone(str string) bool +func IsRGBcolor(str string) bool +func IsRequestURI(rawurl string) bool +func IsRequestURL(rawurl string) bool +func IsSSN(str string) bool +func IsSemver(str string) bool +func IsTime(str string, format string) bool +func IsURL(str string) bool +func IsUTFDigit(str string) bool +func IsUTFLetter(str string) bool +func IsUTFLetterNumeric(str string) bool +func IsUTFNumeric(str string) bool +func IsUUID(str string) bool +func IsUUIDv3(str string) bool +func IsUUIDv4(str string) bool +func IsUUIDv5(str string) bool +func IsUpperCase(str string) bool +func IsVariableWidth(str string) bool +func IsWhole(value float64) bool +func LeftTrim(str, chars string) string +func Map(array []interface{}, iterator ResultIterator) []interface{} +func Matches(str, pattern string) bool +func NormalizeEmail(str string) (string, error) +func PadBoth(str string, padStr string, padLen int) string +func PadLeft(str string, padStr string, padLen int) string +func PadRight(str string, padStr string, padLen int) string +func Range(str string, params ...string) bool +func RemoveTags(s string) string +func ReplacePattern(str, pattern, replace string) string +func Reverse(s string) string +func RightTrim(str, chars string) string +func RuneLength(str string, params ...string) bool +func SafeFileName(str string) string +func SetFieldsRequiredByDefault(value bool) +func Sign(value float64) float64 +func StringLength(str string, params ...string) bool +func StringMatches(s string, params ...string) bool +func StripLow(str string, keepNewLines bool) string +func ToBoolean(str string) (bool, error) +func ToFloat(str string) (float64, error) +func ToInt(str string) (int64, error) +func ToJSON(obj interface{}) (string, error) +func ToString(obj interface{}) string +func Trim(str, chars string) string +func Truncate(str string, length int, ending string) string +func UnderscoreToCamelCase(s string) string +func ValidateStruct(s interface{}) (bool, error) +func WhiteList(str, chars string) string +type ConditionIterator +type CustomTypeValidator +type Error +func (e Error) Error() string +type Errors +func (es Errors) Error() string +func (es Errors) Errors() []error +type ISO3166Entry +type Iterator +type ParamValidator +type ResultIterator +type UnsupportedTypeError +func (e *UnsupportedTypeError) Error() string +type Validator +``` + +#### Examples +###### IsURL +```go +println(govalidator.IsURL(`http://user@pass:domain.com/path/page`)) +``` +###### ToString +```go +type User struct { + FirstName string + LastName string +} + +str := govalidator.ToString(&User{"John", "Juan"}) +println(str) +``` +###### Each, Map, Filter, Count for slices +Each iterates over the slice/array and calls Iterator for every item +```go +data := []interface{}{1, 2, 3, 4, 5} +var fn govalidator.Iterator = func(value interface{}, index int) { + println(value.(int)) +} +govalidator.Each(data, fn) +``` +```go +data := []interface{}{1, 2, 3, 4, 5} +var fn govalidator.ResultIterator = func(value interface{}, index int) interface{} { + return value.(int) * 3 +} +_ = govalidator.Map(data, fn) // result = []interface{}{1, 6, 9, 12, 15} +``` +```go +data := []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} +var fn govalidator.ConditionIterator = func(value interface{}, index int) bool { + return value.(int)%2 == 0 +} +_ = govalidator.Filter(data, fn) // result = []interface{}{2, 4, 6, 8, 10} +_ = govalidator.Count(data, fn) // result = 5 +``` +###### ValidateStruct [#2](https://github.com/asaskevich/govalidator/pull/2) +If you want to validate structs, you can use tag `valid` for any field in your structure. All validators used with this field in one tag are separated by comma. If you want to skip validation, place `-` in your tag. If you need a validator that is not on the list below, you can add it like this: +```go +govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool { + return str == "duck" +}) +``` +For completely custom validators (interface-based), see below. + +Here is a list of available validators for struct fields (validator - used function): +```go +"email": IsEmail, +"url": IsURL, +"dialstring": IsDialString, +"requrl": IsRequestURL, +"requri": IsRequestURI, +"alpha": IsAlpha, +"utfletter": IsUTFLetter, +"alphanum": IsAlphanumeric, +"utfletternum": IsUTFLetterNumeric, +"numeric": IsNumeric, +"utfnumeric": IsUTFNumeric, +"utfdigit": IsUTFDigit, +"hexadecimal": IsHexadecimal, +"hexcolor": IsHexcolor, +"rgbcolor": IsRGBcolor, +"lowercase": IsLowerCase, +"uppercase": IsUpperCase, +"int": IsInt, +"float": IsFloat, +"null": IsNull, +"uuid": IsUUID, +"uuidv3": IsUUIDv3, +"uuidv4": IsUUIDv4, +"uuidv5": IsUUIDv5, +"creditcard": IsCreditCard, +"isbn10": IsISBN10, +"isbn13": IsISBN13, +"json": IsJSON, +"multibyte": IsMultibyte, +"ascii": IsASCII, +"printableascii": IsPrintableASCII, +"fullwidth": IsFullWidth, +"halfwidth": IsHalfWidth, +"variablewidth": IsVariableWidth, +"base64": IsBase64, +"datauri": IsDataURI, +"ip": IsIP, +"port": IsPort, +"ipv4": IsIPv4, +"ipv6": IsIPv6, +"dns": IsDNSName, +"host": IsHost, +"mac": IsMAC, +"latitude": IsLatitude, +"longitude": IsLongitude, +"ssn": IsSSN, +"semver": IsSemver, +"rfc3339": IsRFC3339, +"rfc3339WithoutZone": IsRFC3339WithoutZone, +"ISO3166Alpha2": IsISO3166Alpha2, +"ISO3166Alpha3": IsISO3166Alpha3, +``` +Validators with parameters + +```go +"range(min|max)": Range, +"length(min|max)": ByteLength, +"runelength(min|max)": RuneLength, +"stringlength(min|max)": StringLength, +"matches(pattern)": StringMatches, +"in(string1|string2|...|stringN)": IsIn, +"rsapub(keylength)" : IsRsaPub, +``` + +And here is small example of usage: +```go +type Post struct { + Title string `valid:"alphanum,required"` + Message string `valid:"duck,ascii"` + Message2 string `valid:"animal(dog)"` + AuthorIP string `valid:"ipv4"` + Date string `valid:"-"` +} +post := &Post{ + Title: "My Example Post", + Message: "duck", + Message2: "dog", + AuthorIP: "123.234.54.3", +} + +// Add your own struct validation tags +govalidator.TagMap["duck"] = govalidator.Validator(func(str string) bool { + return str == "duck" +}) + +// Add your own struct validation tags with parameter +govalidator.ParamTagMap["animal"] = govalidator.ParamValidator(func(str string, params ...string) bool { + species := params[0] + return str == species +}) +govalidator.ParamTagRegexMap["animal"] = regexp.MustCompile("^animal\\((\\w+)\\)$") + +result, err := govalidator.ValidateStruct(post) +if err != nil { + println("error: " + err.Error()) +} +println(result) +``` +###### WhiteList +```go +// Remove all characters from string ignoring characters between "a" and "z" +println(govalidator.WhiteList("a3a43a5a4a3a2a23a4a5a4a3a4", "a-z") == "aaaaaaaaaaaa") +``` + +###### Custom validation functions +Custom validation using your own domain specific validators is also available - here's an example of how to use it: +```go +import "github.com/asaskevich/govalidator" + +type CustomByteArray [6]byte // custom types are supported and can be validated + +type StructWithCustomByteArray struct { + ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` // multiple custom validators are possible as well and will be evaluated in sequence + Email string `valid:"email"` + CustomMinLength int `valid:"-"` +} + +govalidator.CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, context interface{}) bool { + switch v := context.(type) { // you can type switch on the context interface being validated + case StructWithCustomByteArray: + // you can check and validate against some other field in the context, + // return early or not validate against the context at all – your choice + case SomeOtherType: + // ... + default: + // expecting some other type? Throw/panic here or continue + } + + switch v := i.(type) { // type switch on the struct field being validated + case CustomByteArray: + for _, e := range v { // this validator checks that the byte array is not empty, i.e. not all zeroes + if e != 0 { + return true + } + } + } + return false +})) +govalidator.CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator(func(i interface{}, context interface{}) bool { + switch v := context.(type) { // this validates a field against the value in another field, i.e. dependent validation + case StructWithCustomByteArray: + return len(v.ID) >= v.CustomMinLength + } + return false +})) +``` + +###### Custom error messages +Custom error messages are supported via annotations by adding the `~` separator - here's an example of how to use it: +```go +type Ticket struct { + Id int64 `json:"id"` + FirstName string `json:"firstname" valid:"required~First name is blank"` +} +``` + +#### Notes +Documentation is available here: [godoc.org](https://godoc.org/github.com/asaskevich/govalidator). +Full information about code coverage is also available here: [govalidator on gocover.io](http://gocover.io/github.com/asaskevich/govalidator). + +#### Support +If you do have a contribution to the package, feel free to create a Pull Request or an Issue. + +#### What to contribute +If you don't know what to do, there are some features and functions that need to be done + +- [ ] Refactor code +- [ ] Edit docs and [README](https://github.com/asaskevich/govalidator/README.md): spellcheck, grammar and typo check +- [ ] Create actual list of contributors and projects that currently using this package +- [ ] Resolve [issues and bugs](https://github.com/asaskevich/govalidator/issues) +- [ ] Update actual [list of functions](https://github.com/asaskevich/govalidator#list-of-functions) +- [ ] Update [list of validators](https://github.com/asaskevich/govalidator#validatestruct-2) that available for `ValidateStruct` and add new +- [ ] Implement new validators: `IsFQDN`, `IsIMEI`, `IsPostalCode`, `IsISIN`, `IsISRC` etc +- [ ] Implement [validation by maps](https://github.com/asaskevich/govalidator/issues/224) +- [ ] Implement fuzzing testing +- [ ] Implement some struct/map/array utilities +- [ ] Implement map/array validation +- [ ] Implement benchmarking +- [ ] Implement batch of examples +- [ ] Look at forks for new features and fixes + +#### Advice +Feel free to create what you want, but keep in mind when you implement new features: +- Code must be clear and readable, names of variables/constants clearly describes what they are doing +- Public functions must be documented and described in source file and added to README.md to the list of available functions +- There are must be unit-tests for any new functions and improvements + +## Credits +### Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + +#### Special thanks to [contributors](https://github.com/asaskevich/govalidator/graphs/contributors) +* [Daniel Lohse](https://github.com/annismckenzie) +* [Attila Oláh](https://github.com/attilaolah) +* [Daniel Korner](https://github.com/Dadie) +* [Steven Wilkin](https://github.com/stevenwilkin) +* [Deiwin Sarjas](https://github.com/deiwin) +* [Noah Shibley](https://github.com/slugmobile) +* [Nathan Davies](https://github.com/nathj07) +* [Matt Sanford](https://github.com/mzsanford) +* [Simon ccl1115](https://github.com/ccl1115) + + + + +### Backers + +Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/govalidator#backer)] + + + + +### Sponsors + +Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/govalidator#sponsor)] + + + + + + + + + + + + + + + +## License +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fasaskevich%2Fgovalidator?ref=badge_large) \ No newline at end of file diff --git a/vendor/github.com/asaskevich/govalidator/arrays.go b/vendor/github.com/asaskevich/govalidator/arrays.go new file mode 100644 index 000000000..5bace2654 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/arrays.go @@ -0,0 +1,58 @@ +package govalidator + +// Iterator is the function that accepts element of slice/array and its index +type Iterator func(interface{}, int) + +// ResultIterator is the function that accepts element of slice/array and its index and returns any result +type ResultIterator func(interface{}, int) interface{} + +// ConditionIterator is the function that accepts element of slice/array and its index and returns boolean +type ConditionIterator func(interface{}, int) bool + +// Each iterates over the slice and apply Iterator to every item +func Each(array []interface{}, iterator Iterator) { + for index, data := range array { + iterator(data, index) + } +} + +// Map iterates over the slice and apply ResultIterator to every item. Returns new slice as a result. +func Map(array []interface{}, iterator ResultIterator) []interface{} { + var result = make([]interface{}, len(array)) + for index, data := range array { + result[index] = iterator(data, index) + } + return result +} + +// Find iterates over the slice and apply ConditionIterator to every item. Returns first item that meet ConditionIterator or nil otherwise. +func Find(array []interface{}, iterator ConditionIterator) interface{} { + for index, data := range array { + if iterator(data, index) { + return data + } + } + return nil +} + +// Filter iterates over the slice and apply ConditionIterator to every item. Returns new slice. +func Filter(array []interface{}, iterator ConditionIterator) []interface{} { + var result = make([]interface{}, 0) + for index, data := range array { + if iterator(data, index) { + result = append(result, data) + } + } + return result +} + +// Count iterates over the slice and apply ConditionIterator to every item. Returns count of items that meets ConditionIterator. +func Count(array []interface{}, iterator ConditionIterator) int { + count := 0 + for index, data := range array { + if iterator(data, index) { + count = count + 1 + } + } + return count +} diff --git a/vendor/github.com/asaskevich/govalidator/converter.go b/vendor/github.com/asaskevich/govalidator/converter.go new file mode 100644 index 000000000..cf1e5d569 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/converter.go @@ -0,0 +1,64 @@ +package govalidator + +import ( + "encoding/json" + "fmt" + "reflect" + "strconv" +) + +// ToString convert the input to a string. +func ToString(obj interface{}) string { + res := fmt.Sprintf("%v", obj) + return string(res) +} + +// ToJSON convert the input to a valid JSON string +func ToJSON(obj interface{}) (string, error) { + res, err := json.Marshal(obj) + if err != nil { + res = []byte("") + } + return string(res), err +} + +// ToFloat convert the input string to a float, or 0.0 if the input is not a float. +func ToFloat(str string) (float64, error) { + res, err := strconv.ParseFloat(str, 64) + if err != nil { + res = 0.0 + } + return res, err +} + +// ToInt convert the input string or any int type to an integer type 64, or 0 if the input is not an integer. +func ToInt(value interface{}) (res int64, err error) { + val := reflect.ValueOf(value) + + switch value.(type) { + case int, int8, int16, int32, int64: + res = val.Int() + case uint, uint8, uint16, uint32, uint64: + res = int64(val.Uint()) + case string: + if IsInt(val.String()) { + res, err = strconv.ParseInt(val.String(), 0, 64) + if err != nil { + res = 0 + } + } else { + err = fmt.Errorf("math: square root of negative number %g", value) + res = 0 + } + default: + err = fmt.Errorf("math: square root of negative number %g", value) + res = 0 + } + + return +} + +// ToBoolean convert the input string to a boolean. +func ToBoolean(str string) (bool, error) { + return strconv.ParseBool(str) +} diff --git a/vendor/github.com/asaskevich/govalidator/error.go b/vendor/github.com/asaskevich/govalidator/error.go new file mode 100644 index 000000000..655b750cb --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/error.go @@ -0,0 +1,43 @@ +package govalidator + +import "strings" + +// Errors is an array of multiple errors and conforms to the error interface. +type Errors []error + +// Errors returns itself. +func (es Errors) Errors() []error { + return es +} + +func (es Errors) Error() string { + var errs []string + for _, e := range es { + errs = append(errs, e.Error()) + } + return strings.Join(errs, ";") +} + +// Error encapsulates a name, an error and whether there's a custom error message or not. +type Error struct { + Name string + Err error + CustomErrorMessageExists bool + + // Validator indicates the name of the validator that failed + Validator string + Path []string +} + +func (e Error) Error() string { + if e.CustomErrorMessageExists { + return e.Err.Error() + } + + errName := e.Name + if len(e.Path) > 0 { + errName = strings.Join(append(e.Path, e.Name), ".") + } + + return errName + ": " + e.Err.Error() +} diff --git a/vendor/github.com/asaskevich/govalidator/numerics.go b/vendor/github.com/asaskevich/govalidator/numerics.go new file mode 100644 index 000000000..7e6c652e1 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/numerics.go @@ -0,0 +1,97 @@ +package govalidator + +import ( + "math" + "reflect" +) + +// Abs returns absolute value of number +func Abs(value float64) float64 { + return math.Abs(value) +} + +// Sign returns signum of number: 1 in case of value > 0, -1 in case of value < 0, 0 otherwise +func Sign(value float64) float64 { + if value > 0 { + return 1 + } else if value < 0 { + return -1 + } else { + return 0 + } +} + +// IsNegative returns true if value < 0 +func IsNegative(value float64) bool { + return value < 0 +} + +// IsPositive returns true if value > 0 +func IsPositive(value float64) bool { + return value > 0 +} + +// IsNonNegative returns true if value >= 0 +func IsNonNegative(value float64) bool { + return value >= 0 +} + +// IsNonPositive returns true if value <= 0 +func IsNonPositive(value float64) bool { + return value <= 0 +} + +// InRange returns true if value lies between left and right border +func InRangeInt(value, left, right interface{}) bool { + value64, _ := ToInt(value) + left64, _ := ToInt(left) + right64, _ := ToInt(right) + if left64 > right64 { + left64, right64 = right64, left64 + } + return value64 >= left64 && value64 <= right64 +} + +// InRange returns true if value lies between left and right border +func InRangeFloat32(value, left, right float32) bool { + if left > right { + left, right = right, left + } + return value >= left && value <= right +} + +// InRange returns true if value lies between left and right border +func InRangeFloat64(value, left, right float64) bool { + if left > right { + left, right = right, left + } + return value >= left && value <= right +} + +// InRange returns true if value lies between left and right border, generic type to handle int, float32 or float64, all types must the same type +func InRange(value interface{}, left interface{}, right interface{}) bool { + + reflectValue := reflect.TypeOf(value).Kind() + reflectLeft := reflect.TypeOf(left).Kind() + reflectRight := reflect.TypeOf(right).Kind() + + if reflectValue == reflect.Int && reflectLeft == reflect.Int && reflectRight == reflect.Int { + return InRangeInt(value.(int), left.(int), right.(int)) + } else if reflectValue == reflect.Float32 && reflectLeft == reflect.Float32 && reflectRight == reflect.Float32 { + return InRangeFloat32(value.(float32), left.(float32), right.(float32)) + } else if reflectValue == reflect.Float64 && reflectLeft == reflect.Float64 && reflectRight == reflect.Float64 { + return InRangeFloat64(value.(float64), left.(float64), right.(float64)) + } else { + return false + } +} + +// IsWhole returns true if value is whole number +func IsWhole(value float64) bool { + return math.Remainder(value, 1) == 0 +} + +// IsNatural returns true if value is natural number (positive and whole) +func IsNatural(value float64) bool { + return IsWhole(value) && IsPositive(value) +} diff --git a/vendor/github.com/asaskevich/govalidator/patterns.go b/vendor/github.com/asaskevich/govalidator/patterns.go new file mode 100644 index 000000000..61a05d438 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/patterns.go @@ -0,0 +1,101 @@ +package govalidator + +import "regexp" + +// Basic regular expressions for validating strings +const ( + Email string = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" + CreditCard string = "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$" + ISBN10 string = "^(?:[0-9]{9}X|[0-9]{10})$" + ISBN13 string = "^(?:[0-9]{13})$" + UUID3 string = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$" + UUID4 string = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + UUID5 string = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + UUID string = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" + Alpha string = "^[a-zA-Z]+$" + Alphanumeric string = "^[a-zA-Z0-9]+$" + Numeric string = "^[0-9]+$" + Int string = "^(?:[-+]?(?:0|[1-9][0-9]*))$" + Float string = "^(?:[-+]?(?:[0-9]+))?(?:\\.[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$" + Hexadecimal string = "^[0-9a-fA-F]+$" + Hexcolor string = "^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" + RGBcolor string = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$" + ASCII string = "^[\x00-\x7F]+$" + Multibyte string = "[^\x00-\x7F]" + FullWidth string = "[^\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]" + HalfWidth string = "[\u0020-\u007E\uFF61-\uFF9F\uFFA0-\uFFDC\uFFE8-\uFFEE0-9a-zA-Z]" + Base64 string = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" + PrintableASCII string = "^[\x20-\x7E]+$" + DataURI string = "^data:.+\\/(.+);base64$" + Latitude string = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" + Longitude string = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" + DNSName string = `^([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*[\._]?$` + IP string = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))` + URLSchema string = `((ftp|tcp|udp|wss?|https?):\/\/)` + URLUsername string = `(\S+(:\S*)?@)` + URLPath string = `((\/|\?|#)[^\s]*)` + URLPort string = `(:(\d{1,5}))` + URLIP string = `([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))` + URLSubdomain string = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))` + URL string = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$` + SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$` + WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$` + UnixPath string = `^(/[^/\x00]*)+/?$` + Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$" + tagName string = "valid" + hasLowerCase string = ".*[[:lower:]]" + hasUpperCase string = ".*[[:upper:]]" + hasWhitespace string = ".*[[:space:]]" + hasWhitespaceOnly string = "^[[:space:]]+$" +) + +// Used by IsFilePath func +const ( + // Unknown is unresolved OS type + Unknown = iota + // Win is Windows type + Win + // Unix is *nix OS types + Unix +) + +var ( + userRegexp = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+$") + hostRegexp = regexp.MustCompile("^[^\\s]+\\.[^\\s]+$") + userDotRegexp = regexp.MustCompile("(^[.]{1})|([.]{1}$)|([.]{2,})") + rxEmail = regexp.MustCompile(Email) + rxCreditCard = regexp.MustCompile(CreditCard) + rxISBN10 = regexp.MustCompile(ISBN10) + rxISBN13 = regexp.MustCompile(ISBN13) + rxUUID3 = regexp.MustCompile(UUID3) + rxUUID4 = regexp.MustCompile(UUID4) + rxUUID5 = regexp.MustCompile(UUID5) + rxUUID = regexp.MustCompile(UUID) + rxAlpha = regexp.MustCompile(Alpha) + rxAlphanumeric = regexp.MustCompile(Alphanumeric) + rxNumeric = regexp.MustCompile(Numeric) + rxInt = regexp.MustCompile(Int) + rxFloat = regexp.MustCompile(Float) + rxHexadecimal = regexp.MustCompile(Hexadecimal) + rxHexcolor = regexp.MustCompile(Hexcolor) + rxRGBcolor = regexp.MustCompile(RGBcolor) + rxASCII = regexp.MustCompile(ASCII) + rxPrintableASCII = regexp.MustCompile(PrintableASCII) + rxMultibyte = regexp.MustCompile(Multibyte) + rxFullWidth = regexp.MustCompile(FullWidth) + rxHalfWidth = regexp.MustCompile(HalfWidth) + rxBase64 = regexp.MustCompile(Base64) + rxDataURI = regexp.MustCompile(DataURI) + rxLatitude = regexp.MustCompile(Latitude) + rxLongitude = regexp.MustCompile(Longitude) + rxDNSName = regexp.MustCompile(DNSName) + rxURL = regexp.MustCompile(URL) + rxSSN = regexp.MustCompile(SSN) + rxWinPath = regexp.MustCompile(WinPath) + rxUnixPath = regexp.MustCompile(UnixPath) + rxSemver = regexp.MustCompile(Semver) + rxHasLowerCase = regexp.MustCompile(hasLowerCase) + rxHasUpperCase = regexp.MustCompile(hasUpperCase) + rxHasWhitespace = regexp.MustCompile(hasWhitespace) + rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly) +) diff --git a/vendor/github.com/asaskevich/govalidator/types.go b/vendor/github.com/asaskevich/govalidator/types.go new file mode 100644 index 000000000..4f7e9274a --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/types.go @@ -0,0 +1,636 @@ +package govalidator + +import ( + "reflect" + "regexp" + "sort" + "sync" +) + +// Validator is a wrapper for a validator function that returns bool and accepts string. +type Validator func(str string) bool + +// CustomTypeValidator is a wrapper for validator functions that returns bool and accepts any type. +// The second parameter should be the context (in the case of validating a struct: the whole object being validated). +type CustomTypeValidator func(i interface{}, o interface{}) bool + +// ParamValidator is a wrapper for validator functions that accepts additional parameters. +type ParamValidator func(str string, params ...string) bool +type tagOptionsMap map[string]tagOption + +func (t tagOptionsMap) orderedKeys() []string { + var keys []string + for k := range t { + keys = append(keys, k) + } + + sort.Slice(keys, func(a, b int) bool { + return t[keys[a]].order < t[keys[b]].order + }) + + return keys +} + +type tagOption struct { + name string + customErrorMessage string + order int +} + +// UnsupportedTypeError is a wrapper for reflect.Type +type UnsupportedTypeError struct { + Type reflect.Type +} + +// stringValues is a slice of reflect.Value holding *reflect.StringValue. +// It implements the methods to sort by string. +type stringValues []reflect.Value + +// ParamTagMap is a map of functions accept variants parameters +var ParamTagMap = map[string]ParamValidator{ + "length": ByteLength, + "range": Range, + "runelength": RuneLength, + "stringlength": StringLength, + "matches": StringMatches, + "in": isInRaw, + "rsapub": IsRsaPub, +} + +// ParamTagRegexMap maps param tags to their respective regexes. +var ParamTagRegexMap = map[string]*regexp.Regexp{ + "range": regexp.MustCompile("^range\\((\\d+)\\|(\\d+)\\)$"), + "length": regexp.MustCompile("^length\\((\\d+)\\|(\\d+)\\)$"), + "runelength": regexp.MustCompile("^runelength\\((\\d+)\\|(\\d+)\\)$"), + "stringlength": regexp.MustCompile("^stringlength\\((\\d+)\\|(\\d+)\\)$"), + "in": regexp.MustCompile(`^in\((.*)\)`), + "matches": regexp.MustCompile(`^matches\((.+)\)$`), + "rsapub": regexp.MustCompile("^rsapub\\((\\d+)\\)$"), +} + +type customTypeTagMap struct { + validators map[string]CustomTypeValidator + + sync.RWMutex +} + +func (tm *customTypeTagMap) Get(name string) (CustomTypeValidator, bool) { + tm.RLock() + defer tm.RUnlock() + v, ok := tm.validators[name] + return v, ok +} + +func (tm *customTypeTagMap) Set(name string, ctv CustomTypeValidator) { + tm.Lock() + defer tm.Unlock() + tm.validators[name] = ctv +} + +// CustomTypeTagMap is a map of functions that can be used as tags for ValidateStruct function. +// Use this to validate compound or custom types that need to be handled as a whole, e.g. +// `type UUID [16]byte` (this would be handled as an array of bytes). +var CustomTypeTagMap = &customTypeTagMap{validators: make(map[string]CustomTypeValidator)} + +// TagMap is a map of functions, that can be used as tags for ValidateStruct function. +var TagMap = map[string]Validator{ + "email": IsEmail, + "url": IsURL, + "dialstring": IsDialString, + "requrl": IsRequestURL, + "requri": IsRequestURI, + "alpha": IsAlpha, + "utfletter": IsUTFLetter, + "alphanum": IsAlphanumeric, + "utfletternum": IsUTFLetterNumeric, + "numeric": IsNumeric, + "utfnumeric": IsUTFNumeric, + "utfdigit": IsUTFDigit, + "hexadecimal": IsHexadecimal, + "hexcolor": IsHexcolor, + "rgbcolor": IsRGBcolor, + "lowercase": IsLowerCase, + "uppercase": IsUpperCase, + "int": IsInt, + "float": IsFloat, + "null": IsNull, + "uuid": IsUUID, + "uuidv3": IsUUIDv3, + "uuidv4": IsUUIDv4, + "uuidv5": IsUUIDv5, + "creditcard": IsCreditCard, + "isbn10": IsISBN10, + "isbn13": IsISBN13, + "json": IsJSON, + "multibyte": IsMultibyte, + "ascii": IsASCII, + "printableascii": IsPrintableASCII, + "fullwidth": IsFullWidth, + "halfwidth": IsHalfWidth, + "variablewidth": IsVariableWidth, + "base64": IsBase64, + "datauri": IsDataURI, + "ip": IsIP, + "port": IsPort, + "ipv4": IsIPv4, + "ipv6": IsIPv6, + "dns": IsDNSName, + "host": IsHost, + "mac": IsMAC, + "latitude": IsLatitude, + "longitude": IsLongitude, + "ssn": IsSSN, + "semver": IsSemver, + "rfc3339": IsRFC3339, + "rfc3339WithoutZone": IsRFC3339WithoutZone, + "ISO3166Alpha2": IsISO3166Alpha2, + "ISO3166Alpha3": IsISO3166Alpha3, + "ISO4217": IsISO4217, +} + +// ISO3166Entry stores country codes +type ISO3166Entry struct { + EnglishShortName string + FrenchShortName string + Alpha2Code string + Alpha3Code string + Numeric string +} + +//ISO3166List based on https://www.iso.org/obp/ui/#search/code/ Code Type "Officially Assigned Codes" +var ISO3166List = []ISO3166Entry{ + {"Afghanistan", "Afghanistan (l')", "AF", "AFG", "004"}, + {"Albania", "Albanie (l')", "AL", "ALB", "008"}, + {"Antarctica", "Antarctique (l')", "AQ", "ATA", "010"}, + {"Algeria", "Algérie (l')", "DZ", "DZA", "012"}, + {"American Samoa", "Samoa américaines (les)", "AS", "ASM", "016"}, + {"Andorra", "Andorre (l')", "AD", "AND", "020"}, + {"Angola", "Angola (l')", "AO", "AGO", "024"}, + {"Antigua and Barbuda", "Antigua-et-Barbuda", "AG", "ATG", "028"}, + {"Azerbaijan", "Azerbaïdjan (l')", "AZ", "AZE", "031"}, + {"Argentina", "Argentine (l')", "AR", "ARG", "032"}, + {"Australia", "Australie (l')", "AU", "AUS", "036"}, + {"Austria", "Autriche (l')", "AT", "AUT", "040"}, + {"Bahamas (the)", "Bahamas (les)", "BS", "BHS", "044"}, + {"Bahrain", "Bahreïn", "BH", "BHR", "048"}, + {"Bangladesh", "Bangladesh (le)", "BD", "BGD", "050"}, + {"Armenia", "Arménie (l')", "AM", "ARM", "051"}, + {"Barbados", "Barbade (la)", "BB", "BRB", "052"}, + {"Belgium", "Belgique (la)", "BE", "BEL", "056"}, + {"Bermuda", "Bermudes (les)", "BM", "BMU", "060"}, + {"Bhutan", "Bhoutan (le)", "BT", "BTN", "064"}, + {"Bolivia (Plurinational State of)", "Bolivie (État plurinational de)", "BO", "BOL", "068"}, + {"Bosnia and Herzegovina", "Bosnie-Herzégovine (la)", "BA", "BIH", "070"}, + {"Botswana", "Botswana (le)", "BW", "BWA", "072"}, + {"Bouvet Island", "Bouvet (l'Île)", "BV", "BVT", "074"}, + {"Brazil", "Brésil (le)", "BR", "BRA", "076"}, + {"Belize", "Belize (le)", "BZ", "BLZ", "084"}, + {"British Indian Ocean Territory (the)", "Indien (le Territoire britannique de l'océan)", "IO", "IOT", "086"}, + {"Solomon Islands", "Salomon (Îles)", "SB", "SLB", "090"}, + {"Virgin Islands (British)", "Vierges britanniques (les Îles)", "VG", "VGB", "092"}, + {"Brunei Darussalam", "Brunéi Darussalam (le)", "BN", "BRN", "096"}, + {"Bulgaria", "Bulgarie (la)", "BG", "BGR", "100"}, + {"Myanmar", "Myanmar (le)", "MM", "MMR", "104"}, + {"Burundi", "Burundi (le)", "BI", "BDI", "108"}, + {"Belarus", "Bélarus (le)", "BY", "BLR", "112"}, + {"Cambodia", "Cambodge (le)", "KH", "KHM", "116"}, + {"Cameroon", "Cameroun (le)", "CM", "CMR", "120"}, + {"Canada", "Canada (le)", "CA", "CAN", "124"}, + {"Cabo Verde", "Cabo Verde", "CV", "CPV", "132"}, + {"Cayman Islands (the)", "Caïmans (les Îles)", "KY", "CYM", "136"}, + {"Central African Republic (the)", "République centrafricaine (la)", "CF", "CAF", "140"}, + {"Sri Lanka", "Sri Lanka", "LK", "LKA", "144"}, + {"Chad", "Tchad (le)", "TD", "TCD", "148"}, + {"Chile", "Chili (le)", "CL", "CHL", "152"}, + {"China", "Chine (la)", "CN", "CHN", "156"}, + {"Taiwan (Province of China)", "Taïwan (Province de Chine)", "TW", "TWN", "158"}, + {"Christmas Island", "Christmas (l'Île)", "CX", "CXR", "162"}, + {"Cocos (Keeling) Islands (the)", "Cocos (les Îles)/ Keeling (les Îles)", "CC", "CCK", "166"}, + {"Colombia", "Colombie (la)", "CO", "COL", "170"}, + {"Comoros (the)", "Comores (les)", "KM", "COM", "174"}, + {"Mayotte", "Mayotte", "YT", "MYT", "175"}, + {"Congo (the)", "Congo (le)", "CG", "COG", "178"}, + {"Congo (the Democratic Republic of the)", "Congo (la République démocratique du)", "CD", "COD", "180"}, + {"Cook Islands (the)", "Cook (les Îles)", "CK", "COK", "184"}, + {"Costa Rica", "Costa Rica (le)", "CR", "CRI", "188"}, + {"Croatia", "Croatie (la)", "HR", "HRV", "191"}, + {"Cuba", "Cuba", "CU", "CUB", "192"}, + {"Cyprus", "Chypre", "CY", "CYP", "196"}, + {"Czech Republic (the)", "tchèque (la République)", "CZ", "CZE", "203"}, + {"Benin", "Bénin (le)", "BJ", "BEN", "204"}, + {"Denmark", "Danemark (le)", "DK", "DNK", "208"}, + {"Dominica", "Dominique (la)", "DM", "DMA", "212"}, + {"Dominican Republic (the)", "dominicaine (la République)", "DO", "DOM", "214"}, + {"Ecuador", "Équateur (l')", "EC", "ECU", "218"}, + {"El Salvador", "El Salvador", "SV", "SLV", "222"}, + {"Equatorial Guinea", "Guinée équatoriale (la)", "GQ", "GNQ", "226"}, + {"Ethiopia", "Éthiopie (l')", "ET", "ETH", "231"}, + {"Eritrea", "Érythrée (l')", "ER", "ERI", "232"}, + {"Estonia", "Estonie (l')", "EE", "EST", "233"}, + {"Faroe Islands (the)", "Féroé (les Îles)", "FO", "FRO", "234"}, + {"Falkland Islands (the) [Malvinas]", "Falkland (les Îles)/Malouines (les Îles)", "FK", "FLK", "238"}, + {"South Georgia and the South Sandwich Islands", "Géorgie du Sud-et-les Îles Sandwich du Sud (la)", "GS", "SGS", "239"}, + {"Fiji", "Fidji (les)", "FJ", "FJI", "242"}, + {"Finland", "Finlande (la)", "FI", "FIN", "246"}, + {"Åland Islands", "Åland(les Îles)", "AX", "ALA", "248"}, + {"France", "France (la)", "FR", "FRA", "250"}, + {"French Guiana", "Guyane française (la )", "GF", "GUF", "254"}, + {"French Polynesia", "Polynésie française (la)", "PF", "PYF", "258"}, + {"French Southern Territories (the)", "Terres australes françaises (les)", "TF", "ATF", "260"}, + {"Djibouti", "Djibouti", "DJ", "DJI", "262"}, + {"Gabon", "Gabon (le)", "GA", "GAB", "266"}, + {"Georgia", "Géorgie (la)", "GE", "GEO", "268"}, + {"Gambia (the)", "Gambie (la)", "GM", "GMB", "270"}, + {"Palestine, State of", "Palestine, État de", "PS", "PSE", "275"}, + {"Germany", "Allemagne (l')", "DE", "DEU", "276"}, + {"Ghana", "Ghana (le)", "GH", "GHA", "288"}, + {"Gibraltar", "Gibraltar", "GI", "GIB", "292"}, + {"Kiribati", "Kiribati", "KI", "KIR", "296"}, + {"Greece", "Grèce (la)", "GR", "GRC", "300"}, + {"Greenland", "Groenland (le)", "GL", "GRL", "304"}, + {"Grenada", "Grenade (la)", "GD", "GRD", "308"}, + {"Guadeloupe", "Guadeloupe (la)", "GP", "GLP", "312"}, + {"Guam", "Guam", "GU", "GUM", "316"}, + {"Guatemala", "Guatemala (le)", "GT", "GTM", "320"}, + {"Guinea", "Guinée (la)", "GN", "GIN", "324"}, + {"Guyana", "Guyana (le)", "GY", "GUY", "328"}, + {"Haiti", "Haïti", "HT", "HTI", "332"}, + {"Heard Island and McDonald Islands", "Heard-et-Îles MacDonald (l'Île)", "HM", "HMD", "334"}, + {"Holy See (the)", "Saint-Siège (le)", "VA", "VAT", "336"}, + {"Honduras", "Honduras (le)", "HN", "HND", "340"}, + {"Hong Kong", "Hong Kong", "HK", "HKG", "344"}, + {"Hungary", "Hongrie (la)", "HU", "HUN", "348"}, + {"Iceland", "Islande (l')", "IS", "ISL", "352"}, + {"India", "Inde (l')", "IN", "IND", "356"}, + {"Indonesia", "Indonésie (l')", "ID", "IDN", "360"}, + {"Iran (Islamic Republic of)", "Iran (République Islamique d')", "IR", "IRN", "364"}, + {"Iraq", "Iraq (l')", "IQ", "IRQ", "368"}, + {"Ireland", "Irlande (l')", "IE", "IRL", "372"}, + {"Israel", "Israël", "IL", "ISR", "376"}, + {"Italy", "Italie (l')", "IT", "ITA", "380"}, + {"Côte d'Ivoire", "Côte d'Ivoire (la)", "CI", "CIV", "384"}, + {"Jamaica", "Jamaïque (la)", "JM", "JAM", "388"}, + {"Japan", "Japon (le)", "JP", "JPN", "392"}, + {"Kazakhstan", "Kazakhstan (le)", "KZ", "KAZ", "398"}, + {"Jordan", "Jordanie (la)", "JO", "JOR", "400"}, + {"Kenya", "Kenya (le)", "KE", "KEN", "404"}, + {"Korea (the Democratic People's Republic of)", "Corée (la République populaire démocratique de)", "KP", "PRK", "408"}, + {"Korea (the Republic of)", "Corée (la République de)", "KR", "KOR", "410"}, + {"Kuwait", "Koweït (le)", "KW", "KWT", "414"}, + {"Kyrgyzstan", "Kirghizistan (le)", "KG", "KGZ", "417"}, + {"Lao People's Democratic Republic (the)", "Lao, République démocratique populaire", "LA", "LAO", "418"}, + {"Lebanon", "Liban (le)", "LB", "LBN", "422"}, + {"Lesotho", "Lesotho (le)", "LS", "LSO", "426"}, + {"Latvia", "Lettonie (la)", "LV", "LVA", "428"}, + {"Liberia", "Libéria (le)", "LR", "LBR", "430"}, + {"Libya", "Libye (la)", "LY", "LBY", "434"}, + {"Liechtenstein", "Liechtenstein (le)", "LI", "LIE", "438"}, + {"Lithuania", "Lituanie (la)", "LT", "LTU", "440"}, + {"Luxembourg", "Luxembourg (le)", "LU", "LUX", "442"}, + {"Macao", "Macao", "MO", "MAC", "446"}, + {"Madagascar", "Madagascar", "MG", "MDG", "450"}, + {"Malawi", "Malawi (le)", "MW", "MWI", "454"}, + {"Malaysia", "Malaisie (la)", "MY", "MYS", "458"}, + {"Maldives", "Maldives (les)", "MV", "MDV", "462"}, + {"Mali", "Mali (le)", "ML", "MLI", "466"}, + {"Malta", "Malte", "MT", "MLT", "470"}, + {"Martinique", "Martinique (la)", "MQ", "MTQ", "474"}, + {"Mauritania", "Mauritanie (la)", "MR", "MRT", "478"}, + {"Mauritius", "Maurice", "MU", "MUS", "480"}, + {"Mexico", "Mexique (le)", "MX", "MEX", "484"}, + {"Monaco", "Monaco", "MC", "MCO", "492"}, + {"Mongolia", "Mongolie (la)", "MN", "MNG", "496"}, + {"Moldova (the Republic of)", "Moldova , République de", "MD", "MDA", "498"}, + {"Montenegro", "Monténégro (le)", "ME", "MNE", "499"}, + {"Montserrat", "Montserrat", "MS", "MSR", "500"}, + {"Morocco", "Maroc (le)", "MA", "MAR", "504"}, + {"Mozambique", "Mozambique (le)", "MZ", "MOZ", "508"}, + {"Oman", "Oman", "OM", "OMN", "512"}, + {"Namibia", "Namibie (la)", "NA", "NAM", "516"}, + {"Nauru", "Nauru", "NR", "NRU", "520"}, + {"Nepal", "Népal (le)", "NP", "NPL", "524"}, + {"Netherlands (the)", "Pays-Bas (les)", "NL", "NLD", "528"}, + {"Curaçao", "Curaçao", "CW", "CUW", "531"}, + {"Aruba", "Aruba", "AW", "ABW", "533"}, + {"Sint Maarten (Dutch part)", "Saint-Martin (partie néerlandaise)", "SX", "SXM", "534"}, + {"Bonaire, Sint Eustatius and Saba", "Bonaire, Saint-Eustache et Saba", "BQ", "BES", "535"}, + {"New Caledonia", "Nouvelle-Calédonie (la)", "NC", "NCL", "540"}, + {"Vanuatu", "Vanuatu (le)", "VU", "VUT", "548"}, + {"New Zealand", "Nouvelle-Zélande (la)", "NZ", "NZL", "554"}, + {"Nicaragua", "Nicaragua (le)", "NI", "NIC", "558"}, + {"Niger (the)", "Niger (le)", "NE", "NER", "562"}, + {"Nigeria", "Nigéria (le)", "NG", "NGA", "566"}, + {"Niue", "Niue", "NU", "NIU", "570"}, + {"Norfolk Island", "Norfolk (l'Île)", "NF", "NFK", "574"}, + {"Norway", "Norvège (la)", "NO", "NOR", "578"}, + {"Northern Mariana Islands (the)", "Mariannes du Nord (les Îles)", "MP", "MNP", "580"}, + {"United States Minor Outlying Islands (the)", "Îles mineures éloignées des États-Unis (les)", "UM", "UMI", "581"}, + {"Micronesia (Federated States of)", "Micronésie (États fédérés de)", "FM", "FSM", "583"}, + {"Marshall Islands (the)", "Marshall (Îles)", "MH", "MHL", "584"}, + {"Palau", "Palaos (les)", "PW", "PLW", "585"}, + {"Pakistan", "Pakistan (le)", "PK", "PAK", "586"}, + {"Panama", "Panama (le)", "PA", "PAN", "591"}, + {"Papua New Guinea", "Papouasie-Nouvelle-Guinée (la)", "PG", "PNG", "598"}, + {"Paraguay", "Paraguay (le)", "PY", "PRY", "600"}, + {"Peru", "Pérou (le)", "PE", "PER", "604"}, + {"Philippines (the)", "Philippines (les)", "PH", "PHL", "608"}, + {"Pitcairn", "Pitcairn", "PN", "PCN", "612"}, + {"Poland", "Pologne (la)", "PL", "POL", "616"}, + {"Portugal", "Portugal (le)", "PT", "PRT", "620"}, + {"Guinea-Bissau", "Guinée-Bissau (la)", "GW", "GNB", "624"}, + {"Timor-Leste", "Timor-Leste (le)", "TL", "TLS", "626"}, + {"Puerto Rico", "Porto Rico", "PR", "PRI", "630"}, + {"Qatar", "Qatar (le)", "QA", "QAT", "634"}, + {"Réunion", "Réunion (La)", "RE", "REU", "638"}, + {"Romania", "Roumanie (la)", "RO", "ROU", "642"}, + {"Russian Federation (the)", "Russie (la Fédération de)", "RU", "RUS", "643"}, + {"Rwanda", "Rwanda (le)", "RW", "RWA", "646"}, + {"Saint Barthélemy", "Saint-Barthélemy", "BL", "BLM", "652"}, + {"Saint Helena, Ascension and Tristan da Cunha", "Sainte-Hélène, Ascension et Tristan da Cunha", "SH", "SHN", "654"}, + {"Saint Kitts and Nevis", "Saint-Kitts-et-Nevis", "KN", "KNA", "659"}, + {"Anguilla", "Anguilla", "AI", "AIA", "660"}, + {"Saint Lucia", "Sainte-Lucie", "LC", "LCA", "662"}, + {"Saint Martin (French part)", "Saint-Martin (partie française)", "MF", "MAF", "663"}, + {"Saint Pierre and Miquelon", "Saint-Pierre-et-Miquelon", "PM", "SPM", "666"}, + {"Saint Vincent and the Grenadines", "Saint-Vincent-et-les Grenadines", "VC", "VCT", "670"}, + {"San Marino", "Saint-Marin", "SM", "SMR", "674"}, + {"Sao Tome and Principe", "Sao Tomé-et-Principe", "ST", "STP", "678"}, + {"Saudi Arabia", "Arabie saoudite (l')", "SA", "SAU", "682"}, + {"Senegal", "Sénégal (le)", "SN", "SEN", "686"}, + {"Serbia", "Serbie (la)", "RS", "SRB", "688"}, + {"Seychelles", "Seychelles (les)", "SC", "SYC", "690"}, + {"Sierra Leone", "Sierra Leone (la)", "SL", "SLE", "694"}, + {"Singapore", "Singapour", "SG", "SGP", "702"}, + {"Slovakia", "Slovaquie (la)", "SK", "SVK", "703"}, + {"Viet Nam", "Viet Nam (le)", "VN", "VNM", "704"}, + {"Slovenia", "Slovénie (la)", "SI", "SVN", "705"}, + {"Somalia", "Somalie (la)", "SO", "SOM", "706"}, + {"South Africa", "Afrique du Sud (l')", "ZA", "ZAF", "710"}, + {"Zimbabwe", "Zimbabwe (le)", "ZW", "ZWE", "716"}, + {"Spain", "Espagne (l')", "ES", "ESP", "724"}, + {"South Sudan", "Soudan du Sud (le)", "SS", "SSD", "728"}, + {"Sudan (the)", "Soudan (le)", "SD", "SDN", "729"}, + {"Western Sahara*", "Sahara occidental (le)*", "EH", "ESH", "732"}, + {"Suriname", "Suriname (le)", "SR", "SUR", "740"}, + {"Svalbard and Jan Mayen", "Svalbard et l'Île Jan Mayen (le)", "SJ", "SJM", "744"}, + {"Swaziland", "Swaziland (le)", "SZ", "SWZ", "748"}, + {"Sweden", "Suède (la)", "SE", "SWE", "752"}, + {"Switzerland", "Suisse (la)", "CH", "CHE", "756"}, + {"Syrian Arab Republic", "République arabe syrienne (la)", "SY", "SYR", "760"}, + {"Tajikistan", "Tadjikistan (le)", "TJ", "TJK", "762"}, + {"Thailand", "Thaïlande (la)", "TH", "THA", "764"}, + {"Togo", "Togo (le)", "TG", "TGO", "768"}, + {"Tokelau", "Tokelau (les)", "TK", "TKL", "772"}, + {"Tonga", "Tonga (les)", "TO", "TON", "776"}, + {"Trinidad and Tobago", "Trinité-et-Tobago (la)", "TT", "TTO", "780"}, + {"United Arab Emirates (the)", "Émirats arabes unis (les)", "AE", "ARE", "784"}, + {"Tunisia", "Tunisie (la)", "TN", "TUN", "788"}, + {"Turkey", "Turquie (la)", "TR", "TUR", "792"}, + {"Turkmenistan", "Turkménistan (le)", "TM", "TKM", "795"}, + {"Turks and Caicos Islands (the)", "Turks-et-Caïcos (les Îles)", "TC", "TCA", "796"}, + {"Tuvalu", "Tuvalu (les)", "TV", "TUV", "798"}, + {"Uganda", "Ouganda (l')", "UG", "UGA", "800"}, + {"Ukraine", "Ukraine (l')", "UA", "UKR", "804"}, + {"Macedonia (the former Yugoslav Republic of)", "Macédoine (l'ex‑République yougoslave de)", "MK", "MKD", "807"}, + {"Egypt", "Égypte (l')", "EG", "EGY", "818"}, + {"United Kingdom of Great Britain and Northern Ireland (the)", "Royaume-Uni de Grande-Bretagne et d'Irlande du Nord (le)", "GB", "GBR", "826"}, + {"Guernsey", "Guernesey", "GG", "GGY", "831"}, + {"Jersey", "Jersey", "JE", "JEY", "832"}, + {"Isle of Man", "Île de Man", "IM", "IMN", "833"}, + {"Tanzania, United Republic of", "Tanzanie, République-Unie de", "TZ", "TZA", "834"}, + {"United States of America (the)", "États-Unis d'Amérique (les)", "US", "USA", "840"}, + {"Virgin Islands (U.S.)", "Vierges des États-Unis (les Îles)", "VI", "VIR", "850"}, + {"Burkina Faso", "Burkina Faso (le)", "BF", "BFA", "854"}, + {"Uruguay", "Uruguay (l')", "UY", "URY", "858"}, + {"Uzbekistan", "Ouzbékistan (l')", "UZ", "UZB", "860"}, + {"Venezuela (Bolivarian Republic of)", "Venezuela (République bolivarienne du)", "VE", "VEN", "862"}, + {"Wallis and Futuna", "Wallis-et-Futuna", "WF", "WLF", "876"}, + {"Samoa", "Samoa (le)", "WS", "WSM", "882"}, + {"Yemen", "Yémen (le)", "YE", "YEM", "887"}, + {"Zambia", "Zambie (la)", "ZM", "ZMB", "894"}, +} + +// ISO4217List is the list of ISO currency codes +var ISO4217List = []string{ + "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", + "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYN", "BZD", + "CAD", "CDF", "CHE", "CHF", "CHW", "CLF", "CLP", "CNY", "COP", "COU", "CRC", "CUC", "CUP", "CVE", "CZK", + "DJF", "DKK", "DOP", "DZD", + "EGP", "ERN", "ETB", "EUR", + "FJD", "FKP", + "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", + "HKD", "HNL", "HRK", "HTG", "HUF", + "IDR", "ILS", "INR", "IQD", "IRR", "ISK", + "JMD", "JOD", "JPY", + "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", + "LAK", "LBP", "LKR", "LRD", "LSL", "LYD", + "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MXV", "MYR", "MZN", + "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", + "OMR", + "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", + "QAR", + "RON", "RSD", "RUB", "RWF", + "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "SVC", "SYP", "SZL", + "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", + "UAH", "UGX", "USD", "USN", "UYI", "UYU", "UZS", + "VEF", "VND", "VUV", + "WST", + "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX", + "YER", + "ZAR", "ZMW", "ZWL", +} + +// ISO693Entry stores ISO language codes +type ISO693Entry struct { + Alpha3bCode string + Alpha2Code string + English string +} + +//ISO693List based on http://data.okfn.org/data/core/language-codes/r/language-codes-3b2.json +var ISO693List = []ISO693Entry{ + {Alpha3bCode: "aar", Alpha2Code: "aa", English: "Afar"}, + {Alpha3bCode: "abk", Alpha2Code: "ab", English: "Abkhazian"}, + {Alpha3bCode: "afr", Alpha2Code: "af", English: "Afrikaans"}, + {Alpha3bCode: "aka", Alpha2Code: "ak", English: "Akan"}, + {Alpha3bCode: "alb", Alpha2Code: "sq", English: "Albanian"}, + {Alpha3bCode: "amh", Alpha2Code: "am", English: "Amharic"}, + {Alpha3bCode: "ara", Alpha2Code: "ar", English: "Arabic"}, + {Alpha3bCode: "arg", Alpha2Code: "an", English: "Aragonese"}, + {Alpha3bCode: "arm", Alpha2Code: "hy", English: "Armenian"}, + {Alpha3bCode: "asm", Alpha2Code: "as", English: "Assamese"}, + {Alpha3bCode: "ava", Alpha2Code: "av", English: "Avaric"}, + {Alpha3bCode: "ave", Alpha2Code: "ae", English: "Avestan"}, + {Alpha3bCode: "aym", Alpha2Code: "ay", English: "Aymara"}, + {Alpha3bCode: "aze", Alpha2Code: "az", English: "Azerbaijani"}, + {Alpha3bCode: "bak", Alpha2Code: "ba", English: "Bashkir"}, + {Alpha3bCode: "bam", Alpha2Code: "bm", English: "Bambara"}, + {Alpha3bCode: "baq", Alpha2Code: "eu", English: "Basque"}, + {Alpha3bCode: "bel", Alpha2Code: "be", English: "Belarusian"}, + {Alpha3bCode: "ben", Alpha2Code: "bn", English: "Bengali"}, + {Alpha3bCode: "bih", Alpha2Code: "bh", English: "Bihari languages"}, + {Alpha3bCode: "bis", Alpha2Code: "bi", English: "Bislama"}, + {Alpha3bCode: "bos", Alpha2Code: "bs", English: "Bosnian"}, + {Alpha3bCode: "bre", Alpha2Code: "br", English: "Breton"}, + {Alpha3bCode: "bul", Alpha2Code: "bg", English: "Bulgarian"}, + {Alpha3bCode: "bur", Alpha2Code: "my", English: "Burmese"}, + {Alpha3bCode: "cat", Alpha2Code: "ca", English: "Catalan; Valencian"}, + {Alpha3bCode: "cha", Alpha2Code: "ch", English: "Chamorro"}, + {Alpha3bCode: "che", Alpha2Code: "ce", English: "Chechen"}, + {Alpha3bCode: "chi", Alpha2Code: "zh", English: "Chinese"}, + {Alpha3bCode: "chu", Alpha2Code: "cu", English: "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic"}, + {Alpha3bCode: "chv", Alpha2Code: "cv", English: "Chuvash"}, + {Alpha3bCode: "cor", Alpha2Code: "kw", English: "Cornish"}, + {Alpha3bCode: "cos", Alpha2Code: "co", English: "Corsican"}, + {Alpha3bCode: "cre", Alpha2Code: "cr", English: "Cree"}, + {Alpha3bCode: "cze", Alpha2Code: "cs", English: "Czech"}, + {Alpha3bCode: "dan", Alpha2Code: "da", English: "Danish"}, + {Alpha3bCode: "div", Alpha2Code: "dv", English: "Divehi; Dhivehi; Maldivian"}, + {Alpha3bCode: "dut", Alpha2Code: "nl", English: "Dutch; Flemish"}, + {Alpha3bCode: "dzo", Alpha2Code: "dz", English: "Dzongkha"}, + {Alpha3bCode: "eng", Alpha2Code: "en", English: "English"}, + {Alpha3bCode: "epo", Alpha2Code: "eo", English: "Esperanto"}, + {Alpha3bCode: "est", Alpha2Code: "et", English: "Estonian"}, + {Alpha3bCode: "ewe", Alpha2Code: "ee", English: "Ewe"}, + {Alpha3bCode: "fao", Alpha2Code: "fo", English: "Faroese"}, + {Alpha3bCode: "fij", Alpha2Code: "fj", English: "Fijian"}, + {Alpha3bCode: "fin", Alpha2Code: "fi", English: "Finnish"}, + {Alpha3bCode: "fre", Alpha2Code: "fr", English: "French"}, + {Alpha3bCode: "fry", Alpha2Code: "fy", English: "Western Frisian"}, + {Alpha3bCode: "ful", Alpha2Code: "ff", English: "Fulah"}, + {Alpha3bCode: "geo", Alpha2Code: "ka", English: "Georgian"}, + {Alpha3bCode: "ger", Alpha2Code: "de", English: "German"}, + {Alpha3bCode: "gla", Alpha2Code: "gd", English: "Gaelic; Scottish Gaelic"}, + {Alpha3bCode: "gle", Alpha2Code: "ga", English: "Irish"}, + {Alpha3bCode: "glg", Alpha2Code: "gl", English: "Galician"}, + {Alpha3bCode: "glv", Alpha2Code: "gv", English: "Manx"}, + {Alpha3bCode: "gre", Alpha2Code: "el", English: "Greek, Modern (1453-)"}, + {Alpha3bCode: "grn", Alpha2Code: "gn", English: "Guarani"}, + {Alpha3bCode: "guj", Alpha2Code: "gu", English: "Gujarati"}, + {Alpha3bCode: "hat", Alpha2Code: "ht", English: "Haitian; Haitian Creole"}, + {Alpha3bCode: "hau", Alpha2Code: "ha", English: "Hausa"}, + {Alpha3bCode: "heb", Alpha2Code: "he", English: "Hebrew"}, + {Alpha3bCode: "her", Alpha2Code: "hz", English: "Herero"}, + {Alpha3bCode: "hin", Alpha2Code: "hi", English: "Hindi"}, + {Alpha3bCode: "hmo", Alpha2Code: "ho", English: "Hiri Motu"}, + {Alpha3bCode: "hrv", Alpha2Code: "hr", English: "Croatian"}, + {Alpha3bCode: "hun", Alpha2Code: "hu", English: "Hungarian"}, + {Alpha3bCode: "ibo", Alpha2Code: "ig", English: "Igbo"}, + {Alpha3bCode: "ice", Alpha2Code: "is", English: "Icelandic"}, + {Alpha3bCode: "ido", Alpha2Code: "io", English: "Ido"}, + {Alpha3bCode: "iii", Alpha2Code: "ii", English: "Sichuan Yi; Nuosu"}, + {Alpha3bCode: "iku", Alpha2Code: "iu", English: "Inuktitut"}, + {Alpha3bCode: "ile", Alpha2Code: "ie", English: "Interlingue; Occidental"}, + {Alpha3bCode: "ina", Alpha2Code: "ia", English: "Interlingua (International Auxiliary Language Association)"}, + {Alpha3bCode: "ind", Alpha2Code: "id", English: "Indonesian"}, + {Alpha3bCode: "ipk", Alpha2Code: "ik", English: "Inupiaq"}, + {Alpha3bCode: "ita", Alpha2Code: "it", English: "Italian"}, + {Alpha3bCode: "jav", Alpha2Code: "jv", English: "Javanese"}, + {Alpha3bCode: "jpn", Alpha2Code: "ja", English: "Japanese"}, + {Alpha3bCode: "kal", Alpha2Code: "kl", English: "Kalaallisut; Greenlandic"}, + {Alpha3bCode: "kan", Alpha2Code: "kn", English: "Kannada"}, + {Alpha3bCode: "kas", Alpha2Code: "ks", English: "Kashmiri"}, + {Alpha3bCode: "kau", Alpha2Code: "kr", English: "Kanuri"}, + {Alpha3bCode: "kaz", Alpha2Code: "kk", English: "Kazakh"}, + {Alpha3bCode: "khm", Alpha2Code: "km", English: "Central Khmer"}, + {Alpha3bCode: "kik", Alpha2Code: "ki", English: "Kikuyu; Gikuyu"}, + {Alpha3bCode: "kin", Alpha2Code: "rw", English: "Kinyarwanda"}, + {Alpha3bCode: "kir", Alpha2Code: "ky", English: "Kirghiz; Kyrgyz"}, + {Alpha3bCode: "kom", Alpha2Code: "kv", English: "Komi"}, + {Alpha3bCode: "kon", Alpha2Code: "kg", English: "Kongo"}, + {Alpha3bCode: "kor", Alpha2Code: "ko", English: "Korean"}, + {Alpha3bCode: "kua", Alpha2Code: "kj", English: "Kuanyama; Kwanyama"}, + {Alpha3bCode: "kur", Alpha2Code: "ku", English: "Kurdish"}, + {Alpha3bCode: "lao", Alpha2Code: "lo", English: "Lao"}, + {Alpha3bCode: "lat", Alpha2Code: "la", English: "Latin"}, + {Alpha3bCode: "lav", Alpha2Code: "lv", English: "Latvian"}, + {Alpha3bCode: "lim", Alpha2Code: "li", English: "Limburgan; Limburger; Limburgish"}, + {Alpha3bCode: "lin", Alpha2Code: "ln", English: "Lingala"}, + {Alpha3bCode: "lit", Alpha2Code: "lt", English: "Lithuanian"}, + {Alpha3bCode: "ltz", Alpha2Code: "lb", English: "Luxembourgish; Letzeburgesch"}, + {Alpha3bCode: "lub", Alpha2Code: "lu", English: "Luba-Katanga"}, + {Alpha3bCode: "lug", Alpha2Code: "lg", English: "Ganda"}, + {Alpha3bCode: "mac", Alpha2Code: "mk", English: "Macedonian"}, + {Alpha3bCode: "mah", Alpha2Code: "mh", English: "Marshallese"}, + {Alpha3bCode: "mal", Alpha2Code: "ml", English: "Malayalam"}, + {Alpha3bCode: "mao", Alpha2Code: "mi", English: "Maori"}, + {Alpha3bCode: "mar", Alpha2Code: "mr", English: "Marathi"}, + {Alpha3bCode: "may", Alpha2Code: "ms", English: "Malay"}, + {Alpha3bCode: "mlg", Alpha2Code: "mg", English: "Malagasy"}, + {Alpha3bCode: "mlt", Alpha2Code: "mt", English: "Maltese"}, + {Alpha3bCode: "mon", Alpha2Code: "mn", English: "Mongolian"}, + {Alpha3bCode: "nau", Alpha2Code: "na", English: "Nauru"}, + {Alpha3bCode: "nav", Alpha2Code: "nv", English: "Navajo; Navaho"}, + {Alpha3bCode: "nbl", Alpha2Code: "nr", English: "Ndebele, South; South Ndebele"}, + {Alpha3bCode: "nde", Alpha2Code: "nd", English: "Ndebele, North; North Ndebele"}, + {Alpha3bCode: "ndo", Alpha2Code: "ng", English: "Ndonga"}, + {Alpha3bCode: "nep", Alpha2Code: "ne", English: "Nepali"}, + {Alpha3bCode: "nno", Alpha2Code: "nn", English: "Norwegian Nynorsk; Nynorsk, Norwegian"}, + {Alpha3bCode: "nob", Alpha2Code: "nb", English: "Bokmål, Norwegian; Norwegian Bokmål"}, + {Alpha3bCode: "nor", Alpha2Code: "no", English: "Norwegian"}, + {Alpha3bCode: "nya", Alpha2Code: "ny", English: "Chichewa; Chewa; Nyanja"}, + {Alpha3bCode: "oci", Alpha2Code: "oc", English: "Occitan (post 1500); Provençal"}, + {Alpha3bCode: "oji", Alpha2Code: "oj", English: "Ojibwa"}, + {Alpha3bCode: "ori", Alpha2Code: "or", English: "Oriya"}, + {Alpha3bCode: "orm", Alpha2Code: "om", English: "Oromo"}, + {Alpha3bCode: "oss", Alpha2Code: "os", English: "Ossetian; Ossetic"}, + {Alpha3bCode: "pan", Alpha2Code: "pa", English: "Panjabi; Punjabi"}, + {Alpha3bCode: "per", Alpha2Code: "fa", English: "Persian"}, + {Alpha3bCode: "pli", Alpha2Code: "pi", English: "Pali"}, + {Alpha3bCode: "pol", Alpha2Code: "pl", English: "Polish"}, + {Alpha3bCode: "por", Alpha2Code: "pt", English: "Portuguese"}, + {Alpha3bCode: "pus", Alpha2Code: "ps", English: "Pushto; Pashto"}, + {Alpha3bCode: "que", Alpha2Code: "qu", English: "Quechua"}, + {Alpha3bCode: "roh", Alpha2Code: "rm", English: "Romansh"}, + {Alpha3bCode: "rum", Alpha2Code: "ro", English: "Romanian; Moldavian; Moldovan"}, + {Alpha3bCode: "run", Alpha2Code: "rn", English: "Rundi"}, + {Alpha3bCode: "rus", Alpha2Code: "ru", English: "Russian"}, + {Alpha3bCode: "sag", Alpha2Code: "sg", English: "Sango"}, + {Alpha3bCode: "san", Alpha2Code: "sa", English: "Sanskrit"}, + {Alpha3bCode: "sin", Alpha2Code: "si", English: "Sinhala; Sinhalese"}, + {Alpha3bCode: "slo", Alpha2Code: "sk", English: "Slovak"}, + {Alpha3bCode: "slv", Alpha2Code: "sl", English: "Slovenian"}, + {Alpha3bCode: "sme", Alpha2Code: "se", English: "Northern Sami"}, + {Alpha3bCode: "smo", Alpha2Code: "sm", English: "Samoan"}, + {Alpha3bCode: "sna", Alpha2Code: "sn", English: "Shona"}, + {Alpha3bCode: "snd", Alpha2Code: "sd", English: "Sindhi"}, + {Alpha3bCode: "som", Alpha2Code: "so", English: "Somali"}, + {Alpha3bCode: "sot", Alpha2Code: "st", English: "Sotho, Southern"}, + {Alpha3bCode: "spa", Alpha2Code: "es", English: "Spanish; Castilian"}, + {Alpha3bCode: "srd", Alpha2Code: "sc", English: "Sardinian"}, + {Alpha3bCode: "srp", Alpha2Code: "sr", English: "Serbian"}, + {Alpha3bCode: "ssw", Alpha2Code: "ss", English: "Swati"}, + {Alpha3bCode: "sun", Alpha2Code: "su", English: "Sundanese"}, + {Alpha3bCode: "swa", Alpha2Code: "sw", English: "Swahili"}, + {Alpha3bCode: "swe", Alpha2Code: "sv", English: "Swedish"}, + {Alpha3bCode: "tah", Alpha2Code: "ty", English: "Tahitian"}, + {Alpha3bCode: "tam", Alpha2Code: "ta", English: "Tamil"}, + {Alpha3bCode: "tat", Alpha2Code: "tt", English: "Tatar"}, + {Alpha3bCode: "tel", Alpha2Code: "te", English: "Telugu"}, + {Alpha3bCode: "tgk", Alpha2Code: "tg", English: "Tajik"}, + {Alpha3bCode: "tgl", Alpha2Code: "tl", English: "Tagalog"}, + {Alpha3bCode: "tha", Alpha2Code: "th", English: "Thai"}, + {Alpha3bCode: "tib", Alpha2Code: "bo", English: "Tibetan"}, + {Alpha3bCode: "tir", Alpha2Code: "ti", English: "Tigrinya"}, + {Alpha3bCode: "ton", Alpha2Code: "to", English: "Tonga (Tonga Islands)"}, + {Alpha3bCode: "tsn", Alpha2Code: "tn", English: "Tswana"}, + {Alpha3bCode: "tso", Alpha2Code: "ts", English: "Tsonga"}, + {Alpha3bCode: "tuk", Alpha2Code: "tk", English: "Turkmen"}, + {Alpha3bCode: "tur", Alpha2Code: "tr", English: "Turkish"}, + {Alpha3bCode: "twi", Alpha2Code: "tw", English: "Twi"}, + {Alpha3bCode: "uig", Alpha2Code: "ug", English: "Uighur; Uyghur"}, + {Alpha3bCode: "ukr", Alpha2Code: "uk", English: "Ukrainian"}, + {Alpha3bCode: "urd", Alpha2Code: "ur", English: "Urdu"}, + {Alpha3bCode: "uzb", Alpha2Code: "uz", English: "Uzbek"}, + {Alpha3bCode: "ven", Alpha2Code: "ve", English: "Venda"}, + {Alpha3bCode: "vie", Alpha2Code: "vi", English: "Vietnamese"}, + {Alpha3bCode: "vol", Alpha2Code: "vo", English: "Volapük"}, + {Alpha3bCode: "wel", Alpha2Code: "cy", English: "Welsh"}, + {Alpha3bCode: "wln", Alpha2Code: "wa", English: "Walloon"}, + {Alpha3bCode: "wol", Alpha2Code: "wo", English: "Wolof"}, + {Alpha3bCode: "xho", Alpha2Code: "xh", English: "Xhosa"}, + {Alpha3bCode: "yid", Alpha2Code: "yi", English: "Yiddish"}, + {Alpha3bCode: "yor", Alpha2Code: "yo", English: "Yoruba"}, + {Alpha3bCode: "zha", Alpha2Code: "za", English: "Zhuang; Chuang"}, + {Alpha3bCode: "zul", Alpha2Code: "zu", English: "Zulu"}, +} diff --git a/vendor/github.com/asaskevich/govalidator/utils.go b/vendor/github.com/asaskevich/govalidator/utils.go new file mode 100644 index 000000000..a0b706a74 --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/utils.go @@ -0,0 +1,270 @@ +package govalidator + +import ( + "errors" + "fmt" + "html" + "math" + "path" + "regexp" + "strings" + "unicode" + "unicode/utf8" +) + +// Contains check if the string contains the substring. +func Contains(str, substring string) bool { + return strings.Contains(str, substring) +} + +// Matches check if string matches the pattern (pattern is regular expression) +// In case of error return false +func Matches(str, pattern string) bool { + match, _ := regexp.MatchString(pattern, str) + return match +} + +// LeftTrim trim characters from the left-side of the input. +// If second argument is empty, it's will be remove leading spaces. +func LeftTrim(str, chars string) string { + if chars == "" { + return strings.TrimLeftFunc(str, unicode.IsSpace) + } + r, _ := regexp.Compile("^[" + chars + "]+") + return r.ReplaceAllString(str, "") +} + +// RightTrim trim characters from the right-side of the input. +// If second argument is empty, it's will be remove spaces. +func RightTrim(str, chars string) string { + if chars == "" { + return strings.TrimRightFunc(str, unicode.IsSpace) + } + r, _ := regexp.Compile("[" + chars + "]+$") + return r.ReplaceAllString(str, "") +} + +// Trim trim characters from both sides of the input. +// If second argument is empty, it's will be remove spaces. +func Trim(str, chars string) string { + return LeftTrim(RightTrim(str, chars), chars) +} + +// WhiteList remove characters that do not appear in the whitelist. +func WhiteList(str, chars string) string { + pattern := "[^" + chars + "]+" + r, _ := regexp.Compile(pattern) + return r.ReplaceAllString(str, "") +} + +// BlackList remove characters that appear in the blacklist. +func BlackList(str, chars string) string { + pattern := "[" + chars + "]+" + r, _ := regexp.Compile(pattern) + return r.ReplaceAllString(str, "") +} + +// StripLow remove characters with a numerical value < 32 and 127, mostly control characters. +// If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD). +func StripLow(str string, keepNewLines bool) string { + chars := "" + if keepNewLines { + chars = "\x00-\x09\x0B\x0C\x0E-\x1F\x7F" + } else { + chars = "\x00-\x1F\x7F" + } + return BlackList(str, chars) +} + +// ReplacePattern replace regular expression pattern in string +func ReplacePattern(str, pattern, replace string) string { + r, _ := regexp.Compile(pattern) + return r.ReplaceAllString(str, replace) +} + +// Escape replace <, >, & and " with HTML entities. +var Escape = html.EscapeString + +func addSegment(inrune, segment []rune) []rune { + if len(segment) == 0 { + return inrune + } + if len(inrune) != 0 { + inrune = append(inrune, '_') + } + inrune = append(inrune, segment...) + return inrune +} + +// UnderscoreToCamelCase converts from underscore separated form to camel case form. +// Ex.: my_func => MyFunc +func UnderscoreToCamelCase(s string) string { + return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1) +} + +// CamelCaseToUnderscore converts from camel case form to underscore separated form. +// Ex.: MyFunc => my_func +func CamelCaseToUnderscore(str string) string { + var output []rune + var segment []rune + for _, r := range str { + + // not treat number as separate segment + if !unicode.IsLower(r) && string(r) != "_" && !unicode.IsNumber(r) { + output = addSegment(output, segment) + segment = nil + } + segment = append(segment, unicode.ToLower(r)) + } + output = addSegment(output, segment) + return string(output) +} + +// Reverse return reversed string +func Reverse(s string) string { + r := []rune(s) + for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 { + r[i], r[j] = r[j], r[i] + } + return string(r) +} + +// GetLines split string by "\n" and return array of lines +func GetLines(s string) []string { + return strings.Split(s, "\n") +} + +// GetLine return specified line of multiline string +func GetLine(s string, index int) (string, error) { + lines := GetLines(s) + if index < 0 || index >= len(lines) { + return "", errors.New("line index out of bounds") + } + return lines[index], nil +} + +// RemoveTags remove all tags from HTML string +func RemoveTags(s string) string { + return ReplacePattern(s, "<[^>]*>", "") +} + +// SafeFileName return safe string that can be used in file names +func SafeFileName(str string) string { + name := strings.ToLower(str) + name = path.Clean(path.Base(name)) + name = strings.Trim(name, " ") + separators, err := regexp.Compile(`[ &_=+:]`) + if err == nil { + name = separators.ReplaceAllString(name, "-") + } + legal, err := regexp.Compile(`[^[:alnum:]-.]`) + if err == nil { + name = legal.ReplaceAllString(name, "") + } + for strings.Contains(name, "--") { + name = strings.Replace(name, "--", "-", -1) + } + return name +} + +// NormalizeEmail canonicalize an email address. +// The local part of the email address is lowercased for all domains; the hostname is always lowercased and +// the local part of the email address is always lowercased for hosts that are known to be case-insensitive (currently only GMail). +// Normalization follows special rules for known providers: currently, GMail addresses have dots removed in the local part and +// are stripped of tags (e.g. some.one+tag@gmail.com becomes someone@gmail.com) and all @googlemail.com addresses are +// normalized to @gmail.com. +func NormalizeEmail(str string) (string, error) { + if !IsEmail(str) { + return "", fmt.Errorf("%s is not an email", str) + } + parts := strings.Split(str, "@") + parts[0] = strings.ToLower(parts[0]) + parts[1] = strings.ToLower(parts[1]) + if parts[1] == "gmail.com" || parts[1] == "googlemail.com" { + parts[1] = "gmail.com" + parts[0] = strings.Split(ReplacePattern(parts[0], `\.`, ""), "+")[0] + } + return strings.Join(parts, "@"), nil +} + +// Truncate a string to the closest length without breaking words. +func Truncate(str string, length int, ending string) string { + var aftstr, befstr string + if len(str) > length { + words := strings.Fields(str) + before, present := 0, 0 + for i := range words { + befstr = aftstr + before = present + aftstr = aftstr + words[i] + " " + present = len(aftstr) + if present > length && i != 0 { + if (length - before) < (present - length) { + return Trim(befstr, " /\\.,\"'#!?&@+-") + ending + } + return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending + } + } + } + + return str +} + +// PadLeft pad left side of string if size of string is less then indicated pad length +func PadLeft(str string, padStr string, padLen int) string { + return buildPadStr(str, padStr, padLen, true, false) +} + +// PadRight pad right side of string if size of string is less then indicated pad length +func PadRight(str string, padStr string, padLen int) string { + return buildPadStr(str, padStr, padLen, false, true) +} + +// PadBoth pad sides of string if size of string is less then indicated pad length +func PadBoth(str string, padStr string, padLen int) string { + return buildPadStr(str, padStr, padLen, true, true) +} + +// PadString either left, right or both sides, not the padding string can be unicode and more then one +// character +func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string { + + // When padded length is less then the current string size + if padLen < utf8.RuneCountInString(str) { + return str + } + + padLen -= utf8.RuneCountInString(str) + + targetLen := padLen + + targetLenLeft := targetLen + targetLenRight := targetLen + if padLeft && padRight { + targetLenLeft = padLen / 2 + targetLenRight = padLen - targetLenLeft + } + + strToRepeatLen := utf8.RuneCountInString(padStr) + + repeatTimes := int(math.Ceil(float64(targetLen) / float64(strToRepeatLen))) + repeatedString := strings.Repeat(padStr, repeatTimes) + + leftSide := "" + if padLeft { + leftSide = repeatedString[0:targetLenLeft] + } + + rightSide := "" + if padRight { + rightSide = repeatedString[0:targetLenRight] + } + + return leftSide + str + rightSide +} + +// TruncatingErrorf removes extra args from fmt.Errorf if not formatted in the str object +func TruncatingErrorf(str string, args ...interface{}) error { + n := strings.Count(str, "%s") + return fmt.Errorf(str, args[:n]...) +} diff --git a/vendor/github.com/asaskevich/govalidator/validator.go b/vendor/github.com/asaskevich/govalidator/validator.go new file mode 100644 index 000000000..b18bbcb4c --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/validator.go @@ -0,0 +1,1278 @@ +// Package govalidator is package of validators and sanitizers for strings, structs and collections. +package govalidator + +import ( + "bytes" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "fmt" + "io/ioutil" + "net" + "net/url" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "time" + "unicode" + "unicode/utf8" +) + +var ( + fieldsRequiredByDefault bool + nilPtrAllowedByRequired = false + notNumberRegexp = regexp.MustCompile("[^0-9]+") + whiteSpacesAndMinus = regexp.MustCompile(`[\s-]+`) + paramsRegexp = regexp.MustCompile(`\(.*\)$`) +) + +const maxURLRuneCount = 2083 +const minURLRuneCount = 3 +const RF3339WithoutZone = "2006-01-02T15:04:05" + +// SetFieldsRequiredByDefault causes validation to fail when struct fields +// do not include validations or are not explicitly marked as exempt (using `valid:"-"` or `valid:"email,optional"`). +// This struct definition will fail govalidator.ValidateStruct() (and the field values do not matter): +// type exampleStruct struct { +// Name string `` +// Email string `valid:"email"` +// This, however, will only fail when Email is empty or an invalid email address: +// type exampleStruct2 struct { +// Name string `valid:"-"` +// Email string `valid:"email"` +// Lastly, this will only fail when Email is an invalid email address but not when it's empty: +// type exampleStruct2 struct { +// Name string `valid:"-"` +// Email string `valid:"email,optional"` +func SetFieldsRequiredByDefault(value bool) { + fieldsRequiredByDefault = value +} + +// SetNilPtrAllowedByRequired causes validation to pass for nil ptrs when a field is set to required. +// The validation will still reject ptr fields in their zero value state. Example with this enabled: +// type exampleStruct struct { +// Name *string `valid:"required"` +// With `Name` set to "", this will be considered invalid input and will cause a validation error. +// With `Name` set to nil, this will be considered valid by validation. +// By default this is disabled. +func SetNilPtrAllowedByRequired(value bool) { + nilPtrAllowedByRequired = value +} + +// IsEmail check if the string is an email. +func IsEmail(str string) bool { + // TODO uppercase letters are not supported + return rxEmail.MatchString(str) +} + +// IsExistingEmail check if the string is an email of existing domain +func IsExistingEmail(email string) bool { + + if len(email) < 6 || len(email) > 254 { + return false + } + at := strings.LastIndex(email, "@") + if at <= 0 || at > len(email)-3 { + return false + } + user := email[:at] + host := email[at+1:] + if len(user) > 64 { + return false + } + if userDotRegexp.MatchString(user) || !userRegexp.MatchString(user) || !hostRegexp.MatchString(host) { + return false + } + switch host { + case "localhost", "example.com": + return true + } + if _, err := net.LookupMX(host); err != nil { + if _, err := net.LookupIP(host); err != nil { + return false + } + } + + return true +} + +// IsURL check if the string is an URL. +func IsURL(str string) bool { + if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") { + return false + } + strTemp := str + if strings.Contains(str, ":") && !strings.Contains(str, "://") { + // support no indicated urlscheme but with colon for port number + // http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString + strTemp = "http://" + str + } + u, err := url.Parse(strTemp) + if err != nil { + return false + } + if strings.HasPrefix(u.Host, ".") { + return false + } + if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) { + return false + } + return rxURL.MatchString(str) +} + +// IsRequestURL check if the string rawurl, assuming +// it was received in an HTTP request, is a valid +// URL confirm to RFC 3986 +func IsRequestURL(rawurl string) bool { + url, err := url.ParseRequestURI(rawurl) + if err != nil { + return false //Couldn't even parse the rawurl + } + if len(url.Scheme) == 0 { + return false //No Scheme found + } + return true +} + +// IsRequestURI check if the string rawurl, assuming +// it was received in an HTTP request, is an +// absolute URI or an absolute path. +func IsRequestURI(rawurl string) bool { + _, err := url.ParseRequestURI(rawurl) + return err == nil +} + +// IsAlpha check if the string contains only letters (a-zA-Z). Empty string is valid. +func IsAlpha(str string) bool { + if IsNull(str) { + return true + } + return rxAlpha.MatchString(str) +} + +//IsUTFLetter check if the string contains only unicode letter characters. +//Similar to IsAlpha but for all languages. Empty string is valid. +func IsUTFLetter(str string) bool { + if IsNull(str) { + return true + } + + for _, c := range str { + if !unicode.IsLetter(c) { + return false + } + } + return true + +} + +// IsAlphanumeric check if the string contains only letters and numbers. Empty string is valid. +func IsAlphanumeric(str string) bool { + if IsNull(str) { + return true + } + return rxAlphanumeric.MatchString(str) +} + +// IsUTFLetterNumeric check if the string contains only unicode letters and numbers. Empty string is valid. +func IsUTFLetterNumeric(str string) bool { + if IsNull(str) { + return true + } + for _, c := range str { + if !unicode.IsLetter(c) && !unicode.IsNumber(c) { //letters && numbers are ok + return false + } + } + return true + +} + +// IsNumeric check if the string contains only numbers. Empty string is valid. +func IsNumeric(str string) bool { + if IsNull(str) { + return true + } + return rxNumeric.MatchString(str) +} + +// IsUTFNumeric check if the string contains only unicode numbers of any kind. +// Numbers can be 0-9 but also Fractions ¾,Roman Ⅸ and Hangzhou 〩. Empty string is valid. +func IsUTFNumeric(str string) bool { + if IsNull(str) { + return true + } + if strings.IndexAny(str, "+-") > 0 { + return false + } + if len(str) > 1 { + str = strings.TrimPrefix(str, "-") + str = strings.TrimPrefix(str, "+") + } + for _, c := range str { + if !unicode.IsNumber(c) { //numbers && minus sign are ok + return false + } + } + return true + +} + +// IsUTFDigit check if the string contains only unicode radix-10 decimal digits. Empty string is valid. +func IsUTFDigit(str string) bool { + if IsNull(str) { + return true + } + if strings.IndexAny(str, "+-") > 0 { + return false + } + if len(str) > 1 { + str = strings.TrimPrefix(str, "-") + str = strings.TrimPrefix(str, "+") + } + for _, c := range str { + if !unicode.IsDigit(c) { //digits && minus sign are ok + return false + } + } + return true + +} + +// IsHexadecimal check if the string is a hexadecimal number. +func IsHexadecimal(str string) bool { + return rxHexadecimal.MatchString(str) +} + +// IsHexcolor check if the string is a hexadecimal color. +func IsHexcolor(str string) bool { + return rxHexcolor.MatchString(str) +} + +// IsRGBcolor check if the string is a valid RGB color in form rgb(RRR, GGG, BBB). +func IsRGBcolor(str string) bool { + return rxRGBcolor.MatchString(str) +} + +// IsLowerCase check if the string is lowercase. Empty string is valid. +func IsLowerCase(str string) bool { + if IsNull(str) { + return true + } + return str == strings.ToLower(str) +} + +// IsUpperCase check if the string is uppercase. Empty string is valid. +func IsUpperCase(str string) bool { + if IsNull(str) { + return true + } + return str == strings.ToUpper(str) +} + +// HasLowerCase check if the string contains at least 1 lowercase. Empty string is valid. +func HasLowerCase(str string) bool { + if IsNull(str) { + return true + } + return rxHasLowerCase.MatchString(str) +} + +// HasUpperCase check if the string contians as least 1 uppercase. Empty string is valid. +func HasUpperCase(str string) bool { + if IsNull(str) { + return true + } + return rxHasUpperCase.MatchString(str) +} + +// IsInt check if the string is an integer. Empty string is valid. +func IsInt(str string) bool { + if IsNull(str) { + return true + } + return rxInt.MatchString(str) +} + +// IsFloat check if the string is a float. +func IsFloat(str string) bool { + return str != "" && rxFloat.MatchString(str) +} + +// IsDivisibleBy check if the string is a number that's divisible by another. +// If second argument is not valid integer or zero, it's return false. +// Otherwise, if first argument is not valid integer or zero, it's return true (Invalid string converts to zero). +func IsDivisibleBy(str, num string) bool { + f, _ := ToFloat(str) + p := int64(f) + q, _ := ToInt(num) + if q == 0 { + return false + } + return (p == 0) || (p%q == 0) +} + +// IsNull check if the string is null. +func IsNull(str string) bool { + return len(str) == 0 +} + +// HasWhitespaceOnly checks the string only contains whitespace +func HasWhitespaceOnly(str string) bool { + return len(str) > 0 && rxHasWhitespaceOnly.MatchString(str) +} + +// HasWhitespace checks if the string contains any whitespace +func HasWhitespace(str string) bool { + return len(str) > 0 && rxHasWhitespace.MatchString(str) +} + +// IsByteLength check if the string's length (in bytes) falls in a range. +func IsByteLength(str string, min, max int) bool { + return len(str) >= min && len(str) <= max +} + +// IsUUIDv3 check if the string is a UUID version 3. +func IsUUIDv3(str string) bool { + return rxUUID3.MatchString(str) +} + +// IsUUIDv4 check if the string is a UUID version 4. +func IsUUIDv4(str string) bool { + return rxUUID4.MatchString(str) +} + +// IsUUIDv5 check if the string is a UUID version 5. +func IsUUIDv5(str string) bool { + return rxUUID5.MatchString(str) +} + +// IsUUID check if the string is a UUID (version 3, 4 or 5). +func IsUUID(str string) bool { + return rxUUID.MatchString(str) +} + +// IsCreditCard check if the string is a credit card. +func IsCreditCard(str string) bool { + sanitized := notNumberRegexp.ReplaceAllString(str, "") + if !rxCreditCard.MatchString(sanitized) { + return false + } + var sum int64 + var digit string + var tmpNum int64 + var shouldDouble bool + for i := len(sanitized) - 1; i >= 0; i-- { + digit = sanitized[i:(i + 1)] + tmpNum, _ = ToInt(digit) + if shouldDouble { + tmpNum *= 2 + if tmpNum >= 10 { + sum += ((tmpNum % 10) + 1) + } else { + sum += tmpNum + } + } else { + sum += tmpNum + } + shouldDouble = !shouldDouble + } + + return sum%10 == 0 +} + +// IsISBN10 check if the string is an ISBN version 10. +func IsISBN10(str string) bool { + return IsISBN(str, 10) +} + +// IsISBN13 check if the string is an ISBN version 13. +func IsISBN13(str string) bool { + return IsISBN(str, 13) +} + +// IsISBN check if the string is an ISBN (version 10 or 13). +// If version value is not equal to 10 or 13, it will be check both variants. +func IsISBN(str string, version int) bool { + sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "") + var checksum int32 + var i int32 + if version == 10 { + if !rxISBN10.MatchString(sanitized) { + return false + } + for i = 0; i < 9; i++ { + checksum += (i + 1) * int32(sanitized[i]-'0') + } + if sanitized[9] == 'X' { + checksum += 10 * 10 + } else { + checksum += 10 * int32(sanitized[9]-'0') + } + if checksum%11 == 0 { + return true + } + return false + } else if version == 13 { + if !rxISBN13.MatchString(sanitized) { + return false + } + factor := []int32{1, 3} + for i = 0; i < 12; i++ { + checksum += factor[i%2] * int32(sanitized[i]-'0') + } + return (int32(sanitized[12]-'0'))-((10-(checksum%10))%10) == 0 + } + return IsISBN(str, 10) || IsISBN(str, 13) +} + +// IsJSON check if the string is valid JSON (note: uses json.Unmarshal). +func IsJSON(str string) bool { + var js json.RawMessage + return json.Unmarshal([]byte(str), &js) == nil +} + +// IsMultibyte check if the string contains one or more multibyte chars. Empty string is valid. +func IsMultibyte(str string) bool { + if IsNull(str) { + return true + } + return rxMultibyte.MatchString(str) +} + +// IsASCII check if the string contains ASCII chars only. Empty string is valid. +func IsASCII(str string) bool { + if IsNull(str) { + return true + } + return rxASCII.MatchString(str) +} + +// IsPrintableASCII check if the string contains printable ASCII chars only. Empty string is valid. +func IsPrintableASCII(str string) bool { + if IsNull(str) { + return true + } + return rxPrintableASCII.MatchString(str) +} + +// IsFullWidth check if the string contains any full-width chars. Empty string is valid. +func IsFullWidth(str string) bool { + if IsNull(str) { + return true + } + return rxFullWidth.MatchString(str) +} + +// IsHalfWidth check if the string contains any half-width chars. Empty string is valid. +func IsHalfWidth(str string) bool { + if IsNull(str) { + return true + } + return rxHalfWidth.MatchString(str) +} + +// IsVariableWidth check if the string contains a mixture of full and half-width chars. Empty string is valid. +func IsVariableWidth(str string) bool { + if IsNull(str) { + return true + } + return rxHalfWidth.MatchString(str) && rxFullWidth.MatchString(str) +} + +// IsBase64 check if a string is base64 encoded. +func IsBase64(str string) bool { + return rxBase64.MatchString(str) +} + +// IsFilePath check is a string is Win or Unix file path and returns it's type. +func IsFilePath(str string) (bool, int) { + if rxWinPath.MatchString(str) { + //check windows path limit see: + // http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath + if len(str[3:]) > 32767 { + return false, Win + } + return true, Win + } else if rxUnixPath.MatchString(str) { + return true, Unix + } + return false, Unknown +} + +// IsDataURI checks if a string is base64 encoded data URI such as an image +func IsDataURI(str string) bool { + dataURI := strings.Split(str, ",") + if !rxDataURI.MatchString(dataURI[0]) { + return false + } + return IsBase64(dataURI[1]) +} + +// IsISO3166Alpha2 checks if a string is valid two-letter country code +func IsISO3166Alpha2(str string) bool { + for _, entry := range ISO3166List { + if str == entry.Alpha2Code { + return true + } + } + return false +} + +// IsISO3166Alpha3 checks if a string is valid three-letter country code +func IsISO3166Alpha3(str string) bool { + for _, entry := range ISO3166List { + if str == entry.Alpha3Code { + return true + } + } + return false +} + +// IsISO693Alpha2 checks if a string is valid two-letter language code +func IsISO693Alpha2(str string) bool { + for _, entry := range ISO693List { + if str == entry.Alpha2Code { + return true + } + } + return false +} + +// IsISO693Alpha3b checks if a string is valid three-letter language code +func IsISO693Alpha3b(str string) bool { + for _, entry := range ISO693List { + if str == entry.Alpha3bCode { + return true + } + } + return false +} + +// IsDNSName will validate the given string as a DNS name +func IsDNSName(str string) bool { + if str == "" || len(strings.Replace(str, ".", "", -1)) > 255 { + // constraints already violated + return false + } + return !IsIP(str) && rxDNSName.MatchString(str) +} + +// IsHash checks if a string is a hash of type algorithm. +// Algorithm is one of ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b'] +func IsHash(str string, algorithm string) bool { + len := "0" + algo := strings.ToLower(algorithm) + + if algo == "crc32" || algo == "crc32b" { + len = "8" + } else if algo == "md5" || algo == "md4" || algo == "ripemd128" || algo == "tiger128" { + len = "32" + } else if algo == "sha1" || algo == "ripemd160" || algo == "tiger160" { + len = "40" + } else if algo == "tiger192" { + len = "48" + } else if algo == "sha256" { + len = "64" + } else if algo == "sha384" { + len = "96" + } else if algo == "sha512" { + len = "128" + } else { + return false + } + + return Matches(str, "^[a-f0-9]{"+len+"}$") +} + +// IsDialString validates the given string for usage with the various Dial() functions +func IsDialString(str string) bool { + + if h, p, err := net.SplitHostPort(str); err == nil && h != "" && p != "" && (IsDNSName(h) || IsIP(h)) && IsPort(p) { + return true + } + + return false +} + +// IsIP checks if a string is either IP version 4 or 6. +func IsIP(str string) bool { + return net.ParseIP(str) != nil +} + +// IsPort checks if a string represents a valid port +func IsPort(str string) bool { + if i, err := strconv.Atoi(str); err == nil && i > 0 && i < 65536 { + return true + } + return false +} + +// IsIPv4 check if the string is an IP version 4. +func IsIPv4(str string) bool { + ip := net.ParseIP(str) + return ip != nil && strings.Contains(str, ".") +} + +// IsIPv6 check if the string is an IP version 6. +func IsIPv6(str string) bool { + ip := net.ParseIP(str) + return ip != nil && strings.Contains(str, ":") +} + +// IsCIDR check if the string is an valid CIDR notiation (IPV4 & IPV6) +func IsCIDR(str string) bool { + _, _, err := net.ParseCIDR(str) + return err == nil +} + +// IsMAC check if a string is valid MAC address. +// Possible MAC formats: +// 01:23:45:67:89:ab +// 01:23:45:67:89:ab:cd:ef +// 01-23-45-67-89-ab +// 01-23-45-67-89-ab-cd-ef +// 0123.4567.89ab +// 0123.4567.89ab.cdef +func IsMAC(str string) bool { + _, err := net.ParseMAC(str) + return err == nil +} + +// IsHost checks if the string is a valid IP (both v4 and v6) or a valid DNS name +func IsHost(str string) bool { + return IsIP(str) || IsDNSName(str) +} + +// IsMongoID check if the string is a valid hex-encoded representation of a MongoDB ObjectId. +func IsMongoID(str string) bool { + return rxHexadecimal.MatchString(str) && (len(str) == 24) +} + +// IsLatitude check if a string is valid latitude. +func IsLatitude(str string) bool { + return rxLatitude.MatchString(str) +} + +// IsLongitude check if a string is valid longitude. +func IsLongitude(str string) bool { + return rxLongitude.MatchString(str) +} + +// IsRsaPublicKey check if a string is valid public key with provided length +func IsRsaPublicKey(str string, keylen int) bool { + bb := bytes.NewBufferString(str) + pemBytes, err := ioutil.ReadAll(bb) + if err != nil { + return false + } + block, _ := pem.Decode(pemBytes) + if block != nil && block.Type != "PUBLIC KEY" { + return false + } + var der []byte + + if block != nil { + der = block.Bytes + } else { + der, err = base64.StdEncoding.DecodeString(str) + if err != nil { + return false + } + } + + key, err := x509.ParsePKIXPublicKey(der) + if err != nil { + return false + } + pubkey, ok := key.(*rsa.PublicKey) + if !ok { + return false + } + bitlen := len(pubkey.N.Bytes()) * 8 + return bitlen == int(keylen) +} + +func toJSONName(tag string) string { + if tag == "" { + return "" + } + + // JSON name always comes first. If there's no options then split[0] is + // JSON name, if JSON name is not set, then split[0] is an empty string. + split := strings.SplitN(tag, ",", 2) + + name := split[0] + + // However it is possible that the field is skipped when + // (de-)serializing from/to JSON, in which case assume that there is no + // tag name to use + if name == "-" { + return "" + } + return name +} + +func PrependPathToErrors(err error, path string) error { + switch err2 := err.(type) { + case Error: + err2.Path = append([]string{path}, err2.Path...) + return err2 + case Errors: + errors := err2.Errors() + for i, err3 := range errors { + errors[i] = PrependPathToErrors(err3, path) + } + return err2 + } + fmt.Println(err) + return err +} + +// ValidateStruct use tags for fields. +// result will be equal to `false` if there are any errors. +func ValidateStruct(s interface{}) (bool, error) { + if s == nil { + return true, nil + } + result := true + var err error + val := reflect.ValueOf(s) + if val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr { + val = val.Elem() + } + // we only accept structs + if val.Kind() != reflect.Struct { + return false, fmt.Errorf("function only accepts structs; got %s", val.Kind()) + } + var errs Errors + for i := 0; i < val.NumField(); i++ { + valueField := val.Field(i) + typeField := val.Type().Field(i) + if typeField.PkgPath != "" { + continue // Private field + } + structResult := true + if valueField.Kind() == reflect.Interface { + valueField = valueField.Elem() + } + if (valueField.Kind() == reflect.Struct || + (valueField.Kind() == reflect.Ptr && valueField.Elem().Kind() == reflect.Struct)) && + typeField.Tag.Get(tagName) != "-" { + var err error + structResult, err = ValidateStruct(valueField.Interface()) + if err != nil { + err = PrependPathToErrors(err, typeField.Name) + errs = append(errs, err) + } + } + resultField, err2 := typeCheck(valueField, typeField, val, nil) + if err2 != nil { + + // Replace structure name with JSON name if there is a tag on the variable + jsonTag := toJSONName(typeField.Tag.Get("json")) + if jsonTag != "" { + switch jsonError := err2.(type) { + case Error: + jsonError.Name = jsonTag + err2 = jsonError + case Errors: + for i2, err3 := range jsonError { + switch customErr := err3.(type) { + case Error: + customErr.Name = jsonTag + jsonError[i2] = customErr + } + } + + err2 = jsonError + } + } + + errs = append(errs, err2) + } + result = result && resultField && structResult + } + if len(errs) > 0 { + err = errs + } + return result, err +} + +// parseTagIntoMap parses a struct tag `valid:required~Some error message,length(2|3)` into map[string]string{"required": "Some error message", "length(2|3)": ""} +func parseTagIntoMap(tag string) tagOptionsMap { + optionsMap := make(tagOptionsMap) + options := strings.Split(tag, ",") + + for i, option := range options { + option = strings.TrimSpace(option) + + validationOptions := strings.Split(option, "~") + if !isValidTag(validationOptions[0]) { + continue + } + if len(validationOptions) == 2 { + optionsMap[validationOptions[0]] = tagOption{validationOptions[0], validationOptions[1], i} + } else { + optionsMap[validationOptions[0]] = tagOption{validationOptions[0], "", i} + } + } + return optionsMap +} + +func isValidTag(s string) bool { + if s == "" { + return false + } + for _, c := range s { + switch { + case strings.ContainsRune("\\'\"!#$%&()*+-./:<=>?@[]^_{|}~ ", c): + // Backslash and quote chars are reserved, but + // otherwise any punctuation chars are allowed + // in a tag name. + default: + if !unicode.IsLetter(c) && !unicode.IsDigit(c) { + return false + } + } + } + return true +} + +// IsSSN will validate the given string as a U.S. Social Security Number +func IsSSN(str string) bool { + if str == "" || len(str) != 11 { + return false + } + return rxSSN.MatchString(str) +} + +// IsSemver check if string is valid semantic version +func IsSemver(str string) bool { + return rxSemver.MatchString(str) +} + +// IsTime check if string is valid according to given format +func IsTime(str string, format string) bool { + _, err := time.Parse(format, str) + return err == nil +} + +// IsRFC3339 check if string is valid timestamp value according to RFC3339 +func IsRFC3339(str string) bool { + return IsTime(str, time.RFC3339) +} + +// IsRFC3339WithoutZone check if string is valid timestamp value according to RFC3339 which excludes the timezone. +func IsRFC3339WithoutZone(str string) bool { + return IsTime(str, RF3339WithoutZone) +} + +// IsISO4217 check if string is valid ISO currency code +func IsISO4217(str string) bool { + for _, currency := range ISO4217List { + if str == currency { + return true + } + } + + return false +} + +// ByteLength check string's length +func ByteLength(str string, params ...string) bool { + if len(params) == 2 { + min, _ := ToInt(params[0]) + max, _ := ToInt(params[1]) + return len(str) >= int(min) && len(str) <= int(max) + } + + return false +} + +// RuneLength check string's length +// Alias for StringLength +func RuneLength(str string, params ...string) bool { + return StringLength(str, params...) +} + +// IsRsaPub check whether string is valid RSA key +// Alias for IsRsaPublicKey +func IsRsaPub(str string, params ...string) bool { + if len(params) == 1 { + len, _ := ToInt(params[0]) + return IsRsaPublicKey(str, int(len)) + } + + return false +} + +// StringMatches checks if a string matches a given pattern. +func StringMatches(s string, params ...string) bool { + if len(params) == 1 { + pattern := params[0] + return Matches(s, pattern) + } + return false +} + +// StringLength check string's length (including multi byte strings) +func StringLength(str string, params ...string) bool { + + if len(params) == 2 { + strLength := utf8.RuneCountInString(str) + min, _ := ToInt(params[0]) + max, _ := ToInt(params[1]) + return strLength >= int(min) && strLength <= int(max) + } + + return false +} + +// Range check string's length +func Range(str string, params ...string) bool { + if len(params) == 2 { + value, _ := ToFloat(str) + min, _ := ToFloat(params[0]) + max, _ := ToFloat(params[1]) + return InRange(value, min, max) + } + + return false +} + +func isInRaw(str string, params ...string) bool { + if len(params) == 1 { + rawParams := params[0] + + parsedParams := strings.Split(rawParams, "|") + + return IsIn(str, parsedParams...) + } + + return false +} + +// IsIn check if string str is a member of the set of strings params +func IsIn(str string, params ...string) bool { + for _, param := range params { + if str == param { + return true + } + } + + return false +} + +func checkRequired(v reflect.Value, t reflect.StructField, options tagOptionsMap) (bool, error) { + if nilPtrAllowedByRequired { + k := v.Kind() + if (k == reflect.Ptr || k == reflect.Interface) && v.IsNil() { + return true, nil + } + } + + if requiredOption, isRequired := options["required"]; isRequired { + if len(requiredOption.customErrorMessage) > 0 { + return false, Error{t.Name, fmt.Errorf(requiredOption.customErrorMessage), true, "required", []string{}} + } + return false, Error{t.Name, fmt.Errorf("non zero value required"), false, "required", []string{}} + } else if _, isOptional := options["optional"]; fieldsRequiredByDefault && !isOptional { + return false, Error{t.Name, fmt.Errorf("Missing required field"), false, "required", []string{}} + } + // not required and empty is valid + return true, nil +} + +func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options tagOptionsMap) (isValid bool, resultErr error) { + if !v.IsValid() { + return false, nil + } + + tag := t.Tag.Get(tagName) + + // Check if the field should be ignored + switch tag { + case "": + if v.Kind() != reflect.Slice && v.Kind() != reflect.Map { + if !fieldsRequiredByDefault { + return true, nil + } + return false, Error{t.Name, fmt.Errorf("All fields are required to at least have one validation defined"), false, "required", []string{}} + } + case "-": + return true, nil + } + + isRootType := false + if options == nil { + isRootType = true + options = parseTagIntoMap(tag) + } + + if isEmptyValue(v) { + // an empty value is not validated, check only required + isValid, resultErr = checkRequired(v, t, options) + for key := range options { + delete(options, key) + } + return isValid, resultErr + } + + var customTypeErrors Errors + optionsOrder := options.orderedKeys() + for _, validatorName := range optionsOrder { + validatorStruct := options[validatorName] + if validatefunc, ok := CustomTypeTagMap.Get(validatorName); ok { + delete(options, validatorName) + + if result := validatefunc(v.Interface(), o.Interface()); !result { + if len(validatorStruct.customErrorMessage) > 0 { + customTypeErrors = append(customTypeErrors, Error{Name: t.Name, Err: TruncatingErrorf(validatorStruct.customErrorMessage, fmt.Sprint(v), validatorName), CustomErrorMessageExists: true, Validator: stripParams(validatorName)}) + continue + } + customTypeErrors = append(customTypeErrors, Error{Name: t.Name, Err: fmt.Errorf("%s does not validate as %s", fmt.Sprint(v), validatorName), CustomErrorMessageExists: false, Validator: stripParams(validatorName)}) + } + } + } + + if len(customTypeErrors.Errors()) > 0 { + return false, customTypeErrors + } + + if isRootType { + // Ensure that we've checked the value by all specified validators before report that the value is valid + defer func() { + delete(options, "optional") + delete(options, "required") + + if isValid && resultErr == nil && len(options) != 0 { + optionsOrder := options.orderedKeys() + for _, validator := range optionsOrder { + isValid = false + resultErr = Error{t.Name, fmt.Errorf( + "The following validator is invalid or can't be applied to the field: %q", validator), false, stripParams(validator), []string{}} + return + } + } + }() + } + + switch v.Kind() { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Float32, reflect.Float64, + reflect.String: + // for each tag option check the map of validator functions + for _, validatorSpec := range optionsOrder { + validatorStruct := options[validatorSpec] + var negate bool + validator := validatorSpec + customMsgExists := len(validatorStruct.customErrorMessage) > 0 + + // Check whether the tag looks like '!something' or 'something' + if validator[0] == '!' { + validator = validator[1:] + negate = true + } + + // Check for param validators + for key, value := range ParamTagRegexMap { + ps := value.FindStringSubmatch(validator) + if len(ps) == 0 { + continue + } + + validatefunc, ok := ParamTagMap[key] + if !ok { + continue + } + + delete(options, validatorSpec) + + switch v.Kind() { + case reflect.String, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64: + + field := fmt.Sprint(v) // make value into string, then validate with regex + if result := validatefunc(field, ps[1:]...); (!result && !negate) || (result && negate) { + if customMsgExists { + return false, Error{t.Name, TruncatingErrorf(validatorStruct.customErrorMessage, field, validator), customMsgExists, stripParams(validatorSpec), []string{}} + } + if negate { + return false, Error{t.Name, fmt.Errorf("%s does validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} + } + return false, Error{t.Name, fmt.Errorf("%s does not validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} + } + default: + // type not yet supported, fail + return false, Error{t.Name, fmt.Errorf("Validator %s doesn't support kind %s", validator, v.Kind()), false, stripParams(validatorSpec), []string{}} + } + } + + if validatefunc, ok := TagMap[validator]; ok { + delete(options, validatorSpec) + + switch v.Kind() { + case reflect.String, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64: + field := fmt.Sprint(v) // make value into string, then validate with regex + if result := validatefunc(field); !result && !negate || result && negate { + if customMsgExists { + return false, Error{t.Name, TruncatingErrorf(validatorStruct.customErrorMessage, field, validator), customMsgExists, stripParams(validatorSpec), []string{}} + } + if negate { + return false, Error{t.Name, fmt.Errorf("%s does validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} + } + return false, Error{t.Name, fmt.Errorf("%s does not validate as %s", field, validator), customMsgExists, stripParams(validatorSpec), []string{}} + } + default: + //Not Yet Supported Types (Fail here!) + err := fmt.Errorf("Validator %s doesn't support kind %s for value %v", validator, v.Kind(), v) + return false, Error{t.Name, err, false, stripParams(validatorSpec), []string{}} + } + } + } + return true, nil + case reflect.Map: + if v.Type().Key().Kind() != reflect.String { + return false, &UnsupportedTypeError{v.Type()} + } + var sv stringValues + sv = v.MapKeys() + sort.Sort(sv) + result := true + for i, k := range sv { + var resultItem bool + var err error + if v.MapIndex(k).Kind() != reflect.Struct { + resultItem, err = typeCheck(v.MapIndex(k), t, o, options) + if err != nil { + return false, err + } + } else { + resultItem, err = ValidateStruct(v.MapIndex(k).Interface()) + if err != nil { + err = PrependPathToErrors(err, t.Name+"."+sv[i].Interface().(string)) + return false, err + } + } + result = result && resultItem + } + return result, nil + case reflect.Slice, reflect.Array: + result := true + for i := 0; i < v.Len(); i++ { + var resultItem bool + var err error + if v.Index(i).Kind() != reflect.Struct { + resultItem, err = typeCheck(v.Index(i), t, o, options) + if err != nil { + return false, err + } + } else { + resultItem, err = ValidateStruct(v.Index(i).Interface()) + if err != nil { + err = PrependPathToErrors(err, t.Name+"."+strconv.Itoa(i)) + return false, err + } + } + result = result && resultItem + } + return result, nil + case reflect.Interface: + // If the value is an interface then encode its element + if v.IsNil() { + return true, nil + } + return ValidateStruct(v.Interface()) + case reflect.Ptr: + // If the value is a pointer then check its element + if v.IsNil() { + return true, nil + } + return typeCheck(v.Elem(), t, o, options) + case reflect.Struct: + return ValidateStruct(v.Interface()) + default: + return false, &UnsupportedTypeError{v.Type()} + } +} + +func stripParams(validatorString string) string { + return paramsRegexp.ReplaceAllString(validatorString, "") +} + +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.String, reflect.Array: + return v.Len() == 0 + case reflect.Map, reflect.Slice: + return v.Len() == 0 || v.IsNil() + 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 v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + + return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) +} + +// ErrorByField returns error for specified field of the struct +// validated by ValidateStruct or empty string if there are no errors +// or this field doesn't exists or doesn't have any errors. +func ErrorByField(e error, field string) string { + if e == nil { + return "" + } + return ErrorsByField(e)[field] +} + +// ErrorsByField returns map of errors of the struct validated +// by ValidateStruct or empty map if there are no errors. +func ErrorsByField(e error) map[string]string { + m := make(map[string]string) + if e == nil { + return m + } + // prototype for ValidateStruct + + switch e.(type) { + case Error: + m[e.(Error).Name] = e.(Error).Err.Error() + case Errors: + for _, item := range e.(Errors).Errors() { + n := ErrorsByField(item) + for k, v := range n { + m[k] = v + } + } + } + + return m +} + +// Error returns string equivalent for reflect.Type +func (e *UnsupportedTypeError) Error() string { + return "validator: unsupported type: " + e.Type.String() +} + +func (sv stringValues) Len() int { return len(sv) } +func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) } +func (sv stringValues) get(i int) string { return sv[i].String() } diff --git a/vendor/github.com/asaskevich/govalidator/wercker.yml b/vendor/github.com/asaskevich/govalidator/wercker.yml new file mode 100644 index 000000000..cac7a5fcf --- /dev/null +++ b/vendor/github.com/asaskevich/govalidator/wercker.yml @@ -0,0 +1,15 @@ +box: golang +build: + steps: + - setup-go-workspace + + - script: + name: go get + code: | + go version + go get -t ./... + + - script: + name: go test + code: | + go test -race ./... diff --git a/vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go index f81594c91..1395a7e10 100644 --- a/vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admission/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AdmissionRequest = map[string]string{ diff --git a/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go index 13067ad80..82598ed57 100644 --- a/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admission/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AdmissionRequest = map[string]string{ diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go b/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go index 6ac9e80ff..9a2d0bccd 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go +++ b/vendor/k8s.io/api/admissionregistration/v1/generated.pb.go @@ -44,10 +44,38 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +func (m *MatchCondition) Reset() { *m = MatchCondition{} } +func (*MatchCondition) ProtoMessage() {} +func (*MatchCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_aaac5994f79683e8, []int{0} +} +func (m *MatchCondition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MatchCondition) 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 *MatchCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_MatchCondition.Merge(m, src) +} +func (m *MatchCondition) XXX_Size() int { + return m.Size() +} +func (m *MatchCondition) XXX_DiscardUnknown() { + xxx_messageInfo_MatchCondition.DiscardUnknown(m) +} + +var xxx_messageInfo_MatchCondition proto.InternalMessageInfo + func (m *MutatingWebhook) Reset() { *m = MutatingWebhook{} } func (*MutatingWebhook) ProtoMessage() {} func (*MutatingWebhook) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{0} + return fileDescriptor_aaac5994f79683e8, []int{1} } func (m *MutatingWebhook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,7 +103,7 @@ var xxx_messageInfo_MutatingWebhook proto.InternalMessageInfo func (m *MutatingWebhookConfiguration) Reset() { *m = MutatingWebhookConfiguration{} } func (*MutatingWebhookConfiguration) ProtoMessage() {} func (*MutatingWebhookConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{1} + return fileDescriptor_aaac5994f79683e8, []int{2} } func (m *MutatingWebhookConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -103,7 +131,7 @@ var xxx_messageInfo_MutatingWebhookConfiguration proto.InternalMessageInfo func (m *MutatingWebhookConfigurationList) Reset() { *m = MutatingWebhookConfigurationList{} } func (*MutatingWebhookConfigurationList) ProtoMessage() {} func (*MutatingWebhookConfigurationList) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{2} + return fileDescriptor_aaac5994f79683e8, []int{3} } func (m *MutatingWebhookConfigurationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -131,7 +159,7 @@ var xxx_messageInfo_MutatingWebhookConfigurationList proto.InternalMessageInfo func (m *Rule) Reset() { *m = Rule{} } func (*Rule) ProtoMessage() {} func (*Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{3} + return fileDescriptor_aaac5994f79683e8, []int{4} } func (m *Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -159,7 +187,7 @@ var xxx_messageInfo_Rule proto.InternalMessageInfo func (m *RuleWithOperations) Reset() { *m = RuleWithOperations{} } func (*RuleWithOperations) ProtoMessage() {} func (*RuleWithOperations) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{4} + return fileDescriptor_aaac5994f79683e8, []int{5} } func (m *RuleWithOperations) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -187,7 +215,7 @@ var xxx_messageInfo_RuleWithOperations proto.InternalMessageInfo func (m *ServiceReference) Reset() { *m = ServiceReference{} } func (*ServiceReference) ProtoMessage() {} func (*ServiceReference) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{5} + return fileDescriptor_aaac5994f79683e8, []int{6} } func (m *ServiceReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -215,7 +243,7 @@ var xxx_messageInfo_ServiceReference proto.InternalMessageInfo func (m *ValidatingWebhook) Reset() { *m = ValidatingWebhook{} } func (*ValidatingWebhook) ProtoMessage() {} func (*ValidatingWebhook) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{6} + return fileDescriptor_aaac5994f79683e8, []int{7} } func (m *ValidatingWebhook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -243,7 +271,7 @@ var xxx_messageInfo_ValidatingWebhook proto.InternalMessageInfo func (m *ValidatingWebhookConfiguration) Reset() { *m = ValidatingWebhookConfiguration{} } func (*ValidatingWebhookConfiguration) ProtoMessage() {} func (*ValidatingWebhookConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{7} + return fileDescriptor_aaac5994f79683e8, []int{8} } func (m *ValidatingWebhookConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -271,7 +299,7 @@ var xxx_messageInfo_ValidatingWebhookConfiguration proto.InternalMessageInfo func (m *ValidatingWebhookConfigurationList) Reset() { *m = ValidatingWebhookConfigurationList{} } func (*ValidatingWebhookConfigurationList) ProtoMessage() {} func (*ValidatingWebhookConfigurationList) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{8} + return fileDescriptor_aaac5994f79683e8, []int{9} } func (m *ValidatingWebhookConfigurationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -299,7 +327,7 @@ var xxx_messageInfo_ValidatingWebhookConfigurationList proto.InternalMessageInfo func (m *WebhookClientConfig) Reset() { *m = WebhookClientConfig{} } func (*WebhookClientConfig) ProtoMessage() {} func (*WebhookClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_aaac5994f79683e8, []int{9} + return fileDescriptor_aaac5994f79683e8, []int{10} } func (m *WebhookClientConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -325,6 +353,7 @@ func (m *WebhookClientConfig) XXX_DiscardUnknown() { var xxx_messageInfo_WebhookClientConfig proto.InternalMessageInfo func init() { + proto.RegisterType((*MatchCondition)(nil), "k8s.io.api.admissionregistration.v1.MatchCondition") proto.RegisterType((*MutatingWebhook)(nil), "k8s.io.api.admissionregistration.v1.MutatingWebhook") proto.RegisterType((*MutatingWebhookConfiguration)(nil), "k8s.io.api.admissionregistration.v1.MutatingWebhookConfiguration") proto.RegisterType((*MutatingWebhookConfigurationList)(nil), "k8s.io.api.admissionregistration.v1.MutatingWebhookConfigurationList") @@ -342,79 +371,116 @@ func init() { } var fileDescriptor_aaac5994f79683e8 = []byte{ - // 1105 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xcf, 0xc6, 0x76, 0x63, 0x8f, 0xf3, 0xa7, 0x19, 0xa0, 0x35, 0xa1, 0xf2, 0x5a, 0xae, 0x84, - 0x8c, 0x80, 0xdd, 0x26, 0x94, 0x52, 0x71, 0x41, 0xd9, 0xf0, 0x47, 0x11, 0x49, 0x1b, 0x4d, 0xda, - 0x14, 0xa1, 0x1c, 0x3a, 0x5e, 0x8f, 0xed, 0x21, 0xf6, 0xce, 0x6a, 0x66, 0xd6, 0x90, 0x1b, 0x1f, - 0x81, 0xaf, 0x00, 0x9f, 0x82, 0x1b, 0xe2, 0x96, 0x63, 0x8f, 0x39, 0xa0, 0x85, 0x2c, 0x17, 0x0e, - 0x7c, 0x82, 0x9c, 0xd0, 0xcc, 0xae, 0x77, 0xfd, 0x27, 0x09, 0x56, 0x0e, 0x3d, 0xe5, 0xe6, 0xf9, - 0xbd, 0x79, 0xbf, 0x37, 0xef, 0xed, 0x7b, 0xef, 0x27, 0x83, 0x9d, 0xa3, 0xc7, 0xc2, 0xa2, 0xcc, - 0x3e, 0x0a, 0x9a, 0x84, 0x7b, 0x44, 0x12, 0x61, 0x0f, 0x88, 0xd7, 0x62, 0xdc, 0x4e, 0x0c, 0xd8, - 0xa7, 0x36, 0x6e, 0xf5, 0xa9, 0x10, 0x94, 0x79, 0x9c, 0x74, 0xa8, 0x90, 0x1c, 0x4b, 0xca, 0x3c, - 0x7b, 0xb0, 0x6e, 0x77, 0x88, 0x47, 0x38, 0x96, 0xa4, 0x65, 0xf9, 0x9c, 0x49, 0x06, 0xef, 0xc7, - 0x4e, 0x16, 0xf6, 0xa9, 0x75, 0xa1, 0x93, 0x35, 0x58, 0x5f, 0xfb, 0xb0, 0x43, 0x65, 0x37, 0x68, - 0x5a, 0x2e, 0xeb, 0xdb, 0x1d, 0xd6, 0x61, 0xb6, 0xf6, 0x6d, 0x06, 0x6d, 0x7d, 0xd2, 0x07, 0xfd, - 0x2b, 0xe6, 0x5c, 0x7b, 0x98, 0x3d, 0xa4, 0x8f, 0xdd, 0x2e, 0xf5, 0x08, 0x3f, 0xb6, 0xfd, 0xa3, - 0x8e, 0x02, 0x84, 0xdd, 0x27, 0x12, 0x5f, 0xf0, 0x92, 0x35, 0xfb, 0x32, 0x2f, 0x1e, 0x78, 0x92, - 0xf6, 0xc9, 0x94, 0xc3, 0xa3, 0xff, 0x73, 0x10, 0x6e, 0x97, 0xf4, 0xf1, 0xa4, 0x5f, 0xfd, 0xb7, - 0x05, 0xb0, 0xb2, 0x1b, 0x48, 0x2c, 0xa9, 0xd7, 0x79, 0x41, 0x9a, 0x5d, 0xc6, 0x8e, 0x60, 0x0d, - 0xe4, 0x3d, 0xdc, 0x27, 0x15, 0xa3, 0x66, 0x34, 0x4a, 0xce, 0xe2, 0x49, 0x68, 0xce, 0x45, 0xa1, - 0x99, 0x7f, 0x82, 0xfb, 0x04, 0x69, 0x0b, 0xe4, 0x60, 0xd1, 0xed, 0x51, 0xe2, 0xc9, 0x2d, 0xe6, - 0xb5, 0x69, 0xa7, 0x32, 0x5f, 0x33, 0x1a, 0xe5, 0x8d, 0xc7, 0xd6, 0x0c, 0xf5, 0xb3, 0x92, 0x28, - 0x5b, 0x23, 0xfe, 0xce, 0x9b, 0x49, 0x8c, 0xc5, 0x51, 0x14, 0x8d, 0xc5, 0x80, 0x87, 0xa0, 0xc0, - 0x83, 0x1e, 0x11, 0x95, 0x5c, 0x2d, 0xd7, 0x28, 0x6f, 0x7c, 0x32, 0x53, 0x30, 0x14, 0xf4, 0xc8, - 0x0b, 0x2a, 0xbb, 0x4f, 0x7d, 0x12, 0x83, 0xc2, 0x59, 0x4a, 0x62, 0x15, 0x94, 0x4d, 0xa0, 0x98, - 0x14, 0xee, 0x80, 0xa5, 0x36, 0xa6, 0xbd, 0x80, 0x93, 0x3d, 0xd6, 0xa3, 0xee, 0x71, 0x25, 0xaf, - 0x93, 0x7f, 0x37, 0x0a, 0xcd, 0xa5, 0x2f, 0x47, 0x0d, 0xe7, 0xa1, 0xb9, 0x3a, 0x06, 0x3c, 0x3b, - 0xf6, 0x09, 0x1a, 0x77, 0x86, 0x9f, 0x83, 0x72, 0x1f, 0x4b, 0xb7, 0x9b, 0x70, 0x95, 0x34, 0x57, - 0x3d, 0x0a, 0xcd, 0xf2, 0x6e, 0x06, 0x9f, 0x87, 0xe6, 0xca, 0xc8, 0x51, 0xf3, 0x8c, 0xba, 0xc1, - 0x1f, 0xc0, 0xaa, 0xaa, 0xb6, 0xf0, 0xb1, 0x4b, 0xf6, 0x49, 0x8f, 0xb8, 0x92, 0xf1, 0x4a, 0x41, - 0x97, 0xfa, 0xa3, 0x91, 0xec, 0xd3, 0xef, 0x6d, 0xf9, 0x47, 0x1d, 0x05, 0x08, 0x4b, 0xb5, 0x95, - 0x4a, 0x7f, 0x07, 0x37, 0x49, 0x6f, 0xe8, 0xea, 0xbc, 0x15, 0x85, 0xe6, 0xea, 0x93, 0x49, 0x46, - 0x34, 0x1d, 0x04, 0x32, 0xb0, 0xcc, 0x9a, 0xdf, 0x11, 0x57, 0xa6, 0x61, 0xcb, 0xd7, 0x0f, 0x0b, - 0xa3, 0xd0, 0x5c, 0x7e, 0x3a, 0x46, 0x87, 0x26, 0xe8, 0x55, 0xc1, 0x04, 0x6d, 0x91, 0x2f, 0xda, - 0x6d, 0xe2, 0x4a, 0x51, 0xb9, 0x95, 0x15, 0x6c, 0x3f, 0x83, 0x55, 0xc1, 0xb2, 0xe3, 0x56, 0x0f, - 0x0b, 0x81, 0x46, 0xdd, 0xe0, 0xa7, 0x60, 0x59, 0xf5, 0x3a, 0x0b, 0xe4, 0x3e, 0x71, 0x99, 0xd7, - 0x12, 0x95, 0x85, 0x9a, 0xd1, 0x28, 0xc4, 0x2f, 0x78, 0x36, 0x66, 0x41, 0x13, 0x37, 0xe1, 0x73, - 0x70, 0x37, 0xed, 0x22, 0x44, 0x06, 0x94, 0x7c, 0x7f, 0x40, 0xb8, 0x3a, 0x88, 0x4a, 0xb1, 0x96, - 0x6b, 0x94, 0x9c, 0x77, 0xa2, 0xd0, 0xbc, 0xbb, 0x79, 0xf1, 0x15, 0x74, 0x99, 0x2f, 0x7c, 0x09, - 0x20, 0x27, 0xd4, 0x1b, 0x30, 0x57, 0xb7, 0x5f, 0xd2, 0x10, 0x40, 0xe7, 0xf7, 0x20, 0x0a, 0x4d, - 0x88, 0xa6, 0xac, 0xe7, 0xa1, 0x79, 0x67, 0x1a, 0xd5, 0xed, 0x71, 0x01, 0x57, 0xfd, 0xd4, 0x00, - 0xf7, 0x26, 0x26, 0x38, 0x9e, 0x98, 0x20, 0xee, 0x78, 0xf8, 0x12, 0x14, 0xd5, 0x87, 0x69, 0x61, - 0x89, 0xf5, 0x48, 0x97, 0x37, 0x1e, 0xcc, 0xf6, 0x19, 0xe3, 0x6f, 0xb6, 0x4b, 0x24, 0x76, 0x60, - 0x32, 0x34, 0x20, 0xc3, 0x50, 0xca, 0x0a, 0x0f, 0x40, 0x31, 0x89, 0x2c, 0x2a, 0xf3, 0x7a, 0x3a, - 0x1f, 0xce, 0x34, 0x9d, 0x13, 0xcf, 0x76, 0xf2, 0x2a, 0x0a, 0x4a, 0xb9, 0xea, 0xff, 0x18, 0xa0, - 0x76, 0x55, 0x6a, 0x3b, 0x54, 0x48, 0x78, 0x38, 0x95, 0x9e, 0x35, 0x63, 0x97, 0x52, 0x11, 0x27, - 0x77, 0x3b, 0x49, 0xae, 0x38, 0x44, 0x46, 0x52, 0x6b, 0x83, 0x02, 0x95, 0xa4, 0x3f, 0xcc, 0x6b, - 0xf3, 0x3a, 0x79, 0x8d, 0xbd, 0x39, 0xdb, 0x3f, 0xdb, 0x8a, 0x17, 0xc5, 0xf4, 0xf5, 0xdf, 0x0d, - 0x90, 0x57, 0x0b, 0x09, 0xbe, 0x0f, 0x4a, 0xd8, 0xa7, 0x5f, 0x71, 0x16, 0xf8, 0xa2, 0x62, 0xe8, - 0xce, 0x5b, 0x8a, 0x42, 0xb3, 0xb4, 0xb9, 0xb7, 0x1d, 0x83, 0x28, 0xb3, 0xc3, 0x75, 0x50, 0xc6, - 0x3e, 0x4d, 0x1b, 0x75, 0x5e, 0x5f, 0x5f, 0x51, 0x63, 0xb3, 0xb9, 0xb7, 0x9d, 0x36, 0xe7, 0xe8, - 0x1d, 0xc5, 0xcf, 0x89, 0x60, 0x01, 0x77, 0x93, 0x55, 0x9a, 0xf0, 0xa3, 0x21, 0x88, 0x32, 0x3b, - 0xfc, 0x00, 0x14, 0x84, 0xcb, 0x7c, 0x92, 0x6c, 0xc3, 0x3b, 0xea, 0xd9, 0xfb, 0x0a, 0x38, 0x0f, - 0xcd, 0x92, 0xfe, 0xa1, 0xdb, 0x32, 0xbe, 0x54, 0xff, 0xc5, 0x00, 0x70, 0x7a, 0xe1, 0xc2, 0xcf, - 0x00, 0x60, 0xe9, 0x29, 0x49, 0xc9, 0xd4, 0xbd, 0x94, 0xa2, 0xe7, 0xa1, 0xb9, 0x94, 0x9e, 0x34, - 0xe5, 0x88, 0x0b, 0xfc, 0x1a, 0xe4, 0xd5, 0x92, 0x4e, 0x54, 0xe6, 0xbd, 0x99, 0x17, 0x7f, 0x26, - 0x5d, 0xea, 0x84, 0x34, 0x49, 0xfd, 0x67, 0x03, 0xdc, 0xde, 0x27, 0x7c, 0x40, 0x5d, 0x82, 0x48, - 0x9b, 0x70, 0xe2, 0xb9, 0x04, 0xda, 0xa0, 0x94, 0x2e, 0xc1, 0x44, 0xf6, 0x56, 0x13, 0xdf, 0x52, - 0xba, 0x30, 0x51, 0x76, 0x27, 0x95, 0xc8, 0xf9, 0x4b, 0x25, 0xf2, 0x1e, 0xc8, 0xfb, 0x58, 0x76, - 0x2b, 0x39, 0x7d, 0xa3, 0xa8, 0xac, 0x7b, 0x58, 0x76, 0x91, 0x46, 0xb5, 0x95, 0x71, 0xa9, 0xeb, - 0x5a, 0x48, 0xac, 0x8c, 0x4b, 0xa4, 0xd1, 0xfa, 0x9f, 0xb7, 0xc0, 0xea, 0x01, 0xee, 0xd1, 0xd6, - 0x8d, 0x2c, 0xdf, 0xc8, 0xf2, 0x95, 0xb2, 0x0c, 0x6e, 0x64, 0xf9, 0x3a, 0xb2, 0x5c, 0xff, 0xc3, - 0x00, 0xd5, 0xa9, 0x09, 0x7b, 0xdd, 0xb2, 0xf9, 0xcd, 0x94, 0x6c, 0x3e, 0x9a, 0x69, 0x7a, 0xa6, - 0x1e, 0x3e, 0x25, 0x9c, 0xff, 0x1a, 0xa0, 0x7e, 0x75, 0x7a, 0xaf, 0x41, 0x3a, 0xbb, 0xe3, 0xd2, - 0xb9, 0x75, 0xbd, 0xdc, 0x66, 0x11, 0xcf, 0x5f, 0x0d, 0xf0, 0xc6, 0x05, 0xfb, 0x0b, 0xbe, 0x0d, - 0x72, 0x01, 0xef, 0x25, 0x2b, 0x78, 0x21, 0x0a, 0xcd, 0xdc, 0x73, 0xb4, 0x83, 0x14, 0x06, 0x0f, - 0xc1, 0x82, 0x88, 0x55, 0x20, 0xc9, 0xfc, 0xe3, 0x99, 0x9e, 0x37, 0xa9, 0x1c, 0x4e, 0x39, 0x0a, - 0xcd, 0x85, 0x21, 0x3a, 0xa4, 0x84, 0x0d, 0x50, 0x74, 0xb1, 0x13, 0x78, 0xad, 0x44, 0xb5, 0x16, - 0x9d, 0x45, 0x55, 0xa4, 0xad, 0xcd, 0x18, 0x43, 0xa9, 0xd5, 0xd9, 0x3e, 0x39, 0xab, 0xce, 0xbd, - 0x3a, 0xab, 0xce, 0x9d, 0x9e, 0x55, 0xe7, 0x7e, 0x8c, 0xaa, 0xc6, 0x49, 0x54, 0x35, 0x5e, 0x45, - 0x55, 0xe3, 0x34, 0xaa, 0x1a, 0x7f, 0x45, 0x55, 0xe3, 0xa7, 0xbf, 0xab, 0x73, 0xdf, 0xde, 0x9f, - 0xe1, 0xdf, 0xec, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x43, 0x44, 0x86, 0xf5, 0x0c, 0x0f, 0x00, + // 1169 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4d, 0x6f, 0x1b, 0x45, + 0x18, 0xce, 0xc6, 0x36, 0xb1, 0xc7, 0x4e, 0xd2, 0x0c, 0xd0, 0x2e, 0xa5, 0xf2, 0x5a, 0xae, 0x84, + 0x82, 0x00, 0x6f, 0x9b, 0x96, 0x52, 0x71, 0x41, 0xb1, 0x29, 0x28, 0x22, 0x69, 0xa3, 0x49, 0x3f, + 0x10, 0xea, 0xa1, 0xe3, 0xf5, 0xd8, 0x1e, 0x62, 0xef, 0xac, 0x66, 0x66, 0x4d, 0x7b, 0xe3, 0x27, + 0xf0, 0x17, 0xe0, 0x4f, 0xc0, 0x95, 0x5b, 0x8f, 0xbd, 0x91, 0x03, 0x5a, 0x91, 0xe5, 0xc2, 0x81, + 0x5f, 0x90, 0x13, 0x9a, 0xd9, 0xf5, 0xae, 0xbf, 0x12, 0x56, 0x39, 0xe4, 0x94, 0x5b, 0xe6, 0x79, + 0xdf, 0xf7, 0x79, 0xe7, 0x19, 0xbf, 0x1f, 0xab, 0x80, 0xdd, 0xc3, 0xfb, 0xa2, 0x41, 0x99, 0x7d, + 0xe8, 0xb7, 0x09, 0x77, 0x89, 0x24, 0xc2, 0x1e, 0x11, 0xb7, 0xc3, 0xb8, 0x1d, 0x1b, 0xb0, 0x47, + 0x6d, 0xdc, 0x19, 0x52, 0x21, 0x28, 0x73, 0x39, 0xe9, 0x51, 0x21, 0x39, 0x96, 0x94, 0xb9, 0xf6, + 0xe8, 0xb6, 0xdd, 0x23, 0x2e, 0xe1, 0x58, 0x92, 0x4e, 0xc3, 0xe3, 0x4c, 0x32, 0x78, 0x33, 0x0a, + 0x6a, 0x60, 0x8f, 0x36, 0x16, 0x06, 0x35, 0x46, 0xb7, 0xaf, 0x7f, 0xd2, 0xa3, 0xb2, 0xef, 0xb7, + 0x1b, 0x0e, 0x1b, 0xda, 0x3d, 0xd6, 0x63, 0xb6, 0x8e, 0x6d, 0xfb, 0x5d, 0x7d, 0xd2, 0x07, 0xfd, + 0x57, 0xc4, 0x79, 0xfd, 0x6e, 0x7a, 0x91, 0x21, 0x76, 0xfa, 0xd4, 0x25, 0xfc, 0x95, 0xed, 0x1d, + 0xf6, 0x14, 0x20, 0xec, 0x21, 0x91, 0x78, 0xc1, 0x4d, 0xae, 0xdb, 0xa7, 0x45, 0x71, 0xdf, 0x95, + 0x74, 0x48, 0xe6, 0x02, 0xee, 0xfd, 0x5f, 0x80, 0x70, 0xfa, 0x64, 0x88, 0x67, 0xe3, 0xea, 0x5d, + 0xb0, 0xb6, 0x87, 0xa5, 0xd3, 0x6f, 0x31, 0xb7, 0x43, 0x95, 0x44, 0x58, 0x03, 0x79, 0x17, 0x0f, + 0x89, 0x69, 0xd4, 0x8c, 0xcd, 0x52, 0xb3, 0xf2, 0x3a, 0xb0, 0x96, 0xc2, 0xc0, 0xca, 0x3f, 0xc4, + 0x43, 0x82, 0xb4, 0x05, 0x6e, 0x01, 0x40, 0x5e, 0x7a, 0x9c, 0xe8, 0xe7, 0x31, 0x97, 0xb5, 0x1f, + 0x8c, 0xfd, 0xc0, 0x83, 0xc4, 0x82, 0x26, 0xbc, 0xea, 0xbf, 0x16, 0xc1, 0xfa, 0x9e, 0x2f, 0xb1, + 0xa4, 0x6e, 0xef, 0x19, 0x69, 0xf7, 0x19, 0x3b, 0xcc, 0x90, 0x89, 0x83, 0x8a, 0x33, 0xa0, 0xc4, + 0x95, 0x2d, 0xe6, 0x76, 0x69, 0x4f, 0xe7, 0x2a, 0x6f, 0xdd, 0x6f, 0x64, 0xf8, 0x9d, 0x1a, 0x71, + 0x96, 0xd6, 0x44, 0x7c, 0xf3, 0x9d, 0x38, 0x47, 0x65, 0x12, 0x45, 0x53, 0x39, 0xe0, 0x73, 0x50, + 0xe0, 0xfe, 0x80, 0x08, 0x33, 0x57, 0xcb, 0x6d, 0x96, 0xb7, 0x3e, 0xcb, 0x94, 0x0c, 0xf9, 0x03, + 0xf2, 0x8c, 0xca, 0xfe, 0x23, 0x8f, 0x44, 0xa0, 0x68, 0xae, 0xc6, 0xb9, 0x0a, 0xca, 0x26, 0x50, + 0x44, 0x0a, 0x77, 0xc1, 0x6a, 0x17, 0xd3, 0x81, 0xcf, 0xc9, 0x3e, 0x1b, 0x50, 0xe7, 0x95, 0x99, + 0xd7, 0xe2, 0x3f, 0x08, 0x03, 0x6b, 0xf5, 0xab, 0x49, 0xc3, 0x49, 0x60, 0x6d, 0x4c, 0x01, 0x8f, + 0x5f, 0x79, 0x04, 0x4d, 0x07, 0xc3, 0x2f, 0x41, 0x79, 0xa8, 0x7e, 0xbd, 0x98, 0xab, 0xa4, 0xb9, + 0xea, 0x61, 0x60, 0x95, 0xf7, 0x52, 0xf8, 0x24, 0xb0, 0xd6, 0x27, 0x8e, 0x9a, 0x67, 0x32, 0x0c, + 0xbe, 0x04, 0x1b, 0xea, 0xb5, 0x85, 0x87, 0x1d, 0x72, 0x40, 0x06, 0xc4, 0x91, 0x8c, 0x9b, 0x05, + 0xfd, 0xd4, 0x77, 0x26, 0xd4, 0x27, 0x75, 0xd5, 0xf0, 0x0e, 0x7b, 0x0a, 0x10, 0x0d, 0x55, 0xbe, + 0x4a, 0xfe, 0x2e, 0x6e, 0x93, 0xc1, 0x38, 0xb4, 0xf9, 0x6e, 0x18, 0x58, 0x1b, 0x0f, 0x67, 0x19, + 0xd1, 0x7c, 0x12, 0xc8, 0xc0, 0x1a, 0x6b, 0x7f, 0x4f, 0x1c, 0x99, 0xa4, 0x2d, 0x9f, 0x3f, 0x2d, + 0x0c, 0x03, 0x6b, 0xed, 0xd1, 0x14, 0x1d, 0x9a, 0xa1, 0x57, 0x0f, 0x26, 0x68, 0x87, 0x3c, 0xe8, + 0x76, 0x89, 0x23, 0x85, 0xf9, 0x56, 0xfa, 0x60, 0x07, 0x29, 0xac, 0x1e, 0x2c, 0x3d, 0xb6, 0x06, + 0x58, 0x08, 0x34, 0x19, 0x06, 0x3f, 0x07, 0x6b, 0xaa, 0xa7, 0x98, 0x2f, 0x0f, 0x88, 0xc3, 0xdc, + 0x8e, 0x30, 0x57, 0x6a, 0xc6, 0x66, 0x21, 0xba, 0xc1, 0xe3, 0x29, 0x0b, 0x9a, 0xf1, 0x84, 0x4f, + 0xc0, 0xb5, 0xa4, 0x8a, 0x10, 0x19, 0x51, 0xf2, 0xc3, 0x53, 0xc2, 0xd5, 0x41, 0x98, 0xc5, 0x5a, + 0x6e, 0xb3, 0xd4, 0x7c, 0x3f, 0x0c, 0xac, 0x6b, 0xdb, 0x8b, 0x5d, 0xd0, 0x69, 0xb1, 0xf0, 0x05, + 0x80, 0x9c, 0x50, 0x77, 0xc4, 0x1c, 0x5d, 0x7e, 0x71, 0x41, 0x00, 0xad, 0xef, 0x56, 0x18, 0x58, + 0x10, 0xcd, 0x59, 0x4f, 0x02, 0xeb, 0xea, 0x3c, 0xaa, 0xcb, 0x63, 0x01, 0x17, 0x1c, 0x81, 0xf5, + 0xe1, 0xd4, 0xa4, 0x10, 0x66, 0x45, 0x77, 0xc8, 0x9d, 0x4c, 0x1d, 0x32, 0x3d, 0x65, 0x9a, 0xd7, + 0xe2, 0xee, 0x58, 0x9f, 0xc6, 0x05, 0x9a, 0x4d, 0x52, 0x3f, 0x32, 0xc0, 0x8d, 0x99, 0xc9, 0x11, + 0x75, 0xaa, 0x1f, 0x91, 0xc3, 0x17, 0xa0, 0xa8, 0x0a, 0xa2, 0x83, 0x25, 0xd6, 0xa3, 0xa4, 0xbc, + 0x75, 0x2b, 0x5b, 0xf9, 0x44, 0xb5, 0xb2, 0x47, 0x24, 0x4e, 0xc7, 0x57, 0x8a, 0xa1, 0x84, 0x15, + 0x3e, 0x05, 0xc5, 0x38, 0xb3, 0x30, 0x97, 0xb5, 0xe6, 0xbb, 0xd9, 0x34, 0x4f, 0x5f, 0xbb, 0x99, + 0x57, 0x59, 0x50, 0xc2, 0x55, 0xff, 0xc7, 0x00, 0xb5, 0xb3, 0xa4, 0xed, 0x52, 0x21, 0xe1, 0xf3, + 0x39, 0x79, 0x8d, 0x8c, 0xdd, 0x41, 0x45, 0x24, 0xee, 0x4a, 0x2c, 0xae, 0x38, 0x46, 0x26, 0xa4, + 0x75, 0x41, 0x81, 0x4a, 0x32, 0x1c, 0xeb, 0xda, 0x3e, 0x8f, 0xae, 0xa9, 0x3b, 0xa7, 0x73, 0x6f, + 0x47, 0xf1, 0xa2, 0x88, 0xbe, 0xfe, 0xbb, 0x01, 0xf2, 0x6a, 0x10, 0xc2, 0x8f, 0x40, 0x09, 0x7b, + 0xf4, 0x6b, 0xce, 0x7c, 0x4f, 0x98, 0x86, 0xae, 0xf8, 0xd5, 0x30, 0xb0, 0x4a, 0xdb, 0xfb, 0x3b, + 0x11, 0x88, 0x52, 0x3b, 0xbc, 0x0d, 0xca, 0xd8, 0xa3, 0x49, 0x83, 0x2c, 0x6b, 0xf7, 0x75, 0xd5, + 0xae, 0xdb, 0xfb, 0x3b, 0x49, 0x53, 0x4c, 0xfa, 0x28, 0x7e, 0x4e, 0x04, 0xf3, 0xb9, 0x13, 0x8f, + 0xf0, 0x98, 0x1f, 0x8d, 0x41, 0x94, 0xda, 0xe1, 0xc7, 0xa0, 0x20, 0x1c, 0xe6, 0x91, 0x78, 0x0a, + 0x5f, 0x55, 0xd7, 0x3e, 0x50, 0xc0, 0x49, 0x60, 0x95, 0xf4, 0x1f, 0xba, 0x1d, 0x22, 0xa7, 0xfa, + 0x2f, 0x06, 0x80, 0xf3, 0x83, 0x1e, 0x7e, 0x01, 0x00, 0x4b, 0x4e, 0xb1, 0x24, 0x4b, 0xd7, 0x52, + 0x82, 0x9e, 0x04, 0xd6, 0x6a, 0x72, 0xd2, 0x94, 0x13, 0x21, 0xf0, 0x1b, 0x90, 0x57, 0xcb, 0x21, + 0xde, 0x6e, 0x1f, 0x66, 0x5e, 0x38, 0xe9, 0xca, 0x54, 0x27, 0xa4, 0x49, 0xea, 0x3f, 0x1b, 0xe0, + 0xca, 0x01, 0xe1, 0x23, 0xea, 0x10, 0x44, 0xba, 0x84, 0x13, 0xd7, 0x21, 0xd0, 0x06, 0xa5, 0x64, + 0xf8, 0xc6, 0xeb, 0x76, 0x23, 0x8e, 0x2d, 0x25, 0x83, 0x1a, 0xa5, 0x3e, 0xc9, 0x6a, 0x5e, 0x3e, + 0x75, 0x35, 0xdf, 0x00, 0x79, 0x0f, 0xcb, 0xbe, 0x99, 0xd3, 0x1e, 0x45, 0x65, 0xdd, 0xc7, 0xb2, + 0x8f, 0x34, 0xaa, 0xad, 0x8c, 0x4b, 0xfd, 0xae, 0x85, 0xd8, 0xca, 0xb8, 0x44, 0x1a, 0xad, 0xff, + 0xb1, 0x02, 0x36, 0x9e, 0xe2, 0x01, 0xed, 0x5c, 0x7e, 0x0e, 0x5c, 0x7e, 0x0e, 0x9c, 0xf9, 0x39, + 0x00, 0x2e, 0x3f, 0x07, 0xce, 0xf5, 0x39, 0xb0, 0x60, 0x59, 0x97, 0x2f, 0x62, 0x59, 0xff, 0x69, + 0x80, 0xea, 0x5c, 0x67, 0x5f, 0xf4, 0xba, 0xfe, 0x76, 0x6e, 0x5d, 0xdf, 0xcb, 0xa4, 0x7a, 0xee, + 0xe2, 0x73, 0x0b, 0xfb, 0x5f, 0x03, 0xd4, 0xcf, 0x96, 0x77, 0x01, 0x2b, 0xbb, 0x3f, 0xbd, 0xb2, + 0x5b, 0xe7, 0xd3, 0x96, 0x65, 0x69, 0xff, 0x66, 0x80, 0xb7, 0x17, 0xcc, 0x4d, 0xf8, 0x1e, 0xc8, + 0xf9, 0x7c, 0x10, 0x8f, 0xfe, 0x95, 0x30, 0xb0, 0x72, 0x4f, 0xd0, 0x2e, 0x52, 0x18, 0x7c, 0x0e, + 0x56, 0x44, 0xb4, 0x7d, 0x62, 0xe5, 0x9f, 0x66, 0xba, 0xde, 0xec, 0xc6, 0x6a, 0x96, 0xc3, 0xc0, + 0x5a, 0x19, 0xa3, 0x63, 0x4a, 0xb8, 0x09, 0x8a, 0x0e, 0x6e, 0xfa, 0x6e, 0x27, 0xde, 0x96, 0x95, + 0x66, 0x45, 0x3d, 0x52, 0x6b, 0x3b, 0xc2, 0x50, 0x62, 0x6d, 0xee, 0xbc, 0x3e, 0xae, 0x2e, 0xbd, + 0x39, 0xae, 0x2e, 0x1d, 0x1d, 0x57, 0x97, 0x7e, 0x0c, 0xab, 0xc6, 0xeb, 0xb0, 0x6a, 0xbc, 0x09, + 0xab, 0xc6, 0x51, 0x58, 0x35, 0xfe, 0x0a, 0xab, 0xc6, 0x4f, 0x7f, 0x57, 0x97, 0xbe, 0xbb, 0x99, + 0xe1, 0xbf, 0x04, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x7f, 0xe1, 0x3a, 0x73, 0x64, 0x10, 0x00, 0x00, } +func (m *MatchCondition) 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 *MatchCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MatchCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + 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 *MutatingWebhook) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -435,6 +501,20 @@ func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 + } + } if m.ObjectSelector != nil { { size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) @@ -791,6 +871,20 @@ func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + } if m.ObjectSelector != nil { { size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) @@ -1036,6 +1130,19 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *MatchCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *MutatingWebhook) Size() (n int) { if m == nil { return 0 @@ -1085,6 +1192,12 @@ func (m *MutatingWebhook) Size() (n int) { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1235,6 +1348,12 @@ func (m *ValidatingWebhook) Size() (n int) { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1299,6 +1418,17 @@ func sovGenerated(x uint64) (n int) { func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (this *MatchCondition) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MatchCondition{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} func (this *MutatingWebhook) String() string { if this == nil { return "nil" @@ -1308,6 +1438,11 @@ func (this *MutatingWebhook) String() string { repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," } repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&MutatingWebhook{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, @@ -1320,6 +1455,7 @@ func (this *MutatingWebhook) String() string { `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, `ReinvocationPolicy:` + valueToStringGenerated(this.ReinvocationPolicy) + `,`, `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, `}`, }, "") return s @@ -1402,6 +1538,11 @@ func (this *ValidatingWebhook) String() string { repeatedStringForRules += strings.Replace(strings.Replace(f.String(), "RuleWithOperations", "RuleWithOperations", 1), `&`, ``, 1) + "," } repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&ValidatingWebhook{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, @@ -1413,6 +1554,7 @@ func (this *ValidatingWebhook) String() string { `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v1.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, `}`, }, "") return s @@ -1469,6 +1611,120 @@ func valueToStringGenerated(v interface{}) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("*%v", pv) } +func (m *MatchCondition) 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: MatchCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchCondition: 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 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 *MutatingWebhook) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1853,6 +2109,40 @@ func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", 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.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2920,6 +3210,40 @@ func (m *ValidatingWebhook) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", 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.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/admissionregistration/v1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1/generated.proto index aa266a2a5..cdf1f4765 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/generated.proto +++ b/vendor/k8s.io/api/admissionregistration/v1/generated.proto @@ -28,6 +28,35 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". option go_package = "k8s.io/api/admissionregistration/v1"; +// MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook. +message MatchCondition { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + optional string name = 1; + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + optional string expression = 2; +} + // MutatingWebhook describes an admission webhook and the resources and operations it applies to. message MutatingWebhook { // The name of the admission webhook. @@ -173,6 +202,28 @@ message MutatingWebhook { // Defaults to "Never". // +optional optional string reinvocationPolicy = 10; + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + repeated MatchCondition matchConditions = 12; } // MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. @@ -409,6 +460,28 @@ message ValidatingWebhook { // include any versions known to the API Server, calls to the webhook will fail // and be subject to the failure policy. repeated string admissionReviewVersions = 8; + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + repeated MatchCondition matchConditions = 11; } // ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. diff --git a/vendor/k8s.io/api/admissionregistration/v1/types.go b/vendor/k8s.io/api/admissionregistration/v1/types.go index e74b276f6..74f17d54a 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/types.go +++ b/vendor/k8s.io/api/admissionregistration/v1/types.go @@ -307,6 +307,28 @@ type ValidatingWebhook struct { // include any versions known to the API Server, calls to the webhook will fail // and be subject to the failure policy. AdmissionReviewVersions []string `json:"admissionReviewVersions" protobuf:"bytes,8,rep,name=admissionReviewVersions"` + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,11,opt,name=matchConditions"` } // MutatingWebhook describes an admission webhook and the resources and operations it applies to. @@ -454,6 +476,28 @@ type MutatingWebhook struct { // Defaults to "Never". // +optional ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,10,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"` + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,12,opt,name=matchConditions"` } // ReinvocationPolicyType specifies what type of policy the admission hook uses. @@ -563,3 +607,32 @@ type ServiceReference struct { // +optional Port *int32 `json:"port,omitempty" protobuf:"varint,4,opt,name=port"` } + +// MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook. +type MatchCondition struct { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + Expression string `json:"expression" protobuf:"bytes,2,opt,name=expression"` +} diff --git a/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go index ba92729c3..ce306b307 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admissionregistration/v1/types_swagger_doc_generated.go @@ -24,9 +24,19 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_MatchCondition = map[string]string{ + "": "MatchCondition represents a condition which must by fulfilled for a request to be sent to a webhook.", + "name": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.", + "expression": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.", +} + +func (MatchCondition) SwaggerDoc() map[string]string { + return map_MatchCondition +} + var map_MutatingWebhook = map[string]string{ "": "MutatingWebhook describes an admission webhook and the resources and operations it applies to.", "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", @@ -40,6 +50,7 @@ var map_MutatingWebhook = map[string]string{ "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", "reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate.", } func (MutatingWebhook) SwaggerDoc() map[string]string { @@ -111,6 +122,7 @@ var map_ValidatingWebhook = map[string]string{ "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: None, NoneOnDryRun (webhooks created via v1beta1 may also specify Some or Unknown). Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some.", "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 10 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate.", } func (ValidatingWebhook) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go index cff7377a5..b95609913 100644 --- a/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/admissionregistration/v1/zz_generated.deepcopy.go @@ -26,6 +26,22 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchCondition) DeepCopyInto(out *MatchCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchCondition. +func (in *MatchCondition) DeepCopy() *MatchCondition { + if in == nil { + return nil + } + out := new(MatchCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = *in @@ -77,6 +93,11 @@ func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = new(ReinvocationPolicyType) **out = **in } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } @@ -286,6 +307,11 @@ func (in *ValidatingWebhook) DeepCopyInto(out *ValidatingWebhook) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go index a00f532d2..746535026 100644 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go @@ -45,10 +45,94 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +func (m *AuditAnnotation) Reset() { *m = AuditAnnotation{} } +func (*AuditAnnotation) ProtoMessage() {} +func (*AuditAnnotation) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{0} +} +func (m *AuditAnnotation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AuditAnnotation) 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 *AuditAnnotation) XXX_Merge(src proto.Message) { + xxx_messageInfo_AuditAnnotation.Merge(m, src) +} +func (m *AuditAnnotation) XXX_Size() int { + return m.Size() +} +func (m *AuditAnnotation) XXX_DiscardUnknown() { + xxx_messageInfo_AuditAnnotation.DiscardUnknown(m) +} + +var xxx_messageInfo_AuditAnnotation proto.InternalMessageInfo + +func (m *ExpressionWarning) Reset() { *m = ExpressionWarning{} } +func (*ExpressionWarning) ProtoMessage() {} +func (*ExpressionWarning) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{1} +} +func (m *ExpressionWarning) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ExpressionWarning) 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 *ExpressionWarning) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExpressionWarning.Merge(m, src) +} +func (m *ExpressionWarning) XXX_Size() int { + return m.Size() +} +func (m *ExpressionWarning) XXX_DiscardUnknown() { + xxx_messageInfo_ExpressionWarning.DiscardUnknown(m) +} + +var xxx_messageInfo_ExpressionWarning proto.InternalMessageInfo + +func (m *MatchCondition) Reset() { *m = MatchCondition{} } +func (*MatchCondition) ProtoMessage() {} +func (*MatchCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{2} +} +func (m *MatchCondition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MatchCondition) 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 *MatchCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_MatchCondition.Merge(m, src) +} +func (m *MatchCondition) XXX_Size() int { + return m.Size() +} +func (m *MatchCondition) XXX_DiscardUnknown() { + xxx_messageInfo_MatchCondition.DiscardUnknown(m) +} + +var xxx_messageInfo_MatchCondition proto.InternalMessageInfo + func (m *MatchResources) Reset() { *m = MatchResources{} } func (*MatchResources) ProtoMessage() {} func (*MatchResources) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{0} + return fileDescriptor_c3be8d256e3ae3cf, []int{3} } func (m *MatchResources) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -76,7 +160,7 @@ var xxx_messageInfo_MatchResources proto.InternalMessageInfo func (m *NamedRuleWithOperations) Reset() { *m = NamedRuleWithOperations{} } func (*NamedRuleWithOperations) ProtoMessage() {} func (*NamedRuleWithOperations) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{1} + return fileDescriptor_c3be8d256e3ae3cf, []int{4} } func (m *NamedRuleWithOperations) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -104,7 +188,7 @@ var xxx_messageInfo_NamedRuleWithOperations proto.InternalMessageInfo func (m *ParamKind) Reset() { *m = ParamKind{} } func (*ParamKind) ProtoMessage() {} func (*ParamKind) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{2} + return fileDescriptor_c3be8d256e3ae3cf, []int{5} } func (m *ParamKind) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -132,7 +216,7 @@ var xxx_messageInfo_ParamKind proto.InternalMessageInfo func (m *ParamRef) Reset() { *m = ParamRef{} } func (*ParamRef) ProtoMessage() {} func (*ParamRef) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{3} + return fileDescriptor_c3be8d256e3ae3cf, []int{6} } func (m *ParamRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -157,10 +241,38 @@ func (m *ParamRef) XXX_DiscardUnknown() { var xxx_messageInfo_ParamRef proto.InternalMessageInfo +func (m *TypeChecking) Reset() { *m = TypeChecking{} } +func (*TypeChecking) ProtoMessage() {} +func (*TypeChecking) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{7} +} +func (m *TypeChecking) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TypeChecking) 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 *TypeChecking) XXX_Merge(src proto.Message) { + xxx_messageInfo_TypeChecking.Merge(m, src) +} +func (m *TypeChecking) XXX_Size() int { + return m.Size() +} +func (m *TypeChecking) XXX_DiscardUnknown() { + xxx_messageInfo_TypeChecking.DiscardUnknown(m) +} + +var xxx_messageInfo_TypeChecking proto.InternalMessageInfo + func (m *ValidatingAdmissionPolicy) Reset() { *m = ValidatingAdmissionPolicy{} } func (*ValidatingAdmissionPolicy) ProtoMessage() {} func (*ValidatingAdmissionPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{4} + return fileDescriptor_c3be8d256e3ae3cf, []int{8} } func (m *ValidatingAdmissionPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -188,7 +300,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicy proto.InternalMessageInfo func (m *ValidatingAdmissionPolicyBinding) Reset() { *m = ValidatingAdmissionPolicyBinding{} } func (*ValidatingAdmissionPolicyBinding) ProtoMessage() {} func (*ValidatingAdmissionPolicyBinding) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{5} + return fileDescriptor_c3be8d256e3ae3cf, []int{9} } func (m *ValidatingAdmissionPolicyBinding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -216,7 +328,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyBinding proto.InternalMessageInfo func (m *ValidatingAdmissionPolicyBindingList) Reset() { *m = ValidatingAdmissionPolicyBindingList{} } func (*ValidatingAdmissionPolicyBindingList) ProtoMessage() {} func (*ValidatingAdmissionPolicyBindingList) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{6} + return fileDescriptor_c3be8d256e3ae3cf, []int{10} } func (m *ValidatingAdmissionPolicyBindingList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -244,7 +356,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyBindingList proto.InternalMessageIn func (m *ValidatingAdmissionPolicyBindingSpec) Reset() { *m = ValidatingAdmissionPolicyBindingSpec{} } func (*ValidatingAdmissionPolicyBindingSpec) ProtoMessage() {} func (*ValidatingAdmissionPolicyBindingSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{7} + return fileDescriptor_c3be8d256e3ae3cf, []int{11} } func (m *ValidatingAdmissionPolicyBindingSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -272,7 +384,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyBindingSpec proto.InternalMessageIn func (m *ValidatingAdmissionPolicyList) Reset() { *m = ValidatingAdmissionPolicyList{} } func (*ValidatingAdmissionPolicyList) ProtoMessage() {} func (*ValidatingAdmissionPolicyList) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{8} + return fileDescriptor_c3be8d256e3ae3cf, []int{12} } func (m *ValidatingAdmissionPolicyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -300,7 +412,7 @@ var xxx_messageInfo_ValidatingAdmissionPolicyList proto.InternalMessageInfo func (m *ValidatingAdmissionPolicySpec) Reset() { *m = ValidatingAdmissionPolicySpec{} } func (*ValidatingAdmissionPolicySpec) ProtoMessage() {} func (*ValidatingAdmissionPolicySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{9} + return fileDescriptor_c3be8d256e3ae3cf, []int{13} } func (m *ValidatingAdmissionPolicySpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -325,10 +437,38 @@ func (m *ValidatingAdmissionPolicySpec) XXX_DiscardUnknown() { var xxx_messageInfo_ValidatingAdmissionPolicySpec proto.InternalMessageInfo +func (m *ValidatingAdmissionPolicyStatus) Reset() { *m = ValidatingAdmissionPolicyStatus{} } +func (*ValidatingAdmissionPolicyStatus) ProtoMessage() {} +func (*ValidatingAdmissionPolicyStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_c3be8d256e3ae3cf, []int{14} +} +func (m *ValidatingAdmissionPolicyStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatingAdmissionPolicyStatus) 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 *ValidatingAdmissionPolicyStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatingAdmissionPolicyStatus.Merge(m, src) +} +func (m *ValidatingAdmissionPolicyStatus) XXX_Size() int { + return m.Size() +} +func (m *ValidatingAdmissionPolicyStatus) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatingAdmissionPolicyStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatingAdmissionPolicyStatus proto.InternalMessageInfo + func (m *Validation) Reset() { *m = Validation{} } func (*Validation) ProtoMessage() {} func (*Validation) Descriptor() ([]byte, []int) { - return fileDescriptor_c3be8d256e3ae3cf, []int{10} + return fileDescriptor_c3be8d256e3ae3cf, []int{15} } func (m *Validation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -354,16 +494,21 @@ func (m *Validation) XXX_DiscardUnknown() { var xxx_messageInfo_Validation proto.InternalMessageInfo func init() { + proto.RegisterType((*AuditAnnotation)(nil), "k8s.io.api.admissionregistration.v1alpha1.AuditAnnotation") + proto.RegisterType((*ExpressionWarning)(nil), "k8s.io.api.admissionregistration.v1alpha1.ExpressionWarning") + proto.RegisterType((*MatchCondition)(nil), "k8s.io.api.admissionregistration.v1alpha1.MatchCondition") proto.RegisterType((*MatchResources)(nil), "k8s.io.api.admissionregistration.v1alpha1.MatchResources") proto.RegisterType((*NamedRuleWithOperations)(nil), "k8s.io.api.admissionregistration.v1alpha1.NamedRuleWithOperations") proto.RegisterType((*ParamKind)(nil), "k8s.io.api.admissionregistration.v1alpha1.ParamKind") proto.RegisterType((*ParamRef)(nil), "k8s.io.api.admissionregistration.v1alpha1.ParamRef") + proto.RegisterType((*TypeChecking)(nil), "k8s.io.api.admissionregistration.v1alpha1.TypeChecking") proto.RegisterType((*ValidatingAdmissionPolicy)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicy") proto.RegisterType((*ValidatingAdmissionPolicyBinding)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBinding") proto.RegisterType((*ValidatingAdmissionPolicyBindingList)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBindingList") proto.RegisterType((*ValidatingAdmissionPolicyBindingSpec)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBindingSpec") proto.RegisterType((*ValidatingAdmissionPolicyList)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyList") proto.RegisterType((*ValidatingAdmissionPolicySpec)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicySpec") + proto.RegisterType((*ValidatingAdmissionPolicyStatus)(nil), "k8s.io.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus") proto.RegisterType((*Validation)(nil), "k8s.io.api.admissionregistration.v1alpha1.Validation") } @@ -372,73 +517,194 @@ func init() { } var fileDescriptor_c3be8d256e3ae3cf = []byte{ - // 1054 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcd, 0x6e, 0x1c, 0x45, - 0x10, 0xf6, 0xc4, 0x9b, 0xc4, 0xdb, 0x1b, 0x3b, 0x76, 0xe3, 0x88, 0xc5, 0x82, 0xdd, 0xd5, 0x2a, - 0x42, 0xf6, 0x81, 0x19, 0xec, 0x04, 0x02, 0x27, 0x94, 0x21, 0x41, 0x44, 0xb1, 0x63, 0xab, 0x8d, - 0x12, 0x09, 0x11, 0x89, 0xf6, 0x4c, 0x7b, 0xb6, 0xb3, 0x3b, 0x3f, 0x4c, 0xf7, 0x58, 0xb6, 0x38, - 0x80, 0xc4, 0x0b, 0x70, 0xe0, 0x41, 0x38, 0x71, 0xe1, 0x05, 0x7c, 0xcc, 0xd1, 0x5c, 0x46, 0x78, - 0xb8, 0xc0, 0x0b, 0x80, 0xe4, 0x13, 0xea, 0x9e, 0x9e, 0xbf, 0xfd, 0xc1, 0xeb, 0x60, 0xe5, 0xb6, - 0x5d, 0x3f, 0xdf, 0x57, 0x55, 0x5d, 0x35, 0xd5, 0x0b, 0x50, 0xff, 0x23, 0xa6, 0x53, 0xdf, 0xe8, - 0x47, 0x7b, 0x24, 0xf4, 0x08, 0x27, 0xcc, 0x38, 0x20, 0x9e, 0xed, 0x87, 0x86, 0x52, 0xe0, 0x80, - 0x1a, 0xd8, 0x76, 0x29, 0x63, 0xd4, 0xf7, 0x42, 0xe2, 0x50, 0xc6, 0x43, 0xcc, 0xa9, 0xef, 0x19, - 0x07, 0xeb, 0x78, 0x10, 0xf4, 0xf0, 0xba, 0xe1, 0x10, 0x8f, 0x84, 0x98, 0x13, 0x5b, 0x0f, 0x42, - 0x9f, 0xfb, 0x70, 0x2d, 0x75, 0xd5, 0x71, 0x40, 0xf5, 0xb1, 0xae, 0x7a, 0xe6, 0xba, 0xf2, 0x9e, - 0x43, 0x79, 0x2f, 0xda, 0xd3, 0x2d, 0xdf, 0x35, 0x1c, 0xdf, 0xf1, 0x0d, 0x89, 0xb0, 0x17, 0xed, - 0xcb, 0x93, 0x3c, 0xc8, 0x5f, 0x29, 0xf2, 0xca, 0x9d, 0x29, 0x82, 0x1a, 0x0e, 0x67, 0xe5, 0x6e, - 0xe1, 0xe4, 0x62, 0xab, 0x47, 0x3d, 0x12, 0x1e, 0x19, 0x41, 0xdf, 0x11, 0x02, 0x66, 0xb8, 0x84, - 0xe3, 0x71, 0x5e, 0xc6, 0x24, 0xaf, 0x30, 0xf2, 0x38, 0x75, 0xc9, 0x88, 0xc3, 0x87, 0xe7, 0x39, - 0x30, 0xab, 0x47, 0x5c, 0x3c, 0xec, 0xd7, 0xfd, 0xad, 0x06, 0x16, 0xb6, 0x30, 0xb7, 0x7a, 0x88, - 0x30, 0x3f, 0x0a, 0x2d, 0xc2, 0xe0, 0x21, 0x58, 0xf2, 0xb0, 0x4b, 0x58, 0x80, 0x2d, 0xb2, 0x4b, - 0x06, 0xc4, 0xe2, 0x7e, 0xd8, 0xd4, 0x3a, 0xda, 0x6a, 0x63, 0xe3, 0x8e, 0x5e, 0x14, 0x37, 0xa7, - 0xd1, 0x83, 0xbe, 0x23, 0x04, 0x4c, 0x17, 0xd9, 0xe8, 0x07, 0xeb, 0xfa, 0x26, 0xde, 0x23, 0x83, - 0xcc, 0xd5, 0xbc, 0x95, 0xc4, 0xed, 0xa5, 0x27, 0xc3, 0x88, 0x68, 0x94, 0x04, 0xfa, 0x60, 0xc1, - 0xdf, 0x7b, 0x41, 0x2c, 0x9e, 0xd3, 0x5e, 0x79, 0x75, 0x5a, 0x98, 0xc4, 0xed, 0x85, 0xed, 0x0a, - 0x1c, 0x1a, 0x82, 0x87, 0xdf, 0x81, 0xf9, 0x50, 0xe5, 0x8d, 0xa2, 0x01, 0x61, 0xcd, 0xd9, 0xce, - 0xec, 0x6a, 0x63, 0xc3, 0xd4, 0xa7, 0xee, 0x21, 0x5d, 0x24, 0x66, 0x0b, 0xe7, 0x67, 0x94, 0xf7, - 0xb6, 0x03, 0x92, 0xea, 0x99, 0x79, 0xeb, 0x38, 0x6e, 0xcf, 0x24, 0x71, 0x7b, 0x1e, 0x95, 0x09, - 0x50, 0x95, 0x0f, 0xfe, 0xa4, 0x81, 0x65, 0x72, 0x68, 0x0d, 0x22, 0x9b, 0x54, 0xec, 0x9a, 0xb5, - 0x4b, 0x0b, 0xe4, 0x6d, 0x15, 0xc8, 0xf2, 0xc3, 0x31, 0x3c, 0x68, 0x2c, 0x3b, 0x7c, 0x00, 0x1a, - 0xae, 0x68, 0x8a, 0x1d, 0x7f, 0x40, 0xad, 0xa3, 0xe6, 0xf5, 0x8e, 0xb6, 0x5a, 0x37, 0xbb, 0x49, - 0xdc, 0x6e, 0x6c, 0x15, 0xe2, 0xb3, 0xb8, 0x7d, 0xb3, 0x74, 0xfc, 0xe2, 0x28, 0x20, 0xa8, 0xec, - 0xd6, 0x3d, 0xd1, 0xc0, 0x9b, 0x13, 0xa2, 0x82, 0xf7, 0x8a, 0xca, 0xcb, 0xd6, 0x68, 0x6a, 0x9d, - 0xd9, 0xd5, 0xba, 0xb9, 0x54, 0xae, 0x98, 0x54, 0xa0, 0xaa, 0x1d, 0xfc, 0x41, 0x03, 0x30, 0x1c, - 0xc1, 0x53, 0x8d, 0x72, 0x6f, 0x9a, 0x7a, 0xe9, 0x63, 0x8a, 0xb4, 0xa2, 0x8a, 0x04, 0x47, 0x75, - 0x68, 0x0c, 0x5d, 0x17, 0x83, 0xfa, 0x0e, 0x0e, 0xb1, 0xfb, 0x98, 0x7a, 0x36, 0xdc, 0x00, 0x00, - 0x07, 0xf4, 0x29, 0x09, 0x05, 0x99, 0x9c, 0x94, 0xba, 0x09, 0x15, 0x20, 0xb8, 0xbf, 0xf3, 0x48, - 0x69, 0x50, 0xc9, 0x0a, 0x76, 0x40, 0xad, 0x4f, 0x3d, 0x5b, 0xc6, 0x5d, 0x37, 0x6f, 0x28, 0xeb, - 0x9a, 0xc0, 0x43, 0x52, 0xd3, 0x7d, 0x0e, 0xe6, 0x24, 0x05, 0x22, 0xfb, 0xc2, 0x5a, 0x4c, 0x8b, - 0xc2, 0xce, 0xad, 0x45, 0x45, 0x90, 0xd4, 0x40, 0x03, 0xd4, 0xf3, 0x79, 0x52, 0xa0, 0x4b, 0xca, - 0xac, 0x9e, 0xcf, 0x1e, 0x2a, 0x6c, 0xba, 0x7f, 0x69, 0xe0, 0xad, 0xa7, 0x78, 0x40, 0x6d, 0xcc, - 0xa9, 0xe7, 0xdc, 0xcf, 0x6a, 0x95, 0x5e, 0x1d, 0xfc, 0x1a, 0xcc, 0x89, 0xa9, 0xb2, 0x31, 0xc7, - 0x6a, 0xf4, 0xdf, 0x9f, 0x6e, 0x06, 0xd3, 0x81, 0xdb, 0x22, 0x1c, 0x17, 0x25, 0x28, 0x64, 0x28, - 0x47, 0x85, 0x2f, 0x40, 0x8d, 0x05, 0xc4, 0x52, 0x17, 0xf7, 0xf9, 0x05, 0x1a, 0x7d, 0x62, 0xd4, - 0xbb, 0x01, 0xb1, 0x8a, 0xe2, 0x88, 0x13, 0x92, 0x1c, 0xdd, 0x7f, 0x34, 0xd0, 0x99, 0xe8, 0x65, - 0x52, 0xcf, 0xa6, 0x9e, 0xf3, 0x1a, 0x52, 0xfe, 0xa6, 0x92, 0xf2, 0xf6, 0x65, 0xa4, 0xac, 0x82, - 0x9f, 0x98, 0xf9, 0xdf, 0x1a, 0xb8, 0x7d, 0x9e, 0xf3, 0x26, 0x65, 0x1c, 0x7e, 0x35, 0x92, 0xbd, - 0x3e, 0xe5, 0x47, 0x97, 0xb2, 0x34, 0xf7, 0x45, 0x45, 0x3f, 0x97, 0x49, 0x4a, 0x99, 0x07, 0xe0, - 0x2a, 0xe5, 0xc4, 0x15, 0x63, 0x2a, 0x3e, 0x6b, 0x8f, 0x2f, 0x31, 0x75, 0x73, 0x5e, 0xf1, 0x5e, - 0x7d, 0x24, 0x18, 0x50, 0x4a, 0xd4, 0xfd, 0xf9, 0xca, 0xf9, 0x89, 0x8b, 0x3a, 0x89, 0xe1, 0x0d, - 0xa4, 0xf0, 0x49, 0x31, 0x60, 0xf9, 0x35, 0xee, 0xe4, 0x1a, 0x54, 0xb2, 0x82, 0xcf, 0xc1, 0x5c, - 0xa0, 0x46, 0x73, 0xcc, 0x86, 0x3a, 0x2f, 0xa3, 0x6c, 0xaa, 0xcd, 0x1b, 0xa2, 0x5a, 0xd9, 0x09, - 0xe5, 0x90, 0x30, 0x02, 0x0b, 0x6e, 0x65, 0x25, 0x37, 0x67, 0x25, 0xc9, 0xc7, 0x17, 0x20, 0xa9, - 0xee, 0xf4, 0x74, 0x19, 0x56, 0x65, 0x68, 0x88, 0xa4, 0xfb, 0xa7, 0x06, 0xde, 0x99, 0x58, 0xb2, - 0xd7, 0xd0, 0x24, 0xb4, 0xda, 0x24, 0x0f, 0x2e, 0xa5, 0x49, 0xc6, 0x77, 0xc7, 0xaf, 0xb3, 0xff, - 0x91, 0xaa, 0x6c, 0x0b, 0x0c, 0xea, 0x41, 0xf6, 0x81, 0x57, 0xb9, 0xde, 0xbd, 0xe8, 0x1d, 0x0b, - 0x5f, 0x73, 0x5e, 0x7c, 0x81, 0xf3, 0x23, 0x2a, 0x50, 0xe1, 0xb7, 0x60, 0x51, 0xde, 0xc0, 0xa7, - 0xbe, 0x27, 0x00, 0xa8, 0xc7, 0xb3, 0x35, 0xf6, 0x3f, 0x2e, 0x7a, 0x39, 0x89, 0xdb, 0x8b, 0x5b, - 0x43, 0xb0, 0x68, 0x84, 0x08, 0x0e, 0x40, 0xe3, 0x40, 0x15, 0x40, 0xac, 0xcf, 0xf4, 0xdd, 0xf3, - 0xc1, 0x2b, 0x94, 0xdc, 0xf7, 0xcc, 0x37, 0x54, 0x8d, 0x1b, 0x85, 0x8c, 0xa1, 0x32, 0x3c, 0xdc, - 0x04, 0xf3, 0xfb, 0x98, 0x0e, 0xa2, 0x90, 0xa8, 0x17, 0x45, 0x4d, 0xce, 0xd9, 0xbb, 0x62, 0xdb, - 0x7f, 0x56, 0x56, 0x9c, 0xc5, 0xed, 0xa5, 0x8a, 0x40, 0xbe, 0x2a, 0xaa, 0xce, 0xdd, 0x5f, 0x34, - 0x00, 0x0a, 0x2a, 0x78, 0x1b, 0x80, 0x87, 0x87, 0x41, 0x48, 0x58, 0x69, 0xfd, 0xd6, 0x44, 0x48, - 0xa8, 0x24, 0x87, 0x6b, 0xe0, 0xba, 0x4b, 0x18, 0xc3, 0x4e, 0xb6, 0x1e, 0x6f, 0xaa, 0xa8, 0xaf, - 0x6f, 0xa5, 0x62, 0x94, 0xe9, 0xe1, 0x33, 0x70, 0x2d, 0x24, 0x98, 0xf9, 0x9e, 0x9c, 0xbb, 0xba, - 0xf9, 0x49, 0x12, 0xb7, 0xaf, 0x21, 0x29, 0x39, 0x8b, 0xdb, 0xeb, 0xd3, 0x3c, 0xe8, 0xf5, 0x5d, - 0x8e, 0x79, 0xc4, 0x52, 0x27, 0xa4, 0xe0, 0xcc, 0xed, 0xe3, 0xd3, 0xd6, 0xcc, 0xcb, 0xd3, 0xd6, - 0xcc, 0xc9, 0x69, 0x6b, 0xe6, 0xfb, 0xa4, 0xa5, 0x1d, 0x27, 0x2d, 0xed, 0x65, 0xd2, 0xd2, 0x4e, - 0x92, 0x96, 0xf6, 0x7b, 0xd2, 0xd2, 0x7e, 0xfc, 0xa3, 0x35, 0xf3, 0xe5, 0xda, 0xd4, 0xff, 0x7d, - 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x20, 0xc8, 0x63, 0x1d, 0x40, 0x0d, 0x00, 0x00, + // 1407 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcb, 0x6f, 0x1b, 0x45, + 0x18, 0xcf, 0xc6, 0x4e, 0x9a, 0x8c, 0xf3, 0xb0, 0x87, 0x56, 0x75, 0x23, 0x6a, 0x47, 0xab, 0x0a, + 0x35, 0x12, 0xec, 0x92, 0xb4, 0x50, 0x40, 0x48, 0x28, 0xdb, 0x17, 0x7d, 0xa4, 0x89, 0xa6, 0x28, + 0x91, 0x10, 0x95, 0x98, 0xec, 0x4e, 0xec, 0xa9, 0xbd, 0x0f, 0x76, 0xd6, 0xa1, 0x11, 0x48, 0x54, + 0xe2, 0x02, 0x37, 0x0e, 0x5c, 0xf8, 0x5f, 0xb8, 0x70, 0xeb, 0xb1, 0xc7, 0x72, 0xc0, 0x22, 0xe6, + 0xc2, 0x5f, 0x00, 0x52, 0x2e, 0xa0, 0x99, 0x9d, 0x7d, 0x3b, 0xc4, 0x2e, 0x81, 0x9b, 0xf7, 0x7b, + 0xfc, 0x7e, 0xf3, 0x7d, 0xf3, 0x7d, 0x33, 0xdf, 0x18, 0xa0, 0xce, 0x3b, 0x4c, 0xa3, 0xae, 0xde, + 0xe9, 0xed, 0x12, 0xdf, 0x21, 0x01, 0x61, 0xfa, 0x3e, 0x71, 0x2c, 0xd7, 0xd7, 0xa5, 0x02, 0x7b, + 0x54, 0xc7, 0x96, 0x4d, 0x19, 0xa3, 0xae, 0xe3, 0x93, 0x16, 0x65, 0x81, 0x8f, 0x03, 0xea, 0x3a, + 0xfa, 0xfe, 0x2a, 0xee, 0x7a, 0x6d, 0xbc, 0xaa, 0xb7, 0x88, 0x43, 0x7c, 0x1c, 0x10, 0x4b, 0xf3, + 0x7c, 0x37, 0x70, 0xe1, 0x4a, 0xe8, 0xaa, 0x61, 0x8f, 0x6a, 0x43, 0x5d, 0xb5, 0xc8, 0x75, 0xe9, + 0x8d, 0x16, 0x0d, 0xda, 0xbd, 0x5d, 0xcd, 0x74, 0x6d, 0xbd, 0xe5, 0xb6, 0x5c, 0x5d, 0x20, 0xec, + 0xf6, 0xf6, 0xc4, 0x97, 0xf8, 0x10, 0xbf, 0x42, 0xe4, 0xa5, 0x2b, 0x23, 0x2c, 0x2a, 0xbf, 0x9c, + 0xa5, 0xab, 0x89, 0x93, 0x8d, 0xcd, 0x36, 0x75, 0x88, 0x7f, 0xa0, 0x7b, 0x9d, 0x16, 0x17, 0x30, + 0xdd, 0x26, 0x01, 0x1e, 0xe6, 0xa5, 0x1f, 0xe7, 0xe5, 0xf7, 0x9c, 0x80, 0xda, 0xa4, 0xe0, 0xf0, + 0xf6, 0x49, 0x0e, 0xcc, 0x6c, 0x13, 0x1b, 0xe7, 0xfd, 0x54, 0x06, 0x16, 0xd7, 0x7b, 0x16, 0x0d, + 0xd6, 0x1d, 0xc7, 0x0d, 0x44, 0x10, 0xf0, 0x22, 0x28, 0x75, 0xc8, 0x41, 0x5d, 0x59, 0x56, 0x2e, + 0xcf, 0x1a, 0x95, 0x67, 0xfd, 0xe6, 0xc4, 0xa0, 0xdf, 0x2c, 0xdd, 0x23, 0x07, 0x88, 0xcb, 0xe1, + 0x3a, 0x58, 0xdc, 0xc7, 0xdd, 0x1e, 0xb9, 0xf9, 0xc4, 0xf3, 0x89, 0x48, 0x41, 0x7d, 0x52, 0x98, + 0x9e, 0x97, 0xa6, 0x8b, 0xdb, 0x59, 0x35, 0xca, 0xdb, 0xab, 0x5d, 0x50, 0x4b, 0xbe, 0x76, 0xb0, + 0xef, 0x50, 0xa7, 0x05, 0x5f, 0x07, 0x33, 0x7b, 0x94, 0x74, 0x2d, 0x44, 0xf6, 0x24, 0x60, 0x55, + 0x02, 0xce, 0xdc, 0x92, 0x72, 0x14, 0x5b, 0xc0, 0x15, 0x70, 0xe6, 0xf3, 0xd0, 0xb1, 0x5e, 0x12, + 0xc6, 0x8b, 0xd2, 0xf8, 0x8c, 0xc4, 0x43, 0x91, 0x5e, 0xdd, 0x03, 0x0b, 0x1b, 0x38, 0x30, 0xdb, + 0xd7, 0x5d, 0xc7, 0xa2, 0x22, 0xc2, 0x65, 0x50, 0x76, 0xb0, 0x4d, 0x64, 0x88, 0x73, 0xd2, 0xb3, + 0xfc, 0x00, 0xdb, 0x04, 0x09, 0x0d, 0x5c, 0x03, 0x80, 0xe4, 0xe3, 0x83, 0xd2, 0x0e, 0xa4, 0x42, + 0x4b, 0x59, 0xa9, 0x3f, 0x97, 0x25, 0x11, 0x22, 0xcc, 0xed, 0xf9, 0x26, 0x61, 0xf0, 0x09, 0xa8, + 0x71, 0x38, 0xe6, 0x61, 0x93, 0x3c, 0x24, 0x5d, 0x62, 0x06, 0xae, 0x2f, 0x58, 0x2b, 0x6b, 0x57, + 0xb4, 0xa4, 0x4e, 0xe3, 0x1d, 0xd3, 0xbc, 0x4e, 0x8b, 0x0b, 0x98, 0xc6, 0x0b, 0x43, 0xdb, 0x5f, + 0xd5, 0xee, 0xe3, 0x5d, 0xd2, 0x8d, 0x5c, 0x8d, 0x73, 0x83, 0x7e, 0xb3, 0xf6, 0x20, 0x8f, 0x88, + 0x8a, 0x24, 0xd0, 0x05, 0x0b, 0xee, 0xee, 0x63, 0x62, 0x06, 0x31, 0xed, 0xe4, 0xcb, 0xd3, 0xc2, + 0x41, 0xbf, 0xb9, 0xb0, 0x99, 0x81, 0x43, 0x39, 0x78, 0xf8, 0x15, 0x98, 0xf7, 0x65, 0xdc, 0xa8, + 0xd7, 0x25, 0xac, 0x5e, 0x5a, 0x2e, 0x5d, 0xae, 0xac, 0x19, 0xda, 0xc8, 0xed, 0xa8, 0xf1, 0xc0, + 0x2c, 0xee, 0xbc, 0x43, 0x83, 0xf6, 0xa6, 0x47, 0x42, 0x3d, 0x33, 0xce, 0xc9, 0xc4, 0xcf, 0xa3, + 0x34, 0x01, 0xca, 0xf2, 0xc1, 0xef, 0x15, 0x70, 0x96, 0x3c, 0x31, 0xbb, 0x3d, 0x8b, 0x64, 0xec, + 0xea, 0xe5, 0x53, 0x5b, 0xc8, 0xab, 0x72, 0x21, 0x67, 0x6f, 0x0e, 0xe1, 0x41, 0x43, 0xd9, 0xe1, + 0x0d, 0x50, 0xb1, 0x79, 0x51, 0x6c, 0xb9, 0x5d, 0x6a, 0x1e, 0xd4, 0xcf, 0x88, 0x52, 0x52, 0x07, + 0xfd, 0x66, 0x65, 0x23, 0x11, 0x1f, 0xf5, 0x9b, 0x8b, 0xa9, 0xcf, 0x8f, 0x0e, 0x3c, 0x82, 0xd2, + 0x6e, 0xea, 0x0b, 0x05, 0x9c, 0x3f, 0x66, 0x55, 0xf0, 0x5a, 0x92, 0x79, 0x51, 0x1a, 0x75, 0x65, + 0xb9, 0x74, 0x79, 0xd6, 0xa8, 0xa5, 0x33, 0x26, 0x14, 0x28, 0x6b, 0x07, 0xbf, 0x56, 0x00, 0xf4, + 0x0b, 0x78, 0xb2, 0x50, 0xae, 0x8d, 0x92, 0x2f, 0x6d, 0x48, 0x92, 0x96, 0x64, 0x92, 0x60, 0x51, + 0x87, 0x86, 0xd0, 0xa9, 0x18, 0xcc, 0x6e, 0x61, 0x1f, 0xdb, 0xf7, 0xa8, 0x63, 0xf1, 0xbe, 0xc3, + 0x1e, 0xdd, 0x26, 0xbe, 0xe8, 0x3b, 0x25, 0xdb, 0x77, 0xeb, 0x5b, 0x77, 0xa4, 0x06, 0xa5, 0xac, + 0x78, 0x37, 0x77, 0xa8, 0x63, 0xc9, 0x2e, 0x8d, 0xbb, 0x99, 0xe3, 0x21, 0xa1, 0x51, 0x1f, 0x81, + 0x19, 0x41, 0xc1, 0x0f, 0x8e, 0x93, 0x7b, 0x5f, 0x07, 0xb3, 0x71, 0x3f, 0x49, 0xd0, 0x9a, 0x34, + 0x9b, 0x8d, 0x7b, 0x0f, 0x25, 0x36, 0xea, 0x0f, 0x0a, 0x98, 0xe3, 0x5b, 0x76, 0xbd, 0x4d, 0xcc, + 0x0e, 0x3f, 0xca, 0xbe, 0x51, 0x00, 0x24, 0xf9, 0x03, 0x2e, 0xdc, 0x97, 0xca, 0xda, 0xfb, 0x63, + 0x14, 0x62, 0xe1, 0x94, 0x4c, 0xb2, 0x5b, 0x50, 0x31, 0x34, 0x84, 0x53, 0xfd, 0x65, 0x12, 0x5c, + 0xd8, 0xc6, 0x5d, 0x6a, 0xe1, 0x80, 0x3a, 0xad, 0xf5, 0x88, 0x2e, 0x2c, 0x2b, 0xf8, 0x29, 0x98, + 0xe1, 0x1d, 0x6f, 0xe1, 0x00, 0xcb, 0x63, 0xe9, 0xcd, 0xd1, 0xce, 0x87, 0xf0, 0x30, 0xd8, 0x20, + 0x01, 0x4e, 0xb6, 0x27, 0x91, 0xa1, 0x18, 0x15, 0x3e, 0x06, 0x65, 0xe6, 0x11, 0x53, 0x16, 0xd5, + 0x87, 0x63, 0xc4, 0x7e, 0xec, 0xaa, 0x1f, 0x7a, 0xc4, 0x4c, 0x36, 0x8e, 0x7f, 0x21, 0xc1, 0x01, + 0x7d, 0x30, 0xcd, 0x02, 0x1c, 0xf4, 0x98, 0xb8, 0x12, 0x2a, 0x6b, 0x77, 0x4f, 0x85, 0x4d, 0x20, + 0x1a, 0x0b, 0x92, 0x6f, 0x3a, 0xfc, 0x46, 0x92, 0x49, 0xfd, 0x53, 0x01, 0xcb, 0xc7, 0xfa, 0x1a, + 0xd4, 0xb1, 0x78, 0x3d, 0xfc, 0xf7, 0x69, 0xfe, 0x2c, 0x93, 0xe6, 0xcd, 0xd3, 0x08, 0x5c, 0x2e, + 0xfe, 0xb8, 0x6c, 0xab, 0x7f, 0x28, 0xe0, 0xd2, 0x49, 0xce, 0xf7, 0x29, 0x0b, 0xe0, 0x27, 0x85, + 0xe8, 0xb5, 0x11, 0x2f, 0x21, 0xca, 0xc2, 0xd8, 0xe3, 0x41, 0x20, 0x92, 0xa4, 0x22, 0xf7, 0xc0, + 0x14, 0x0d, 0x88, 0xcd, 0x8f, 0x2d, 0xde, 0x5d, 0xf7, 0x4e, 0x31, 0x74, 0x63, 0x5e, 0xf2, 0x4e, + 0xdd, 0xe1, 0x0c, 0x28, 0x24, 0x52, 0xbf, 0x2d, 0x9d, 0x1c, 0x38, 0xcf, 0x13, 0x3f, 0xcc, 0x3c, + 0x21, 0x7c, 0x90, 0x1c, 0x38, 0xf1, 0x36, 0x6e, 0xc5, 0x1a, 0x94, 0xb2, 0x82, 0x8f, 0xc0, 0x8c, + 0x27, 0x8f, 0xaa, 0x21, 0x37, 0xf6, 0x49, 0x11, 0x45, 0xa7, 0x9c, 0x31, 0xc7, 0xb3, 0x15, 0x7d, + 0xa1, 0x18, 0x12, 0xf6, 0xc0, 0x82, 0x9d, 0x19, 0x51, 0x64, 0xab, 0xbc, 0x3b, 0x06, 0x49, 0x76, + 0xc6, 0x09, 0x87, 0x83, 0xac, 0x0c, 0xe5, 0x48, 0xe0, 0x0e, 0xa8, 0xed, 0xcb, 0x8c, 0xb9, 0xce, + 0xba, 0x19, 0xde, 0x33, 0x65, 0x71, 0x4d, 0xad, 0xf0, 0x91, 0x66, 0x3b, 0xaf, 0x3c, 0xea, 0x37, + 0xab, 0x79, 0x21, 0x2a, 0x62, 0xa8, 0xbf, 0x2b, 0xe0, 0xe2, 0xb1, 0x7b, 0xf1, 0x3f, 0x54, 0x1f, + 0xcd, 0x56, 0xdf, 0x8d, 0x53, 0xa9, 0xbe, 0xe1, 0x65, 0xf7, 0xe3, 0xd4, 0x3f, 0x84, 0x2a, 0xea, + 0x0d, 0x83, 0x59, 0x2f, 0xba, 0x49, 0x65, 0xac, 0x57, 0xc7, 0x2d, 0x1e, 0xee, 0x6b, 0xcc, 0xf3, + 0xab, 0x2e, 0xfe, 0x44, 0x09, 0x2a, 0xfc, 0x02, 0x54, 0x6d, 0x39, 0x4b, 0x73, 0x00, 0xea, 0x04, + 0xd1, 0xbc, 0xf0, 0x2f, 0x2a, 0xe8, 0xec, 0xa0, 0xdf, 0xac, 0x6e, 0xe4, 0x60, 0x51, 0x81, 0x08, + 0x76, 0x41, 0x25, 0xa9, 0x80, 0x68, 0xc0, 0x7c, 0xeb, 0x25, 0x52, 0xee, 0x3a, 0xc6, 0x2b, 0x32, + 0xc7, 0x95, 0x44, 0xc6, 0x50, 0x1a, 0x1e, 0xde, 0x07, 0xf3, 0x7b, 0x98, 0x76, 0x7b, 0x3e, 0x91, + 0xa3, 0x5b, 0x59, 0x34, 0xf0, 0x6b, 0x7c, 0xac, 0xba, 0x95, 0x56, 0x1c, 0xf5, 0x9b, 0xb5, 0x8c, + 0x40, 0x8c, 0x6f, 0x59, 0x67, 0xf8, 0x54, 0x01, 0x55, 0x9c, 0x7d, 0x68, 0xb1, 0xfa, 0x94, 0x88, + 0xe0, 0xbd, 0x31, 0x22, 0xc8, 0xbd, 0xd5, 0x8c, 0xba, 0x0c, 0xa3, 0x9a, 0x53, 0x30, 0x54, 0x60, + 0x83, 0x5f, 0x82, 0x45, 0x3b, 0xf3, 0x0e, 0x62, 0xf5, 0x69, 0xb1, 0x80, 0xb1, 0xb7, 0x2e, 0x46, + 0x48, 0xde, 0x7c, 0x59, 0x39, 0x43, 0x79, 0x2a, 0xf5, 0xa7, 0x49, 0xd0, 0x3c, 0xe1, 0x92, 0x85, + 0x77, 0x01, 0x74, 0x77, 0x19, 0xf1, 0xf7, 0x89, 0x75, 0x3b, 0x7c, 0xa7, 0x46, 0x53, 0x60, 0x29, + 0x19, 0x7c, 0x36, 0x0b, 0x16, 0x68, 0x88, 0x17, 0xb4, 0xc1, 0x5c, 0x90, 0x9a, 0xc9, 0xc6, 0x99, + 0x6a, 0x65, 0xa8, 0xe9, 0x91, 0xce, 0xa8, 0x0e, 0xfa, 0xcd, 0xcc, 0x90, 0x87, 0x32, 0xf0, 0xd0, + 0x04, 0xc0, 0x4c, 0xf2, 0x1a, 0x96, 0xa6, 0x3e, 0xda, 0x41, 0x93, 0x64, 0x33, 0xbe, 0x1c, 0x52, + 0x89, 0x4c, 0xc1, 0xaa, 0x7f, 0x29, 0x00, 0x24, 0xf5, 0x0a, 0x2f, 0x81, 0xd4, 0x53, 0x54, 0xde, + 0x2f, 0x65, 0x0e, 0x81, 0x52, 0x72, 0xfe, 0x52, 0xb6, 0x09, 0x63, 0xb8, 0x15, 0x0d, 0xb3, 0xf1, + 0x4b, 0x79, 0x23, 0x14, 0xa3, 0x48, 0x0f, 0x77, 0xc0, 0xb4, 0x4f, 0x30, 0x73, 0x1d, 0xf9, 0xa6, + 0xfe, 0x80, 0x0f, 0x3c, 0x48, 0x48, 0x8e, 0xfa, 0xcd, 0xd5, 0x51, 0xfe, 0xc9, 0xd0, 0xe4, 0x7c, + 0x24, 0x9c, 0x90, 0x84, 0x83, 0xb7, 0x41, 0x4d, 0x72, 0xa4, 0x16, 0x1c, 0xf6, 0xd3, 0x05, 0xb9, + 0x9a, 0xda, 0x46, 0xde, 0x00, 0x15, 0x7d, 0x8c, 0xcd, 0x67, 0x87, 0x8d, 0x89, 0xe7, 0x87, 0x8d, + 0x89, 0x17, 0x87, 0x8d, 0x89, 0xa7, 0x83, 0x86, 0xf2, 0x6c, 0xd0, 0x50, 0x9e, 0x0f, 0x1a, 0xca, + 0x8b, 0x41, 0x43, 0xf9, 0x75, 0xd0, 0x50, 0xbe, 0xfb, 0xad, 0x31, 0xf1, 0xf1, 0xca, 0xc8, 0xff, + 0x1e, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x08, 0xaf, 0xaa, 0x52, 0x82, 0x12, 0x00, 0x00, +} + +func (m *AuditAnnotation) 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 *AuditAnnotation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AuditAnnotation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.ValueExpression) + copy(dAtA[i:], m.ValueExpression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ValueExpression))) + i-- + dAtA[i] = 0x12 + 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 *ExpressionWarning) 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 *ExpressionWarning) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ExpressionWarning) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Warning) + copy(dAtA[i:], m.Warning) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Warning))) + i-- + dAtA[i] = 0x1a + i -= len(m.FieldRef) + copy(dAtA[i:], m.FieldRef) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.FieldRef))) + i-- + dAtA[i] = 0x12 + return len(dAtA) - i, nil +} + +func (m *MatchCondition) 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 *MatchCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MatchCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + 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 *MatchResources) Marshal() (dAtA []byte, err error) { @@ -631,6 +897,43 @@ func (m *ParamRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *TypeChecking) 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 *TypeChecking) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TypeChecking) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ExpressionWarnings) > 0 { + for iNdEx := len(m.ExpressionWarnings) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ExpressionWarnings[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 (m *ValidatingAdmissionPolicy) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -651,6 +954,16 @@ func (m *ValidatingAdmissionPolicy) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = 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 { @@ -784,6 +1097,15 @@ func (m *ValidatingAdmissionPolicyBindingSpec) MarshalToSizedBuffer(dAtA []byte) _ = i var l int _ = l + if len(m.ValidationActions) > 0 { + for iNdEx := len(m.ValidationActions) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ValidationActions[iNdEx]) + copy(dAtA[i:], m.ValidationActions[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ValidationActions[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } if m.MatchResources != nil { { size, err := m.MatchResources.MarshalToSizedBuffer(dAtA[:i]) @@ -883,6 +1205,34 @@ func (m *ValidatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.AuditAnnotations) > 0 { + for iNdEx := len(m.AuditAnnotations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AuditAnnotations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } if m.FailurePolicy != nil { i -= len(*m.FailurePolicy) copy(dAtA[i:], *m.FailurePolicy) @@ -931,6 +1281,58 @@ func (m *ValidatingAdmissionPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } +func (m *ValidatingAdmissionPolicyStatus) 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 *ValidatingAdmissionPolicyStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatingAdmissionPolicyStatus) 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] = 0x1a + } + } + if m.TypeChecking != nil { + { + size, err := m.TypeChecking.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} + func (m *Validation) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -951,6 +1353,11 @@ func (m *Validation) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.MessageExpression) + copy(dAtA[i:], m.MessageExpression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression))) + i-- + dAtA[i] = 0x22 if m.Reason != nil { i -= len(*m.Reason) copy(dAtA[i:], *m.Reason) @@ -982,6 +1389,45 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *AuditAnnotation) 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.ValueExpression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ExpressionWarning) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FieldRef) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Warning) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *MatchCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *MatchResources) Size() (n int) { if m == nil { return 0 @@ -1058,6 +1504,21 @@ func (m *ParamRef) Size() (n int) { return n } +func (m *TypeChecking) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ExpressionWarnings) > 0 { + for _, e := range m.ExpressionWarnings { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *ValidatingAdmissionPolicy) Size() (n int) { if m == nil { return 0 @@ -1068,6 +1529,8 @@ func (m *ValidatingAdmissionPolicy) 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 } @@ -1117,6 +1580,12 @@ func (m *ValidatingAdmissionPolicyBindingSpec) Size() (n int) { l = m.MatchResources.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.ValidationActions) > 0 { + for _, s := range m.ValidationActions { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1161,6 +1630,38 @@ func (m *ValidatingAdmissionPolicySpec) Size() (n int) { l = len(*m.FailurePolicy) n += 1 + l + sovGenerated(uint64(l)) } + if len(m.AuditAnnotations) > 0 { + for _, e := range m.AuditAnnotations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ValidatingAdmissionPolicyStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovGenerated(uint64(m.ObservedGeneration)) + if m.TypeChecking != nil { + l = m.TypeChecking.Size() + 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)) + } + } return n } @@ -1178,6 +1679,8 @@ func (m *Validation) Size() (n int) { l = len(*m.Reason) n += 1 + l + sovGenerated(uint64(l)) } + l = len(m.MessageExpression) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -1187,6 +1690,39 @@ func sovGenerated(x uint64) (n int) { func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (this *AuditAnnotation) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&AuditAnnotation{`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, + `ValueExpression:` + fmt.Sprintf("%v", this.ValueExpression) + `,`, + `}`, + }, "") + return s +} +func (this *ExpressionWarning) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ExpressionWarning{`, + `FieldRef:` + fmt.Sprintf("%v", this.FieldRef) + `,`, + `Warning:` + fmt.Sprintf("%v", this.Warning) + `,`, + `}`, + }, "") + return s +} +func (this *MatchCondition) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MatchCondition{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} func (this *MatchResources) String() string { if this == nil { return "nil" @@ -1244,6 +1780,21 @@ func (this *ParamRef) String() string { }, "") return s } +func (this *TypeChecking) String() string { + if this == nil { + return "nil" + } + repeatedStringForExpressionWarnings := "[]ExpressionWarning{" + for _, f := range this.ExpressionWarnings { + repeatedStringForExpressionWarnings += strings.Replace(strings.Replace(f.String(), "ExpressionWarning", "ExpressionWarning", 1), `&`, ``, 1) + "," + } + repeatedStringForExpressionWarnings += "}" + s := strings.Join([]string{`&TypeChecking{`, + `ExpressionWarnings:` + repeatedStringForExpressionWarnings + `,`, + `}`, + }, "") + return s +} func (this *ValidatingAdmissionPolicy) String() string { if this == nil { return "nil" @@ -1251,6 +1802,7 @@ func (this *ValidatingAdmissionPolicy) String() string { s := strings.Join([]string{`&ValidatingAdmissionPolicy{`, `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ValidatingAdmissionPolicySpec", "ValidatingAdmissionPolicySpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ValidatingAdmissionPolicyStatus", "ValidatingAdmissionPolicyStatus", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -1290,6 +1842,7 @@ func (this *ValidatingAdmissionPolicyBindingSpec) String() string { `PolicyName:` + fmt.Sprintf("%v", this.PolicyName) + `,`, `ParamRef:` + strings.Replace(this.ParamRef.String(), "ParamRef", "ParamRef", 1) + `,`, `MatchResources:` + strings.Replace(this.MatchResources.String(), "MatchResources", "MatchResources", 1) + `,`, + `ValidationActions:` + fmt.Sprintf("%v", this.ValidationActions) + `,`, `}`, }, "") return s @@ -1319,11 +1872,40 @@ func (this *ValidatingAdmissionPolicySpec) String() string { repeatedStringForValidations += strings.Replace(strings.Replace(f.String(), "Validation", "Validation", 1), `&`, ``, 1) + "," } repeatedStringForValidations += "}" + repeatedStringForAuditAnnotations := "[]AuditAnnotation{" + for _, f := range this.AuditAnnotations { + repeatedStringForAuditAnnotations += strings.Replace(strings.Replace(f.String(), "AuditAnnotation", "AuditAnnotation", 1), `&`, ``, 1) + "," + } + repeatedStringForAuditAnnotations += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&ValidatingAdmissionPolicySpec{`, `ParamKind:` + strings.Replace(this.ParamKind.String(), "ParamKind", "ParamKind", 1) + `,`, `MatchConstraints:` + strings.Replace(this.MatchConstraints.String(), "MatchResources", "MatchResources", 1) + `,`, `Validations:` + repeatedStringForValidations + `,`, `FailurePolicy:` + valueToStringGenerated(this.FailurePolicy) + `,`, + `AuditAnnotations:` + repeatedStringForAuditAnnotations + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, + `}`, + }, "") + return s +} +func (this *ValidatingAdmissionPolicyStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForConditions := "[]Condition{" + for _, f := range this.Conditions { + repeatedStringForConditions += fmt.Sprintf("%v", f) + "," + } + repeatedStringForConditions += "}" + s := strings.Join([]string{`&ValidatingAdmissionPolicyStatus{`, + `ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`, + `TypeChecking:` + strings.Replace(this.TypeChecking.String(), "TypeChecking", "TypeChecking", 1) + `,`, + `Conditions:` + repeatedStringForConditions + `,`, `}`, }, "") return s @@ -1336,6 +1918,7 @@ func (this *Validation) String() string { `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, `Message:` + fmt.Sprintf("%v", this.Message) + `,`, `Reason:` + valueToStringGenerated(this.Reason) + `,`, + `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`, `}`, }, "") return s @@ -1348,6 +1931,348 @@ func valueToStringGenerated(v interface{}) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("*%v", pv) } +func (m *AuditAnnotation) 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: AuditAnnotation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuditAnnotation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", 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.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValueExpression", 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.ValueExpression = 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 *ExpressionWarning) 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: ExpressionWarning: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExpressionWarning: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FieldRef", 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.FieldRef = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Warning", 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.Warning = 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 *MatchCondition) 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: MatchCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchCondition: 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 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 *MatchResources) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1914,6 +2839,90 @@ func (m *ParamRef) Unmarshal(dAtA []byte) error { } return nil } +func (m *TypeChecking) 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: TypeChecking: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TypeChecking: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpressionWarnings", 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.ExpressionWarnings = append(m.ExpressionWarnings, ExpressionWarning{}) + if err := m.ExpressionWarnings[len(m.ExpressionWarnings)-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 *ValidatingAdmissionPolicy) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -2009,6 +3018,39 @@ func (m *ValidatingAdmissionPolicy) Unmarshal(dAtA []byte) error { 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 default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2396,6 +3438,38 @@ func (m *ValidatingAdmissionPolicyBindingSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidationActions", 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.ValidationActions = append(m.ValidationActions, ValidationAction(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2702,6 +3776,213 @@ func (m *ValidatingAdmissionPolicySpec) Unmarshal(dAtA []byte) error { s := FailurePolicyType(dAtA[iNdEx:postIndex]) m.FailurePolicy = &s iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuditAnnotations", 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.AuditAnnotations = append(m.AuditAnnotations, AuditAnnotation{}) + if err := m.AuditAnnotations[len(m.AuditAnnotations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", 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.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-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 *ValidatingAdmissionPolicyStatus) 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: ValidatingAdmissionPolicyStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatingAdmissionPolicyStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TypeChecking", 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.TypeChecking == nil { + m.TypeChecking = &TypeChecking{} + } + if err := m.TypeChecking.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + 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 default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2849,6 +4130,38 @@ func (m *Validation) Unmarshal(dAtA []byte) error { s := k8s_io_apimachinery_pkg_apis_meta_v1.StatusReason(dAtA[iNdEx:postIndex]) m.Reason = &s iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MessageExpression", 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.MessageExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto index fe8236cd3..c718c5464 100644 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto @@ -29,6 +29,84 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". option go_package = "k8s.io/api/admissionregistration/v1alpha1"; +// AuditAnnotation describes how to produce an audit annotation for an API request. +message AuditAnnotation { + // key specifies the audit annotation key. The audit annotation keys of + // a ValidatingAdmissionPolicy must be unique. The key must be a qualified + // name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length. + // + // The key is combined with the resource name of the + // ValidatingAdmissionPolicy to construct an audit annotation key: + // "{ValidatingAdmissionPolicy name}/{key}". + // + // If an admission webhook uses the same resource name as this ValidatingAdmissionPolicy + // and the same audit annotation key, the annotation key will be identical. + // In this case, the first annotation written with the key will be included + // in the audit event and all subsequent annotations with the same key + // will be discarded. + // + // Required. + optional string key = 1; + + // valueExpression represents the expression which is evaluated by CEL to + // produce an audit annotation value. The expression must evaluate to either + // a string or null value. If the expression evaluates to a string, the + // audit annotation is included with the string value. If the expression + // evaluates to null or empty string the audit annotation will be omitted. + // The valueExpression may be no longer than 5kb in length. + // If the result of the valueExpression is more than 10kb in length, it + // will be truncated to 10kb. + // + // If multiple ValidatingAdmissionPolicyBinding resources match an + // API request, then the valueExpression will be evaluated for + // each binding. All unique values produced by the valueExpressions + // will be joined together in a comma-separated list. + // + // Required. + optional string valueExpression = 2; +} + +// ExpressionWarning is a warning information that targets a specific expression. +message ExpressionWarning { + // The path to the field that refers the expression. + // For example, the reference to the expression of the first item of + // validations is "spec.validations[0].expression" + optional string fieldRef = 2; + + // The content of type checking information in a human-readable form. + // Each line of the warning contains the type that the expression is checked + // against, followed by the type check error from the compiler. + optional string warning = 3; +} + +message MatchCondition { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + optional string name = 1; + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + optional string expression = 2; +} + // 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) @@ -161,6 +239,15 @@ message ParamRef { optional string namespace = 2; } +// TypeChecking contains results of type checking the expressions in the +// ValidatingAdmissionPolicy +message TypeChecking { + // The type checking warnings for each expression. + // +optional + // +listType=atomic + repeated ExpressionWarning expressionWarnings = 1; +} + // ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it. message ValidatingAdmissionPolicy { // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. @@ -169,6 +256,13 @@ message ValidatingAdmissionPolicy { // Specification of the desired behavior of the ValidatingAdmissionPolicy. optional ValidatingAdmissionPolicySpec spec = 2; + + // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // behaves in the expected way. + // Populated by the system. + // Read-only. + // +optional + optional ValidatingAdmissionPolicyStatus status = 3; } // ValidatingAdmissionPolicyBinding binds the ValidatingAdmissionPolicy with paramerized resources. @@ -213,6 +307,48 @@ message ValidatingAdmissionPolicyBindingSpec { // Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required. // +optional optional MatchResources matchResources = 3; + + // validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. + // If a validation evaluates to false it is always enforced according to these actions. + // + // Failures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according + // to these actions only if the FailurePolicy is set to Fail, otherwise the failures are + // ignored. This includes compilation errors, runtime errors and misconfigurations of the policy. + // + // validationActions is declared as a set of action values. Order does + // not matter. validationActions may not contain duplicates of the same action. + // + // The supported actions values are: + // + // "Deny" specifies that a validation failure results in a denied request. + // + // "Warn" specifies that a validation failure is reported to the request client + // in HTTP Warning headers, with a warning code of 299. Warnings can be sent + // both for allowed or denied admission responses. + // + // "Audit" specifies that a validation failure is included in the published + // audit event for the request. The audit event will contain a + // `validation.policy.admission.k8s.io/validation_failure` audit annotation + // with a value containing the details of the validation failures, formatted as + // a JSON list of objects, each with the following fields: + // - message: The validation failure message string + // - policy: The resource name of the ValidatingAdmissionPolicy + // - binding: The resource name of the ValidatingAdmissionPolicyBinding + // - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy + // - validationActions: The enforcement actions enacted for the validation failure + // Example audit annotation: + // `"validation.policy.admission.k8s.io/validation_failure": "[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]"` + // + // Clients should expect to handle additional values by ignoring + // any values not recognized. + // + // "Deny" and "Warn" may not be used together since this combination + // needlessly duplicates the validation failure both in the + // API response body and the HTTP warning headers. + // + // Required. + // +listType=set + repeated string validationActions = 4; } // ValidatingAdmissionPolicyList is a list of ValidatingAdmissionPolicy. @@ -243,30 +379,91 @@ message ValidatingAdmissionPolicySpec { optional MatchResources matchConstraints = 2; // Validations contain CEL expressions which is used to apply the validation. - // A minimum of one validation is required for a policy definition. + // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is + // required. // +listType=atomic - // Required. + // +optional repeated Validation validations = 3; - // FailurePolicy defines how to handle failures for the admission policy. - // Failures can occur from invalid or mis-configured policy definitions or bindings. + // failurePolicy defines how to handle failures for the admission policy. Failures can + // occur from CEL expression parse errors, type check errors, runtime errors and invalid + // or mis-configured policy definitions or bindings. + // // A policy is invalid if spec.paramKind refers to a non-existent Kind. // A binding is invalid if spec.paramRef.name refers to a non-existent resource. + // + // failurePolicy does not define how validations that evaluate to false are handled. + // + // When failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions + // define how failures are enforced. + // // Allowed values are Ignore or Fail. Defaults to Fail. // +optional optional string failurePolicy = 4; + + // auditAnnotations contains CEL expressions which are used to produce audit + // annotations for the audit event of the API request. + // validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is + // required. + // +listType=atomic + // +optional + repeated AuditAnnotation auditAnnotations = 5; + + // MatchConditions is a list of conditions that must be met for a request to be validated. + // Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // If a parameter object is provided, it can be accessed via the `params` handle in the same + // manner as validation expressions. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the policy is skipped + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +optional + repeated MatchCondition matchConditions = 6; +} + +// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy. +message ValidatingAdmissionPolicyStatus { + // The generation observed by the controller. + // +optional + optional int64 observedGeneration = 1; + + // The results of type checking for each expression. + // Presence of this field indicates the completion of the type checking. + // +optional + optional TypeChecking typeChecking = 2; + + // The conditions represent the latest available observations of a policy's current state. + // +optional + // +listType=map + // +listMapKey=type + repeated k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 3; } // Validation specifies the CEL expression which is used to apply the validation. message Validation { // Expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec - // CEL expressions have access to the contents of the Admission request/response, organized into CEL variables as well as some other useful variables: + // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // - // 'object' - The object from the incoming request. The value is null for DELETE requests. - // 'oldObject' - The existing object. The value is null for CREATE requests. - // 'request' - Attributes of the admission request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - // 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. // // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the // object. No other metadata properties are accessible. @@ -313,5 +510,18 @@ message Validation { // If not set, StatusReasonInvalid is used in the response to the client. // +optional optional string reason = 3; + + // messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. + // If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. + // Example: + // "object.x must be less than max ("+string(params.max)+")" + // +optional + optional string messageExpression = 4; } diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go index b64bc628f..2bbb55a47 100644 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go @@ -74,6 +74,49 @@ type ValidatingAdmissionPolicy struct { metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Specification of the desired behavior of the ValidatingAdmissionPolicy. Spec ValidatingAdmissionPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` + // The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy + // behaves in the expected way. + // Populated by the system. + // Read-only. + // +optional + Status ValidatingAdmissionPolicyStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy. +type ValidatingAdmissionPolicyStatus struct { + // The generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` + // The results of type checking for each expression. + // Presence of this field indicates the completion of the type checking. + // +optional + TypeChecking *TypeChecking `json:"typeChecking,omitempty" protobuf:"bytes,2,opt,name=typeChecking"` + // The conditions represent the latest available observations of a policy's current state. + // +optional + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" protobuf:"bytes,3,rep,name=conditions"` +} + +// TypeChecking contains results of type checking the expressions in the +// ValidatingAdmissionPolicy +type TypeChecking struct { + // The type checking warnings for each expression. + // +optional + // +listType=atomic + ExpressionWarnings []ExpressionWarning `json:"expressionWarnings,omitempty" protobuf:"bytes,1,rep,name=expressionWarnings"` +} + +// ExpressionWarning is a warning information that targets a specific expression. +type ExpressionWarning struct { + // The path to the field that refers the expression. + // For example, the reference to the expression of the first item of + // validations is "spec.validations[0].expression" + FieldRef string `json:"fieldRef" protobuf:"bytes,2,opt,name=fieldRef"` + // The content of type checking information in a human-readable form. + // Each line of the warning contains the type that the expression is checked + // against, followed by the type check error from the compiler. + Warning string `json:"warning" protobuf:"bytes,3,opt,name=warning"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -107,20 +150,61 @@ type ValidatingAdmissionPolicySpec struct { MatchConstraints *MatchResources `json:"matchConstraints,omitempty" protobuf:"bytes,2,rep,name=matchConstraints"` // Validations contain CEL expressions which is used to apply the validation. - // A minimum of one validation is required for a policy definition. + // Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is + // required. // +listType=atomic - // Required. - Validations []Validation `json:"validations" protobuf:"bytes,3,rep,name=validations"` + // +optional + Validations []Validation `json:"validations,omitempty" protobuf:"bytes,3,rep,name=validations"` - // FailurePolicy defines how to handle failures for the admission policy. - // Failures can occur from invalid or mis-configured policy definitions or bindings. + // failurePolicy defines how to handle failures for the admission policy. Failures can + // occur from CEL expression parse errors, type check errors, runtime errors and invalid + // or mis-configured policy definitions or bindings. + // // A policy is invalid if spec.paramKind refers to a non-existent Kind. // A binding is invalid if spec.paramRef.name refers to a non-existent resource. + // + // failurePolicy does not define how validations that evaluate to false are handled. + // + // When failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions + // define how failures are enforced. + // // Allowed values are Ignore or Fail. Defaults to Fail. // +optional FailurePolicy *FailurePolicyType `json:"failurePolicy,omitempty" protobuf:"bytes,4,opt,name=failurePolicy,casttype=FailurePolicyType"` + + // auditAnnotations contains CEL expressions which are used to produce audit + // annotations for the audit event of the API request. + // validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is + // required. + // +listType=atomic + // +optional + AuditAnnotations []AuditAnnotation `json:"auditAnnotations,omitempty" protobuf:"bytes,5,rep,name=auditAnnotations"` + + // MatchConditions is a list of conditions that must be met for a request to be validated. + // Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // If a parameter object is provided, it can be accessed via the `params` handle in the same + // manner as validation expressions. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the policy is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the policy is skipped + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,6,rep,name=matchConditions"` } +type MatchCondition v1.MatchCondition + // ParamKind is a tuple of Group Kind and Version. // +structType=atomic type ParamKind struct { @@ -138,12 +222,16 @@ type ParamKind struct { type Validation struct { // Expression represents the expression which will be evaluated by CEL. // ref: https://github.com/google/cel-spec - // CEL expressions have access to the contents of the Admission request/response, organized into CEL variables as well as some other useful variables: + // CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables: // - //'object' - The object from the incoming request. The value is null for DELETE requests. - //'oldObject' - The existing object. The value is null for CREATE requests. - //'request' - Attributes of the admission request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - //'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'object' - The object from the incoming request. The value is null for DELETE requests. + // - 'oldObject' - The existing object. The value is null for CREATE requests. + // - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). + // - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. + // - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // - 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. // // The `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the // object. No other metadata properties are accessible. @@ -188,6 +276,55 @@ type Validation struct { // If not set, StatusReasonInvalid is used in the response to the client. // +optional Reason *metav1.StatusReason `json:"reason,omitempty" protobuf:"bytes,3,opt,name=reason"` + // messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. + // If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. + // Example: + // "object.x must be less than max ("+string(params.max)+")" + // +optional + MessageExpression string `json:"messageExpression,omitempty" protobuf:"bytes,4,opt,name=messageExpression"` +} + +// AuditAnnotation describes how to produce an audit annotation for an API request. +type AuditAnnotation struct { + // key specifies the audit annotation key. The audit annotation keys of + // a ValidatingAdmissionPolicy must be unique. The key must be a qualified + // name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length. + // + // The key is combined with the resource name of the + // ValidatingAdmissionPolicy to construct an audit annotation key: + // "{ValidatingAdmissionPolicy name}/{key}". + // + // If an admission webhook uses the same resource name as this ValidatingAdmissionPolicy + // and the same audit annotation key, the annotation key will be identical. + // In this case, the first annotation written with the key will be included + // in the audit event and all subsequent annotations with the same key + // will be discarded. + // + // Required. + Key string `json:"key" protobuf:"bytes,1,opt,name=key"` + + // valueExpression represents the expression which is evaluated by CEL to + // produce an audit annotation value. The expression must evaluate to either + // a string or null value. If the expression evaluates to a string, the + // audit annotation is included with the string value. If the expression + // evaluates to null or empty string the audit annotation will be omitted. + // The valueExpression may be no longer than 5kb in length. + // If the result of the valueExpression is more than 10kb in length, it + // will be truncated to 10kb. + // + // If multiple ValidatingAdmissionPolicyBinding resources match an + // API request, then the valueExpression will be evaluated for + // each binding. All unique values produced by the valueExpressions + // will be joined together in a comma-separated list. + // + // Required. + ValueExpression string `json:"valueExpression" protobuf:"bytes,2,opt,name=valueExpression"` } // +genclient @@ -240,6 +377,48 @@ type ValidatingAdmissionPolicyBindingSpec struct { // Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required. // +optional MatchResources *MatchResources `json:"matchResources,omitempty" protobuf:"bytes,3,rep,name=matchResources"` + + // validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. + // If a validation evaluates to false it is always enforced according to these actions. + // + // Failures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according + // to these actions only if the FailurePolicy is set to Fail, otherwise the failures are + // ignored. This includes compilation errors, runtime errors and misconfigurations of the policy. + // + // validationActions is declared as a set of action values. Order does + // not matter. validationActions may not contain duplicates of the same action. + // + // The supported actions values are: + // + // "Deny" specifies that a validation failure results in a denied request. + // + // "Warn" specifies that a validation failure is reported to the request client + // in HTTP Warning headers, with a warning code of 299. Warnings can be sent + // both for allowed or denied admission responses. + // + // "Audit" specifies that a validation failure is included in the published + // audit event for the request. The audit event will contain a + // `validation.policy.admission.k8s.io/validation_failure` audit annotation + // with a value containing the details of the validation failures, formatted as + // a JSON list of objects, each with the following fields: + // - message: The validation failure message string + // - policy: The resource name of the ValidatingAdmissionPolicy + // - binding: The resource name of the ValidatingAdmissionPolicyBinding + // - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy + // - validationActions: The enforcement actions enacted for the validation failure + // Example audit annotation: + // `"validation.policy.admission.k8s.io/validation_failure": "[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]"` + // + // Clients should expect to handle additional values by ignoring + // any values not recognized. + // + // "Deny" and "Warn" may not be used together since this combination + // needlessly duplicates the validation failure both in the + // API response body and the HTTP warning headers. + // + // Required. + // +listType=set + ValidationActions []ValidationAction `json:"validationActions,omitempty" protobuf:"bytes,4,rep,name=validationActions"` } // ParamRef references a parameter resource @@ -344,6 +523,24 @@ type MatchResources struct { MatchPolicy *MatchPolicyType `json:"matchPolicy,omitempty" protobuf:"bytes,7,opt,name=matchPolicy,casttype=MatchPolicyType"` } +// ValidationAction specifies a policy enforcement action. +// +enum +type ValidationAction string + +const ( + // Deny specifies that a validation failure results in a denied request. + Deny ValidationAction = "Deny" + // Warn specifies that a validation failure is reported to the request client + // in HTTP Warning headers, with a warning code of 299. Warnings can be sent + // both for allowed or denied admission responses. + Warn ValidationAction = "Warn" + // Audit specifies that a validation failure is included in the published + // audit event for the request. The audit event will contain a + // `validation.policy.admission.k8s.io/validation_failure` audit annotation + // with a value containing the details of the validation failure. + Audit ValidationAction = "Audit" +) + // NamedRuleWithOperations is a tuple of Operations and Resources with ResourceNames. // +structType=atomic type NamedRuleWithOperations struct { diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go index a670bb206..b3cac1821 100644 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go @@ -24,9 +24,29 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_AuditAnnotation = map[string]string{ + "": "AuditAnnotation describes how to produce an audit annotation for an API request.", + "key": "key specifies the audit annotation key. The audit annotation keys of a ValidatingAdmissionPolicy must be unique. The key must be a qualified name ([A-Za-z0-9][-A-Za-z0-9_.]*) no more than 63 bytes in length.\n\nThe key is combined with the resource name of the ValidatingAdmissionPolicy to construct an audit annotation key: \"{ValidatingAdmissionPolicy name}/{key}\".\n\nIf an admission webhook uses the same resource name as this ValidatingAdmissionPolicy and the same audit annotation key, the annotation key will be identical. In this case, the first annotation written with the key will be included in the audit event and all subsequent annotations with the same key will be discarded.\n\nRequired.", + "valueExpression": "valueExpression represents the expression which is evaluated by CEL to produce an audit annotation value. The expression must evaluate to either a string or null value. If the expression evaluates to a string, the audit annotation is included with the string value. If the expression evaluates to null or empty string the audit annotation will be omitted. The valueExpression may be no longer than 5kb in length. If the result of the valueExpression is more than 10kb in length, it will be truncated to 10kb.\n\nIf multiple ValidatingAdmissionPolicyBinding resources match an API request, then the valueExpression will be evaluated for each binding. All unique values produced by the valueExpressions will be joined together in a comma-separated list.\n\nRequired.", +} + +func (AuditAnnotation) SwaggerDoc() map[string]string { + return map_AuditAnnotation +} + +var map_ExpressionWarning = map[string]string{ + "": "ExpressionWarning is a warning information that targets a specific expression.", + "fieldRef": "The path to the field that refers the expression. For example, the reference to the expression of the first item of validations is \"spec.validations[0].expression\"", + "warning": "The content of type checking information in a human-readable form. Each line of the warning contains the type that the expression is checked against, followed by the type check error from the compiler.", +} + +func (ExpressionWarning) SwaggerDoc() map[string]string { + return map_ExpressionWarning +} + 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.", @@ -69,10 +89,20 @@ func (ParamRef) SwaggerDoc() map[string]string { return map_ParamRef } +var map_TypeChecking = map[string]string{ + "": "TypeChecking contains results of type checking the expressions in the ValidatingAdmissionPolicy", + "expressionWarnings": "The type checking warnings for each expression.", +} + +func (TypeChecking) SwaggerDoc() map[string]string { + return map_TypeChecking +} + var map_ValidatingAdmissionPolicy = map[string]string{ "": "ValidatingAdmissionPolicy describes the definition of an admission validation policy that accepts or rejects an object without changing it.", "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", "spec": "Specification of the desired behavior of the ValidatingAdmissionPolicy.", + "status": "The status of the ValidatingAdmissionPolicy, including warnings that are useful to determine if the policy behaves in the expected way. Populated by the system. Read-only.", } func (ValidatingAdmissionPolicy) SwaggerDoc() map[string]string { @@ -100,10 +130,11 @@ func (ValidatingAdmissionPolicyBindingList) SwaggerDoc() map[string]string { } var map_ValidatingAdmissionPolicyBindingSpec = map[string]string{ - "": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.", - "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", - "paramRef": "ParamRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied.", - "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", + "": "ValidatingAdmissionPolicyBindingSpec is the specification of the ValidatingAdmissionPolicyBinding.", + "policyName": "PolicyName references a ValidatingAdmissionPolicy name which the ValidatingAdmissionPolicyBinding binds to. If the referenced resource does not exist, this binding is considered invalid and will be ignored Required.", + "paramRef": "ParamRef specifies the parameter resource used to configure the admission control policy. It should point to a resource of the type specified in ParamKind of the bound ValidatingAdmissionPolicy. If the policy specifies a ParamKind and the resource referred to by ParamRef does not exist, this binding is considered mis-configured and the FailurePolicy of the ValidatingAdmissionPolicy applied.", + "matchResources": "MatchResources declares what resources match this binding and will be validated by it. Note that this is intersected with the policy's matchConstraints, so only requests that are matched by the policy can be selected by this. If this is unset, all resources matched by the policy are validated by this binding When resourceRules is unset, it does not constrain resource matching. If a resource is matched by the other fields of this object, it will be validated. Note that this is differs from ValidatingAdmissionPolicy matchConstraints, where resourceRules are required.", + "validationActions": "validationActions declares how Validations of the referenced ValidatingAdmissionPolicy are enforced. If a validation evaluates to false it is always enforced according to these actions.\n\nFailures defined by the ValidatingAdmissionPolicy's FailurePolicy are enforced according to these actions only if the FailurePolicy is set to Fail, otherwise the failures are ignored. This includes compilation errors, runtime errors and misconfigurations of the policy.\n\nvalidationActions is declared as a set of action values. Order does not matter. validationActions may not contain duplicates of the same action.\n\nThe supported actions values are:\n\n\"Deny\" specifies that a validation failure results in a denied request.\n\n\"Warn\" specifies that a validation failure is reported to the request client in HTTP Warning headers, with a warning code of 299. Warnings can be sent both for allowed or denied admission responses.\n\n\"Audit\" specifies that a validation failure is included in the published audit event for the request. The audit event will contain a `validation.policy.admission.k8s.io/validation_failure` audit annotation with a value containing the details of the validation failures, formatted as a JSON list of objects, each with the following fields: - message: The validation failure message string - policy: The resource name of the ValidatingAdmissionPolicy - binding: The resource name of the ValidatingAdmissionPolicyBinding - expressionIndex: The index of the failed validations in the ValidatingAdmissionPolicy - validationActions: The enforcement actions enacted for the validation failure Example audit annotation: `\"validation.policy.admission.k8s.io/validation_failure\": \"[{\"message\": \"Invalid value\", {\"policy\": \"policy.example.com\", {\"binding\": \"policybinding.example.com\", {\"expressionIndex\": \"1\", {\"validationActions\": [\"Audit\"]}]\"`\n\nClients should expect to handle additional values by ignoring any values not recognized.\n\n\"Deny\" and \"Warn\" may not be used together since this combination needlessly duplicates the validation failure both in the API response body and the HTTP warning headers.\n\nRequired.", } func (ValidatingAdmissionPolicyBindingSpec) SwaggerDoc() map[string]string { @@ -124,19 +155,33 @@ var map_ValidatingAdmissionPolicySpec = map[string]string{ "": "ValidatingAdmissionPolicySpec is the specification of the desired behavior of the AdmissionPolicy.", "paramKind": "ParamKind specifies the kind of resources used to parameterize this policy. If absent, there are no parameters for this policy and the param CEL variable will not be provided to validation expressions. If ParamKind refers to a non-existent kind, this policy definition is mis-configured and the FailurePolicy is applied. If paramKind is specified but paramRef is unset in ValidatingAdmissionPolicyBinding, the params variable will be null.", "matchConstraints": "MatchConstraints specifies what resources this policy is designed to validate. The AdmissionPolicy cares about a request if it matches _all_ Constraints. However, in order to prevent clusters from being put into an unstable state that cannot be recovered from via the API ValidatingAdmissionPolicy cannot match ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding. Required.", - "validations": "Validations contain CEL expressions which is used to apply the validation. A minimum of one validation is required for a policy definition. Required.", - "failurePolicy": "FailurePolicy defines how to handle failures for the admission policy. Failures can occur from invalid or mis-configured policy definitions or bindings. A policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource. Allowed values are Ignore or Fail. Defaults to Fail.", + "validations": "Validations contain CEL expressions which is used to apply the validation. Validations and AuditAnnotations may not both be empty; a minimum of one Validations or AuditAnnotations is required.", + "failurePolicy": "failurePolicy defines how to handle failures for the admission policy. Failures can occur from CEL expression parse errors, type check errors, runtime errors and invalid or mis-configured policy definitions or bindings.\n\nA policy is invalid if spec.paramKind refers to a non-existent Kind. A binding is invalid if spec.paramRef.name refers to a non-existent resource.\n\nfailurePolicy does not define how validations that evaluate to false are handled.\n\nWhen failurePolicy is set to Fail, ValidatingAdmissionPolicyBinding validationActions define how failures are enforced.\n\nAllowed values are Ignore or Fail. Defaults to Fail.", + "auditAnnotations": "auditAnnotations contains CEL expressions which are used to produce audit annotations for the audit event of the API request. validations and auditAnnotations may not both be empty; a least one of validations or auditAnnotations is required.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be validated. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nIf a parameter object is provided, it can be accessed via the `params` handle in the same manner as validation expressions.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the policy is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the policy is evaluated.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the policy is skipped", } func (ValidatingAdmissionPolicySpec) SwaggerDoc() map[string]string { return map_ValidatingAdmissionPolicySpec } +var map_ValidatingAdmissionPolicyStatus = map[string]string{ + "": "ValidatingAdmissionPolicyStatus represents the status of a ValidatingAdmissionPolicy.", + "observedGeneration": "The generation observed by the controller.", + "typeChecking": "The results of type checking for each expression. Presence of this field indicates the completion of the type checking.", + "conditions": "The conditions represent the latest available observations of a policy's current state.", +} + +func (ValidatingAdmissionPolicyStatus) SwaggerDoc() map[string]string { + return map_ValidatingAdmissionPolicyStatus +} + var map_Validation = map[string]string{ - "": "Validation specifies the CEL expression which is used to apply the validation.", - "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the Admission request/response, organized into CEL variables as well as some other useful variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", - "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", - "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", + "": "Validation specifies the CEL expression which is used to apply the validation.", + "expression": "Expression represents the expression which will be evaluated by CEL. ref: https://github.com/google/cel-spec CEL expressions have access to the contents of the API request/response, organized into CEL variables as well as some other useful variables:\n\n- 'object' - The object from the incoming request. The value is null for DELETE requests. - 'oldObject' - The existing object. The value is null for CREATE requests. - 'request' - Attributes of the API request([ref](/pkg/apis/admission/types.go#AdmissionRequest)). - 'params' - Parameter resource referred to by the policy binding being evaluated. Only populated if the policy has a ParamKind. - 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n- 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\n\nThe `apiVersion`, `kind`, `metadata.name` and `metadata.generateName` are always accessible from the root of the object. No other metadata properties are accessible.\n\nOnly property names of the form `[a-zA-Z_.-/][a-zA-Z0-9_.-/]*` are accessible. Accessible property names are escaped according to the following rules when accessed in the expression: - '__' escapes to '__underscores__' - '.' escapes to '__dot__' - '-' escapes to '__dash__' - '/' escapes to '__slash__' - Property names that exactly match a CEL RESERVED keyword escape to '__{keyword}__'. The keywords are:\n\t \"true\", \"false\", \"null\", \"in\", \"as\", \"break\", \"const\", \"continue\", \"else\", \"for\", \"function\", \"if\",\n\t \"import\", \"let\", \"loop\", \"package\", \"namespace\", \"return\".\nExamples:\n - Expression accessing a property named \"namespace\": {\"Expression\": \"object.__namespace__ > 0\"}\n - Expression accessing a property named \"x-prop\": {\"Expression\": \"object.x__dash__prop > 0\"}\n - Expression accessing a property named \"redact__d\": {\"Expression\": \"object.redact__underscores__d > 0\"}\n\nEquality on arrays with list type of 'set' or 'map' ignores element order, i.e. [1, 2] == [2, 1]. Concatenation on arrays with x-kubernetes-list-type use the semantics of the list type:\n - 'set': `X + Y` performs a union where the array positions of all elements in `X` are preserved and\n non-intersecting elements in `Y` are appended, retaining their partial order.\n - 'map': `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values\n are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with\n non-intersecting keys are appended, retaining their partial order.\nRequired.", + "message": "Message represents the message displayed when validation fails. The message is required if the Expression contains line breaks. The message must not contain line breaks. If unset, the message is \"failed rule: {Rule}\". e.g. \"must be a URL with the host matching spec.host\" If the Expression contains line breaks. Message is required. The message must not contain line breaks. If unset, the message is \"failed Expression: {Expression}\".", + "reason": "Reason represents a machine-readable description of why this validation failed. If this is the first validation in the list to fail, this reason, as well as the corresponding HTTP response code, are used in the HTTP response to the client. The currently supported reasons are: \"Unauthorized\", \"Forbidden\", \"Invalid\", \"RequestEntityTooLarge\". If not set, StatusReasonInvalid is used in the response to the client.", + "messageExpression": "messageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. Since messageExpression is used as a failure message, it must evaluate to a string. If both message and messageExpression are present on a validation, then messageExpression will be used if validation fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. messageExpression has access to all the same variables as the `expression` except for 'authorizer' and 'authorizer.requestResource'. Example: \"object.x must be less than max (\"+string(params.max)+\")\"", } func (Validation) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.deepcopy.go index 4f29ac7a9..8e4abfd08 100644 --- a/vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/admissionregistration/v1alpha1/zz_generated.deepcopy.go @@ -26,6 +26,54 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuditAnnotation) DeepCopyInto(out *AuditAnnotation) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuditAnnotation. +func (in *AuditAnnotation) DeepCopy() *AuditAnnotation { + if in == nil { + return nil + } + out := new(AuditAnnotation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExpressionWarning) DeepCopyInto(out *ExpressionWarning) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExpressionWarning. +func (in *ExpressionWarning) DeepCopy() *ExpressionWarning { + if in == nil { + return nil + } + out := new(ExpressionWarning) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchCondition) DeepCopyInto(out *MatchCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchCondition. +func (in *MatchCondition) DeepCopy() *MatchCondition { + if in == nil { + return nil + } + out := new(MatchCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MatchResources) DeepCopyInto(out *MatchResources) { *out = *in @@ -125,12 +173,34 @@ func (in *ParamRef) DeepCopy() *ParamRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TypeChecking) DeepCopyInto(out *TypeChecking) { + *out = *in + if in.ExpressionWarnings != nil { + in, out := &in.ExpressionWarnings, &out.ExpressionWarnings + *out = make([]ExpressionWarning, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TypeChecking. +func (in *TypeChecking) DeepCopy() *TypeChecking { + if in == nil { + return nil + } + out := new(TypeChecking) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ValidatingAdmissionPolicy) DeepCopyInto(out *ValidatingAdmissionPolicy) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) return } @@ -225,6 +295,11 @@ func (in *ValidatingAdmissionPolicyBindingSpec) DeepCopyInto(out *ValidatingAdmi *out = new(MatchResources) (*in).DeepCopyInto(*out) } + if in.ValidationActions != nil { + in, out := &in.ValidationActions, &out.ValidationActions + *out = make([]ValidationAction, len(*in)) + copy(*out, *in) + } return } @@ -296,6 +371,16 @@ func (in *ValidatingAdmissionPolicySpec) DeepCopyInto(out *ValidatingAdmissionPo *out = new(FailurePolicyType) **out = **in } + if in.AuditAnnotations != nil { + in, out := &in.AuditAnnotations, &out.AuditAnnotations + *out = make([]AuditAnnotation, len(*in)) + copy(*out, *in) + } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } @@ -309,6 +394,34 @@ func (in *ValidatingAdmissionPolicySpec) DeepCopy() *ValidatingAdmissionPolicySp return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValidatingAdmissionPolicyStatus) DeepCopyInto(out *ValidatingAdmissionPolicyStatus) { + *out = *in + if in.TypeChecking != nil { + in, out := &in.TypeChecking, &out.TypeChecking + *out = new(TypeChecking) + (*in).DeepCopyInto(*out) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.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 ValidatingAdmissionPolicyStatus. +func (in *ValidatingAdmissionPolicyStatus) DeepCopy() *ValidatingAdmissionPolicyStatus { + if in == nil { + return nil + } + out := new(ValidatingAdmissionPolicyStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Validation) DeepCopyInto(out *Validation) { *out = *in diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go index 56a9f10e5..8fb354c31 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.pb.go @@ -45,10 +45,38 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +func (m *MatchCondition) Reset() { *m = MatchCondition{} } +func (*MatchCondition) ProtoMessage() {} +func (*MatchCondition) Descriptor() ([]byte, []int) { + return fileDescriptor_abeea74cbc46f55a, []int{0} +} +func (m *MatchCondition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MatchCondition) 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 *MatchCondition) XXX_Merge(src proto.Message) { + xxx_messageInfo_MatchCondition.Merge(m, src) +} +func (m *MatchCondition) XXX_Size() int { + return m.Size() +} +func (m *MatchCondition) XXX_DiscardUnknown() { + xxx_messageInfo_MatchCondition.DiscardUnknown(m) +} + +var xxx_messageInfo_MatchCondition proto.InternalMessageInfo + func (m *MutatingWebhook) Reset() { *m = MutatingWebhook{} } func (*MutatingWebhook) ProtoMessage() {} func (*MutatingWebhook) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{0} + return fileDescriptor_abeea74cbc46f55a, []int{1} } func (m *MutatingWebhook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -76,7 +104,7 @@ var xxx_messageInfo_MutatingWebhook proto.InternalMessageInfo func (m *MutatingWebhookConfiguration) Reset() { *m = MutatingWebhookConfiguration{} } func (*MutatingWebhookConfiguration) ProtoMessage() {} func (*MutatingWebhookConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{1} + return fileDescriptor_abeea74cbc46f55a, []int{2} } func (m *MutatingWebhookConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -104,7 +132,7 @@ var xxx_messageInfo_MutatingWebhookConfiguration proto.InternalMessageInfo func (m *MutatingWebhookConfigurationList) Reset() { *m = MutatingWebhookConfigurationList{} } func (*MutatingWebhookConfigurationList) ProtoMessage() {} func (*MutatingWebhookConfigurationList) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{2} + return fileDescriptor_abeea74cbc46f55a, []int{3} } func (m *MutatingWebhookConfigurationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -132,7 +160,7 @@ var xxx_messageInfo_MutatingWebhookConfigurationList proto.InternalMessageInfo func (m *ServiceReference) Reset() { *m = ServiceReference{} } func (*ServiceReference) ProtoMessage() {} func (*ServiceReference) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{3} + return fileDescriptor_abeea74cbc46f55a, []int{4} } func (m *ServiceReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -160,7 +188,7 @@ var xxx_messageInfo_ServiceReference proto.InternalMessageInfo func (m *ValidatingWebhook) Reset() { *m = ValidatingWebhook{} } func (*ValidatingWebhook) ProtoMessage() {} func (*ValidatingWebhook) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{4} + return fileDescriptor_abeea74cbc46f55a, []int{5} } func (m *ValidatingWebhook) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -188,7 +216,7 @@ var xxx_messageInfo_ValidatingWebhook proto.InternalMessageInfo func (m *ValidatingWebhookConfiguration) Reset() { *m = ValidatingWebhookConfiguration{} } func (*ValidatingWebhookConfiguration) ProtoMessage() {} func (*ValidatingWebhookConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{5} + return fileDescriptor_abeea74cbc46f55a, []int{6} } func (m *ValidatingWebhookConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -216,7 +244,7 @@ var xxx_messageInfo_ValidatingWebhookConfiguration proto.InternalMessageInfo func (m *ValidatingWebhookConfigurationList) Reset() { *m = ValidatingWebhookConfigurationList{} } func (*ValidatingWebhookConfigurationList) ProtoMessage() {} func (*ValidatingWebhookConfigurationList) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{6} + return fileDescriptor_abeea74cbc46f55a, []int{7} } func (m *ValidatingWebhookConfigurationList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -244,7 +272,7 @@ var xxx_messageInfo_ValidatingWebhookConfigurationList proto.InternalMessageInfo func (m *WebhookClientConfig) Reset() { *m = WebhookClientConfig{} } func (*WebhookClientConfig) ProtoMessage() {} func (*WebhookClientConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_abeea74cbc46f55a, []int{7} + return fileDescriptor_abeea74cbc46f55a, []int{8} } func (m *WebhookClientConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -270,6 +298,7 @@ func (m *WebhookClientConfig) XXX_DiscardUnknown() { var xxx_messageInfo_WebhookClientConfig proto.InternalMessageInfo func init() { + proto.RegisterType((*MatchCondition)(nil), "k8s.io.api.admissionregistration.v1beta1.MatchCondition") proto.RegisterType((*MutatingWebhook)(nil), "k8s.io.api.admissionregistration.v1beta1.MutatingWebhook") proto.RegisterType((*MutatingWebhookConfiguration)(nil), "k8s.io.api.admissionregistration.v1beta1.MutatingWebhookConfiguration") proto.RegisterType((*MutatingWebhookConfigurationList)(nil), "k8s.io.api.admissionregistration.v1beta1.MutatingWebhookConfigurationList") @@ -285,68 +314,106 @@ func init() { } var fileDescriptor_abeea74cbc46f55a = []byte{ - // 974 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0x49, 0x6f, 0xdb, 0x46, - 0x14, 0x36, 0x2d, 0x29, 0x92, 0x46, 0xb2, 0x13, 0x4d, 0x97, 0xb0, 0x6e, 0x40, 0x0a, 0x3a, 0x14, - 0xba, 0x94, 0x4c, 0x9c, 0xa2, 0x4b, 0x8a, 0x1e, 0x42, 0xb7, 0x41, 0x0b, 0xd8, 0x4e, 0x3a, 0xce, - 0x02, 0xb4, 0x29, 0x90, 0x11, 0xf5, 0x24, 0x4d, 0x45, 0x72, 0x04, 0xce, 0x50, 0xa9, 0x6f, 0xfd, - 0x09, 0xfd, 0x0b, 0xfd, 0x21, 0xbd, 0xf5, 0xe0, 0x63, 0x8e, 0xb9, 0x94, 0xa8, 0xd9, 0x5e, 0x7b, - 0xe8, 0xd5, 0xa7, 0x82, 0x8b, 0x76, 0x39, 0x21, 0x5c, 0x20, 0x27, 0xdf, 0x34, 0xdf, 0xe3, 0xf7, - 0xbd, 0x79, 0x6f, 0xde, 0x02, 0xa1, 0x6f, 0x87, 0x9f, 0x0a, 0x83, 0x71, 0x73, 0x18, 0x74, 0xc0, - 0xf7, 0x40, 0x82, 0x30, 0xc7, 0xe0, 0x75, 0xb9, 0x6f, 0x66, 0x06, 0x3a, 0x62, 0x26, 0xed, 0xba, - 0x4c, 0x08, 0xc6, 0x3d, 0x1f, 0xfa, 0x4c, 0x48, 0x9f, 0x4a, 0xc6, 0x3d, 0x73, 0x7c, 0xab, 0x03, - 0x92, 0xde, 0x32, 0xfb, 0xe0, 0x81, 0x4f, 0x25, 0x74, 0x8d, 0x91, 0xcf, 0x25, 0xc7, 0xed, 0x94, - 0x69, 0xd0, 0x11, 0x33, 0xd6, 0x32, 0x8d, 0x8c, 0xb9, 0xf3, 0x61, 0x9f, 0xc9, 0x41, 0xd0, 0x31, - 0x6c, 0xee, 0x9a, 0x7d, 0xde, 0xe7, 0x66, 0x22, 0xd0, 0x09, 0x7a, 0xc9, 0x29, 0x39, 0x24, 0xbf, - 0x52, 0xe1, 0x9d, 0xdb, 0x39, 0xae, 0xb4, 0x7c, 0x9b, 0x9d, 0x8f, 0x66, 0x24, 0x97, 0xda, 0x03, - 0xe6, 0x81, 0x7f, 0x6c, 0x8e, 0x86, 0xfd, 0x18, 0x10, 0xa6, 0x0b, 0x92, 0xae, 0x63, 0x99, 0xe7, - 0xb1, 0xfc, 0xc0, 0x93, 0xcc, 0x85, 0x15, 0xc2, 0xc7, 0xaf, 0x23, 0x08, 0x7b, 0x00, 0x2e, 0x5d, - 0xe6, 0xb5, 0x7e, 0x2f, 0xa3, 0xab, 0x07, 0x81, 0xa4, 0x92, 0x79, 0xfd, 0x27, 0xd0, 0x19, 0x70, - 0x3e, 0xc4, 0x4d, 0x54, 0xf4, 0xa8, 0x0b, 0xaa, 0xd2, 0x54, 0xda, 0x55, 0xab, 0x7e, 0x12, 0xea, - 0x1b, 0x51, 0xa8, 0x17, 0x0f, 0xa9, 0x0b, 0x24, 0xb1, 0xe0, 0xe7, 0xa8, 0x6e, 0x3b, 0x0c, 0x3c, - 0xb9, 0xc7, 0xbd, 0x1e, 0xeb, 0xab, 0x9b, 0x4d, 0xa5, 0x5d, 0xdb, 0xfd, 0xc2, 0xc8, 0x9b, 0x79, - 0x23, 0x73, 0xb5, 0x37, 0x27, 0x62, 0xbd, 0x9d, 0x39, 0xaa, 0xcf, 0xa3, 0x64, 0xc1, 0x11, 0x7e, - 0x8a, 0x4a, 0x7e, 0xe0, 0x80, 0x50, 0x0b, 0xcd, 0x42, 0xbb, 0xb6, 0xfb, 0x49, 0x1e, 0x8f, 0x06, - 0x09, 0x1c, 0x78, 0xc2, 0xe4, 0xe0, 0xfe, 0x08, 0x52, 0x50, 0x58, 0x5b, 0x99, 0xaf, 0x52, 0x6c, - 0x13, 0x24, 0x15, 0xc5, 0xfb, 0x68, 0xab, 0x47, 0x99, 0x13, 0xf8, 0xf0, 0x80, 0x3b, 0xcc, 0x3e, - 0x56, 0x8b, 0x49, 0x06, 0x3e, 0x88, 0x42, 0x7d, 0xeb, 0xde, 0xbc, 0xe1, 0x2c, 0xd4, 0x1b, 0x0b, - 0xc0, 0xc3, 0xe3, 0x11, 0x90, 0x45, 0x32, 0xfe, 0x12, 0xd5, 0x5c, 0x2a, 0xed, 0x41, 0xa6, 0x55, - 0x4d, 0xb4, 0x5a, 0x51, 0xa8, 0xd7, 0x0e, 0x66, 0xf0, 0x59, 0xa8, 0x5f, 0x9d, 0x3b, 0x26, 0x3a, - 0xf3, 0x34, 0xfc, 0x13, 0x6a, 0xc4, 0x29, 0x17, 0x23, 0x6a, 0xc3, 0x11, 0x38, 0x60, 0x4b, 0xee, - 0xab, 0xa5, 0x24, 0xdf, 0xb7, 0xe7, 0xa2, 0x9f, 0x3e, 0xba, 0x31, 0x1a, 0xf6, 0x63, 0x40, 0x18, - 0x71, 0x6d, 0xc5, 0xe1, 0xef, 0xd3, 0x0e, 0x38, 0x13, 0xaa, 0xf5, 0x4e, 0x14, 0xea, 0x8d, 0xc3, - 0x65, 0x45, 0xb2, 0xea, 0x04, 0x73, 0xb4, 0xcd, 0x3b, 0x3f, 0x82, 0x2d, 0xa7, 0x6e, 0x6b, 0x17, - 0x77, 0x8b, 0xa3, 0x50, 0xdf, 0xbe, 0xbf, 0x20, 0x47, 0x96, 0xe4, 0xe3, 0x84, 0x09, 0xd6, 0x85, - 0xaf, 0x7a, 0x3d, 0xb0, 0xa5, 0x50, 0xaf, 0xcc, 0x12, 0x76, 0x34, 0x83, 0xe3, 0x84, 0xcd, 0x8e, - 0x7b, 0x0e, 0x15, 0x82, 0xcc, 0xd3, 0xf0, 0x1d, 0xb4, 0x1d, 0x17, 0x3c, 0x0f, 0xe4, 0x11, 0xd8, - 0xdc, 0xeb, 0x0a, 0xb5, 0xdc, 0x54, 0xda, 0xa5, 0xf4, 0x06, 0x0f, 0x17, 0x2c, 0x64, 0xe9, 0x4b, - 0xfc, 0x08, 0x5d, 0x9f, 0x56, 0x11, 0x81, 0x31, 0x83, 0xe7, 0x8f, 0xc1, 0x8f, 0x0f, 0x42, 0xad, - 0x34, 0x0b, 0xed, 0xaa, 0xf5, 0x7e, 0x14, 0xea, 0xd7, 0xef, 0xae, 0xff, 0x84, 0x9c, 0xc7, 0xc5, - 0xcf, 0x10, 0xf6, 0x81, 0x79, 0x63, 0x6e, 0x27, 0xe5, 0x97, 0x15, 0x04, 0x4a, 0xe2, 0xbb, 0x19, - 0x85, 0x3a, 0x26, 0x2b, 0xd6, 0xb3, 0x50, 0x7f, 0x77, 0x15, 0x4d, 0xca, 0x63, 0x8d, 0x56, 0xeb, - 0x0f, 0x05, 0xdd, 0x58, 0x6a, 0xe3, 0xb4, 0x63, 0x82, 0xb4, 0xe2, 0xf1, 0x33, 0x54, 0x89, 0x1f, - 0xa6, 0x4b, 0x25, 0x4d, 0xfa, 0xba, 0xb6, 0x7b, 0x33, 0xdf, 0x33, 0xa6, 0x6f, 0x76, 0x00, 0x92, - 0x5a, 0x38, 0x6b, 0x1a, 0x34, 0xc3, 0xc8, 0x54, 0x15, 0x7f, 0x8f, 0x2a, 0x99, 0x67, 0xa1, 0x6e, - 0x26, 0xdd, 0xf9, 0x59, 0xfe, 0x79, 0xb0, 0x74, 0x77, 0xab, 0x18, 0xbb, 0x22, 0x53, 0xc1, 0xd6, - 0x3f, 0x0a, 0x6a, 0xbe, 0x2a, 0xbe, 0x7d, 0x26, 0x24, 0x7e, 0xba, 0x12, 0xa3, 0x91, 0xb3, 0x54, - 0x99, 0x48, 0x23, 0xbc, 0x96, 0x45, 0x58, 0x99, 0x20, 0x73, 0xf1, 0x0d, 0x51, 0x89, 0x49, 0x70, - 0x27, 0xc1, 0xdd, 0xbb, 0x70, 0x70, 0x0b, 0x17, 0x9f, 0x4d, 0xa2, 0x6f, 0x62, 0x71, 0x92, 0xfa, - 0x68, 0xfd, 0xaa, 0xa0, 0x6b, 0x47, 0xe0, 0x8f, 0x99, 0x0d, 0x04, 0x7a, 0xe0, 0x83, 0x67, 0x03, - 0x36, 0x51, 0x75, 0xda, 0xa5, 0xd9, 0x70, 0x6e, 0x64, 0xec, 0xea, 0xb4, 0xa3, 0xc9, 0xec, 0x9b, - 0xe9, 0x20, 0xdf, 0x3c, 0x77, 0x90, 0xdf, 0x40, 0xc5, 0x11, 0x95, 0x03, 0xb5, 0x90, 0x7c, 0x51, - 0x89, 0xad, 0x0f, 0xa8, 0x1c, 0x90, 0x04, 0x4d, 0xac, 0xdc, 0x97, 0xc9, 0x18, 0x2c, 0x65, 0x56, - 0xee, 0x4b, 0x92, 0xa0, 0xad, 0xbf, 0xaf, 0xa0, 0xc6, 0x63, 0xea, 0xb0, 0xee, 0xe5, 0xf2, 0xb8, - 0x5c, 0x1e, 0xaf, 0x5f, 0x1e, 0xe8, 0x72, 0x79, 0x5c, 0x64, 0x79, 0xb4, 0x4e, 0x15, 0xa4, 0xad, - 0xb4, 0xd9, 0x9b, 0x1e, 0xee, 0x3f, 0xac, 0x0c, 0xf7, 0xcf, 0xf3, 0xf7, 0xeb, 0xca, 0xed, 0x57, - 0xc6, 0xfb, 0xbf, 0x0a, 0x6a, 0xbd, 0x3a, 0xc6, 0x37, 0x30, 0xe0, 0xdd, 0xc5, 0x01, 0xff, 0xf5, - 0xff, 0x08, 0x30, 0xcf, 0x88, 0xff, 0x4d, 0x41, 0x6f, 0xad, 0x99, 0x64, 0xf8, 0x3d, 0x54, 0x08, - 0x7c, 0x27, 0x9b, 0xc8, 0xe5, 0x28, 0xd4, 0x0b, 0x8f, 0xc8, 0x3e, 0x89, 0x31, 0x4c, 0x51, 0x59, - 0xa4, 0x4b, 0x21, 0x0b, 0xff, 0x4e, 0xfe, 0x3b, 0x2e, 0x6f, 0x13, 0xab, 0x16, 0x85, 0x7a, 0x79, - 0x82, 0x4e, 0x74, 0x71, 0x1b, 0x55, 0x6c, 0x6a, 0x05, 0x5e, 0xd7, 0x49, 0xd7, 0x46, 0xdd, 0xaa, - 0xc7, 0xe9, 0xda, 0xbb, 0x9b, 0x62, 0x64, 0x6a, 0xb5, 0x0e, 0x4f, 0x4e, 0xb5, 0x8d, 0x17, 0xa7, - 0xda, 0xc6, 0xcb, 0x53, 0x6d, 0xe3, 0xe7, 0x48, 0x53, 0x4e, 0x22, 0x4d, 0x79, 0x11, 0x69, 0xca, - 0xcb, 0x48, 0x53, 0xfe, 0x8c, 0x34, 0xe5, 0x97, 0xbf, 0xb4, 0x8d, 0xef, 0xda, 0x79, 0xff, 0xc6, - 0xfd, 0x17, 0x00, 0x00, 0xff, 0xff, 0x7e, 0xc9, 0x34, 0x4c, 0x0a, 0x0e, 0x00, 0x00, + // 1041 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0x4f, 0x73, 0xdb, 0xc4, + 0x1b, 0x8e, 0xe2, 0xf8, 0x17, 0x67, 0xed, 0x24, 0xcd, 0xfe, 0x80, 0x88, 0xd0, 0xb1, 0x3c, 0x3e, + 0x30, 0xbe, 0x20, 0xb5, 0x29, 0x03, 0xa5, 0x0c, 0x87, 0x2a, 0xb4, 0x03, 0x33, 0x49, 0x5a, 0x36, + 0xfd, 0x33, 0x03, 0x65, 0xa6, 0x6b, 0xf9, 0xb5, 0xbd, 0x58, 0xd2, 0x7a, 0xb4, 0xab, 0xb4, 0x19, + 0x2e, 0x7c, 0x04, 0xbe, 0x02, 0x1f, 0x84, 0x03, 0xb7, 0x1c, 0x7b, 0xec, 0x05, 0x0d, 0x11, 0x67, + 0x0e, 0x5c, 0x73, 0x62, 0xb4, 0x52, 0x6c, 0xcb, 0x76, 0x5a, 0x11, 0x66, 0x72, 0xca, 0xcd, 0xfb, + 0xbc, 0xfb, 0xbe, 0xcf, 0x3e, 0xab, 0x77, 0xdf, 0x67, 0x8c, 0xbe, 0x19, 0xdc, 0x16, 0x26, 0xe3, + 0xd6, 0x20, 0x6c, 0x43, 0xe0, 0x83, 0x04, 0x61, 0x1d, 0x82, 0xdf, 0xe1, 0x81, 0x95, 0x05, 0xe8, + 0x90, 0x59, 0xb4, 0xe3, 0x31, 0x21, 0x18, 0xf7, 0x03, 0xe8, 0x31, 0x21, 0x03, 0x2a, 0x19, 0xf7, + 0xad, 0xc3, 0x9b, 0x6d, 0x90, 0xf4, 0xa6, 0xd5, 0x03, 0x1f, 0x02, 0x2a, 0xa1, 0x63, 0x0e, 0x03, + 0x2e, 0x39, 0x6e, 0xa5, 0x99, 0x26, 0x1d, 0x32, 0x73, 0x6e, 0xa6, 0x99, 0x65, 0x6e, 0x7d, 0xd4, + 0x63, 0xb2, 0x1f, 0xb6, 0x4d, 0x87, 0x7b, 0x56, 0x8f, 0xf7, 0xb8, 0xa5, 0x0a, 0xb4, 0xc3, 0xae, + 0x5a, 0xa9, 0x85, 0xfa, 0x95, 0x16, 0xde, 0xba, 0x55, 0xe0, 0x48, 0xd3, 0xa7, 0xd9, 0xfa, 0x78, + 0x9c, 0xe4, 0x51, 0xa7, 0xcf, 0x7c, 0x08, 0x8e, 0xac, 0xe1, 0xa0, 0x97, 0x00, 0xc2, 0xf2, 0x40, + 0xd2, 0x79, 0x59, 0xd6, 0x79, 0x59, 0x41, 0xe8, 0x4b, 0xe6, 0xc1, 0x4c, 0xc2, 0x27, 0x6f, 0x4b, + 0x10, 0x4e, 0x1f, 0x3c, 0x3a, 0x9d, 0xd7, 0xec, 0xa2, 0xb5, 0x3d, 0x2a, 0x9d, 0xfe, 0x0e, 0xf7, + 0x3b, 0x2c, 0xd1, 0x80, 0x1b, 0x68, 0xc9, 0xa7, 0x1e, 0xe8, 0x5a, 0x43, 0x6b, 0xad, 0xd8, 0xb5, + 0xe3, 0xc8, 0x58, 0x88, 0x23, 0x63, 0x69, 0x9f, 0x7a, 0x40, 0x54, 0x04, 0x6f, 0x23, 0x04, 0x2f, + 0x87, 0x01, 0x28, 0xfd, 0xfa, 0xa2, 0xda, 0x87, 0xb3, 0x7d, 0xe8, 0xde, 0x28, 0x42, 0x26, 0x76, + 0x35, 0x7f, 0xab, 0xa0, 0xf5, 0xbd, 0x50, 0x52, 0xc9, 0xfc, 0xde, 0x53, 0x68, 0xf7, 0x39, 0x1f, + 0x14, 0x60, 0x7a, 0x81, 0x6a, 0x8e, 0xcb, 0xc0, 0x97, 0x3b, 0xdc, 0xef, 0xb2, 0x9e, 0xe2, 0xaa, + 0x6e, 0x7f, 0x61, 0x16, 0xfd, 0xc2, 0x66, 0x46, 0xb5, 0x33, 0x51, 0xc4, 0x7e, 0x27, 0x23, 0xaa, + 0x4d, 0xa2, 0x24, 0x47, 0x84, 0x9f, 0xa1, 0x72, 0x10, 0xba, 0x20, 0xf4, 0x52, 0xa3, 0xd4, 0xaa, + 0x6e, 0x7f, 0x5a, 0x84, 0xd1, 0x24, 0xa1, 0x0b, 0x4f, 0x99, 0xec, 0x3f, 0x18, 0x42, 0x0a, 0x0a, + 0x7b, 0x35, 0xe3, 0x2a, 0x27, 0x31, 0x41, 0xd2, 0xa2, 0x78, 0x17, 0xad, 0x76, 0x29, 0x73, 0xc3, + 0x00, 0x1e, 0x72, 0x97, 0x39, 0x47, 0xfa, 0x92, 0xba, 0x81, 0x0f, 0xe3, 0xc8, 0x58, 0xbd, 0x3f, + 0x19, 0x38, 0x8d, 0x8c, 0x8d, 0x1c, 0xf0, 0xe8, 0x68, 0x08, 0x24, 0x9f, 0x8c, 0xbf, 0x44, 0x55, + 0x2f, 0xf9, 0x84, 0x59, 0xad, 0x15, 0x55, 0xab, 0x19, 0x47, 0x46, 0x75, 0x6f, 0x0c, 0x9f, 0x46, + 0xc6, 0xfa, 0xc4, 0x52, 0xd5, 0x99, 0x4c, 0xc3, 0x2f, 0xd1, 0x46, 0x72, 0xe5, 0x62, 0x48, 0x1d, + 0x38, 0x00, 0x17, 0x1c, 0xc9, 0x03, 0xbd, 0xac, 0xee, 0xfb, 0xd6, 0x84, 0xfa, 0x51, 0x73, 0x99, + 0xc3, 0x41, 0x2f, 0x01, 0x84, 0x99, 0xf4, 0x70, 0x22, 0x7f, 0x97, 0xb6, 0xc1, 0x3d, 0x4b, 0xb5, + 0xdf, 0x8d, 0x23, 0x63, 0x63, 0x7f, 0xba, 0x22, 0x99, 0x25, 0xc1, 0x1c, 0xad, 0xf1, 0xf6, 0x0f, + 0xe0, 0xc8, 0x11, 0x6d, 0xf5, 0xe2, 0xb4, 0x38, 0x8e, 0x8c, 0xb5, 0x07, 0xb9, 0x72, 0x64, 0xaa, + 0x7c, 0x72, 0x61, 0x82, 0x75, 0xe0, 0x5e, 0xb7, 0x0b, 0x8e, 0x14, 0xfa, 0xff, 0xc6, 0x17, 0x76, + 0x30, 0x86, 0x93, 0x0b, 0x1b, 0x2f, 0x77, 0x5c, 0x2a, 0x04, 0x99, 0x4c, 0xc3, 0x77, 0xd0, 0x5a, + 0xf2, 0xb0, 0x78, 0x28, 0x0f, 0xc0, 0xe1, 0x7e, 0x47, 0xe8, 0xcb, 0x0d, 0xad, 0x55, 0x4e, 0x4f, + 0xf0, 0x28, 0x17, 0x21, 0x53, 0x3b, 0xf1, 0x63, 0xb4, 0x39, 0xea, 0x22, 0x02, 0x87, 0x0c, 0x5e, + 0x3c, 0x81, 0x20, 0x59, 0x08, 0xbd, 0xd2, 0x28, 0xb5, 0x56, 0xec, 0x0f, 0xe2, 0xc8, 0xd8, 0xbc, + 0x3b, 0x7f, 0x0b, 0x39, 0x2f, 0x17, 0x3f, 0x47, 0x38, 0x00, 0xe6, 0x1f, 0x72, 0x47, 0xb5, 0x5f, + 0xd6, 0x10, 0x48, 0xe9, 0xbb, 0x11, 0x47, 0x06, 0x26, 0x33, 0xd1, 0xd3, 0xc8, 0x78, 0x6f, 0x16, + 0x55, 0xed, 0x31, 0xa7, 0x16, 0xfe, 0x11, 0xad, 0x7b, 0xb9, 0x71, 0x21, 0xf4, 0x9a, 0x7a, 0x21, + 0xb7, 0x8b, 0xbf, 0xc9, 0xfc, 0xbc, 0xb1, 0x37, 0xb3, 0x27, 0xb2, 0x9e, 0xc7, 0x05, 0x99, 0x66, + 0x6a, 0xfe, 0xae, 0xa1, 0xeb, 0x53, 0x33, 0x24, 0x7d, 0xae, 0x61, 0xca, 0x80, 0x9f, 0xa3, 0x4a, + 0xd2, 0x15, 0x1d, 0x2a, 0xa9, 0x1a, 0x2a, 0xd5, 0xed, 0x1b, 0xc5, 0x7a, 0x28, 0x6d, 0x98, 0x3d, + 0x90, 0x74, 0x3c, 0xc8, 0xc6, 0x18, 0x19, 0x55, 0xc5, 0xdf, 0xa1, 0x4a, 0xc6, 0x2c, 0xf4, 0x45, + 0x25, 0xfc, 0xb3, 0x7f, 0x21, 0x3c, 0x7f, 0x76, 0x7b, 0x29, 0xa1, 0x22, 0xa3, 0x82, 0xcd, 0xbf, + 0x34, 0xd4, 0x78, 0x93, 0xbe, 0x5d, 0x26, 0x24, 0x7e, 0x36, 0xa3, 0xd1, 0x2c, 0xf8, 0x4e, 0x98, + 0x48, 0x15, 0x5e, 0xcb, 0x14, 0x56, 0xce, 0x90, 0x09, 0x7d, 0x03, 0x54, 0x66, 0x12, 0xbc, 0x33, + 0x71, 0xf7, 0x2f, 0x2c, 0x2e, 0x77, 0xf0, 0xf1, 0x18, 0xfc, 0x3a, 0x29, 0x4e, 0x52, 0x8e, 0xe6, + 0x2f, 0x1a, 0xba, 0x76, 0x00, 0xc1, 0x21, 0x73, 0x80, 0x40, 0x17, 0x02, 0xf0, 0x1d, 0xc0, 0x16, + 0x5a, 0x19, 0x8d, 0x88, 0xcc, 0x19, 0x36, 0xb2, 0xec, 0x95, 0xd1, 0x38, 0x21, 0xe3, 0x3d, 0x23, + 0x17, 0x59, 0x3c, 0xd7, 0x45, 0xae, 0xa3, 0xa5, 0x21, 0x95, 0x7d, 0xbd, 0xa4, 0x76, 0x54, 0x92, + 0xe8, 0x43, 0x2a, 0xfb, 0x44, 0xa1, 0x2a, 0xca, 0x03, 0xa9, 0x66, 0x70, 0x39, 0x8b, 0xf2, 0x40, + 0x12, 0x85, 0x36, 0x4f, 0x96, 0xd1, 0xc6, 0x13, 0xea, 0xb2, 0xce, 0x95, 0x73, 0x5d, 0x39, 0xd7, + 0xdb, 0x9d, 0x0b, 0x5d, 0x39, 0xd7, 0x85, 0x9c, 0x6b, 0x8e, 0xaf, 0x54, 0x2f, 0xcd, 0x57, 0x4e, + 0x34, 0x54, 0x9f, 0x79, 0xe3, 0x97, 0xed, 0x2c, 0xdf, 0xcf, 0x38, 0xcb, 0xe7, 0xc5, 0xa5, 0xcf, + 0x9c, 0x7e, 0xc6, 0x5b, 0xfe, 0xd6, 0x50, 0xf3, 0xcd, 0x1a, 0x2f, 0xc1, 0x5d, 0xbc, 0xbc, 0xbb, + 0x7c, 0xf5, 0x1f, 0x04, 0x16, 0xf1, 0x97, 0x5f, 0x35, 0xf4, 0xff, 0x39, 0x63, 0x14, 0xbf, 0x8f, + 0x4a, 0x61, 0xe0, 0x66, 0x76, 0xb0, 0x1c, 0x47, 0x46, 0xe9, 0x31, 0xd9, 0x25, 0x09, 0x86, 0x29, + 0x5a, 0x16, 0xa9, 0x23, 0x65, 0xf2, 0xef, 0x14, 0x3f, 0xe3, 0xb4, 0x95, 0xd9, 0xd5, 0x38, 0x32, + 0x96, 0xcf, 0xd0, 0xb3, 0xba, 0xb8, 0x85, 0x2a, 0x0e, 0xb5, 0x43, 0xbf, 0xe3, 0xa6, 0x9e, 0x55, + 0xb3, 0x6b, 0xc9, 0x75, 0xed, 0xdc, 0x4d, 0x31, 0x32, 0x8a, 0xda, 0xfb, 0xc7, 0x27, 0xf5, 0x85, + 0x57, 0x27, 0xf5, 0x85, 0xd7, 0x27, 0xf5, 0x85, 0x9f, 0xe2, 0xba, 0x76, 0x1c, 0xd7, 0xb5, 0x57, + 0x71, 0x5d, 0x7b, 0x1d, 0xd7, 0xb5, 0x3f, 0xe2, 0xba, 0xf6, 0xf3, 0x9f, 0xf5, 0x85, 0x6f, 0x5b, + 0x45, 0xff, 0x28, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0x1f, 0xf5, 0x97, 0x1c, 0x6c, 0x0f, 0x00, + 0x00, +} + +func (m *MatchCondition) 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 *MatchCondition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MatchCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Expression) + copy(dAtA[i:], m.Expression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Expression))) + 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 *MutatingWebhook) Marshal() (dAtA []byte, err error) { @@ -369,6 +436,20 @@ func (m *MutatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 + } + } if m.ObjectSelector != nil { { size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) @@ -626,6 +707,20 @@ func (m *ValidatingWebhook) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MatchConditions) > 0 { + for iNdEx := len(m.MatchConditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MatchConditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + } if m.ObjectSelector != nil { { size, err := m.ObjectSelector.MarshalToSizedBuffer(dAtA[:i]) @@ -871,6 +966,19 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *MatchCondition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *MutatingWebhook) Size() (n int) { if m == nil { return 0 @@ -920,6 +1028,12 @@ func (m *MutatingWebhook) Size() (n int) { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1022,6 +1136,12 @@ func (m *ValidatingWebhook) Size() (n int) { l = m.ObjectSelector.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.MatchConditions) > 0 { + for _, e := range m.MatchConditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -1086,6 +1206,17 @@ func sovGenerated(x uint64) (n int) { func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (this *MatchCondition) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MatchCondition{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Expression:` + fmt.Sprintf("%v", this.Expression) + `,`, + `}`, + }, "") + return s +} func (this *MutatingWebhook) String() string { if this == nil { return "nil" @@ -1095,6 +1226,11 @@ func (this *MutatingWebhook) String() string { repeatedStringForRules += fmt.Sprintf("%v", f) + "," } repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&MutatingWebhook{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, @@ -1107,6 +1243,7 @@ func (this *MutatingWebhook) String() string { `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, `ReinvocationPolicy:` + valueToStringGenerated(this.ReinvocationPolicy) + `,`, `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v11.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, `}`, }, "") return s @@ -1165,6 +1302,11 @@ func (this *ValidatingWebhook) String() string { repeatedStringForRules += fmt.Sprintf("%v", f) + "," } repeatedStringForRules += "}" + repeatedStringForMatchConditions := "[]MatchCondition{" + for _, f := range this.MatchConditions { + repeatedStringForMatchConditions += strings.Replace(strings.Replace(f.String(), "MatchCondition", "MatchCondition", 1), `&`, ``, 1) + "," + } + repeatedStringForMatchConditions += "}" s := strings.Join([]string{`&ValidatingWebhook{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `ClientConfig:` + strings.Replace(strings.Replace(this.ClientConfig.String(), "WebhookClientConfig", "WebhookClientConfig", 1), `&`, ``, 1) + `,`, @@ -1176,6 +1318,7 @@ func (this *ValidatingWebhook) String() string { `AdmissionReviewVersions:` + fmt.Sprintf("%v", this.AdmissionReviewVersions) + `,`, `MatchPolicy:` + valueToStringGenerated(this.MatchPolicy) + `,`, `ObjectSelector:` + strings.Replace(fmt.Sprintf("%v", this.ObjectSelector), "LabelSelector", "v11.LabelSelector", 1) + `,`, + `MatchConditions:` + repeatedStringForMatchConditions + `,`, `}`, }, "") return s @@ -1232,6 +1375,120 @@ func valueToStringGenerated(v interface{}) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("*%v", pv) } +func (m *MatchCondition) 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: MatchCondition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchCondition: 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 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 *MutatingWebhook) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -1616,6 +1873,40 @@ func (m *MutatingWebhook) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", 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.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2389,6 +2680,40 @@ func (m *ValidatingWebhook) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchConditions", 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.MatchConditions = append(m.MatchConditions, MatchCondition{}) + if err := m.MatchConditions[len(m.MatchConditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto index c7016afbf..cfd759285 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/generated.proto @@ -29,6 +29,35 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". option go_package = "k8s.io/api/admissionregistration/v1beta1"; +// MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook. +message MatchCondition { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + optional string name = 1; + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + optional string expression = 2; +} + // MutatingWebhook describes an admission webhook and the resources and operations it applies to. message MutatingWebhook { // The name of the admission webhook. @@ -177,6 +206,28 @@ message MutatingWebhook { // Defaults to "Never". // +optional optional string reinvocationPolicy = 10; + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + repeated MatchCondition matchConditions = 12; } // MutatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and may change the object. @@ -356,6 +407,28 @@ message ValidatingWebhook { // Default to `['v1beta1']`. // +optional repeated string admissionReviewVersions = 8; + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + repeated MatchCondition matchConditions = 11; } // ValidatingWebhookConfiguration describes the configuration of and admission webhook that accept or reject and object without changing it. diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/types.go b/vendor/k8s.io/api/admissionregistration/v1beta1/types.go index 5fdf8e3fa..82ee7df9b 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/types.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/types.go @@ -283,6 +283,28 @@ type ValidatingWebhook struct { // Default to `['v1beta1']`. // +optional AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty" protobuf:"bytes,8,rep,name=admissionReviewVersions"` + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,11,rep,name=matchConditions"` } // MutatingWebhook describes an admission webhook and the resources and operations it applies to. @@ -433,6 +455,28 @@ type MutatingWebhook struct { // Defaults to "Never". // +optional ReinvocationPolicy *ReinvocationPolicyType `json:"reinvocationPolicy,omitempty" protobuf:"bytes,10,opt,name=reinvocationPolicy,casttype=ReinvocationPolicyType"` + + // MatchConditions is a list of conditions that must be met for a request to be sent to this + // webhook. Match conditions filter requests that have already been matched by the rules, + // namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. + // There are a maximum of 64 match conditions allowed. + // + // The exact matching logic is (in order): + // 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped. + // 2. If ALL matchConditions evaluate to TRUE, the webhook is called. + // 3. If any matchCondition evaluates to an error (but none are FALSE): + // - If failurePolicy=Fail, reject the request + // - If failurePolicy=Ignore, the error is ignored and the webhook is skipped + // + // This is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate. + // + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +featureGate=AdmissionWebhookMatchConditions + // +optional + MatchConditions []MatchCondition `json:"matchConditions,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,12,rep,name=matchConditions"` } // ReinvocationPolicyType specifies what type of policy the admission hook uses. @@ -531,3 +575,32 @@ type ServiceReference struct { // +optional Port *int32 `json:"port,omitempty" protobuf:"varint,4,opt,name=port"` } + +// MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook. +type MatchCondition struct { + // Name is an identifier for this match condition, used for strategic merging of MatchConditions, + // as well as providing an identifier for logging purposes. A good name should be descriptive of + // the associated expression. + // Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and + // must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or + // '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an + // optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName') + // + // Required. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + + // Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. + // CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables: + // + // 'object' - The object from the incoming request. The value is null for DELETE requests. + // 'oldObject' - The existing object. The value is null for CREATE requests. + // 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). + // 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request. + // See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz + // 'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the + // request resource. + // Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/ + // + // Required. + Expression string `json:"expression" protobuf:"bytes,2,opt,name=expression"` +} diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go index c57c5b7fa..2c0a9f011 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/types_swagger_doc_generated.go @@ -24,9 +24,19 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_MatchCondition = map[string]string{ + "": "MatchCondition represents a condition which must be fulfilled for a request to be sent to a webhook.", + "name": "Name is an identifier for this match condition, used for strategic merging of MatchConditions, as well as providing an identifier for logging purposes. A good name should be descriptive of the associated expression. Name must be a qualified name consisting of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyName')\n\nRequired.", + "expression": "Expression represents the expression which will be evaluated by CEL. Must evaluate to bool. CEL expressions have access to the contents of the AdmissionRequest and Authorizer, organized into CEL variables:\n\n'object' - The object from the incoming request. The value is null for DELETE requests. 'oldObject' - The existing object. The value is null for CREATE requests. 'request' - Attributes of the admission request(/pkg/apis/admission/types.go#AdmissionRequest). 'authorizer' - A CEL Authorizer. May be used to perform authorization checks for the principal (user or service account) of the request.\n See https://pkg.go.dev/k8s.io/apiserver/pkg/cel/library#Authz\n'authorizer.requestResource' - A CEL ResourceCheck constructed from the 'authorizer' and configured with the\n request resource.\nDocumentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/\n\nRequired.", +} + +func (MatchCondition) SwaggerDoc() map[string]string { + return map_MatchCondition +} + var map_MutatingWebhook = map[string]string{ "": "MutatingWebhook describes an admission webhook and the resources and operations it applies to.", "name": "The name of the admission webhook. Name should be fully qualified, e.g., imagepolicy.kubernetes.io, where \"imagepolicy\" is the name of the webhook, and kubernetes.io is the name of the organization. Required.", @@ -40,6 +50,7 @@ var map_MutatingWebhook = map[string]string{ "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", "reinvocationPolicy": "reinvocationPolicy indicates whether this webhook should be called multiple times as part of a single admission evaluation. Allowed values are \"Never\" and \"IfNeeded\".\n\nNever: the webhook will not be called more than once in a single admission evaluation.\n\nIfNeeded: the webhook will be called at least one additional time as part of the admission evaluation if the object being admitted is modified by other admission plugins after the initial webhook call. Webhooks that specify this option *must* be idempotent, able to process objects they previously admitted. Note: * the number of additional invocations is not guaranteed to be exactly one. * if additional invocations result in further modifications to the object, webhooks are not guaranteed to be invoked again. * webhooks that use this option may be reordered to minimize the number of additional invocations. * to validate an object after all mutations are guaranteed complete, use a validating admission webhook instead.\n\nDefaults to \"Never\".", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate.", } func (MutatingWebhook) SwaggerDoc() map[string]string { @@ -90,6 +101,7 @@ var map_ValidatingWebhook = map[string]string{ "sideEffects": "SideEffects states whether this webhook has side effects. Acceptable values are: Unknown, None, Some, NoneOnDryRun Webhooks with side effects MUST implement a reconciliation system, since a request may be rejected by a future step in the admission chain and the side effects therefore need to be undone. Requests with the dryRun attribute will be auto-rejected if they match a webhook with sideEffects == Unknown or Some. Defaults to Unknown.", "timeoutSeconds": "TimeoutSeconds specifies the timeout for this webhook. After the timeout passes, the webhook call will be ignored or the API call will fail based on the failure policy. The timeout value must be between 1 and 30 seconds. Default to 30 seconds.", "admissionReviewVersions": "AdmissionReviewVersions is an ordered list of preferred `AdmissionReview` versions the Webhook expects. API server will try to use first version in the list which it supports. If none of the versions specified in this list supported by API server, validation will fail for this object. If a persisted webhook configuration specifies allowed versions and does not include any versions known to the API Server, calls to the webhook will fail and be subject to the failure policy. Default to `['v1beta1']`.", + "matchConditions": "MatchConditions is a list of conditions that must be met for a request to be sent to this webhook. Match conditions filter requests that have already been matched by the rules, namespaceSelector, and objectSelector. An empty list of matchConditions matches all requests. There are a maximum of 64 match conditions allowed.\n\nThe exact matching logic is (in order):\n 1. If ANY matchCondition evaluates to FALSE, the webhook is skipped.\n 2. If ALL matchConditions evaluate to TRUE, the webhook is called.\n 3. If any matchCondition evaluates to an error (but none are FALSE):\n - If failurePolicy=Fail, reject the request\n - If failurePolicy=Ignore, the error is ignored and the webhook is skipped\n\nThis is an alpha feature and managed by the AdmissionWebhookMatchConditions feature gate.", } func (ValidatingWebhook) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go index ced4af19c..9c5299bdf 100644 --- a/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/admissionregistration/v1beta1/zz_generated.deepcopy.go @@ -27,6 +27,22 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchCondition) DeepCopyInto(out *MatchCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchCondition. +func (in *MatchCondition) DeepCopy() *MatchCondition { + if in == nil { + return nil + } + out := new(MatchCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = *in @@ -78,6 +94,11 @@ func (in *MutatingWebhook) DeepCopyInto(out *MutatingWebhook) { *out = new(ReinvocationPolicyType) **out = **in } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } @@ -229,6 +250,11 @@ func (in *ValidatingWebhook) DeepCopyInto(out *ValidatingWebhook) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.MatchConditions != nil { + in, out := &in.MatchConditions, &out.MatchConditions + *out = make([]MatchCondition, len(*in)) + copy(*out, *in) + } return } diff --git a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go index 6de934200..3b75fa65b 100644 --- a/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apiserverinternal/v1alpha1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ServerStorageVersion = map[string]string{ diff --git a/vendor/k8s.io/api/apps/v1/generated.proto b/vendor/k8s.io/api/apps/v1/generated.proto index 534b550fe..a7a7e7c54 100644 --- a/vendor/k8s.io/api/apps/v1/generated.proto +++ b/vendor/k8s.io/api/apps/v1/generated.proto @@ -127,6 +127,7 @@ message DaemonSetSpec { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template optional k8s.io.api.core.v1.PodTemplateSpec template = 2; @@ -277,6 +278,7 @@ message DeploymentSpec { optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // The deployment strategy to use to replace existing pods with new ones. @@ -675,6 +677,7 @@ message StatefulSetSpec { // of the StatefulSet. Each pod will be named with the format // -. For example, a pod in a StatefulSet named // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -735,7 +738,7 @@ message StatefulSetSpec { // default ordinals behavior assigns a "0" index to the first replica and // increments the index by one for each additional replica requested. Using // the ordinals field requires the StatefulSetStartOrdinal feature gate to be - // enabled, which is alpha. + // enabled, which is beta. // +optional optional StatefulSetOrdinals ordinals = 11; } diff --git a/vendor/k8s.io/api/apps/v1/types.go b/vendor/k8s.io/api/apps/v1/types.go index 09766c295..15dc3150a 100644 --- a/vendor/k8s.io/api/apps/v1/types.go +++ b/vendor/k8s.io/api/apps/v1/types.go @@ -199,6 +199,7 @@ type StatefulSetSpec struct { // of the StatefulSet. Each pod will be named with the format // -. For example, a pod in a StatefulSet named // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -259,7 +260,7 @@ type StatefulSetSpec struct { // default ordinals behavior assigns a "0" index to the first replica and // increments the index by one for each additional replica requested. Using // the ordinals field requires the StatefulSetStartOrdinal feature gate to be - // enabled, which is alpha. + // enabled, which is beta. // +optional Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" protobuf:"bytes,11,opt,name=ordinals"` } @@ -379,6 +380,7 @@ type DeploymentSpec struct { Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,2,opt,name=selector"` // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // The deployment strategy to use to replace existing pods with new ones. @@ -638,6 +640,7 @@ type DaemonSetSpec struct { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,2,opt,name=template"` diff --git a/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go index 509bb11c5..6676da064 100644 --- a/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ControllerRevision = map[string]string{ @@ -85,7 +85,7 @@ func (DaemonSetList) SwaggerDoc() map[string]string { var map_DaemonSetSpec = map[string]string{ "": "DaemonSetSpec is the specification of a daemon set.", "selector": "A label query over pods that are managed by the daemon set. Must match in order to be controlled. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", + "template": "An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). The only allowed template.spec.restartPolicy value is \"Always\". More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", "updateStrategy": "An update strategy to replace existing DaemonSet pods with new pods.", "minReadySeconds": "The minimum number of seconds for which a newly created DaemonSet 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).", "revisionHistoryLimit": "The number of old history to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", @@ -162,7 +162,7 @@ var map_DeploymentSpec = map[string]string{ "": "DeploymentSpec is the specification of the desired behavior of the Deployment.", "replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", "selector": "Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment. It must match the pod template's labels.", - "template": "Template describes the pods that will be created.", + "template": "Template describes the pods that will be created. The only allowed template.spec.restartPolicy value is \"Always\".", "strategy": "The deployment strategy to use to replace existing pods with new ones.", "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)", "revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", @@ -347,7 +347,7 @@ var map_StatefulSetSpec = map[string]string{ "": "A StatefulSetSpec is the specification of a StatefulSet.", "replicas": "replicas is the desired number of replicas of the given Template. These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1.", "selector": "selector is a label query over pods that should match the replica count. 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. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format -. For example, a pod in a StatefulSet named \"web\" with index number \"3\" would be named \"web-3\".", + "template": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format -. For example, a pod in a StatefulSet named \"web\" with index number \"3\" would be named \"web-3\". The only allowed template.spec.restartPolicy value is \"Always\".", "volumeClaimTemplates": "volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.", "serviceName": "serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for 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.", "podManagementPolicy": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.", @@ -355,7 +355,7 @@ var map_StatefulSetSpec = map[string]string{ "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", "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)", "persistentVolumeClaimRetentionPolicy": "persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. +optional", - "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is alpha.", + "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is beta.", } func (StatefulSetSpec) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/apps/v1beta1/generated.proto b/vendor/k8s.io/api/apps/v1beta1/generated.proto index 15fb1aa87..245ec30f4 100644 --- a/vendor/k8s.io/api/apps/v1beta1/generated.proto +++ b/vendor/k8s.io/api/apps/v1beta1/generated.proto @@ -47,10 +47,10 @@ message ControllerRevision { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Data is the serialized representation of the state. + // data is the serialized representation of the state. optional k8s.io.apimachinery.pkg.runtime.RawExtension data = 2; - // Revision indicates the revision of the state represented by Data. + // revision indicates the revision of the state represented by Data. optional int64 revision = 3; } @@ -128,17 +128,18 @@ message DeploymentRollback { // DeploymentSpec is the specification of the desired behavior of the Deployment. message DeploymentSpec { - // Number of desired pods. This is a pointer to distinguish between explicit + // replicas is the number of desired pods. This is a pointer to distinguish between explicit // zero and not specified. Defaults to 1. // +optional optional int32 replicas = 1; - // Label selector for pods. Existing ReplicaSets whose pods are + // selector is the label selector for pods. Existing ReplicaSets whose pods are // selected by this will be the ones affected by this deployment. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // The deployment strategy to use to replace existing pods with new ones. @@ -146,28 +147,28 @@ message DeploymentSpec { // +patchStrategy=retainKeys optional DeploymentStrategy strategy = 4; - // Minimum number of seconds for which a newly created pod should be ready + // minReadySeconds is the 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 optional int32 minReadySeconds = 5; - // The number of old ReplicaSets to retain to allow rollback. + // revisionHistoryLimit is the number of old ReplicaSets to retain to allow rollback. // This is a pointer to distinguish between explicit zero and not specified. // Defaults to 2. // +optional optional int32 revisionHistoryLimit = 6; - // Indicates that the deployment is paused. + // paused indicates that the deployment is paused. // +optional optional bool paused = 7; // DEPRECATED. - // The config this deployment is rolling back to. Will be cleared after rollback is done. + // rollbackTo is the config this deployment is rolling back to. Will be cleared after rollback is done. // +optional optional RollbackConfig rollbackTo = 8; - // The maximum time in seconds for a deployment to make progress before it + // progressDeadlineSeconds is the maximum time in seconds for a deployment to make progress before it // is considered to be failed. The deployment controller will continue to // process failed deployments and a condition with a ProgressDeadlineExceeded // reason will be surfaced in the deployment status. Note that progress will @@ -178,15 +179,15 @@ message DeploymentSpec { // DeploymentStatus is the most recently observed status of the Deployment. message DeploymentStatus { - // The generation observed by the deployment controller. + // observedGeneration is the generation observed by the deployment controller. // +optional optional int64 observedGeneration = 1; - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // replicas is the total number of non-terminated 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. + // updatedReplicas is the total number of non-terminated pods targeted by this deployment that have the desired template spec. // +optional optional int32 updatedReplicas = 3; @@ -198,18 +199,18 @@ message DeploymentStatus { // +optional optional int32 availableReplicas = 4; - // Total number of unavailable pods targeted by this deployment. This is the total number of + // 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. // +optional optional int32 unavailableReplicas = 5; - // Represents the latest available observations of a deployment's current state. + // Conditions represent the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge repeated DeploymentCondition conditions = 6; - // Count of hash collisions for the Deployment. The Deployment controller uses this + // 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. // +optional @@ -276,7 +277,7 @@ message RollingUpdateStatefulSetStrategy { // This is helpful in being able to do a canary based deployment. The default value is 0. optional int32 partition = 1; - // The maximum number of pods that can be unavailable during the update. + // maxUnavailable is the maximum number of pods that can be unavailable during the update. // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). // Absolute number is calculated from percentage by rounding up. This can not be 0. // Defaults to 1. This field is alpha-level and is only honored by servers that enable the @@ -293,32 +294,32 @@ message Scale { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional optional ScaleSpec spec = 2; - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status defines current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional optional ScaleStatus status = 3; } // ScaleSpec describes the attributes of a scale subresource message ScaleSpec { - // desired number of instances for the scaled object. + // replicas is the number of observed instances of the scaled object. // +optional optional int32 replicas = 1; } // ScaleStatus represents the current status of a scale subresource. message ScaleStatus { - // actual number of observed instances of the scaled object. + // replias is the actual number of observed instances of the scaled object. optional int32 replicas = 1; - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional map selector = 2; - // label selector for pods that should match the replicas count. This is a serializated + // targetSelector is the label selector for pods that should match the replicas count. This is a serializated // version of both map-based and more expressive set-based selectors. This is done to // avoid introspection in the clients. The string will be in the same format as the // query-param syntax. If the target type only supports map-based selectors, both this @@ -398,13 +399,13 @@ message StatefulSetOrdinals { // StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs // created from the StatefulSet VolumeClaimTemplates. message StatefulSetPersistentVolumeClaimRetentionPolicy { - // WhenDeleted specifies what happens to PVCs created from StatefulSet + // whenDeleted specifies what happens to PVCs created from StatefulSet // VolumeClaimTemplates when the StatefulSet is deleted. The default policy // of `Retain` causes PVCs to not be affected by StatefulSet deletion. The // `Delete` policy causes those PVCs to be deleted. optional string whenDeleted = 1; - // WhenScaled specifies what happens to PVCs created from StatefulSet + // whenScaled specifies what happens to PVCs created from StatefulSet // VolumeClaimTemplates when the StatefulSet is scaled down. The default // policy of `Retain` causes PVCs to not be affected by a scaledown. The // `Delete` policy causes the associated PVCs for any excess pods above @@ -475,7 +476,7 @@ message StatefulSetSpec { // StatefulSetSpec version. The default value is 10. optional int32 revisionHistoryLimit = 8; - // Minimum number of seconds for which a newly created pod should be ready + // minReadySeconds is the 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 @@ -491,7 +492,7 @@ message StatefulSetSpec { // default ordinals behavior assigns a "0" index to the first replica and // increments the index by one for each additional replica requested. Using // the ordinals field requires the StatefulSetStartOrdinal feature gate to be - // enabled, which is alpha. + // enabled, which is beta. // +optional optional StatefulSetOrdinals ordinals = 11; } @@ -531,13 +532,13 @@ message StatefulSetStatus { // +optional optional int32 collisionCount = 9; - // Represents the latest available observations of a statefulset's current state. + // conditions represent the latest available observations of a statefulset's current state. // +optional // +patchMergeKey=type // +patchStrategy=merge repeated StatefulSetCondition conditions = 10; - // Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. + // availableReplicas is the total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. // +optional optional int32 availableReplicas = 11; } diff --git a/vendor/k8s.io/api/apps/v1beta1/types.go b/vendor/k8s.io/api/apps/v1beta1/types.go index 910023090..59ed9c2ac 100644 --- a/vendor/k8s.io/api/apps/v1beta1/types.go +++ b/vendor/k8s.io/api/apps/v1beta1/types.go @@ -31,21 +31,21 @@ const ( // ScaleSpec describes the attributes of a scale subresource type ScaleSpec struct { - // desired number of instances for the scaled object. + // replicas is the number of observed instances of the scaled object. // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } // ScaleStatus represents the current status of a scale subresource. type ScaleStatus struct { - // actual number of observed instances of the scaled object. + // replias is the actual number of observed instances of the scaled object. Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"` - // label selector for pods that should match the replicas count. This is a serializated + // targetSelector is the label selector for pods that should match the replicas count. This is a serializated // version of both map-based and more expressive set-based selectors. This is done to // avoid introspection in the clients. The string will be in the same format as the // query-param syntax. If the target type only supports map-based selectors, both this @@ -68,11 +68,11 @@ type Scale struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional Spec ScaleSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status defines current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional Status ScaleStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -159,7 +159,7 @@ type RollingUpdateStatefulSetStrategy struct { // Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. // This is helpful in being able to do a canary based deployment. The default value is 0. Partition *int32 `json:"partition,omitempty" protobuf:"varint,1,opt,name=partition"` - // The maximum number of pods that can be unavailable during the update. + // maxUnavailable is the maximum number of pods that can be unavailable during the update. // Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). // Absolute number is calculated from percentage by rounding up. This can not be 0. // Defaults to 1. This field is alpha-level and is only honored by servers that enable the @@ -191,12 +191,12 @@ const ( // StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs // created from the StatefulSet VolumeClaimTemplates. type StatefulSetPersistentVolumeClaimRetentionPolicy struct { - // WhenDeleted specifies what happens to PVCs created from StatefulSet + // whenDeleted specifies what happens to PVCs created from StatefulSet // VolumeClaimTemplates when the StatefulSet is deleted. The default policy // of `Retain` causes PVCs to not be affected by StatefulSet deletion. The // `Delete` policy causes those PVCs to be deleted. WhenDeleted PersistentVolumeClaimRetentionPolicyType `json:"whenDeleted,omitempty" protobuf:"bytes,1,opt,name=whenDeleted,casttype=PersistentVolumeClaimRetentionPolicyType"` - // WhenScaled specifies what happens to PVCs created from StatefulSet + // whenScaled specifies what happens to PVCs created from StatefulSet // VolumeClaimTemplates when the StatefulSet is scaled down. The default // policy of `Retain` causes PVCs to not be affected by a scaledown. The // `Delete` policy causes the associated PVCs for any excess pods above @@ -282,7 +282,7 @@ type StatefulSetSpec struct { // StatefulSetSpec version. The default value is 10. RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,8,opt,name=revisionHistoryLimit"` - // Minimum number of seconds for which a newly created pod should be ready + // minReadySeconds is the 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 @@ -298,7 +298,7 @@ type StatefulSetSpec struct { // default ordinals behavior assigns a "0" index to the first replica and // increments the index by one for each additional replica requested. Using // the ordinals field requires the StatefulSetStartOrdinal feature gate to be - // enabled, which is alpha. + // enabled, which is beta. // +optional Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" protobuf:"bytes,11,opt,name=ordinals"` } @@ -338,13 +338,13 @@ type StatefulSetStatus struct { // +optional CollisionCount *int32 `json:"collisionCount,omitempty" protobuf:"varint,9,opt,name=collisionCount"` - // Represents the latest available observations of a statefulset's current state. + // conditions represent the latest available observations of a statefulset's current state. // +optional // +patchMergeKey=type // +patchStrategy=merge Conditions []StatefulSetCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,10,rep,name=conditions"` - // Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. + // availableReplicas is the total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet. // +optional AvailableReplicas int32 `json:"availableReplicas" protobuf:"varint,11,opt,name=availableReplicas"` } @@ -409,17 +409,18 @@ type Deployment struct { // DeploymentSpec is the specification of the desired behavior of the Deployment. type DeploymentSpec struct { - // Number of desired pods. This is a pointer to distinguish between explicit + // replicas is the number of desired pods. This is a pointer to distinguish between explicit // zero and not specified. Defaults to 1. // +optional Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` - // Label selector for pods. Existing ReplicaSets whose pods are + // selector is the label selector for pods. Existing ReplicaSets whose pods are // selected by this will be the ones affected by this deployment. // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"` // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // The deployment strategy to use to replace existing pods with new ones. @@ -427,28 +428,28 @@ type DeploymentSpec struct { // +patchStrategy=retainKeys Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" protobuf:"bytes,4,opt,name=strategy"` - // Minimum number of seconds for which a newly created pod should be ready + // minReadySeconds is the 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 MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,5,opt,name=minReadySeconds"` - // The number of old ReplicaSets to retain to allow rollback. + // revisionHistoryLimit is the number of old ReplicaSets to retain to allow rollback. // This is a pointer to distinguish between explicit zero and not specified. // Defaults to 2. // +optional RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,6,opt,name=revisionHistoryLimit"` - // Indicates that the deployment is paused. + // paused indicates that the deployment is paused. // +optional Paused bool `json:"paused,omitempty" protobuf:"varint,7,opt,name=paused"` // DEPRECATED. - // The config this deployment is rolling back to. Will be cleared after rollback is done. + // rollbackTo is the config this deployment is rolling back to. Will be cleared after rollback is done. // +optional RollbackTo *RollbackConfig `json:"rollbackTo,omitempty" protobuf:"bytes,8,opt,name=rollbackTo"` - // The maximum time in seconds for a deployment to make progress before it + // progressDeadlineSeconds is the maximum time in seconds for a deployment to make progress before it // is considered to be failed. The deployment controller will continue to // process failed deployments and a condition with a ProgressDeadlineExceeded // reason will be surfaced in the deployment status. Note that progress will @@ -547,15 +548,15 @@ type RollingUpdateDeployment struct { // DeploymentStatus is the most recently observed status of the Deployment. type DeploymentStatus struct { - // The generation observed by the deployment controller. + // observedGeneration is the generation observed by the deployment controller. // +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). + // replicas is the total number of non-terminated 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. + // updatedReplicas is the total number of non-terminated pods targeted by this deployment that have the desired template spec. // +optional UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,3,opt,name=updatedReplicas"` @@ -567,18 +568,18 @@ type DeploymentStatus struct { // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,4,opt,name=availableReplicas"` - // Total number of unavailable pods targeted by this deployment. This is the total number of + // 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. // +optional UnavailableReplicas int32 `json:"unavailableReplicas,omitempty" protobuf:"varint,5,opt,name=unavailableReplicas"` - // Represents the latest available observations of a deployment's current state. + // Conditions represent the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge Conditions []DeploymentCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,6,rep,name=conditions"` - // Count of hash collisions for the Deployment. The Deployment controller uses this + // 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. // +optional @@ -660,10 +661,10 @@ type ControllerRevision struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Data is the serialized representation of the state. + // data is the serialized representation of the state. Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,2,opt,name=data"` - // Revision indicates the revision of the state represented by Data. + // revision indicates the revision of the state represented by Data. Revision int64 `json:"revision" protobuf:"varint,3,opt,name=revision"` } diff --git a/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go index 00d6d1825..a62e9869d 100644 --- a/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go @@ -24,14 +24,14 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ControllerRevision = map[string]string{ "": "DEPRECATED - This group version of ControllerRevision is deprecated by apps/v1beta2/ControllerRevision. See the release notes for more information. ControllerRevision implements an immutable snapshot of state data. Clients are responsible for serializing and deserializing the objects that contain their internal state. Once a ControllerRevision has been successfully created, it can not be updated. The API Server will fail validation of all requests that attempt to mutate the Data field. ControllerRevisions may, however, be deleted. Note that, due to its use by both the DaemonSet and StatefulSet controllers for update and rollback, this object is beta. However, it may be subject to name and representation changes in future releases, and clients should not depend on its stability. It is primarily for internal use by controllers.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "data": "Data is the serialized representation of the state.", - "revision": "Revision indicates the revision of the state represented by Data.", + "data": "data is the serialized representation of the state.", + "revision": "revision indicates the revision of the state represented by Data.", } func (ControllerRevision) SwaggerDoc() map[string]string { @@ -96,15 +96,15 @@ func (DeploymentRollback) SwaggerDoc() map[string]string { var map_DeploymentSpec = map[string]string{ "": "DeploymentSpec is the specification of the desired behavior of the Deployment.", - "replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", - "selector": "Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment.", - "template": "Template describes the pods that will be created.", + "replicas": "replicas is the number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", + "selector": "selector is the label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment.", + "template": "Template describes the pods that will be created. The only allowed template.spec.restartPolicy value is \"Always\".", "strategy": "The deployment strategy to use to replace existing pods with new ones.", - "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)", - "revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 2.", - "paused": "Indicates that the deployment is paused.", - "rollbackTo": "DEPRECATED. The config this deployment is rolling back to. Will be cleared after rollback is done.", - "progressDeadlineSeconds": "The maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. Defaults to 600s.", + "minReadySeconds": "minReadySeconds is the 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)", + "revisionHistoryLimit": "revisionHistoryLimit is the number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 2.", + "paused": "paused indicates that the deployment is paused.", + "rollbackTo": "DEPRECATED. rollbackTo is the config this deployment is rolling back to. Will be cleared after rollback is done.", + "progressDeadlineSeconds": "progressDeadlineSeconds is the maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. Defaults to 600s.", } func (DeploymentSpec) SwaggerDoc() map[string]string { @@ -113,14 +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": "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.", + "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": "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": "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.", + "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.", + "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.", } func (DeploymentStatus) SwaggerDoc() map[string]string { @@ -159,7 +159,7 @@ func (RollingUpdateDeployment) SwaggerDoc() map[string]string { var map_RollingUpdateStatefulSetStrategy = map[string]string{ "": "RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.", "partition": "Partition indicates the ordinal at which the StatefulSet should be partitioned for updates. During a rolling update, all pods from ordinal Replicas-1 to Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. This is helpful in being able to do a canary based deployment. The default value is 0.", - "maxUnavailable": "The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0. Defaults to 1. This field is alpha-level and is only honored by servers that enable the MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it will be counted towards MaxUnavailable.", + "maxUnavailable": "maxUnavailable is the maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0. Defaults to 1. This field is alpha-level and is only honored by servers that enable the MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it will be counted towards MaxUnavailable.", } func (RollingUpdateStatefulSetStrategy) SwaggerDoc() map[string]string { @@ -169,8 +169,8 @@ func (RollingUpdateStatefulSetStrategy) SwaggerDoc() map[string]string { var map_Scale = map[string]string{ "": "Scale represents a scaling request for a resource.", "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", - "status": "current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.", + "spec": "spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", + "status": "status defines current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.", } func (Scale) SwaggerDoc() map[string]string { @@ -179,7 +179,7 @@ func (Scale) SwaggerDoc() map[string]string { var map_ScaleSpec = map[string]string{ "": "ScaleSpec describes the attributes of a scale subresource", - "replicas": "desired number of instances for the scaled object.", + "replicas": "replicas is the number of observed instances of the scaled object.", } func (ScaleSpec) SwaggerDoc() map[string]string { @@ -188,9 +188,9 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "ScaleStatus represents the current status of a scale subresource.", - "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors", - "targetSelector": "label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", + "replicas": "replias is the actual number of observed instances of the scaled object.", + "selector": "selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", + "targetSelector": "targetSelector is the label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", } func (ScaleStatus) SwaggerDoc() map[string]string { @@ -239,8 +239,8 @@ func (StatefulSetOrdinals) SwaggerDoc() map[string]string { var map_StatefulSetPersistentVolumeClaimRetentionPolicy = map[string]string{ "": "StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates.", - "whenDeleted": "WhenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted. The default policy of `Retain` causes PVCs to not be affected by StatefulSet deletion. The `Delete` policy causes those PVCs to be deleted.", - "whenScaled": "WhenScaled specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is scaled down. The default policy of `Retain` causes PVCs to not be affected by a scaledown. The `Delete` policy causes the associated PVCs for any excess pods above the replica count to be deleted.", + "whenDeleted": "whenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted. The default policy of `Retain` causes PVCs to not be affected by StatefulSet deletion. The `Delete` policy causes those PVCs to be deleted.", + "whenScaled": "whenScaled specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is scaled down. The default policy of `Retain` causes PVCs to not be affected by a scaledown. The `Delete` policy causes the associated PVCs for any excess pods above the replica count to be deleted.", } func (StatefulSetPersistentVolumeClaimRetentionPolicy) SwaggerDoc() map[string]string { @@ -257,9 +257,9 @@ var map_StatefulSetSpec = map[string]string{ "podManagementPolicy": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.", "updateStrategy": "updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template.", "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", - "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)", + "minReadySeconds": "minReadySeconds is the 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)", "persistentVolumeClaimRetentionPolicy": "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha.", - "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is alpha.", + "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is beta.", } func (StatefulSetSpec) SwaggerDoc() map[string]string { @@ -276,8 +276,8 @@ var map_StatefulSetStatus = map[string]string{ "currentRevision": "currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [0,currentReplicas).", "updateRevision": "updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)", "collisionCount": "collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ControllerRevision.", - "conditions": "Represents the latest available observations of a statefulset's current state.", - "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet.", + "conditions": "conditions represent the latest available observations of a statefulset's current state.", + "availableReplicas": "availableReplicas is the total number of available pods (ready for at least minReadySeconds) targeted by this StatefulSet.", } func (StatefulSetStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/apps/v1beta2/generated.proto b/vendor/k8s.io/api/apps/v1beta2/generated.proto index af8c4fe41..ddbe35441 100644 --- a/vendor/k8s.io/api/apps/v1beta2/generated.proto +++ b/vendor/k8s.io/api/apps/v1beta2/generated.proto @@ -131,6 +131,7 @@ message DaemonSetSpec { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template optional k8s.io.api.core.v1.PodTemplateSpec template = 2; @@ -282,6 +283,7 @@ message DeploymentSpec { optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector selector = 2; // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // The deployment strategy to use to replace existing pods with new ones. @@ -600,7 +602,7 @@ message ScaleStatus { // actual number of observed instances of the scaled object. optional int32 replicas = 1; - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional // +mapType=atomic map selector = 2; @@ -720,6 +722,7 @@ message StatefulSetSpec { // of the StatefulSet. Each pod will be named with the format // -. For example, a pod in a StatefulSet named // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". optional k8s.io.api.core.v1.PodTemplateSpec template = 3; // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -777,7 +780,7 @@ message StatefulSetSpec { // default ordinals behavior assigns a "0" index to the first replica and // increments the index by one for each additional replica requested. Using // the ordinals field requires the StatefulSetStartOrdinal feature gate to be - // enabled, which is alpha. + // enabled, which is beta. // +optional optional StatefulSetOrdinals ordinals = 11; } diff --git a/vendor/k8s.io/api/apps/v1beta2/types.go b/vendor/k8s.io/api/apps/v1beta2/types.go index dbe4d23bf..a97ac6fcf 100644 --- a/vendor/k8s.io/api/apps/v1beta2/types.go +++ b/vendor/k8s.io/api/apps/v1beta2/types.go @@ -43,7 +43,7 @@ type ScaleStatus struct { // actual number of observed instances of the scaled object. Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional // +mapType=atomic Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"` @@ -250,6 +250,7 @@ type StatefulSetSpec struct { // of the StatefulSet. Each pod will be named with the format // -. For example, a pod in a StatefulSet named // "web" with index number "3" would be named "web-3". + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // volumeClaimTemplates is a list of claims that pods are allowed to reference. @@ -307,7 +308,7 @@ type StatefulSetSpec struct { // default ordinals behavior assigns a "0" index to the first replica and // increments the index by one for each additional replica requested. Using // the ordinals field requires the StatefulSetStartOrdinal feature gate to be - // enabled, which is alpha. + // enabled, which is beta. // +optional Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" protobuf:"bytes,11,opt,name=ordinals"` } @@ -429,6 +430,7 @@ type DeploymentSpec struct { Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,2,opt,name=selector"` // Template describes the pods that will be created. + // The only allowed template.spec.restartPolicy value is "Always". Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"` // The deployment strategy to use to replace existing pods with new ones. @@ -690,6 +692,7 @@ type DaemonSetSpec struct { // The DaemonSet will create exactly one copy of this pod on every node // that matches the template's node selector (or on every node if no node // selector is specified). + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,2,opt,name=template"` diff --git a/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go b/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go index 1936a2467..d7e920991 100644 --- a/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta2 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ControllerRevision = map[string]string{ @@ -85,7 +85,7 @@ func (DaemonSetList) SwaggerDoc() map[string]string { var map_DaemonSetSpec = map[string]string{ "": "DaemonSetSpec is the specification of a daemon set.", "selector": "A label query over pods that are managed by the daemon set. Must match in order to be controlled. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", + "template": "An object that describes the pod that will be created. The DaemonSet will create exactly one copy of this pod on every node that matches the template's node selector (or on every node if no node selector is specified). The only allowed template.spec.restartPolicy value is \"Always\". More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", "updateStrategy": "An update strategy to replace existing DaemonSet pods with new pods.", "minReadySeconds": "The minimum number of seconds for which a newly created DaemonSet 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).", "revisionHistoryLimit": "The number of old history to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", @@ -162,7 +162,7 @@ var map_DeploymentSpec = map[string]string{ "": "DeploymentSpec is the specification of the desired behavior of the Deployment.", "replicas": "Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1.", "selector": "Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment. It must match the pod template's labels.", - "template": "Template describes the pods that will be created.", + "template": "Template describes the pods that will be created. The only allowed template.spec.restartPolicy value is \"Always\".", "strategy": "The deployment strategy to use to replace existing pods with new ones.", "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)", "revisionHistoryLimit": "The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10.", @@ -313,7 +313,7 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "ScaleStatus represents the current status of a scale subresource.", "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors", + "selector": "selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", "targetSelector": "label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", } @@ -375,7 +375,7 @@ var map_StatefulSetSpec = map[string]string{ "": "A StatefulSetSpec is the specification of a StatefulSet.", "replicas": "replicas is the desired number of replicas of the given Template. These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1.", "selector": "selector is a label query over pods that should match the replica count. 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. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format -. For example, a pod in a StatefulSet named \"web\" with index number \"3\" would be named \"web-3\".", + "template": "template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format -. For example, a pod in a StatefulSet named \"web\" with index number \"3\" would be named \"web-3\". The only allowed template.spec.restartPolicy value is \"Always\".", "volumeClaimTemplates": "volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name.", "serviceName": "serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for 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.", "podManagementPolicy": "podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once.", @@ -383,7 +383,7 @@ var map_StatefulSetSpec = map[string]string{ "revisionHistoryLimit": "revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10.", "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)", "persistentVolumeClaimRetentionPolicy": "PersistentVolumeClaimRetentionPolicy describes the policy used for PVCs created from the StatefulSet VolumeClaimTemplates. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha.", - "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is alpha.", + "ordinals": "ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a \"0\" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is beta.", } func (StatefulSetSpec) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go index 5d37ac1f8..b1a730b81 100644 --- a/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authentication/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_BoundObjectReference = map[string]string{ diff --git a/vendor/k8s.io/api/authentication/v1alpha1/generated.proto b/vendor/k8s.io/api/authentication/v1alpha1/generated.proto index 3198dce3b..51d925244 100644 --- a/vendor/k8s.io/api/authentication/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/authentication/v1alpha1/generated.proto @@ -30,7 +30,8 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; option go_package = "k8s.io/api/authentication/v1alpha1"; // SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. -// When using impersonation, users will receive the user info of the user being impersonated. +// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or +// request header authentication is used, any extra keys will have their case ignored and returned as lowercase. message SelfSubjectReview { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata diff --git a/vendor/k8s.io/api/authentication/v1alpha1/types.go b/vendor/k8s.io/api/authentication/v1alpha1/types.go index da65028cd..1ee3612fb 100644 --- a/vendor/k8s.io/api/authentication/v1alpha1/types.go +++ b/vendor/k8s.io/api/authentication/v1alpha1/types.go @@ -25,10 +25,11 @@ import ( // +genclient:nonNamespaced // +genclient:onlyVerbs=create // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.25 +// +k8s:prerelease-lifecycle-gen:introduced=1.26 // SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. -// When using impersonation, users will receive the user info of the user being impersonated. +// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or +// request header authentication is used, any extra keys will have their case ignored and returned as lowercase. type SelfSubjectReview struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. diff --git a/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go index bc17c5f30..1ffcc99e7 100644 --- a/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authentication/v1alpha1/types_swagger_doc_generated.go @@ -24,11 +24,11 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_SelfSubjectReview = map[string]string{ - "": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated.", + "": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "status": "Status is filled in by the server with the user attributes.", } diff --git a/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.prerelease-lifecycle.go index b86dfbef6..62a70a781 100644 --- a/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/authentication/v1alpha1/zz_generated.prerelease-lifecycle.go @@ -24,17 +24,17 @@ package v1alpha1 // 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 *SelfSubjectReview) APILifecycleIntroduced() (major, minor int) { - return 1, 25 + return 1, 26 } // 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 *SelfSubjectReview) APILifecycleDeprecated() (major, minor int) { - return 1, 28 + return 1, 29 } // 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 *SelfSubjectReview) APILifecycleRemoved() (major, minor int) { - return 1, 31 + return 1, 32 } diff --git a/vendor/k8s.io/api/authentication/v1beta1/generated.pb.go b/vendor/k8s.io/api/authentication/v1beta1/generated.pb.go index 1978dcf6a..7f1d5ca6c 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/authentication/v1beta1/generated.pb.go @@ -72,10 +72,66 @@ func (m *ExtraValue) XXX_DiscardUnknown() { var xxx_messageInfo_ExtraValue proto.InternalMessageInfo +func (m *SelfSubjectReview) Reset() { *m = SelfSubjectReview{} } +func (*SelfSubjectReview) ProtoMessage() {} +func (*SelfSubjectReview) Descriptor() ([]byte, []int) { + return fileDescriptor_77c9b20d3ad27844, []int{1} +} +func (m *SelfSubjectReview) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SelfSubjectReview) 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 *SelfSubjectReview) XXX_Merge(src proto.Message) { + xxx_messageInfo_SelfSubjectReview.Merge(m, src) +} +func (m *SelfSubjectReview) XXX_Size() int { + return m.Size() +} +func (m *SelfSubjectReview) XXX_DiscardUnknown() { + xxx_messageInfo_SelfSubjectReview.DiscardUnknown(m) +} + +var xxx_messageInfo_SelfSubjectReview proto.InternalMessageInfo + +func (m *SelfSubjectReviewStatus) Reset() { *m = SelfSubjectReviewStatus{} } +func (*SelfSubjectReviewStatus) ProtoMessage() {} +func (*SelfSubjectReviewStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_77c9b20d3ad27844, []int{2} +} +func (m *SelfSubjectReviewStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SelfSubjectReviewStatus) 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 *SelfSubjectReviewStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_SelfSubjectReviewStatus.Merge(m, src) +} +func (m *SelfSubjectReviewStatus) XXX_Size() int { + return m.Size() +} +func (m *SelfSubjectReviewStatus) XXX_DiscardUnknown() { + xxx_messageInfo_SelfSubjectReviewStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_SelfSubjectReviewStatus proto.InternalMessageInfo + func (m *TokenReview) Reset() { *m = TokenReview{} } func (*TokenReview) ProtoMessage() {} func (*TokenReview) Descriptor() ([]byte, []int) { - return fileDescriptor_77c9b20d3ad27844, []int{1} + return fileDescriptor_77c9b20d3ad27844, []int{3} } func (m *TokenReview) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -103,7 +159,7 @@ var xxx_messageInfo_TokenReview proto.InternalMessageInfo func (m *TokenReviewSpec) Reset() { *m = TokenReviewSpec{} } func (*TokenReviewSpec) ProtoMessage() {} func (*TokenReviewSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_77c9b20d3ad27844, []int{2} + return fileDescriptor_77c9b20d3ad27844, []int{4} } func (m *TokenReviewSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -131,7 +187,7 @@ var xxx_messageInfo_TokenReviewSpec proto.InternalMessageInfo func (m *TokenReviewStatus) Reset() { *m = TokenReviewStatus{} } func (*TokenReviewStatus) ProtoMessage() {} func (*TokenReviewStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_77c9b20d3ad27844, []int{3} + return fileDescriptor_77c9b20d3ad27844, []int{5} } func (m *TokenReviewStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -159,7 +215,7 @@ var xxx_messageInfo_TokenReviewStatus proto.InternalMessageInfo func (m *UserInfo) Reset() { *m = UserInfo{} } func (*UserInfo) ProtoMessage() {} func (*UserInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_77c9b20d3ad27844, []int{4} + return fileDescriptor_77c9b20d3ad27844, []int{6} } func (m *UserInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -186,6 +242,8 @@ var xxx_messageInfo_UserInfo proto.InternalMessageInfo func init() { proto.RegisterType((*ExtraValue)(nil), "k8s.io.api.authentication.v1beta1.ExtraValue") + proto.RegisterType((*SelfSubjectReview)(nil), "k8s.io.api.authentication.v1beta1.SelfSubjectReview") + proto.RegisterType((*SelfSubjectReviewStatus)(nil), "k8s.io.api.authentication.v1beta1.SelfSubjectReviewStatus") proto.RegisterType((*TokenReview)(nil), "k8s.io.api.authentication.v1beta1.TokenReview") proto.RegisterType((*TokenReviewSpec)(nil), "k8s.io.api.authentication.v1beta1.TokenReviewSpec") proto.RegisterType((*TokenReviewStatus)(nil), "k8s.io.api.authentication.v1beta1.TokenReviewStatus") @@ -198,49 +256,53 @@ func init() { } var fileDescriptor_77c9b20d3ad27844 = []byte{ - // 666 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcf, 0x4e, 0x13, 0x5f, - 0x14, 0x9e, 0xe9, 0x1f, 0xd2, 0xde, 0xfe, 0xfa, 0x13, 0x6f, 0x62, 0xd2, 0x34, 0x71, 0x0a, 0x75, - 0x43, 0x82, 0xdc, 0x11, 0x42, 0x90, 0xe0, 0x8a, 0x51, 0x42, 0x30, 0x21, 0x26, 0x57, 0x70, 0xa1, - 0x2e, 0xbc, 0x9d, 0x1e, 0xa6, 0x63, 0x9d, 0x3f, 0xb9, 0x73, 0xa7, 0xca, 0x8e, 0x47, 0x70, 0xe9, - 0xd2, 0xc4, 0x27, 0x71, 0xc7, 0x92, 0x25, 0x0b, 0xd3, 0xc8, 0xf8, 0x04, 0xbe, 0x81, 0xb9, 0x77, - 0x2e, 0x4c, 0x81, 0x68, 0x61, 0x37, 0xf7, 0x3b, 0xe7, 0xfb, 0xce, 0x39, 0xdf, 0xe9, 0x29, 0x7a, - 0x3e, 0x5c, 0x4f, 0x88, 0x1f, 0xd9, 0xc3, 0xb4, 0x07, 0x3c, 0x04, 0x01, 0x89, 0x3d, 0x82, 0xb0, - 0x1f, 0x71, 0x5b, 0x07, 0x58, 0xec, 0xdb, 0x2c, 0x15, 0x03, 0x08, 0x85, 0xef, 0x32, 0xe1, 0x47, - 0xa1, 0x3d, 0x5a, 0xee, 0x81, 0x60, 0xcb, 0xb6, 0x07, 0x21, 0x70, 0x26, 0xa0, 0x4f, 0x62, 0x1e, - 0x89, 0x08, 0xcf, 0xe7, 0x14, 0xc2, 0x62, 0x9f, 0x5c, 0xa6, 0x10, 0x4d, 0x69, 0x2f, 0x79, 0xbe, - 0x18, 0xa4, 0x3d, 0xe2, 0x46, 0x81, 0xed, 0x45, 0x5e, 0x64, 0x2b, 0x66, 0x2f, 0x3d, 0x50, 0x2f, - 0xf5, 0x50, 0x5f, 0xb9, 0x62, 0x7b, 0xb5, 0x68, 0x22, 0x60, 0xee, 0xc0, 0x0f, 0x81, 0x1f, 0xda, - 0xf1, 0xd0, 0x93, 0x40, 0x62, 0x07, 0x20, 0x98, 0x3d, 0xba, 0xd6, 0x47, 0xdb, 0xfe, 0x1b, 0x8b, - 0xa7, 0xa1, 0xf0, 0x03, 0xb8, 0x46, 0x58, 0x9b, 0x46, 0x48, 0xdc, 0x01, 0x04, 0xec, 0x2a, 0xaf, - 0xfb, 0x18, 0xa1, 0xad, 0x4f, 0x82, 0xb3, 0x57, 0xec, 0x43, 0x0a, 0xb8, 0x83, 0xaa, 0xbe, 0x80, - 0x20, 0x69, 0x99, 0x73, 0xe5, 0x85, 0xba, 0x53, 0xcf, 0xc6, 0x9d, 0xea, 0x8e, 0x04, 0x68, 0x8e, - 0x6f, 0xd4, 0xbe, 0x7c, 0xed, 0x18, 0x47, 0x3f, 0xe6, 0x8c, 0xee, 0xb7, 0x12, 0x6a, 0xec, 0x45, - 0x43, 0x08, 0x29, 0x8c, 0x7c, 0xf8, 0x88, 0xdf, 0xa1, 0x9a, 0x1c, 0xa6, 0xcf, 0x04, 0x6b, 0x99, - 0x73, 0xe6, 0x42, 0x63, 0xe5, 0x11, 0x29, 0xcc, 0xbc, 0xe8, 0x89, 0xc4, 0x43, 0x4f, 0x02, 0x09, - 0x91, 0xd9, 0x64, 0xb4, 0x4c, 0x5e, 0xf4, 0xde, 0x83, 0x2b, 0x76, 0x41, 0x30, 0x07, 0x1f, 0x8f, - 0x3b, 0x46, 0x36, 0xee, 0xa0, 0x02, 0xa3, 0x17, 0xaa, 0x78, 0x0f, 0x55, 0x92, 0x18, 0xdc, 0x56, - 0x49, 0xa9, 0xaf, 0x90, 0xa9, 0xab, 0x22, 0x13, 0xfd, 0xbd, 0x8c, 0xc1, 0x75, 0xfe, 0xd3, 0xfa, - 0x15, 0xf9, 0xa2, 0x4a, 0x0d, 0xbf, 0x45, 0x33, 0x89, 0x60, 0x22, 0x4d, 0x5a, 0x65, 0xa5, 0xbb, - 0x7a, 0x4b, 0x5d, 0xc5, 0x75, 0xfe, 0xd7, 0xca, 0x33, 0xf9, 0x9b, 0x6a, 0xcd, 0xae, 0x8b, 0xee, - 0x5c, 0x69, 0x02, 0x3f, 0x40, 0x55, 0x21, 0x21, 0xe5, 0x52, 0xdd, 0x69, 0x6a, 0x66, 0x35, 0xcf, - 0xcb, 0x63, 0x78, 0x11, 0xd5, 0x59, 0xda, 0xf7, 0x21, 0x74, 0x21, 0x69, 0x95, 0xd4, 0x32, 0x9a, - 0xd9, 0xb8, 0x53, 0xdf, 0x3c, 0x07, 0x69, 0x11, 0xef, 0xfe, 0x36, 0xd1, 0xdd, 0x6b, 0x2d, 0xe1, - 0x27, 0xa8, 0x39, 0xd1, 0x3e, 0xf4, 0x55, 0xbd, 0x9a, 0x73, 0x4f, 0xd7, 0x6b, 0x6e, 0x4e, 0x06, - 0xe9, 0xe5, 0x5c, 0xbc, 0x8b, 0x2a, 0x69, 0x02, 0x5c, 0x7b, 0xbd, 0x78, 0x03, 0x4f, 0xf6, 0x13, - 0xe0, 0x3b, 0xe1, 0x41, 0x54, 0x98, 0x2c, 0x11, 0xaa, 0x64, 0x2e, 0x8f, 0x53, 0xf9, 0xf7, 0x38, - 0xd2, 0x20, 0xe0, 0x3c, 0xe2, 0x6a, 0x21, 0x13, 0x06, 0x6d, 0x49, 0x90, 0xe6, 0xb1, 0xee, 0xf7, - 0x12, 0xaa, 0x9d, 0x97, 0xc4, 0x0f, 0x51, 0x4d, 0x96, 0x09, 0x59, 0x00, 0xda, 0xd5, 0x59, 0x4d, - 0x52, 0x39, 0x12, 0xa7, 0x17, 0x19, 0xf8, 0x3e, 0x2a, 0xa7, 0x7e, 0x5f, 0x8d, 0x56, 0x77, 0x1a, - 0x3a, 0xb1, 0xbc, 0xbf, 0xf3, 0x8c, 0x4a, 0x1c, 0x77, 0xd1, 0x8c, 0xc7, 0xa3, 0x34, 0x96, 0x3f, - 0x08, 0xd9, 0x28, 0x92, 0x6b, 0xdd, 0x56, 0x08, 0xd5, 0x11, 0xfc, 0x06, 0x55, 0x41, 0x5e, 0x8d, - 0x9a, 0xa5, 0xb1, 0xb2, 0x76, 0x0b, 0x7f, 0x88, 0x3a, 0xb7, 0xad, 0x50, 0xf0, 0xc3, 0x89, 0xd1, - 0x24, 0x46, 0x73, 0xcd, 0xb6, 0xa7, 0x4f, 0x52, 0xe5, 0xe0, 0x59, 0x54, 0x1e, 0xc2, 0x61, 0x3e, - 0x16, 0x95, 0x9f, 0xf8, 0x29, 0xaa, 0x8e, 0xe4, 0xb5, 0xea, 0xe5, 0x2c, 0xdd, 0xa0, 0x78, 0x71, - 0xe2, 0x34, 0xe7, 0x6e, 0x94, 0xd6, 0x4d, 0x67, 0xfb, 0xf8, 0xcc, 0x32, 0x4e, 0xce, 0x2c, 0xe3, - 0xf4, 0xcc, 0x32, 0x8e, 0x32, 0xcb, 0x3c, 0xce, 0x2c, 0xf3, 0x24, 0xb3, 0xcc, 0xd3, 0xcc, 0x32, - 0x7f, 0x66, 0x96, 0xf9, 0xf9, 0x97, 0x65, 0xbc, 0x9e, 0x9f, 0xfa, 0x2f, 0xfa, 0x27, 0x00, 0x00, - 0xff, 0xff, 0xb8, 0x72, 0x2c, 0x2c, 0x82, 0x05, 0x00, 0x00, + // 725 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4f, 0x4f, 0x13, 0x41, + 0x14, 0xef, 0xf6, 0x0f, 0x69, 0xa7, 0x56, 0x61, 0x12, 0x23, 0x69, 0xe2, 0x16, 0x6a, 0x62, 0x48, + 0x80, 0x59, 0x21, 0x04, 0x09, 0x9e, 0x58, 0x25, 0x04, 0x13, 0x62, 0x32, 0x05, 0x0f, 0xea, 0xc1, + 0xe9, 0xf6, 0xb1, 0x5d, 0x4b, 0x77, 0x37, 0xbb, 0xb3, 0x55, 0x6e, 0x7c, 0x04, 0x8f, 0x1e, 0x4d, + 0xfc, 0x24, 0xde, 0x38, 0x72, 0xc4, 0xc4, 0x34, 0xb2, 0x7e, 0x02, 0xbf, 0x81, 0x99, 0xd9, 0x61, + 0xdb, 0x82, 0x14, 0xb8, 0x78, 0xdb, 0xf9, 0xcd, 0xfb, 0xfd, 0xde, 0x7b, 0xbf, 0xf7, 0x32, 0x8b, + 0x5e, 0x76, 0xd6, 0x42, 0xe2, 0x78, 0x46, 0x27, 0x6a, 0x42, 0xe0, 0x02, 0x87, 0xd0, 0xe8, 0x81, + 0xdb, 0xf2, 0x02, 0x43, 0x5d, 0x30, 0xdf, 0x31, 0x58, 0xc4, 0xdb, 0xe0, 0x72, 0xc7, 0x62, 0xdc, + 0xf1, 0x5c, 0xa3, 0xb7, 0xd4, 0x04, 0xce, 0x96, 0x0c, 0x1b, 0x5c, 0x08, 0x18, 0x87, 0x16, 0xf1, + 0x03, 0x8f, 0x7b, 0x78, 0x36, 0xa1, 0x10, 0xe6, 0x3b, 0x64, 0x94, 0x42, 0x14, 0xa5, 0xba, 0x68, + 0x3b, 0xbc, 0x1d, 0x35, 0x89, 0xe5, 0x75, 0x0d, 0xdb, 0xb3, 0x3d, 0x43, 0x32, 0x9b, 0xd1, 0xbe, + 0x3c, 0xc9, 0x83, 0xfc, 0x4a, 0x14, 0xab, 0x0b, 0xe3, 0x8a, 0xb8, 0x98, 0xbf, 0xba, 0x32, 0x88, + 0xee, 0x32, 0xab, 0xed, 0xb8, 0x10, 0x1c, 0x1a, 0x7e, 0xc7, 0x16, 0x40, 0x68, 0x74, 0x81, 0xb3, + 0x7f, 0xb1, 0x8c, 0xab, 0x58, 0x41, 0xe4, 0x72, 0xa7, 0x0b, 0x97, 0x08, 0xab, 0xd7, 0x11, 0x42, + 0xab, 0x0d, 0x5d, 0x76, 0x91, 0x57, 0x7f, 0x8a, 0xd0, 0xe6, 0x27, 0x1e, 0xb0, 0xd7, 0xec, 0x20, + 0x02, 0x5c, 0x43, 0x05, 0x87, 0x43, 0x37, 0x9c, 0xd6, 0x66, 0x72, 0x73, 0x25, 0xb3, 0x14, 0xf7, + 0x6b, 0x85, 0x6d, 0x01, 0xd0, 0x04, 0x5f, 0x2f, 0x7e, 0xf9, 0x5a, 0xcb, 0x1c, 0xfd, 0x9c, 0xc9, + 0xd4, 0x7f, 0x68, 0x68, 0xaa, 0x01, 0x07, 0xfb, 0x8d, 0xa8, 0xf9, 0x01, 0x2c, 0x4e, 0xa1, 0xe7, + 0xc0, 0x47, 0xfc, 0x1e, 0x15, 0x45, 0x4b, 0x2d, 0xc6, 0xd9, 0xb4, 0x36, 0xa3, 0xcd, 0x95, 0x97, + 0x9f, 0x90, 0xc1, 0x00, 0xd2, 0xca, 0x88, 0xdf, 0xb1, 0x05, 0x10, 0x12, 0x11, 0x4d, 0x7a, 0x4b, + 0xe4, 0x95, 0x54, 0xd9, 0x01, 0xce, 0x4c, 0x7c, 0xdc, 0xaf, 0x65, 0xe2, 0x7e, 0x0d, 0x0d, 0x30, + 0x9a, 0xaa, 0xe2, 0x26, 0x9a, 0x08, 0x39, 0xe3, 0x51, 0x38, 0x9d, 0x95, 0xfa, 0xeb, 0xe4, 0xda, + 0x01, 0x93, 0x4b, 0x75, 0x36, 0xa4, 0x82, 0x79, 0x57, 0x65, 0x9a, 0x48, 0xce, 0x54, 0x29, 0xd7, + 0x3d, 0xf4, 0xe0, 0x0a, 0x0a, 0xde, 0x45, 0xc5, 0x28, 0x84, 0x60, 0xdb, 0xdd, 0xf7, 0x54, 0x83, + 0x8f, 0xc7, 0x16, 0x40, 0xf6, 0x54, 0xb4, 0x39, 0xa9, 0x92, 0x15, 0xcf, 0x11, 0x9a, 0x2a, 0xd5, + 0xbf, 0x65, 0x51, 0x79, 0xd7, 0xeb, 0x80, 0xfb, 0xdf, 0x6c, 0xdc, 0x45, 0xf9, 0xd0, 0x07, 0x4b, + 0x99, 0xb8, 0x7c, 0x03, 0x13, 0x87, 0xea, 0x6b, 0xf8, 0x60, 0x99, 0x77, 0x94, 0x7e, 0x5e, 0x9c, + 0xa8, 0x54, 0xc3, 0xef, 0xd2, 0xe1, 0xe4, 0xa4, 0xee, 0xca, 0x2d, 0x75, 0xc7, 0x8f, 0xc5, 0x42, + 0xf7, 0x2e, 0x14, 0x81, 0x1f, 0xa1, 0x02, 0x17, 0x90, 0x74, 0xa9, 0x64, 0x56, 0x14, 0xb3, 0x90, + 0xc4, 0x25, 0x77, 0x78, 0x1e, 0x95, 0x58, 0xd4, 0x72, 0xc0, 0xb5, 0x40, 0x6c, 0x8d, 0xd8, 0xec, + 0x4a, 0xdc, 0xaf, 0x95, 0x36, 0xce, 0x41, 0x3a, 0xb8, 0xaf, 0xff, 0xd1, 0xd0, 0xd4, 0xa5, 0x92, + 0xf0, 0x33, 0x54, 0x19, 0x2a, 0x1f, 0x5a, 0x32, 0x5f, 0xd1, 0xbc, 0xaf, 0xf2, 0x55, 0x36, 0x86, + 0x2f, 0xe9, 0x68, 0x2c, 0xde, 0x41, 0x79, 0x31, 0x69, 0xe5, 0xf5, 0xfc, 0x0d, 0x3c, 0x49, 0x97, + 0x26, 0x35, 0x59, 0x20, 0x54, 0xca, 0x8c, 0xb6, 0x93, 0x1f, 0xdf, 0x8e, 0x30, 0x08, 0x82, 0xc0, + 0x0b, 0xe4, 0x40, 0x86, 0x0c, 0xda, 0x14, 0x20, 0x4d, 0xee, 0xea, 0xdf, 0xb3, 0x28, 0xdd, 0x4a, + 0xbc, 0x90, 0x6c, 0xb8, 0xcb, 0xba, 0xa0, 0x5c, 0x1d, 0xd9, 0x5c, 0x81, 0xd3, 0x34, 0x02, 0x3f, + 0x44, 0xb9, 0xc8, 0x69, 0xc9, 0xd6, 0x4a, 0x66, 0x59, 0x05, 0xe6, 0xf6, 0xb6, 0x5f, 0x50, 0x81, + 0xe3, 0x3a, 0x9a, 0xb0, 0x03, 0x2f, 0xf2, 0xc5, 0x42, 0x88, 0x42, 0x91, 0x18, 0xeb, 0x96, 0x44, + 0xa8, 0xba, 0xc1, 0x6f, 0x51, 0x01, 0xc4, 0x13, 0x24, 0x7b, 0x29, 0x2f, 0xaf, 0xde, 0xc2, 0x1f, + 0x22, 0xdf, 0xae, 0x4d, 0x97, 0x07, 0x87, 0x43, 0xad, 0x09, 0x8c, 0x26, 0x9a, 0x55, 0x5b, 0xbd, + 0x6f, 0x32, 0x06, 0x4f, 0xa2, 0x5c, 0x07, 0x0e, 0x93, 0xb6, 0xa8, 0xf8, 0xc4, 0xcf, 0x51, 0xa1, + 0x27, 0x9e, 0x3e, 0x35, 0x9c, 0xc5, 0x1b, 0x24, 0x1f, 0xbc, 0x97, 0x34, 0xe1, 0xae, 0x67, 0xd7, + 0x34, 0x73, 0xeb, 0xf8, 0x4c, 0xcf, 0x9c, 0x9c, 0xe9, 0x99, 0xd3, 0x33, 0x3d, 0x73, 0x14, 0xeb, + 0xda, 0x71, 0xac, 0x6b, 0x27, 0xb1, 0xae, 0x9d, 0xc6, 0xba, 0xf6, 0x2b, 0xd6, 0xb5, 0xcf, 0xbf, + 0xf5, 0xcc, 0x9b, 0xd9, 0x6b, 0x7f, 0x60, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x19, 0x49, + 0x3f, 0xfd, 0x06, 0x00, 0x00, } func (m ExtraValue) Marshal() (dAtA []byte, err error) { @@ -275,6 +337,82 @@ func (m ExtraValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SelfSubjectReview) 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 *SelfSubjectReview) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SelfSubjectReview) 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] = 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 *SelfSubjectReviewStatus) 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 *SelfSubjectReviewStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SelfSubjectReviewStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.UserInfo.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 *TokenReview) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -517,6 +655,30 @@ func (m ExtraValue) Size() (n int) { return n } +func (m *SelfSubjectReview) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *SelfSubjectReviewStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.UserInfo.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *TokenReview) Size() (n int) { if m == nil { return 0 @@ -603,6 +765,27 @@ func sovGenerated(x uint64) (n int) { func sozGenerated(x uint64) (n int) { return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (this *SelfSubjectReview) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SelfSubjectReview{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "SelfSubjectReviewStatus", "SelfSubjectReviewStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *SelfSubjectReviewStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SelfSubjectReviewStatus{`, + `UserInfo:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.UserInfo), "UserInfo", "v11.UserInfo", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} func (this *TokenReview) String() string { if this == nil { return "nil" @@ -752,6 +935,205 @@ func (m *ExtraValue) Unmarshal(dAtA []byte) error { } return nil } +func (m *SelfSubjectReview) 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: SelfSubjectReview: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SelfSubjectReview: 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 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 + 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 *SelfSubjectReviewStatus) 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: SelfSubjectReviewStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SelfSubjectReviewStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserInfo", 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.UserInfo.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 *TokenReview) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/authentication/v1beta1/generated.proto b/vendor/k8s.io/api/authentication/v1beta1/generated.proto index d1847a02e..53b4635d7 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/generated.proto +++ b/vendor/k8s.io/api/authentication/v1beta1/generated.proto @@ -21,6 +21,7 @@ syntax = "proto2"; package k8s.io.api.authentication.v1beta1; +import "k8s.io/api/authentication/v1/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; @@ -37,6 +38,26 @@ message ExtraValue { repeated string items = 1; } +// SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. +// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or +// request header authentication is used, any extra keys will have their case ignored and returned as lowercase. +message SelfSubjectReview { + // 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; + + // Status is filled in by the server with the user attributes. + optional SelfSubjectReviewStatus status = 2; +} + +// SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. +message SelfSubjectReviewStatus { + // User attributes of the user making this request. + // +optional + optional k8s.io.api.authentication.v1.UserInfo userInfo = 1; +} + // TokenReview attempts to authenticate a token to a known user. // Note: TokenReview requests may be cached by the webhook token authenticator // plugin in the kube-apiserver. diff --git a/vendor/k8s.io/api/authentication/v1beta1/register.go b/vendor/k8s.io/api/authentication/v1beta1/register.go index ed23e50f7..075ee1263 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/register.go +++ b/vendor/k8s.io/api/authentication/v1beta1/register.go @@ -44,6 +44,7 @@ var ( // Adds the list of known types to the given scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, + &SelfSubjectReview{}, &TokenReview{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/vendor/k8s.io/api/authentication/v1beta1/types.go b/vendor/k8s.io/api/authentication/v1beta1/types.go index 08e1e09b6..5bce82e7c 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/types.go +++ b/vendor/k8s.io/api/authentication/v1beta1/types.go @@ -19,6 +19,7 @@ package v1beta1 import ( "fmt" + v1 "k8s.io/api/authentication/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -113,3 +114,29 @@ type ExtraValue []string func (t ExtraValue) String() string { return fmt.Sprintf("%v", []string(t)) } + +// +genclient +// +genclient:nonNamespaced +// +genclient:onlyVerbs=create +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.27 + +// SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. +// When using impersonation, users will receive the user info of the user being impersonated. If impersonation or +// request header authentication is used, any extra keys will have their case ignored and returned as lowercase. +type SelfSubjectReview 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"` + // Status is filled in by the server with the user attributes. + Status SelfSubjectReviewStatus `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"` +} + +// SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user. +type SelfSubjectReviewStatus struct { + // User attributes of the user making this request. + // +optional + UserInfo v1.UserInfo `json:"userInfo,omitempty" protobuf:"bytes,1,opt,name=userInfo"` +} diff --git a/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go index 1086955c3..d6644f2cf 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go @@ -24,9 +24,28 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +var map_SelfSubjectReview = map[string]string{ + "": "SelfSubjectReview contains the user information that the kube-apiserver has about the user making this request. When using impersonation, users will receive the user info of the user being impersonated. If impersonation or request header authentication is used, any extra keys will have their case ignored and returned as lowercase.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "status": "Status is filled in by the server with the user attributes.", +} + +func (SelfSubjectReview) SwaggerDoc() map[string]string { + return map_SelfSubjectReview +} + +var map_SelfSubjectReviewStatus = map[string]string{ + "": "SelfSubjectReviewStatus is filled by the kube-apiserver and sent back to a user.", + "userInfo": "User attributes of the user making this request.", +} + +func (SelfSubjectReviewStatus) SwaggerDoc() map[string]string { + return map_SelfSubjectReviewStatus +} + var map_TokenReview = map[string]string{ "": "TokenReview attempts to authenticate a token to a known user. Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", diff --git a/vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go index 059ec1a86..99ffadf7b 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go @@ -45,6 +45,50 @@ func (in ExtraValue) DeepCopy() ExtraValue { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SelfSubjectReview) DeepCopyInto(out *SelfSubjectReview) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SelfSubjectReview. +func (in *SelfSubjectReview) DeepCopy() *SelfSubjectReview { + if in == nil { + return nil + } + out := new(SelfSubjectReview) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SelfSubjectReview) 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 *SelfSubjectReviewStatus) DeepCopyInto(out *SelfSubjectReviewStatus) { + *out = *in + in.UserInfo.DeepCopyInto(&out.UserInfo) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SelfSubjectReviewStatus. +func (in *SelfSubjectReviewStatus) DeepCopy() *SelfSubjectReviewStatus { + if in == nil { + return nil + } + out := new(SelfSubjectReviewStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TokenReview) DeepCopyInto(out *TokenReview) { *out = *in diff --git a/vendor/k8s.io/api/authentication/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/authentication/v1beta1/zz_generated.prerelease-lifecycle.go index e448106e4..904796925 100644 --- a/vendor/k8s.io/api/authentication/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/authentication/v1beta1/zz_generated.prerelease-lifecycle.go @@ -25,6 +25,24 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" ) +// 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 *SelfSubjectReview) APILifecycleIntroduced() (major, minor int) { + return 1, 27 +} + +// 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 *SelfSubjectReview) APILifecycleDeprecated() (major, minor int) { + return 1, 30 +} + +// 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 *SelfSubjectReview) APILifecycleRemoved() (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 *TokenReview) APILifecycleIntroduced() (major, minor int) { diff --git a/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go index 2e5fbea7a..93229485c 100644 --- a/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authorization/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_LocalSubjectAccessReview = map[string]string{ diff --git a/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go index 2d291189e..e0846be7a 100644 --- a/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_LocalSubjectAccessReview = map[string]string{ diff --git a/vendor/k8s.io/api/autoscaling/v1/generated.proto b/vendor/k8s.io/api/autoscaling/v1/generated.proto index 8cf997a75..1dbafd1a5 100644 --- a/vendor/k8s.io/api/autoscaling/v1/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v1/generated.proto @@ -87,13 +87,13 @@ message ContainerResourceMetricStatus { // CrossVersionObjectReference contains enough information to let you identify the referred resource. // +structType=atomic message CrossVersionObjectReference { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds optional string kind = 1; - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional string name = 2; - // API version of the referent + // apiVersion is the API version of the referent // +optional optional string apiVersion = 3; } @@ -147,11 +147,11 @@ message HorizontalPodAutoscaler { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional optional HorizontalPodAutoscalerSpec spec = 2; - // current information about the autoscaler. + // status is the current information about the autoscaler. // +optional optional HorizontalPodAutoscalerStatus status = 3; } @@ -186,7 +186,7 @@ message HorizontalPodAutoscalerList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // list of horizontal pod autoscaler objects. + // items is the list of horizontal pod autoscaler objects. repeated HorizontalPodAutoscaler items = 2; } @@ -204,10 +204,10 @@ message HorizontalPodAutoscalerSpec { // +optional optional int32 minReplicas = 2; - // upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. + // maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. optional int32 maxReplicas = 3; - // target average CPU utilization (represented as a percentage of requested CPU) over all the pods; + // targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods; // if not specified the default autoscaling policy will be used. // +optional optional int32 targetCPUUtilizationPercentage = 4; @@ -215,22 +215,22 @@ message HorizontalPodAutoscalerSpec { // current status of a horizontal pod autoscaler message HorizontalPodAutoscalerStatus { - // most recent generation observed by this autoscaler. + // observedGeneration is the most recent generation observed by this autoscaler. // +optional optional int64 observedGeneration = 1; - // last time the HorizontalPodAutoscaler scaled the number of pods; + // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods; // used by the autoscaler to control how often the number of pods is changed. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastScaleTime = 2; - // current number of replicas of pods managed by this autoscaler. + // currentReplicas is the current number of replicas of pods managed by this autoscaler. optional int32 currentReplicas = 3; - // desired number of replicas of pods managed by this autoscaler. + // desiredReplicas is the desired number of replicas of pods managed by this autoscaler. optional int32 desiredReplicas = 4; - // current average CPU utilization over all pods, represented as a percentage of requested CPU, + // currentCPUUtilizationPercentage is the current average CPU utilization over all pods, represented as a percentage of requested CPU, // e.g. 70 means that an average pod is using now 70% of its requested CPU. // +optional optional int32 currentCPUUtilizationPercentage = 5; @@ -264,7 +264,7 @@ message MetricSpec { // +optional optional ResourceMetricSource resource = 4; - // container resource refers to a resource metric (such as those specified in + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod of the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available @@ -309,7 +309,7 @@ message MetricStatus { // +optional optional ResourceMetricStatus resource = 4; - // container resource refers to a resource metric (such as those specified in + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available @@ -464,31 +464,31 @@ message Scale { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional optional ScaleSpec spec = 2; - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status is the current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional optional ScaleStatus status = 3; } // ScaleSpec describes the attributes of a scale subresource. message ScaleSpec { - // desired number of instances for the scaled object. + // replicas is the desired number of instances for the scaled object. // +optional optional int32 replicas = 1; } // ScaleStatus represents the current status of a scale subresource. message ScaleStatus { - // actual number of observed instances of the scaled object. + // replicas is the actual number of observed instances of the scaled object. optional int32 replicas = 1; - // label query over pods that should match the replicas count. This is same + // selector is the label query over pods that should match the replicas count. This is same // as the label selector but in the string format to avoid introspection // by clients. The string will be in the same format as the query-param syntax. - // More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + // More info about label selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional optional string selector = 2; } diff --git a/vendor/k8s.io/api/autoscaling/v1/types.go b/vendor/k8s.io/api/autoscaling/v1/types.go index 6397430a2..450829017 100644 --- a/vendor/k8s.io/api/autoscaling/v1/types.go +++ b/vendor/k8s.io/api/autoscaling/v1/types.go @@ -25,11 +25,13 @@ import ( // CrossVersionObjectReference contains enough information to let you identify the referred resource. // +structType=atomic type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // API version of the referent + + // apiVersion is the API version of the referent // +optional APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"` } @@ -46,9 +48,11 @@ type HorizontalPodAutoscalerSpec struct { // available. // +optional MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` - // upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. + + // maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` - // target average CPU utilization (represented as a percentage of requested CPU) over all the pods; + + // targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods; // if not specified the default autoscaling policy will be used. // +optional TargetCPUUtilizationPercentage *int32 `json:"targetCPUUtilizationPercentage,omitempty" protobuf:"varint,4,opt,name=targetCPUUtilizationPercentage"` @@ -56,22 +60,22 @@ type HorizontalPodAutoscalerSpec struct { // current status of a horizontal pod autoscaler type HorizontalPodAutoscalerStatus struct { - // most recent generation observed by this autoscaler. + // observedGeneration is the most recent generation observed by this autoscaler. // +optional ObservedGeneration *int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // last time the HorizontalPodAutoscaler scaled the number of pods; + // lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods; // used by the autoscaler to control how often the number of pods is changed. // +optional LastScaleTime *metav1.Time `json:"lastScaleTime,omitempty" protobuf:"bytes,2,opt,name=lastScaleTime"` - // current number of replicas of pods managed by this autoscaler. + // currentReplicas is the current number of replicas of pods managed by this autoscaler. CurrentReplicas int32 `json:"currentReplicas" protobuf:"varint,3,opt,name=currentReplicas"` - // desired number of replicas of pods managed by this autoscaler. + // desiredReplicas is the desired number of replicas of pods managed by this autoscaler. DesiredReplicas int32 `json:"desiredReplicas" protobuf:"varint,4,opt,name=desiredReplicas"` - // current average CPU utilization over all pods, represented as a percentage of requested CPU, + // currentCPUUtilizationPercentage is the current average CPU utilization over all pods, represented as a percentage of requested CPU, // e.g. 70 means that an average pod is using now 70% of its requested CPU. // +optional CurrentCPUUtilizationPercentage *int32 `json:"currentCPUUtilizationPercentage,omitempty" protobuf:"varint,5,opt,name=currentCPUUtilizationPercentage"` @@ -87,11 +91,11 @@ type HorizontalPodAutoscaler struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // current information about the autoscaler. + // status is the current information about the autoscaler. // +optional Status HorizontalPodAutoscalerStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } @@ -105,7 +109,7 @@ type HorizontalPodAutoscalerList struct { // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // list of horizontal pod autoscaler objects. + // items is the list of horizontal pod autoscaler objects. Items []HorizontalPodAutoscaler `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -118,31 +122,31 @@ type Scale struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. + // spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. // +optional Spec ScaleSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. + // status is the current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only. // +optional Status ScaleStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } // ScaleSpec describes the attributes of a scale subresource. type ScaleSpec struct { - // desired number of instances for the scaled object. + // replicas is the desired number of instances for the scaled object. // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } // ScaleStatus represents the current status of a scale subresource. type ScaleStatus struct { - // actual number of observed instances of the scaled object. + // replicas is the actual number of observed instances of the scaled object. Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // label query over pods that should match the replicas count. This is same + // selector is the label query over pods that should match the replicas count. This is same // as the label selector but in the string format to avoid introspection // by clients. The string will be in the same format as the query-param syntax. - // More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + // More info about label selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional Selector string `json:"selector,omitempty" protobuf:"bytes,2,opt,name=selector"` } @@ -194,11 +198,13 @@ type MetricSpec struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricSource `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricSource `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -206,7 +212,8 @@ type MetricSpec struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - // container resource refers to a resource metric (such as those specified in + + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod of the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available @@ -214,6 +221,7 @@ type MetricSpec struct { // This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag. // +optional ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -231,6 +239,7 @@ type ObjectMetricSource struct { // metricName is the name of the metric in question. MetricName string `json:"metricName" protobuf:"bytes,2,name=metricName"` + // targetValue is the target value of the metric (as a quantity). TargetValue resource.Quantity `json:"targetValue" protobuf:"bytes,3,name=targetValue"` @@ -239,6 +248,7 @@ type ObjectMetricSource struct { // When unset, just the metricName will be used to gather metrics. // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,4,name=selector"` + // averageValue is the target value of the average of the // metric across all relevant pods (as a quantity) // +optional @@ -252,6 +262,7 @@ type ObjectMetricSource struct { type PodsMetricSource struct { // metricName is the name of the metric in question MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` + // targetAverageValue is the target value of the average of the // metric across all relevant pods (as a quantity) TargetAverageValue resource.Quantity `json:"targetAverageValue" protobuf:"bytes,2,name=targetAverageValue"` @@ -273,11 +284,13 @@ type PodsMetricSource struct { type ResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // targetAverageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // +optional TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty" protobuf:"varint,2,opt,name=targetAverageUtilization"` + // targetAverageValue is the target value of the average of the // resource metric across all relevant pods, as a raw value (instead of as // a percentage of the request), similar to the "pods" metric source type. @@ -295,16 +308,19 @@ type ResourceMetricSource struct { type ContainerResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // targetAverageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // +optional TargetAverageUtilization *int32 `json:"targetAverageUtilization,omitempty" protobuf:"varint,2,opt,name=targetAverageUtilization"` + // targetAverageValue is the target value of the average of the // resource metric across all relevant pods, as a raw value (instead of as // a percentage of the request), similar to the "pods" metric source type. // +optional TargetAverageValue *resource.Quantity `json:"targetAverageValue,omitempty" protobuf:"bytes,3,opt,name=targetAverageValue"` + // container is the name of the container in the pods of the scaling target. Container string `json:"container" protobuf:"bytes,5,opt,name=container"` } @@ -315,14 +331,17 @@ type ContainerResourceMetricSource struct { type ExternalMetricSource struct { // metricName is the name of the metric in question. MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` + // metricSelector is used to identify a specific time series // within a given metric. // +optional MetricSelector *metav1.LabelSelector `json:"metricSelector,omitempty" protobuf:"bytes,2,opt,name=metricSelector"` + // targetValue is the target value of the metric (as a quantity). // Mutually exclusive with TargetAverageValue. // +optional TargetValue *resource.Quantity `json:"targetValue,omitempty" protobuf:"bytes,3,opt,name=targetValue"` + // targetAverageValue is the target per-pod value of global metric (as a quantity). // Mutually exclusive with TargetValue. // +optional @@ -341,11 +360,13 @@ type MetricStatus struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricStatus `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricStatus `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -353,13 +374,15 @@ type MetricStatus struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - // container resource refers to a resource metric (such as those specified in + + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available // to normal per-pod metrics using the "pods" source. // +optional ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -390,15 +413,19 @@ const ( type HorizontalPodAutoscalerCondition struct { // type describes the current condition Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` + // status is the status of the condition (True, False, Unknown) Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` + // lastTransitionTime is the last time the condition transitioned from // one status to another // +optional LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // reason is the reason for the condition's last transition. // +optional Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // message is a human-readable explanation containing details about // the transition // +optional @@ -413,6 +440,7 @@ type ObjectMetricStatus struct { // metricName is the name of the metric in question. MetricName string `json:"metricName" protobuf:"bytes,2,name=metricName"` + // currentValue is the current value of the metric (as a quantity). CurrentValue resource.Quantity `json:"currentValue" protobuf:"bytes,3,name=currentValue"` @@ -421,6 +449,7 @@ type ObjectMetricStatus struct { // When unset, just the metricName will be used to gather metrics. // +optional Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,4,name=selector"` + // averageValue is the current value of the average of the // metric across all relevant pods (as a quantity) // +optional @@ -432,6 +461,7 @@ type ObjectMetricStatus struct { type PodsMetricStatus struct { // metricName is the name of the metric in question MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` + // currentAverageValue is the current value of the average of the // metric across all relevant pods (as a quantity) CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,2,name=currentAverageValue"` @@ -451,6 +481,7 @@ type PodsMetricStatus struct { type ResourceMetricStatus struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // currentAverageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. It will only be @@ -458,6 +489,7 @@ type ResourceMetricStatus struct { // specification. // +optional CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty" protobuf:"bytes,2,opt,name=currentAverageUtilization"` + // currentAverageValue is the current value of the average of the // resource metric across all relevant pods, as a raw value (instead of as // a percentage of the request), similar to the "pods" metric source type. @@ -473,6 +505,7 @@ type ResourceMetricStatus struct { type ContainerResourceMetricStatus struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // currentAverageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. It will only be @@ -480,11 +513,13 @@ type ContainerResourceMetricStatus struct { // specification. // +optional CurrentAverageUtilization *int32 `json:"currentAverageUtilization,omitempty" protobuf:"bytes,2,opt,name=currentAverageUtilization"` + // currentAverageValue is the current value of the average of the // resource metric across all relevant pods, as a raw value (instead of as // a percentage of the request), similar to the "pods" metric source type. // It will always be set, regardless of the corresponding metric specification. CurrentAverageValue resource.Quantity `json:"currentAverageValue" protobuf:"bytes,3,name=currentAverageValue"` + // container is the name of the container in the pods of the scaling taget Container string `json:"container" protobuf:"bytes,4,opt,name=container"` } @@ -495,12 +530,14 @@ type ExternalMetricStatus struct { // metricName is the name of a metric used for autoscaling in // metric system. MetricName string `json:"metricName" protobuf:"bytes,1,name=metricName"` + // metricSelector is used to identify a specific time series // within a given metric. // +optional MetricSelector *metav1.LabelSelector `json:"metricSelector,omitempty" protobuf:"bytes,2,opt,name=metricSelector"` // currentValue is the current value of the metric (as a quantity) CurrentValue resource.Quantity `json:"currentValue" protobuf:"bytes,3,name=currentValue"` + // currentAverageValue is the current value of metric averaged over autoscaled pods. // +optional CurrentAverageValue *resource.Quantity `json:"currentAverageValue,omitempty" protobuf:"bytes,4,opt,name=currentAverageValue"` diff --git a/vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go index ca288e912..37c2b36a5 100644 --- a/vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/autoscaling/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ContainerResourceMetricSource = map[string]string{ @@ -53,9 +53,9 @@ func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "name": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "apiVersion": "API version of the referent", + "kind": "kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "name": "name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "apiVersion": "apiVersion is the API version of the referent", } func (CrossVersionObjectReference) SwaggerDoc() map[string]string { @@ -89,8 +89,8 @@ func (ExternalMetricStatus) SwaggerDoc() map[string]string { var map_HorizontalPodAutoscaler = map[string]string{ "": "configuration of a horizontal pod autoscaler.", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", - "status": "current information about the autoscaler.", + "spec": "spec defines the behaviour of autoscaler. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", + "status": "status is the current information about the autoscaler.", } func (HorizontalPodAutoscaler) SwaggerDoc() map[string]string { @@ -113,7 +113,7 @@ func (HorizontalPodAutoscalerCondition) SwaggerDoc() map[string]string { var map_HorizontalPodAutoscalerList = map[string]string{ "": "list of horizontal pod autoscaler objects.", "metadata": "Standard list metadata.", - "items": "list of horizontal pod autoscaler objects.", + "items": "items is the list of horizontal pod autoscaler objects.", } func (HorizontalPodAutoscalerList) SwaggerDoc() map[string]string { @@ -124,8 +124,8 @@ var map_HorizontalPodAutoscalerSpec = map[string]string{ "": "specification of a horizontal pod autoscaler.", "scaleTargetRef": "reference to scaled resource; horizontal pod autoscaler will learn the current resource consumption and will set the desired number of pods by using its Scale subresource.", "minReplicas": "minReplicas is the lower limit for the number of replicas to which the autoscaler can scale down. It defaults to 1 pod. minReplicas is allowed to be 0 if the alpha feature gate HPAScaleToZero is enabled and at least one Object or External metric is configured. Scaling is active as long as at least one metric value is available.", - "maxReplicas": "upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.", - "targetCPUUtilizationPercentage": "target average CPU utilization (represented as a percentage of requested CPU) over all the pods; if not specified the default autoscaling policy will be used.", + "maxReplicas": "maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.", + "targetCPUUtilizationPercentage": "targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods; if not specified the default autoscaling policy will be used.", } func (HorizontalPodAutoscalerSpec) SwaggerDoc() map[string]string { @@ -134,11 +134,11 @@ func (HorizontalPodAutoscalerSpec) SwaggerDoc() map[string]string { var map_HorizontalPodAutoscalerStatus = map[string]string{ "": "current status of a horizontal pod autoscaler", - "observedGeneration": "most recent generation observed by this autoscaler.", - "lastScaleTime": "last time the HorizontalPodAutoscaler scaled the number of pods; used by the autoscaler to control how often the number of pods is changed.", - "currentReplicas": "current number of replicas of pods managed by this autoscaler.", - "desiredReplicas": "desired number of replicas of pods managed by this autoscaler.", - "currentCPUUtilizationPercentage": "current average CPU utilization over all pods, represented as a percentage of requested CPU, e.g. 70 means that an average pod is using now 70% of its requested CPU.", + "observedGeneration": "observedGeneration is the most recent generation observed by this autoscaler.", + "lastScaleTime": "lastScaleTime is the last time the HorizontalPodAutoscaler scaled the number of pods; used by the autoscaler to control how often the number of pods is changed.", + "currentReplicas": "currentReplicas is the current number of replicas of pods managed by this autoscaler.", + "desiredReplicas": "desiredReplicas is the desired number of replicas of pods managed by this autoscaler.", + "currentCPUUtilizationPercentage": "currentCPUUtilizationPercentage is the current average CPU utilization over all pods, represented as a percentage of requested CPU, e.g. 70 means that an average pod is using now 70% of its requested CPU.", } func (HorizontalPodAutoscalerStatus) SwaggerDoc() map[string]string { @@ -151,7 +151,7 @@ var map_MetricSpec = map[string]string{ "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.", + "containerResource": "containerResource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod of the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source. This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag.", "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", } @@ -165,7 +165,7 @@ var map_MetricStatus = map[string]string{ "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", + "containerResource": "containerResource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", } @@ -246,8 +246,8 @@ func (ResourceMetricStatus) SwaggerDoc() map[string]string { var map_Scale = map[string]string{ "": "Scale represents a scaling request for a resource.", "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", - "spec": "defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", - "status": "current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.", + "spec": "spec defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.", + "status": "status is the current status of the scale. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status. Read-only.", } func (Scale) SwaggerDoc() map[string]string { @@ -256,7 +256,7 @@ func (Scale) SwaggerDoc() map[string]string { var map_ScaleSpec = map[string]string{ "": "ScaleSpec describes the attributes of a scale subresource.", - "replicas": "desired number of instances for the scaled object.", + "replicas": "replicas is the desired number of instances for the scaled object.", } func (ScaleSpec) SwaggerDoc() map[string]string { @@ -265,8 +265,8 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "ScaleStatus represents the current status of a scale subresource.", - "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. This is same as the label selector but in the string format to avoid introspection by clients. The string will be in the same format as the query-param syntax. More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors", + "replicas": "replicas is the actual number of observed instances of the scaled object.", + "selector": "selector is the label query over pods that should match the replicas count. This is same as the label selector but in the string format to avoid introspection by clients. The string will be in the same format as the query-param syntax. More info about label selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", } func (ScaleStatus) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/autoscaling/v2/generated.proto b/vendor/k8s.io/api/autoscaling/v2/generated.proto index c08328023..a9e36975f 100644 --- a/vendor/k8s.io/api/autoscaling/v2/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v2/generated.proto @@ -54,25 +54,25 @@ message ContainerResourceMetricSource { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. message ContainerResourceMetricStatus { - // Name is the name of the resource in question. + // name is the name of the resource in question. optional string name = 1; // current contains the current value for the given metric optional MetricValueStatus current = 2; - // Container is the name of the container in the pods of the scaling target + // container is the name of the container in the pods of the scaling target optional string container = 3; } // CrossVersionObjectReference contains enough information to let you identify the referred resource. message CrossVersionObjectReference { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds optional string kind = 1; - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional string name = 2; - // API version of the referent + // apiVersion is the API version of the referent // +optional optional string apiVersion = 3; } @@ -100,14 +100,14 @@ message ExternalMetricStatus { // HPAScalingPolicy is a single policy which must hold true for a specified past interval. message HPAScalingPolicy { - // Type is used to specify the scaling policy. + // type is used to specify the scaling policy. optional string type = 1; - // Value contains the amount of change which is permitted by the policy. + // value contains the amount of change which is permitted by the policy. // It must be greater than zero optional int32 value = 2; - // PeriodSeconds specifies the window of time for which the policy should hold true. + // periodSeconds specifies the window of time for which the policy should hold true. // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). optional int32 periodSeconds = 3; } @@ -119,7 +119,7 @@ message HPAScalingPolicy { // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. message HPAScalingRules { - // StabilizationWindowSeconds is the number of seconds for which past recommendations should be + // 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: @@ -495,7 +495,7 @@ message ResourceMetricSource { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. message ResourceMetricStatus { - // Name is the name of the resource in question. + // name is the name of the resource in question. optional string name = 1; // current contains the current value for the given metric diff --git a/vendor/k8s.io/api/autoscaling/v2/types.go b/vendor/k8s.io/api/autoscaling/v2/types.go index 9b2dc36e3..c12a83df1 100644 --- a/vendor/k8s.io/api/autoscaling/v2/types.go +++ b/vendor/k8s.io/api/autoscaling/v2/types.go @@ -59,9 +59,11 @@ type HorizontalPodAutoscalerSpec struct { // available. // +optional MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` + // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. // It cannot be less that minReplicas. MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` + // metrics contains the specifications for which to use to calculate the // desired replica count (the maximum replica count across all metrics will // be used). The desired replica count is calculated multiplying the @@ -83,11 +85,13 @@ type HorizontalPodAutoscalerSpec struct { // CrossVersionObjectReference contains enough information to let you identify the referred resource. type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // API version of the referent + + // apiVersion is the API version of the referent // +optional APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"` } @@ -105,11 +109,13 @@ type MetricSpec struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricSource `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricSource `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -117,6 +123,7 @@ type MetricSpec struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in // each pod of the current scale target (e.g. CPU or memory). Such metrics are @@ -125,6 +132,7 @@ type MetricSpec struct { // This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag. // +optional ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -144,6 +152,7 @@ type HorizontalPodAutoscalerBehavior struct { // No stabilization is used. // +optional ScaleUp *HPAScalingRules `json:"scaleUp,omitempty" protobuf:"bytes,1,opt,name=scaleUp"` + // scaleDown is scaling policy for scaling Down. // If not set, the default value is to allow to scale down to minReplicas pods, with a // 300 second stabilization window (i.e., the highest recommendation for @@ -171,7 +180,7 @@ const ( // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. type HPAScalingRules struct { - // StabilizationWindowSeconds is the number of seconds for which past recommendations should be + // 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: @@ -179,10 +188,12 @@ type HPAScalingRules struct { // - For scale down: 300 (i.e. the stabilization window is 300 seconds long). // +optional StabilizationWindowSeconds *int32 `json:"stabilizationWindowSeconds,omitempty" protobuf:"varint,3,opt,name=stabilizationWindowSeconds"` + // selectPolicy is used to specify which policy should be used. // If not set, the default value Max is used. // +optional 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 // +listType=atomic @@ -203,12 +214,14 @@ const ( // HPAScalingPolicy is a single policy which must hold true for a specified past interval. type HPAScalingPolicy struct { - // Type is used to specify the scaling policy. + // type is used to specify the scaling policy. Type HPAScalingPolicyType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=HPAScalingPolicyType"` - // Value contains the amount of change which is permitted by the policy. + + // value contains the amount of change which is permitted by the policy. // It must be greater than zero Value int32 `json:"value" protobuf:"varint,2,opt,name=value"` - // PeriodSeconds specifies the window of time for which the policy should hold true. + + // periodSeconds specifies the window of time for which the policy should hold true. // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). PeriodSeconds int32 `json:"periodSeconds" protobuf:"varint,3,opt,name=periodSeconds"` } @@ -249,8 +262,10 @@ const ( type ObjectMetricSource struct { // describedObject specifies the descriptions of a object,such as kind,name apiVersion DescribedObject CrossVersionObjectReference `json:"describedObject" protobuf:"bytes,1,name=describedObject"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` + // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,3,name=metric"` } @@ -262,6 +277,7 @@ type ObjectMetricSource struct { type PodsMetricSource struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -276,6 +292,7 @@ type PodsMetricSource struct { type ResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -290,8 +307,10 @@ type ResourceMetricSource struct { type ContainerResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` + // container is the name of the container in the pods of the scaling target Container string `json:"container" protobuf:"bytes,3,opt,name=container"` } @@ -302,6 +321,7 @@ type ContainerResourceMetricSource struct { type ExternalMetricSource struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -310,6 +330,7 @@ type ExternalMetricSource struct { type MetricIdentifier struct { // name is the name of the given metric Name string `json:"name" protobuf:"bytes,1,name=name"` + // selector is the string-encoded form of a standard kubernetes label selector for the given metric // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. // When unset, just the metricName will be used to gather metrics. @@ -321,13 +342,16 @@ type MetricIdentifier struct { type MetricTarget struct { // type represents whether the metric type is Utilization, Value, or AverageValue Type MetricTargetType `json:"type" protobuf:"bytes,1,name=type"` + // value is the target value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + // averageValue is the target value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,3,opt,name=averageValue"` + // averageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. @@ -405,15 +429,19 @@ const ( type HorizontalPodAutoscalerCondition struct { // type describes the current condition Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` + // status is the status of the condition (True, False, Unknown) Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` + // lastTransitionTime is the last time the condition transitioned from // one status to another // +optional LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // reason is the reason for the condition's last transition. // +optional Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // message is a human-readable explanation containing details about // the transition // +optional @@ -432,11 +460,13 @@ type MetricStatus struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricStatus `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricStatus `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -444,6 +474,7 @@ type MetricStatus struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` + // container resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -451,6 +482,7 @@ type MetricStatus struct { // to normal per-pod metrics using the "pods" source. // +optional ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -465,8 +497,10 @@ type MetricStatus struct { type ObjectMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` + // DescribedObject specifies the descriptions of a object,such as kind,name apiVersion DescribedObject CrossVersionObjectReference `json:"describedObject" protobuf:"bytes,3,name=describedObject"` } @@ -476,6 +510,7 @@ type ObjectMetricStatus struct { type PodsMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -486,8 +521,9 @@ type PodsMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -498,11 +534,13 @@ type ResourceMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ContainerResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` - // Container is the name of the container in the pods of the scaling target + + // container is the name of the container in the pods of the scaling target Container string `json:"container" protobuf:"bytes,3,opt,name=container"` } @@ -511,6 +549,7 @@ type ContainerResourceMetricStatus struct { type ExternalMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -520,10 +559,12 @@ type MetricValueStatus struct { // value is the current value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,1,opt,name=value"` + // averageValue is the current value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,2,opt,name=averageValue"` + // currentAverageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. diff --git a/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go index 41ab32a4c..1941b1ef5 100644 --- a/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v2 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ContainerResourceMetricSource = map[string]string{ @@ -40,9 +40,9 @@ func (ContainerResourceMetricSource) SwaggerDoc() map[string]string { var map_ContainerResourceMetricStatus = map[string]string{ "": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "Name is the name of the resource in question.", + "name": "name is the name of the resource in question.", "current": "current contains the current value for the given metric", - "container": "Container is the name of the container in the pods of the scaling target", + "container": "container is the name of the container in the pods of the scaling target", } func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { @@ -51,9 +51,9 @@ func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "name": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "apiVersion": "API version of the referent", + "kind": "kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "name": "name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "apiVersion": "apiVersion is the API version of the referent", } func (CrossVersionObjectReference) SwaggerDoc() map[string]string { @@ -82,9 +82,9 @@ func (ExternalMetricStatus) SwaggerDoc() map[string]string { var map_HPAScalingPolicy = map[string]string{ "": "HPAScalingPolicy is a single policy which must hold true for a specified past interval.", - "type": "Type is used to specify the scaling policy.", - "value": "Value contains the amount of change which is permitted by the policy. It must be greater than zero", - "periodSeconds": "PeriodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", + "type": "type is used to specify the scaling policy.", + "value": "value contains the amount of change which is permitted by the policy. It must be greater than zero", + "periodSeconds": "periodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", } func (HPAScalingPolicy) SwaggerDoc() map[string]string { @@ -93,7 +93,7 @@ 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.", - "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).", + "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", } @@ -288,7 +288,7 @@ func (ResourceMetricSource) SwaggerDoc() map[string]string { var map_ResourceMetricStatus = map[string]string{ "": "ResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "Name is the name of the resource in question.", + "name": "name is the name of the resource in question.", "current": "current contains the current value for the given metric", } diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto b/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto index 33d27a962..6b3d41521 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v2beta1/generated.proto @@ -89,7 +89,7 @@ message CrossVersionObjectReference { // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds optional string kind = 1; - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional string name = 2; // API version of the referent diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/types.go b/vendor/k8s.io/api/autoscaling/v2beta1/types.go index c1480ab39..842284072 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta1/types.go +++ b/vendor/k8s.io/api/autoscaling/v2beta1/types.go @@ -26,7 +26,7 @@ import ( type CrossVersionObjectReference struct { // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string `json:"name" protobuf:"bytes,2,opt,name=name"` // API version of the referent // +optional diff --git a/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go index 6f555487d..d656ee416 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/autoscaling/v2beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v2beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ContainerResourceMetricSource = map[string]string{ @@ -54,7 +54,7 @@ func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "name": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "name": "Name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", "apiVersion": "API version of the referent", } diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto b/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto index 1bafbf6c7..5b2fe9442 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto +++ b/vendor/k8s.io/api/autoscaling/v2beta2/generated.proto @@ -54,25 +54,25 @@ message ContainerResourceMetricSource { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. message ContainerResourceMetricStatus { - // Name is the name of the resource in question. + // name is the name of the resource in question. optional string name = 1; // current contains the current value for the given metric optional MetricValueStatus current = 2; - // Container is the name of the container in the pods of the scaling target + // container is the name of the container in the pods of the scaling target optional string container = 3; } // CrossVersionObjectReference contains enough information to let you identify the referred resource. message CrossVersionObjectReference { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds optional string kind = 1; - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names optional string name = 2; - // API version of the referent + // apiVersion is the API version of the referent // +optional optional string apiVersion = 3; } @@ -100,14 +100,14 @@ message ExternalMetricStatus { // HPAScalingPolicy is a single policy which must hold true for a specified past interval. message HPAScalingPolicy { - // Type is used to specify the scaling policy. + // type is used to specify the scaling policy. optional string type = 1; - // Value contains the amount of change which is permitted by the policy. + // value contains the amount of change which is permitted by the policy. // It must be greater than zero optional int32 value = 2; - // PeriodSeconds specifies the window of time for which the policy should hold true. + // periodSeconds specifies the window of time for which the policy should hold true. // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). optional int32 periodSeconds = 3; } @@ -119,7 +119,7 @@ message HPAScalingPolicy { // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. message HPAScalingRules { - // StabilizationWindowSeconds is the number of seconds for which past recommendations should be + // 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: @@ -361,7 +361,7 @@ message MetricStatus { // +optional optional ResourceMetricStatus resource = 4; - // container resource refers to a resource metric (such as those specified in + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available @@ -411,7 +411,7 @@ message MetricValueStatus { // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity averageValue = 2; - // currentAverageUtilization is the current value of the average of the + // averageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // +optional @@ -485,7 +485,7 @@ message ResourceMetricSource { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. message ResourceMetricStatus { - // Name is the name of the resource in question. + // name is the name of the resource in question. optional string name = 1; // current contains the current value for the given metric diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/types.go b/vendor/k8s.io/api/autoscaling/v2beta2/types.go index 60da3ba04..b0b7681c0 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta2/types.go +++ b/vendor/k8s.io/api/autoscaling/v2beta2/types.go @@ -62,9 +62,11 @@ type HorizontalPodAutoscalerSpec struct { // available. // +optional MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"` + // maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up. // It cannot be less that minReplicas. MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"` + // metrics contains the specifications for which to use to calculate the // desired replica count (the maximum replica count across all metrics will // be used). The desired replica count is calculated multiplying the @@ -85,11 +87,13 @@ type HorizontalPodAutoscalerSpec struct { // CrossVersionObjectReference contains enough information to let you identify the referred resource. type CrossVersionObjectReference struct { - // Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + // kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` - // Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names + + // name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Name string `json:"name" protobuf:"bytes,2,opt,name=name"` - // API version of the referent + + // apiVersion is the API version of the referent // +optional APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"` } @@ -107,11 +111,13 @@ type MetricSpec struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricSource `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. // +optional Pods *PodsMetricSource `json:"pods,omitempty" protobuf:"bytes,3,opt,name=pods"` + // resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to @@ -119,6 +125,7 @@ type MetricSpec struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricSource `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` + // container resource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in // each pod of the current scale target (e.g. CPU or memory). Such metrics are @@ -127,6 +134,7 @@ type MetricSpec struct { // This is an alpha feature and can be enabled by the HPAContainerMetrics feature flag. // +optional ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -146,6 +154,7 @@ type HorizontalPodAutoscalerBehavior struct { // No stabilization is used. // +optional ScaleUp *HPAScalingRules `json:"scaleUp,omitempty" protobuf:"bytes,1,opt,name=scaleUp"` + // scaleDown is scaling policy for scaling Down. // If not set, the default value is to allow to scale down to minReplicas pods, with a // 300 second stabilization window (i.e., the highest recommendation for @@ -173,7 +182,7 @@ const ( // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. type HPAScalingRules struct { - // StabilizationWindowSeconds is the number of seconds for which past recommendations should be + // 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: @@ -181,10 +190,12 @@ type HPAScalingRules struct { // - For scale down: 300 (i.e. the stabilization window is 300 seconds long). // +optional StabilizationWindowSeconds *int32 `json:"stabilizationWindowSeconds,omitempty" protobuf:"varint,3,opt,name=stabilizationWindowSeconds"` + // selectPolicy is used to specify which policy should be used. // If not set, the default value MaxPolicySelect is used. // +optional 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 // +optional @@ -204,12 +215,14 @@ const ( // HPAScalingPolicy is a single policy which must hold true for a specified past interval. type HPAScalingPolicy struct { - // Type is used to specify the scaling policy. + // type is used to specify the scaling policy. Type HPAScalingPolicyType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=HPAScalingPolicyType"` - // Value contains the amount of change which is permitted by the policy. + + // value contains the amount of change which is permitted by the policy. // It must be greater than zero Value int32 `json:"value" protobuf:"varint,2,opt,name=value"` - // PeriodSeconds specifies the window of time for which the policy should hold true. + + // periodSeconds specifies the window of time for which the policy should hold true. // PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). PeriodSeconds int32 `json:"periodSeconds" protobuf:"varint,3,opt,name=periodSeconds"` } @@ -251,6 +264,7 @@ type ObjectMetricSource struct { DescribedObject CrossVersionObjectReference `json:"describedObject" protobuf:"bytes,1,name=describedObject"` // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` + // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,3,name=metric"` } @@ -262,6 +276,7 @@ type ObjectMetricSource struct { type PodsMetricSource struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -276,6 +291,7 @@ type PodsMetricSource struct { type ResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -290,8 +306,10 @@ type ResourceMetricSource struct { type ContainerResourceMetricSource struct { // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` + // container is the name of the container in the pods of the scaling target Container string `json:"container" protobuf:"bytes,3,opt,name=container"` } @@ -302,6 +320,7 @@ type ContainerResourceMetricSource struct { type ExternalMetricSource struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // target specifies the target value for the given metric Target MetricTarget `json:"target" protobuf:"bytes,2,name=target"` } @@ -310,6 +329,7 @@ type ExternalMetricSource struct { type MetricIdentifier struct { // name is the name of the given metric Name string `json:"name" protobuf:"bytes,1,name=name"` + // selector is the string-encoded form of a standard kubernetes label selector for the given metric // When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. // When unset, just the metricName will be used to gather metrics. @@ -321,13 +341,16 @@ type MetricIdentifier struct { type MetricTarget struct { // type represents whether the metric type is Utilization, Value, or AverageValue Type MetricTargetType `json:"type" protobuf:"bytes,1,name=type"` + // value is the target value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"` + // averageValue is the target value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,3,opt,name=averageValue"` + // averageUtilization is the target value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. @@ -399,15 +422,19 @@ const ( type HorizontalPodAutoscalerCondition struct { // type describes the current condition Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"` + // status is the status of the condition (True, False, Unknown) Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"` + // lastTransitionTime is the last time the condition transitioned from // one status to another // +optional LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"` + // reason is the reason for the condition's last transition. // +optional Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` + // message is a human-readable explanation containing details about // the transition // +optional @@ -426,6 +453,7 @@ type MetricStatus struct { // (for example, hits-per-second on an Ingress object). // +optional Object *ObjectMetricStatus `json:"object,omitempty" protobuf:"bytes,2,opt,name=object"` + // pods refers to a metric describing each pod in the current scale target // (for example, transactions-processed-per-second). The values will be // averaged together before being compared to the target value. @@ -438,13 +466,15 @@ type MetricStatus struct { // to normal per-pod metrics using the "pods" source. // +optional Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` - // container resource refers to a resource metric (such as those specified in + + // containerResource refers to a resource metric (such as those specified in // requests and limits) known to Kubernetes describing a single container in each pod in the // current scale target (e.g. CPU or memory). Such metrics are built in to // Kubernetes, and have special scaling options on top of those available // to normal per-pod metrics using the "pods" source. // +optional ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" protobuf:"bytes,7,opt,name=containerResource"` + // external refers to a global metric that is not associated // with any Kubernetes object. It allows autoscaling based on information // coming from components running outside of cluster @@ -459,6 +489,7 @@ type MetricStatus struct { type ObjectMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` @@ -470,6 +501,7 @@ type ObjectMetricStatus struct { type PodsMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -480,8 +512,9 @@ type PodsMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -492,11 +525,13 @@ type ResourceMetricStatus struct { // Kubernetes, and have special scaling options on top of those available to // normal per-pod metrics using the "pods" source. type ContainerResourceMetricStatus struct { - // Name is the name of the resource in question. + // name is the name of the resource in question. Name v1.ResourceName `json:"name" protobuf:"bytes,1,name=name"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` - // Container is the name of the container in the pods of the scaling target + + // container is the name of the container in the pods of the scaling target Container string `json:"container" protobuf:"bytes,3,opt,name=container"` } @@ -505,6 +540,7 @@ type ContainerResourceMetricStatus struct { type ExternalMetricStatus struct { // metric identifies the target metric by name and selector Metric MetricIdentifier `json:"metric" protobuf:"bytes,1,name=metric"` + // current contains the current value for the given metric Current MetricValueStatus `json:"current" protobuf:"bytes,2,name=current"` } @@ -514,11 +550,13 @@ type MetricValueStatus struct { // value is the current value of the metric (as a quantity). // +optional Value *resource.Quantity `json:"value,omitempty" protobuf:"bytes,1,opt,name=value"` + // averageValue is the current value of the average of the // metric across all relevant pods (as a quantity) // +optional AverageValue *resource.Quantity `json:"averageValue,omitempty" protobuf:"bytes,2,opt,name=averageValue"` - // currentAverageUtilization is the current value of the average of the + + // averageUtilization is the current value of the average of the // resource metric across all relevant pods, represented as a percentage of // the requested value of the resource for the pods. // +optional diff --git a/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go b/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go index cb92e9e34..4af7d0ec0 100644 --- a/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/autoscaling/v2beta2/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v2beta2 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ContainerResourceMetricSource = map[string]string{ @@ -40,9 +40,9 @@ func (ContainerResourceMetricSource) SwaggerDoc() map[string]string { var map_ContainerResourceMetricStatus = map[string]string{ "": "ContainerResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "Name is the name of the resource in question.", + "name": "name is the name of the resource in question.", "current": "current contains the current value for the given metric", - "container": "Container is the name of the container in the pods of the scaling target", + "container": "container is the name of the container in the pods of the scaling target", } func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { @@ -51,9 +51,9 @@ func (ContainerResourceMetricStatus) SwaggerDoc() map[string]string { var map_CrossVersionObjectReference = map[string]string{ "": "CrossVersionObjectReference contains enough information to let you identify the referred resource.", - "kind": "Kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "name": "Name of the referent; More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "apiVersion": "API version of the referent", + "kind": "kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "name": "name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "apiVersion": "apiVersion is the API version of the referent", } func (CrossVersionObjectReference) SwaggerDoc() map[string]string { @@ -82,9 +82,9 @@ func (ExternalMetricStatus) SwaggerDoc() map[string]string { var map_HPAScalingPolicy = map[string]string{ "": "HPAScalingPolicy is a single policy which must hold true for a specified past interval.", - "type": "Type is used to specify the scaling policy.", - "value": "Value contains the amount of change which is permitted by the policy. It must be greater than zero", - "periodSeconds": "PeriodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", + "type": "type is used to specify the scaling policy.", + "value": "value contains the amount of change which is permitted by the policy. It must be greater than zero", + "periodSeconds": "periodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", } func (HPAScalingPolicy) SwaggerDoc() map[string]string { @@ -93,7 +93,7 @@ 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.", - "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).", + "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 MaxPolicySelect 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", } @@ -203,7 +203,7 @@ var map_MetricStatus = map[string]string{ "object": "object refers to a metric describing a single kubernetes object (for example, hits-per-second on an Ingress object).", "pods": "pods refers to a metric describing each pod in the current scale target (for example, transactions-processed-per-second). The values will be averaged together before being compared to the target value.", "resource": "resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "containerResource": "container resource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", + "containerResource": "containerResource refers to a resource metric (such as those specified in requests and limits) known to Kubernetes describing a single container in each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", "external": "external refers to a global metric that is not associated with any Kubernetes object. It allows autoscaling based on information coming from components running outside of cluster (for example length of queue in cloud messaging service, or QPS from loadbalancer running outside of cluster).", } @@ -227,7 +227,7 @@ var map_MetricValueStatus = map[string]string{ "": "MetricValueStatus holds the current value for a metric", "value": "value is the current value of the metric (as a quantity).", "averageValue": "averageValue is the current value of the average of the metric across all relevant pods (as a quantity)", - "averageUtilization": "currentAverageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.", + "averageUtilization": "averageUtilization is the current value of the average of the resource metric across all relevant pods, represented as a percentage of the requested value of the resource for the pods.", } func (MetricValueStatus) SwaggerDoc() map[string]string { @@ -286,7 +286,7 @@ func (ResourceMetricSource) SwaggerDoc() map[string]string { var map_ResourceMetricStatus = map[string]string{ "": "ResourceMetricStatus indicates the current value of a resource metric known to Kubernetes, as specified in requests and limits, describing each pod in the current scale target (e.g. CPU or memory). Such metrics are built in to Kubernetes, and have special scaling options on top of those available to normal per-pod metrics using the \"pods\" source.", - "name": "Name is the name of the resource in question.", + "name": "name is the name of the resource in question.", "current": "current contains the current value for the given metric", } diff --git a/vendor/k8s.io/api/batch/v1/generated.proto b/vendor/k8s.io/api/batch/v1/generated.proto index 74ccac921..df4381c73 100644 --- a/vendor/k8s.io/api/batch/v1/generated.proto +++ b/vendor/k8s.io/api/batch/v1/generated.proto @@ -72,7 +72,6 @@ message CronJobSpec { // configuration, the controller will stop creating new new Jobs and will create a system event with the // reason UnknownTimeZone. // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones - // This is beta field and must be enabled via the `CronJobTimeZone` feature gate. // +optional optional string timeZone = 8; @@ -83,6 +82,7 @@ message CronJobSpec { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one @@ -189,7 +189,7 @@ message JobSpec { optional int32 parallelism = 1; // Specifies the desired number of successfully finished pods the - // job should be run with. Setting to nil means that the success of any + // 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. @@ -213,8 +213,8 @@ message JobSpec { // checked against the backoffLimit. This field cannot be used in combination // with restartPolicy=OnFailure. // - // This field is alpha-level. To use this field, you must enable the - // `JobPodFailurePolicy` feature gate (disabled by default). + // This field is beta-level. It can be used when the `JobPodFailurePolicy` + // feature gate is enabled (enabled by default). // +optional optional PodFailurePolicy podFailurePolicy = 11; @@ -243,6 +243,7 @@ message JobSpec { optional bool manualSelector = 5; // 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/ optional k8s.io.api.core.v1.PodTemplateSpec template = 6; @@ -256,7 +257,7 @@ message JobSpec { // +optional optional int32 ttlSecondsAfterFinished = 8; - // CompletionMode specifies how Pod completions are tracked. It can be + // completionMode specifies how Pod completions are tracked. It can be // `NonIndexed` (default) or `Indexed`. // // `NonIndexed` means that the Job is considered complete when there have @@ -281,7 +282,7 @@ message JobSpec { // +optional optional string completionMode = 9; - // Suspend specifies whether the Job controller should create Pods or not. If + // suspend specifies whether the Job controller should create Pods or not. If // a Job is created with suspend set to true, no Pods are created by the Job // controller. If a Job is suspended after creation (i.e. the flag goes from // false to true), the Job controller will delete all active Pods associated @@ -334,7 +335,7 @@ message JobStatus { // +optional optional int32 failed = 6; - // CompletedIndexes holds the completed indexes when .spec.completionMode = + // 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 @@ -344,15 +345,16 @@ message JobStatus { // +optional optional string completedIndexes = 7; - // UncountedTerminatedPods holds the UIDs of Pods that have terminated but + // uncountedTerminatedPods holds the UIDs of Pods that have terminated but // the job controller hasn't yet accounted for in the status counters. // // The 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: - // (1) 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 + // + // 1. 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 // counter. // // Old jobs might not be tracked using this field, in which case the field @@ -409,6 +411,7 @@ message PodFailurePolicyOnExitCodesRequirement { // Represents the relationship between the container exit code(s) and the // specified values. Containers completed with success (exit code 0) are // excluded from the requirement check. Possible values are: + // // - In: the requirement is satisfied if at least one container exit code // (might be multiple if there are multiple containers not restricted // by the 'containerName' field) is in the set of specified values. @@ -442,10 +445,11 @@ message PodFailurePolicyOnPodConditionsPattern { } // 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. +// One of onExitCodes and onPodConditions, but not both, can be used in each rule. message PodFailurePolicyRule { // Specifies the action taken on a pod failure when the requirements are satisfied. // Possible values are: + // // - FailJob: indicates that the pod's job is marked as Failed and all // running pods are terminated. // - Ignore: indicates that the counter towards the .backoffLimit is not @@ -470,12 +474,12 @@ message PodFailurePolicyRule { // UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't // been accounted in Job status counters. message UncountedTerminatedPods { - // Succeeded holds UIDs of succeeded Pods. + // succeeded holds UIDs of succeeded Pods. // +listType=set // +optional repeated string succeeded = 1; - // Failed holds UIDs of failed Pods. + // failed holds UIDs of failed Pods. // +listType=set // +optional repeated string failed = 2; diff --git a/vendor/k8s.io/api/batch/v1/types.go b/vendor/k8s.io/api/batch/v1/types.go index dcb15728f..22cf9ee9c 100644 --- a/vendor/k8s.io/api/batch/v1/types.go +++ b/vendor/k8s.io/api/batch/v1/types.go @@ -23,8 +23,11 @@ import ( ) const ( - JobCompletionIndexAnnotation = "batch.kubernetes.io/job-completion-index" + // All Kubernetes labels need to be prefixed with Kubernetes to distinguish them from end-user labels + // More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#label-selector-and-annotation-conventions + labelPrefix = "batch.kubernetes.io/" + JobCompletionIndexAnnotation = labelPrefix + "job-completion-index" // JobTrackingFinalizer is a finalizer for Job's pods. It prevents them from // being deleted before being accounted in the Job status. // @@ -34,7 +37,14 @@ const ( // 1.27+, one release after JobTrackingWithFinalizers graduates to GA, the // apiserver and job controller will ignore this annotation and they will // always track jobs using finalizers. - JobTrackingFinalizer = "batch.kubernetes.io/job-tracking" + JobTrackingFinalizer = labelPrefix + "job-tracking" + // The Job labels will use batch.kubernetes.io as a prefix for all labels + // Historically the job controller uses unprefixed labels for job-name and controller-uid and + // Kubernetes continutes to recognize those unprefixed labels for consistency. + JobNameLabel = labelPrefix + "job-name" + // ControllerUid is used to programatically get pods corresponding to a Job. + // There is a corresponding label without the batch.kubernetes.io that we support for legacy reasons. + ControllerUidLabel = labelPrefix + "controller-uid" ) // +genclient @@ -135,6 +145,7 @@ type PodFailurePolicyOnExitCodesRequirement struct { // Represents the relationship between the container exit code(s) and the // specified values. Containers completed with success (exit code 0) are // excluded from the requirement check. Possible values are: + // // - In: the requirement is satisfied if at least one container exit code // (might be multiple if there are multiple containers not restricted // by the 'containerName' field) is in the set of specified values. @@ -168,10 +179,11 @@ type PodFailurePolicyOnPodConditionsPattern struct { } // 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. +// One of onExitCodes and onPodConditions, but not both, can be used in each rule. type PodFailurePolicyRule struct { // Specifies the action taken on a pod failure when the requirements are satisfied. // Possible values are: + // // - FailJob: indicates that the pod's job is marked as Failed and all // running pods are terminated. // - Ignore: indicates that the counter towards the .backoffLimit is not @@ -216,7 +228,7 @@ type JobSpec struct { Parallelism *int32 `json:"parallelism,omitempty" protobuf:"varint,1,opt,name=parallelism"` // Specifies the desired number of successfully finished pods the - // job should be run with. Setting to nil means that the success of any + // 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. @@ -240,8 +252,8 @@ type JobSpec struct { // checked against the backoffLimit. This field cannot be used in combination // with restartPolicy=OnFailure. // - // This field is alpha-level. To use this field, you must enable the - // `JobPodFailurePolicy` feature gate (disabled by default). + // This field is beta-level. It can be used when the `JobPodFailurePolicy` + // feature gate is enabled (enabled by default). // +optional PodFailurePolicy *PodFailurePolicy `json:"podFailurePolicy,omitempty" protobuf:"bytes,11,opt,name=podFailurePolicy"` @@ -275,6 +287,7 @@ type JobSpec struct { ManualSelector *bool `json:"manualSelector,omitempty" protobuf:"varint,5,opt,name=manualSelector"` // 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/ Template corev1.PodTemplateSpec `json:"template" protobuf:"bytes,6,opt,name=template"` @@ -288,7 +301,7 @@ type JobSpec struct { // +optional TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty" protobuf:"varint,8,opt,name=ttlSecondsAfterFinished"` - // CompletionMode specifies how Pod completions are tracked. It can be + // completionMode specifies how Pod completions are tracked. It can be // `NonIndexed` (default) or `Indexed`. // // `NonIndexed` means that the Job is considered complete when there have @@ -313,7 +326,7 @@ type JobSpec struct { // +optional CompletionMode *CompletionMode `json:"completionMode,omitempty" protobuf:"bytes,9,opt,name=completionMode,casttype=CompletionMode"` - // Suspend specifies whether the Job controller should create Pods or not. If + // suspend specifies whether the Job controller should create Pods or not. If // a Job is created with suspend set to true, no Pods are created by the Job // controller. If a Job is suspended after creation (i.e. the flag goes from // false to true), the Job controller will delete all active Pods associated @@ -366,7 +379,7 @@ type JobStatus struct { // +optional Failed int32 `json:"failed,omitempty" protobuf:"varint,6,opt,name=failed"` - // CompletedIndexes holds the completed indexes when .spec.completionMode = + // 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 @@ -376,15 +389,16 @@ type JobStatus struct { // +optional CompletedIndexes string `json:"completedIndexes,omitempty" protobuf:"bytes,7,opt,name=completedIndexes"` - // UncountedTerminatedPods holds the UIDs of Pods that have terminated but + // uncountedTerminatedPods holds the UIDs of Pods that have terminated but // the job controller hasn't yet accounted for in the status counters. // // The 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: - // (1) 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 + // + // 1. 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 // counter. // // Old jobs might not be tracked using this field, in which case the field @@ -403,12 +417,12 @@ type JobStatus struct { // UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't // been accounted in Job status counters. type UncountedTerminatedPods struct { - // Succeeded holds UIDs of succeeded Pods. + // succeeded holds UIDs of succeeded Pods. // +listType=set // +optional Succeeded []types.UID `json:"succeeded,omitempty" protobuf:"bytes,1,rep,name=succeeded,casttype=k8s.io/apimachinery/pkg/types.UID"` - // Failed holds UIDs of failed Pods. + // failed holds UIDs of failed Pods. // +listType=set // +optional Failed []types.UID `json:"failed,omitempty" protobuf:"bytes,2,rep,name=failed,casttype=k8s.io/apimachinery/pkg/types.UID"` @@ -513,7 +527,6 @@ type CronJobSpec struct { // configuration, the controller will stop creating new new Jobs and will create a system event with the // reason UnknownTimeZone. // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones - // This is beta field and must be enabled via the `CronJobTimeZone` feature gate. // +optional TimeZone *string `json:"timeZone,omitempty" protobuf:"bytes,8,opt,name=timeZone"` @@ -524,6 +537,7 @@ type CronJobSpec struct { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one diff --git a/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go index 89470dcc6..f6f3141f1 100644 --- a/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CronJob = map[string]string{ @@ -51,9 +51,9 @@ func (CronJobList) SwaggerDoc() map[string]string { var map_CronJobSpec = map[string]string{ "": "CronJobSpec describes how the job execution will look like and when it will actually run.", "schedule": "The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.", - "timeZone": "The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will default to the time zone of the kube-controller-manager process. The set of valid time zone names and the time zone offset is loaded from the system-wide time zone database by the API server during CronJob validation and the controller manager during execution. If no system-wide time zone database can be found a bundled version of the database is used instead. If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host configuration, the controller will stop creating new new Jobs and will create a system event with the reason UnknownTimeZone. More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones This is beta field and must be enabled via the `CronJobTimeZone` feature gate.", + "timeZone": "The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will default to the time zone of the kube-controller-manager process. The set of valid time zone names and the time zone offset is loaded from the system-wide time zone database by the API server during CronJob validation and the controller manager during execution. If no system-wide time zone database can be found a bundled version of the database is used instead. If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host configuration, the controller will stop creating new new Jobs and will create a system event with the reason UnknownTimeZone. More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones", "startingDeadlineSeconds": "Optional deadline in seconds for starting the job if it misses scheduled time for any reason. Missed jobs executions will be counted as failed ones.", - "concurrencyPolicy": "Specifies how to treat concurrent executions of a Job. Valid values are: - \"Allow\" (default): allows CronJobs to run concurrently; - \"Forbid\": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - \"Replace\": cancels currently running job and replaces it with a new one", + "concurrencyPolicy": "Specifies how to treat concurrent executions of a Job. Valid values are:\n\n- \"Allow\" (default): allows CronJobs to run concurrently; - \"Forbid\": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - \"Replace\": cancels currently running job and replaces it with a new one", "suspend": "This flag tells the controller to suspend subsequent executions, it does not apply to already started executions. Defaults to false.", "jobTemplate": "Specifies the job that will be created when executing a CronJob.", "successfulJobsHistoryLimit": "The number of successful finished jobs to retain. Value must be non-negative integer. Defaults to 3.", @@ -113,16 +113,16 @@ func (JobList) SwaggerDoc() map[string]string { var map_JobSpec = map[string]string{ "": "JobSpec describes how the job execution will look like.", "parallelism": "Specifies the maximum desired number of pods the job should run at any given time. The actual number of pods running in steady state will be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism), i.e. when the work left to do is less than max parallelism. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", - "completions": "Specifies the desired number of successfully finished pods the job should be run with. Setting to nil 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/", + "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.\n\nThis field is alpha-level. To use this field, you must enable the `JobPodFailurePolicy` feature gate (disabled by default).", + "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.\n\nThis field is beta-level. It can be used when the `JobPodFailurePolicy` feature gate is enabled (enabled by default).", "backoffLimit": "Specifies the number of retries before marking this job failed. Defaults to 6", "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. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", + "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/", "ttlSecondsAfterFinished": "ttlSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed). If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes.", - "completionMode": "CompletionMode specifies how Pod completions are tracked. It can be `NonIndexed` (default) or `Indexed`.\n\n`NonIndexed` means that the Job is considered complete when there have been .spec.completions successfully completed Pods. Each Pod completion is homologous to each other.\n\n`Indexed` means that the Pods of a Job get an associated completion index from 0 to (.spec.completions - 1), available in the annotation batch.kubernetes.io/job-completion-index. The Job is considered complete when there is one successfully completed Pod for each index. When value is `Indexed`, .spec.completions must be specified and `.spec.parallelism` must be less than or equal to 10^5. In addition, The Pod name takes the form `$(job-name)-$(index)-$(random-string)`, the Pod hostname takes the form `$(job-name)-$(index)`.\n\nMore completion modes can be added in the future. If the Job controller observes a mode that it doesn't recognize, which is possible during upgrades due to version skew, the controller skips updates for the Job.", - "suspend": "Suspend specifies whether the Job controller should create Pods or not. If a Job is created with suspend set to true, no Pods are created by the Job controller. If a Job is suspended after creation (i.e. the flag goes from false to true), the Job controller will delete all active Pods associated with this Job. Users must design their workload to gracefully handle this. Suspending a Job will reset the StartTime field of the Job, effectively resetting the ActiveDeadlineSeconds timer too. Defaults to false.", + "completionMode": "completionMode specifies how Pod completions are tracked. It can be `NonIndexed` (default) or `Indexed`.\n\n`NonIndexed` means that the Job is considered complete when there have been .spec.completions successfully completed Pods. Each Pod completion is homologous to each other.\n\n`Indexed` means that the Pods of a Job get an associated completion index from 0 to (.spec.completions - 1), available in the annotation batch.kubernetes.io/job-completion-index. The Job is considered complete when there is one successfully completed Pod for each index. When value is `Indexed`, .spec.completions must be specified and `.spec.parallelism` must be less than or equal to 10^5. In addition, The Pod name takes the form `$(job-name)-$(index)-$(random-string)`, the Pod hostname takes the form `$(job-name)-$(index)`.\n\nMore completion modes can be added in the future. If the Job controller observes a mode that it doesn't recognize, which is possible during upgrades due to version skew, the controller skips updates for the Job.", + "suspend": "suspend specifies whether the Job controller should create Pods or not. If a Job is created with suspend set to true, no Pods are created by the Job controller. If a Job is suspended after creation (i.e. the flag goes from false to true), the Job controller will delete all active Pods associated with this Job. Users must design their workload to gracefully handle this. Suspending a Job will reset the StartTime field of the Job, effectively resetting the ActiveDeadlineSeconds timer too. Defaults to false.", } func (JobSpec) SwaggerDoc() map[string]string { @@ -137,8 +137,8 @@ var map_JobStatus = map[string]string{ "active": "The number of pending and running pods.", "succeeded": "The number of pods which reached phase Succeeded.", "failed": "The number of pods which reached phase Failed.", - "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\".", - "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: (1) 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.", + "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\".", + "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.", "ready": "The number of pods which have a Ready condition.\n\nThis field is beta-level. The job controller populates the field when the feature gate JobReadyPods is enabled (enabled by default).", } @@ -168,7 +168,7 @@ func (PodFailurePolicy) SwaggerDoc() map[string]string { var map_PodFailurePolicyOnExitCodesRequirement = map[string]string{ "": "PodFailurePolicyOnExitCodesRequirement describes the requirement for handling a failed pod based on its container exit codes. In particular, it lookups the .state.terminated.exitCode for each app container and init container status, represented by the .status.containerStatuses and .status.initContainerStatuses fields in the Pod status, respectively. Containers completed with success (exit code 0) are excluded from the requirement check.", "containerName": "Restricts the check for exit codes to the container with the specified name. When null, the rule applies to all containers. When specified, it should match one the container or initContainer names in the pod template.", - "operator": "Represents the relationship between the container exit code(s) and the specified values. Containers completed with success (exit code 0) are excluded from the requirement check. Possible values are: - In: the requirement is satisfied if at least one container exit code\n (might be multiple if there are multiple containers not restricted\n by the 'containerName' field) is in the set of specified values.\n- NotIn: the requirement is satisfied if at least one container exit code\n (might be multiple if there are multiple containers not restricted\n by the 'containerName' field) is not in the set of specified values.\nAdditional values are considered to be added in the future. Clients should react to an unknown operator by assuming the requirement is not satisfied.", + "operator": "Represents the relationship between the container exit code(s) and the specified values. Containers completed with success (exit code 0) are excluded from the requirement check. Possible values are:\n\n- In: the requirement is satisfied if at least one container exit code\n (might be multiple if there are multiple containers not restricted\n by the 'containerName' field) is in the set of specified values.\n- NotIn: the requirement is satisfied if at least one container exit code\n (might be multiple if there are multiple containers not restricted\n by the 'containerName' field) is not in the set of specified values.\nAdditional values are considered to be added in the future. Clients should react to an unknown operator by assuming the requirement is not satisfied.", "values": "Specifies the set of values. Each returned container exit code (might be multiple in case of multiple containers) is checked against this set of values with respect to the operator. The list of values must be ordered and must not contain duplicates. Value '0' cannot be used for the In operator. At least one element is required. At most 255 elements are allowed.", } @@ -187,8 +187,8 @@ 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: - FailJob: indicates that the pod's job is marked as Failed and all\n running pods are terminated.\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.", + "": "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- 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.", } @@ -199,8 +199,8 @@ func (PodFailurePolicyRule) SwaggerDoc() map[string]string { var map_UncountedTerminatedPods = map[string]string{ "": "UncountedTerminatedPods holds UIDs of Pods that have terminated but haven't been accounted in Job status counters.", - "succeeded": "Succeeded holds UIDs of succeeded Pods.", - "failed": "Failed holds UIDs of failed Pods.", + "succeeded": "succeeded holds UIDs of succeeded Pods.", + "failed": "failed holds UIDs of failed Pods.", } func (UncountedTerminatedPods) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/batch/v1beta1/generated.pb.go b/vendor/k8s.io/api/batch/v1beta1/generated.pb.go index d042fc695..03feb2cea 100644 --- a/vendor/k8s.io/api/batch/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/batch/v1beta1/generated.pb.go @@ -157,38 +157,10 @@ func (m *CronJobStatus) XXX_DiscardUnknown() { var xxx_messageInfo_CronJobStatus proto.InternalMessageInfo -func (m *JobTemplate) Reset() { *m = JobTemplate{} } -func (*JobTemplate) ProtoMessage() {} -func (*JobTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_e57b277b05179ae7, []int{4} -} -func (m *JobTemplate) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *JobTemplate) 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 *JobTemplate) XXX_Merge(src proto.Message) { - xxx_messageInfo_JobTemplate.Merge(m, src) -} -func (m *JobTemplate) XXX_Size() int { - return m.Size() -} -func (m *JobTemplate) XXX_DiscardUnknown() { - xxx_messageInfo_JobTemplate.DiscardUnknown(m) -} - -var xxx_messageInfo_JobTemplate proto.InternalMessageInfo - func (m *JobTemplateSpec) Reset() { *m = JobTemplateSpec{} } func (*JobTemplateSpec) ProtoMessage() {} func (*JobTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_e57b277b05179ae7, []int{5} + return fileDescriptor_e57b277b05179ae7, []int{4} } func (m *JobTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -218,7 +190,6 @@ func init() { proto.RegisterType((*CronJobList)(nil), "k8s.io.api.batch.v1beta1.CronJobList") proto.RegisterType((*CronJobSpec)(nil), "k8s.io.api.batch.v1beta1.CronJobSpec") proto.RegisterType((*CronJobStatus)(nil), "k8s.io.api.batch.v1beta1.CronJobStatus") - proto.RegisterType((*JobTemplate)(nil), "k8s.io.api.batch.v1beta1.JobTemplate") proto.RegisterType((*JobTemplateSpec)(nil), "k8s.io.api.batch.v1beta1.JobTemplateSpec") } @@ -227,58 +198,57 @@ func init() { } var fileDescriptor_e57b277b05179ae7 = []byte{ - // 814 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0x41, 0x6f, 0x1b, 0x45, - 0x14, 0xc7, 0xbd, 0x4e, 0x9c, 0xb8, 0xe3, 0x16, 0xd2, 0x01, 0xa5, 0x2b, 0x83, 0xd6, 0xc1, 0x55, - 0x85, 0x41, 0x30, 0x4b, 0x22, 0x84, 0x38, 0x55, 0xea, 0x16, 0x15, 0x08, 0x41, 0x45, 0xe3, 0x22, - 0xa4, 0xaa, 0x42, 0x9d, 0x1d, 0xbf, 0x38, 0xd3, 0x78, 0x77, 0x56, 0x3b, 0xb3, 0x91, 0x72, 0xe3, - 0xc2, 0x9d, 0xef, 0xc2, 0x9d, 0x73, 0x8e, 0xbd, 0xd1, 0xd3, 0x8a, 0x2c, 0xdf, 0x82, 0x13, 0x9a, - 0xf1, 0x7a, 0xed, 0xda, 0xeb, 0xa6, 0xbd, 0xf4, 0xe6, 0x79, 0xf3, 0xff, 0xff, 0xe6, 0xed, 0x7b, - 0x6f, 0x67, 0x8d, 0xee, 0x9d, 0x7e, 0xad, 0x88, 0x90, 0xfe, 0x69, 0x16, 0x42, 0x1a, 0x83, 0x06, - 0xe5, 0x9f, 0x41, 0x3c, 0x92, 0xa9, 0x5f, 0x6e, 0xb0, 0x44, 0xf8, 0x21, 0xd3, 0xfc, 0xc4, 0x3f, - 0xdb, 0x0f, 0x41, 0xb3, 0x7d, 0x7f, 0x0c, 0x31, 0xa4, 0x4c, 0xc3, 0x88, 0x24, 0xa9, 0xd4, 0x12, - 0xbb, 0x53, 0x25, 0x61, 0x89, 0x20, 0x56, 0x49, 0x4a, 0x65, 0xf7, 0xf3, 0xb1, 0xd0, 0x27, 0x59, - 0x48, 0xb8, 0x8c, 0xfc, 0xb1, 0x1c, 0x4b, 0xdf, 0x1a, 0xc2, 0xec, 0xd8, 0xae, 0xec, 0xc2, 0xfe, - 0x9a, 0x82, 0xba, 0xb7, 0x6b, 0x8e, 0x5c, 0x3e, 0xad, 0xdb, 0x5f, 0x10, 0x71, 0x99, 0x42, 0x9d, - 0xe6, 0xcb, 0xb9, 0x26, 0x62, 0xfc, 0x44, 0xc4, 0x90, 0x9e, 0xfb, 0xc9, 0xe9, 0xd8, 0x04, 0x94, - 0x1f, 0x81, 0x66, 0x75, 0x2e, 0x7f, 0x9d, 0x2b, 0xcd, 0x62, 0x2d, 0x22, 0x58, 0x31, 0x7c, 0x75, - 0x95, 0x41, 0xf1, 0x13, 0x88, 0xd8, 0xb2, 0xaf, 0xff, 0x7b, 0x13, 0x6d, 0xdf, 0x4f, 0x65, 0x7c, - 0x28, 0x43, 0xfc, 0x14, 0xb5, 0x4d, 0x3e, 0x23, 0xa6, 0x99, 0xeb, 0xec, 0x39, 0x83, 0xce, 0xc1, - 0x17, 0x64, 0x5e, 0xcf, 0x0a, 0x4b, 0x92, 0xd3, 0xb1, 0x09, 0x28, 0x62, 0xd4, 0xe4, 0x6c, 0x9f, - 0x3c, 0x0c, 0x9f, 0x01, 0xd7, 0x3f, 0x82, 0x66, 0x01, 0xbe, 0xc8, 0x7b, 0x8d, 0x22, 0xef, 0xa1, - 0x79, 0x8c, 0x56, 0x54, 0xfc, 0x2d, 0xda, 0x54, 0x09, 0x70, 0xb7, 0x69, 0xe9, 0x77, 0xc8, 0xba, - 0x6e, 0x91, 0x32, 0xa5, 0x61, 0x02, 0x3c, 0xb8, 0x5e, 0x22, 0x37, 0xcd, 0x8a, 0x5a, 0x00, 0x7e, - 0x88, 0xb6, 0x94, 0x66, 0x3a, 0x53, 0xee, 0x86, 0x45, 0x7d, 0x7c, 0x35, 0xca, 0xca, 0x83, 0x77, - 0x4a, 0xd8, 0xd6, 0x74, 0x4d, 0x4b, 0x4c, 0xff, 0x4f, 0x07, 0x75, 0x4a, 0xe5, 0x91, 0x50, 0x1a, - 0x3f, 0x59, 0xa9, 0x05, 0x79, 0xbd, 0x5a, 0x18, 0xb7, 0xad, 0xc4, 0x4e, 0x79, 0x52, 0x7b, 0x16, - 0x59, 0xa8, 0xc3, 0x03, 0xd4, 0x12, 0x1a, 0x22, 0xe5, 0x36, 0xf7, 0x36, 0x06, 0x9d, 0x83, 0x8f, - 0xae, 0xcc, 0x3e, 0xb8, 0x51, 0xd2, 0x5a, 0xdf, 0x1b, 0x1f, 0x9d, 0xda, 0xfb, 0x7f, 0x6f, 0x56, - 0x59, 0x9b, 0xe2, 0xe0, 0xcf, 0x50, 0xdb, 0xf4, 0x79, 0x94, 0x4d, 0xc0, 0x66, 0x7d, 0x6d, 0x9e, - 0xc5, 0xb0, 0x8c, 0xd3, 0x4a, 0x81, 0x07, 0xa8, 0x6d, 0x46, 0xe3, 0xb1, 0x8c, 0xc1, 0x6d, 0x5b, - 0xf5, 0x75, 0xa3, 0x7c, 0x54, 0xc6, 0x68, 0xb5, 0x8b, 0x7f, 0x46, 0xb7, 0x94, 0x66, 0xa9, 0x16, - 0xf1, 0xf8, 0x1b, 0x60, 0xa3, 0x89, 0x88, 0x61, 0x08, 0x5c, 0xc6, 0x23, 0x65, 0x5b, 0xb9, 0x11, - 0x7c, 0x50, 0xe4, 0xbd, 0x5b, 0xc3, 0x7a, 0x09, 0x5d, 0xe7, 0xc5, 0x4f, 0xd0, 0x4d, 0x2e, 0x63, - 0x9e, 0xa5, 0x29, 0xc4, 0xfc, 0xfc, 0x27, 0x39, 0x11, 0xfc, 0xdc, 0x36, 0xf4, 0x5a, 0x40, 0xca, - 0xbc, 0x6f, 0xde, 0x5f, 0x16, 0xfc, 0x57, 0x17, 0xa4, 0xab, 0x20, 0x7c, 0x07, 0x6d, 0xab, 0x4c, - 0x25, 0x10, 0x8f, 0xdc, 0xcd, 0x3d, 0x67, 0xd0, 0x0e, 0x3a, 0x45, 0xde, 0xdb, 0x1e, 0x4e, 0x43, - 0x74, 0xb6, 0x87, 0x9f, 0xa2, 0xce, 0x33, 0x19, 0x3e, 0x82, 0x28, 0x99, 0x30, 0x0d, 0x6e, 0xcb, - 0x36, 0xfb, 0x93, 0xf5, 0x1d, 0x39, 0x9c, 0x8b, 0xed, 0x78, 0xbe, 0x57, 0x66, 0xda, 0x59, 0xd8, - 0xa0, 0x8b, 0x48, 0xfc, 0x2b, 0xea, 0xaa, 0x8c, 0x73, 0x50, 0xea, 0x38, 0x9b, 0x1c, 0xca, 0x50, - 0x7d, 0x27, 0x94, 0x96, 0xe9, 0xf9, 0x91, 0x88, 0x84, 0x76, 0xb7, 0xf6, 0x9c, 0x41, 0x2b, 0xf0, - 0x8a, 0xbc, 0xd7, 0x1d, 0xae, 0x55, 0xd1, 0x57, 0x10, 0x30, 0x45, 0xbb, 0xc7, 0x4c, 0x4c, 0x60, - 0xb4, 0xc2, 0xde, 0xb6, 0xec, 0x6e, 0x91, 0xf7, 0x76, 0x1f, 0xd4, 0x2a, 0xe8, 0x1a, 0x67, 0xff, - 0xaf, 0x26, 0xba, 0xf1, 0xd2, 0x9b, 0x83, 0x7f, 0x40, 0x5b, 0x8c, 0x6b, 0x71, 0x66, 0x26, 0xcb, - 0x0c, 0xed, 0xed, 0xc5, 0x12, 0x99, 0xdb, 0x6f, 0x7e, 0x13, 0x50, 0x38, 0x06, 0xd3, 0x09, 0x98, - 0xbf, 0x6e, 0xf7, 0xac, 0x95, 0x96, 0x08, 0x3c, 0x41, 0x3b, 0x13, 0xa6, 0xf4, 0x6c, 0x28, 0xcd, - 0xc8, 0xd9, 0x26, 0x75, 0x0e, 0x3e, 0x7d, 0xbd, 0xd7, 0xcc, 0x38, 0x82, 0xf7, 0x8b, 0xbc, 0xb7, - 0x73, 0xb4, 0xc4, 0xa1, 0x2b, 0x64, 0x9c, 0x22, 0x6c, 0x63, 0x55, 0x09, 0xed, 0x79, 0xad, 0x37, - 0x3e, 0x6f, 0xb7, 0xc8, 0x7b, 0xf8, 0x68, 0x85, 0x44, 0x6b, 0xe8, 0xfd, 0x0b, 0x07, 0x2d, 0x4e, - 0xc4, 0x5b, 0xb8, 0x5c, 0x7f, 0x41, 0x6d, 0x3d, 0x9b, 0xe2, 0xe6, 0x9b, 0x4e, 0x71, 0x75, 0x4f, - 0x54, 0x23, 0x5c, 0xc1, 0xcc, 0xdd, 0xf8, 0xee, 0x92, 0xfe, 0x2d, 0x3c, 0xce, 0xdd, 0x97, 0xbe, - 0x15, 0x1f, 0xd6, 0x3d, 0x0a, 0x79, 0xc5, 0x27, 0x22, 0xb8, 0x7b, 0x71, 0xe9, 0x35, 0x9e, 0x5f, - 0x7a, 0x8d, 0x17, 0x97, 0x5e, 0xe3, 0xb7, 0xc2, 0x73, 0x2e, 0x0a, 0xcf, 0x79, 0x5e, 0x78, 0xce, - 0x8b, 0xc2, 0x73, 0xfe, 0x29, 0x3c, 0xe7, 0x8f, 0x7f, 0xbd, 0xc6, 0x63, 0x77, 0xdd, 0x5f, 0x8b, - 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xd7, 0xf2, 0x8b, 0xe9, 0x8e, 0x08, 0x00, 0x00, + // 787 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0x41, 0x6f, 0x1b, 0x45, + 0x14, 0xc7, 0xbd, 0x49, 0x9c, 0xb8, 0xe3, 0x16, 0xd2, 0x01, 0xa5, 0x2b, 0x83, 0xd6, 0xc1, 0x55, + 0x85, 0x41, 0x30, 0x4b, 0x22, 0x84, 0x38, 0x55, 0xea, 0x16, 0x15, 0x08, 0x41, 0x45, 0xe3, 0x72, + 0xa9, 0x2a, 0xd4, 0xd9, 0xd9, 0x17, 0x67, 0x9a, 0xdd, 0x9d, 0xd5, 0xce, 0x6c, 0xa4, 0xdc, 0xb8, + 0x70, 0xe7, 0xbb, 0x70, 0xe7, 0x9c, 0x63, 0x6f, 0xf4, 0xb4, 0x22, 0xcb, 0xb7, 0xe0, 0x84, 0x66, + 0xbc, 0xb1, 0x5d, 0x7b, 0xdd, 0x84, 0x4b, 0x6f, 0x9e, 0x37, 0xff, 0xff, 0x6f, 0x9e, 0xde, 0x7b, + 0xfb, 0x8c, 0x1e, 0x9c, 0x7c, 0xad, 0x88, 0x90, 0xfe, 0x49, 0x11, 0x42, 0x9e, 0x82, 0x06, 0xe5, + 0x9f, 0x42, 0x1a, 0xc9, 0xdc, 0xaf, 0x2f, 0x58, 0x26, 0xfc, 0x90, 0x69, 0x7e, 0xec, 0x9f, 0xee, + 0x85, 0xa0, 0xd9, 0x9e, 0x3f, 0x86, 0x14, 0x72, 0xa6, 0x21, 0x22, 0x59, 0x2e, 0xb5, 0xc4, 0xee, + 0x44, 0x49, 0x58, 0x26, 0x88, 0x55, 0x92, 0x5a, 0xd9, 0xfb, 0x7c, 0x2c, 0xf4, 0x71, 0x11, 0x12, + 0x2e, 0x13, 0x7f, 0x2c, 0xc7, 0xd2, 0xb7, 0x86, 0xb0, 0x38, 0xb2, 0x27, 0x7b, 0xb0, 0xbf, 0x26, + 0xa0, 0xde, 0xdd, 0x86, 0x27, 0x17, 0x5f, 0xeb, 0x0d, 0xe6, 0x44, 0x5c, 0xe6, 0xd0, 0xa4, 0xf9, + 0x72, 0xa6, 0x49, 0x18, 0x3f, 0x16, 0x29, 0xe4, 0x67, 0x7e, 0x76, 0x32, 0x36, 0x01, 0xe5, 0x27, + 0xa0, 0x59, 0x93, 0xcb, 0x5f, 0xe5, 0xca, 0x8b, 0x54, 0x8b, 0x04, 0x96, 0x0c, 0x5f, 0x5d, 0x65, + 0x50, 0xfc, 0x18, 0x12, 0xb6, 0xe8, 0x1b, 0xfc, 0xb6, 0x86, 0xb6, 0x1e, 0xe6, 0x32, 0x3d, 0x90, + 0x21, 0x7e, 0x8e, 0x3a, 0x26, 0x9f, 0x88, 0x69, 0xe6, 0x3a, 0xbb, 0xce, 0xb0, 0xbb, 0xff, 0x05, + 0x99, 0xd5, 0x73, 0x8a, 0x25, 0xd9, 0xc9, 0xd8, 0x04, 0x14, 0x31, 0x6a, 0x72, 0xba, 0x47, 0x1e, + 0x87, 0x2f, 0x80, 0xeb, 0x1f, 0x41, 0xb3, 0x00, 0x9f, 0x97, 0xfd, 0x56, 0x55, 0xf6, 0xd1, 0x2c, + 0x46, 0xa7, 0x54, 0xfc, 0x2d, 0xda, 0x50, 0x19, 0x70, 0x77, 0xcd, 0xd2, 0xef, 0x91, 0x55, 0xdd, + 0x22, 0x75, 0x4a, 0xa3, 0x0c, 0x78, 0x70, 0xb3, 0x46, 0x6e, 0x98, 0x13, 0xb5, 0x00, 0xfc, 0x18, + 0x6d, 0x2a, 0xcd, 0x74, 0xa1, 0xdc, 0x75, 0x8b, 0xfa, 0xf8, 0x6a, 0x94, 0x95, 0x07, 0xef, 0xd4, + 0xb0, 0xcd, 0xc9, 0x99, 0xd6, 0x98, 0xc1, 0x1f, 0x0e, 0xea, 0xd6, 0xca, 0x43, 0xa1, 0x34, 0x7e, + 0xb6, 0x54, 0x0b, 0x72, 0xbd, 0x5a, 0x18, 0xb7, 0xad, 0xc4, 0x76, 0xfd, 0x52, 0xe7, 0x32, 0x32, + 0x57, 0x87, 0x47, 0xa8, 0x2d, 0x34, 0x24, 0xca, 0x5d, 0xdb, 0x5d, 0x1f, 0x76, 0xf7, 0x3f, 0xba, + 0x32, 0xfb, 0xe0, 0x56, 0x4d, 0x6b, 0x7f, 0x6f, 0x7c, 0x74, 0x62, 0x1f, 0xfc, 0xb5, 0x31, 0xcd, + 0xda, 0x14, 0x07, 0x7f, 0x86, 0x3a, 0xa6, 0xcf, 0x51, 0x11, 0x83, 0xcd, 0xfa, 0xc6, 0x2c, 0x8b, + 0x51, 0x1d, 0xa7, 0x53, 0x05, 0x1e, 0xa2, 0x8e, 0x19, 0x8d, 0xa7, 0x32, 0x05, 0xb7, 0x63, 0xd5, + 0x37, 0x8d, 0xf2, 0x49, 0x1d, 0xa3, 0xd3, 0x5b, 0xfc, 0x33, 0xba, 0xa3, 0x34, 0xcb, 0xb5, 0x48, + 0xc7, 0xdf, 0x00, 0x8b, 0x62, 0x91, 0xc2, 0x08, 0xb8, 0x4c, 0x23, 0x65, 0x5b, 0xb9, 0x1e, 0x7c, + 0x50, 0x95, 0xfd, 0x3b, 0xa3, 0x66, 0x09, 0x5d, 0xe5, 0xc5, 0xcf, 0xd0, 0x6d, 0x2e, 0x53, 0x5e, + 0xe4, 0x39, 0xa4, 0xfc, 0xec, 0x27, 0x19, 0x0b, 0x7e, 0x66, 0x1b, 0x7a, 0x23, 0x20, 0x75, 0xde, + 0xb7, 0x1f, 0x2e, 0x0a, 0xfe, 0x6d, 0x0a, 0xd2, 0x65, 0x10, 0xbe, 0x87, 0xb6, 0x54, 0xa1, 0x32, + 0x48, 0x23, 0x77, 0x63, 0xd7, 0x19, 0x76, 0x82, 0x6e, 0x55, 0xf6, 0xb7, 0x46, 0x93, 0x10, 0xbd, + 0xbc, 0xc3, 0xcf, 0x51, 0xf7, 0x85, 0x0c, 0x9f, 0x40, 0x92, 0xc5, 0x4c, 0x83, 0xdb, 0xb6, 0xcd, + 0xfe, 0x64, 0x75, 0x47, 0x0e, 0x66, 0x62, 0x3b, 0x9e, 0xef, 0xd5, 0x99, 0x76, 0xe7, 0x2e, 0xe8, + 0x3c, 0x12, 0xff, 0x82, 0x7a, 0xaa, 0xe0, 0x1c, 0x94, 0x3a, 0x2a, 0xe2, 0x03, 0x19, 0xaa, 0xef, + 0x84, 0xd2, 0x32, 0x3f, 0x3b, 0x14, 0x89, 0xd0, 0xee, 0xe6, 0xae, 0x33, 0x6c, 0x07, 0x5e, 0x55, + 0xf6, 0x7b, 0xa3, 0x95, 0x2a, 0xfa, 0x06, 0x02, 0xa6, 0x68, 0xe7, 0x88, 0x89, 0x18, 0xa2, 0x25, + 0xf6, 0x96, 0x65, 0xf7, 0xaa, 0xb2, 0xbf, 0xf3, 0xa8, 0x51, 0x41, 0x57, 0x38, 0x07, 0x7f, 0xae, + 0xa1, 0x5b, 0xaf, 0x7d, 0x39, 0xf8, 0x07, 0xb4, 0xc9, 0xb8, 0x16, 0xa7, 0x66, 0xb2, 0xcc, 0xd0, + 0xde, 0x9d, 0x2f, 0x91, 0xd9, 0x7e, 0xb3, 0x4d, 0x40, 0xe1, 0x08, 0x4c, 0x27, 0x60, 0xf6, 0xb9, + 0x3d, 0xb0, 0x56, 0x5a, 0x23, 0x70, 0x8c, 0xb6, 0x63, 0xa6, 0xf4, 0xe5, 0x50, 0x9a, 0x91, 0xb3, + 0x4d, 0xea, 0xee, 0x7f, 0x7a, 0xbd, 0xcf, 0xcc, 0x38, 0x82, 0xf7, 0xab, 0xb2, 0xbf, 0x7d, 0xb8, + 0xc0, 0xa1, 0x4b, 0x64, 0x9c, 0x23, 0x6c, 0x63, 0xd3, 0x12, 0xda, 0xf7, 0xda, 0xff, 0xfb, 0xbd, + 0x9d, 0xaa, 0xec, 0xe3, 0xc3, 0x25, 0x12, 0x6d, 0xa0, 0x9b, 0x85, 0xf2, 0xee, 0xc2, 0xa8, 0xbc, + 0x85, 0x05, 0x7b, 0xff, 0xb5, 0x05, 0xfb, 0x61, 0xd3, 0x14, 0x93, 0x37, 0xec, 0xd5, 0xe0, 0xfe, + 0xf9, 0x85, 0xd7, 0x7a, 0x79, 0xe1, 0xb5, 0x5e, 0x5d, 0x78, 0xad, 0x5f, 0x2b, 0xcf, 0x39, 0xaf, + 0x3c, 0xe7, 0x65, 0xe5, 0x39, 0xaf, 0x2a, 0xcf, 0xf9, 0xbb, 0xf2, 0x9c, 0xdf, 0xff, 0xf1, 0x5a, + 0x4f, 0xdd, 0x55, 0xff, 0xc7, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x61, 0x72, 0xc3, 0xe0, 0xc3, + 0x07, 0x00, 0x00, } func (m *CronJob) Marshal() (dAtA []byte, err error) { @@ -517,49 +487,6 @@ func (m *CronJobStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *JobTemplate) 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 *JobTemplate) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *JobTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Template.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 *JobTemplateSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -700,19 +627,6 @@ func (m *CronJobStatus) Size() (n int) { return n } -func (m *JobTemplate) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.ObjectMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.Template.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n -} - func (m *JobTemplateSpec) Size() (n int) { if m == nil { return 0 @@ -794,17 +708,6 @@ func (this *CronJobStatus) String() string { }, "") return s } -func (this *JobTemplate) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&JobTemplate{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Template:` + strings.Replace(strings.Replace(this.Template.String(), "JobTemplateSpec", "JobTemplateSpec", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} func (this *JobTemplateSpec) String() string { if this == nil { return "nil" @@ -1507,122 +1410,6 @@ func (m *CronJobStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *JobTemplate) 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: JobTemplate: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: JobTemplate: 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 Template", 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.Template.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 *JobTemplateSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/batch/v1beta1/generated.proto b/vendor/k8s.io/api/batch/v1beta1/generated.proto index d8386a8f5..ac774f19a 100644 --- a/vendor/k8s.io/api/batch/v1beta1/generated.proto +++ b/vendor/k8s.io/api/batch/v1beta1/generated.proto @@ -73,7 +73,6 @@ message CronJobSpec { // configuration, the controller will stop creating new new Jobs and will create a system event with the // reason UnknownTimeZone. // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones - // This is beta field and must be enabled via the `CronJobTimeZone` feature gate. // +optional optional string timeZone = 8; @@ -84,6 +83,7 @@ message CronJobSpec { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one @@ -127,19 +127,6 @@ message CronJobStatus { optional k8s.io.apimachinery.pkg.apis.meta.v1.Time lastSuccessfulTime = 5; } -// JobTemplate describes a template for creating copies of a predefined pod. -message JobTemplate { - // 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; - - // Defines jobs that will be created from this template. - // https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional - optional JobTemplateSpec template = 2; -} - // JobTemplateSpec describes the data a Job should have when created from a template message JobTemplateSpec { // Standard object's metadata of the jobs created from this template. diff --git a/vendor/k8s.io/api/batch/v1beta1/register.go b/vendor/k8s.io/api/batch/v1beta1/register.go index 226de49f4..9382ca23f 100644 --- a/vendor/k8s.io/api/batch/v1beta1/register.go +++ b/vendor/k8s.io/api/batch/v1beta1/register.go @@ -44,7 +44,6 @@ var ( // Adds the list of known types to the given scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &JobTemplate{}, &CronJob{}, &CronJobList{}, ) diff --git a/vendor/k8s.io/api/batch/v1beta1/types.go b/vendor/k8s.io/api/batch/v1beta1/types.go index 4c0d69dd6..976752a92 100644 --- a/vendor/k8s.io/api/batch/v1beta1/types.go +++ b/vendor/k8s.io/api/batch/v1beta1/types.go @@ -22,24 +22,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.8 -// +k8s:prerelease-lifecycle-gen:deprecated=1.22 - -// JobTemplate describes a template for creating copies of a predefined pod. -type JobTemplate 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"` - - // Defines jobs that will be created from this template. - // https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status - // +optional - Template JobTemplateSpec `json:"template,omitempty" protobuf:"bytes,2,opt,name=template"` -} - // JobTemplateSpec describes the data a Job should have when created from a template type JobTemplateSpec struct { // Standard object's metadata of the jobs created from this template. @@ -113,7 +95,6 @@ type CronJobSpec struct { // configuration, the controller will stop creating new new Jobs and will create a system event with the // reason UnknownTimeZone. // More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones - // This is beta field and must be enabled via the `CronJobTimeZone` feature gate. // +optional TimeZone *string `json:"timeZone,omitempty" protobuf:"bytes,8,opt,name=timeZone"` @@ -124,6 +105,7 @@ type CronJobSpec struct { // Specifies how to treat concurrent executions of a Job. // Valid values are: + // // - "Allow" (default): allows CronJobs to run concurrently; // - "Forbid": forbids concurrent runs, skipping next run if previous run hasn't finished yet; // - "Replace": cancels currently running job and replaces it with a new one diff --git a/vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go index 5716bbb86..3b3eafe8c 100644 --- a/vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/batch/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CronJob = map[string]string{ @@ -51,9 +51,9 @@ func (CronJobList) SwaggerDoc() map[string]string { var map_CronJobSpec = map[string]string{ "": "CronJobSpec describes how the job execution will look like and when it will actually run.", "schedule": "The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.", - "timeZone": "The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will default to the time zone of the kube-controller-manager process. The set of valid time zone names and the time zone offset is loaded from the system-wide time zone database by the API server during CronJob validation and the controller manager during execution. If no system-wide time zone database can be found a bundled version of the database is used instead. If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host configuration, the controller will stop creating new new Jobs and will create a system event with the reason UnknownTimeZone. More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones This is beta field and must be enabled via the `CronJobTimeZone` feature gate.", + "timeZone": "The time zone name for the given schedule, see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones. If not specified, this will default to the time zone of the kube-controller-manager process. The set of valid time zone names and the time zone offset is loaded from the system-wide time zone database by the API server during CronJob validation and the controller manager during execution. If no system-wide time zone database can be found a bundled version of the database is used instead. If the time zone name becomes invalid during the lifetime of a CronJob or due to a change in host configuration, the controller will stop creating new new Jobs and will create a system event with the reason UnknownTimeZone. More information can be found in https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#time-zones", "startingDeadlineSeconds": "Optional deadline in seconds for starting the job if it misses scheduled time for any reason. Missed jobs executions will be counted as failed ones.", - "concurrencyPolicy": "Specifies how to treat concurrent executions of a Job. Valid values are: - \"Allow\" (default): allows CronJobs to run concurrently; - \"Forbid\": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - \"Replace\": cancels currently running job and replaces it with a new one", + "concurrencyPolicy": "Specifies how to treat concurrent executions of a Job. Valid values are:\n\n- \"Allow\" (default): allows CronJobs to run concurrently; - \"Forbid\": forbids concurrent runs, skipping next run if previous run hasn't finished yet; - \"Replace\": cancels currently running job and replaces it with a new one", "suspend": "This flag tells the controller to suspend subsequent executions, it does not apply to already started executions. Defaults to false.", "jobTemplate": "Specifies the job that will be created when executing a CronJob.", "successfulJobsHistoryLimit": "The number of successful finished jobs to retain. This is a pointer to distinguish between explicit zero and not specified. Defaults to 3.", @@ -75,16 +75,6 @@ func (CronJobStatus) SwaggerDoc() map[string]string { return map_CronJobStatus } -var map_JobTemplate = map[string]string{ - "": "JobTemplate describes a template for creating copies of a predefined pod.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "template": "Defines jobs that will be created from this template. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", -} - -func (JobTemplate) SwaggerDoc() map[string]string { - return map_JobTemplate -} - var map_JobTemplateSpec = map[string]string{ "": "JobTemplateSpec describes the data a Job should have when created from a template", "metadata": "Standard object's metadata of the jobs created from this template. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", diff --git a/vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go index c3a3494c4..2c8570332 100644 --- a/vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/batch/v1beta1/zz_generated.deepcopy.go @@ -158,33 +158,6 @@ func (in *CronJobStatus) DeepCopy() *CronJobStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JobTemplate) DeepCopyInto(out *JobTemplate) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Template.DeepCopyInto(&out.Template) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobTemplate. -func (in *JobTemplate) DeepCopy() *JobTemplate { - if in == nil { - return nil - } - out := new(JobTemplate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *JobTemplate) 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 *JobTemplateSpec) DeepCopyInto(out *JobTemplateSpec) { *out = *in diff --git a/vendor/k8s.io/api/batch/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/batch/v1beta1/zz_generated.prerelease-lifecycle.go index 2836b3b01..b57e9f1b8 100644 --- a/vendor/k8s.io/api/batch/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/batch/v1beta1/zz_generated.prerelease-lifecycle.go @@ -72,21 +72,3 @@ func (in *CronJobList) APILifecycleReplacement() schema.GroupVersionKind { func (in *CronJobList) APILifecycleRemoved() (major, minor int) { return 1, 25 } - -// 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 *JobTemplate) APILifecycleIntroduced() (major, minor int) { - return 1, 8 -} - -// 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 *JobTemplate) APILifecycleDeprecated() (major, minor int) { - return 1, 22 -} - -// 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 *JobTemplate) APILifecycleRemoved() (major, minor int) { - return 1, 25 -} diff --git a/vendor/k8s.io/api/certificates/v1/types.go b/vendor/k8s.io/api/certificates/v1/types.go index af5efb516..92b2018e7 100644 --- a/vendor/k8s.io/api/certificates/v1/types.go +++ b/vendor/k8s.io/api/certificates/v1/types.go @@ -274,8 +274,9 @@ type CertificateSigningRequestList struct { } // KeyUsage specifies valid usage contexts for keys. -// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 +// See: // +// https://tools.ietf.org/html/rfc5280#section-4.2.1.3 // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 // // +enum diff --git a/vendor/k8s.io/api/certificates/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/certificates/v1/types_swagger_doc_generated.go index 0dc8a4c69..4bdf39ebb 100644 --- a/vendor/k8s.io/api/certificates/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/certificates/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CertificateSigningRequest = map[string]string{ diff --git a/vendor/k8s.io/api/certificates/v1alpha1/doc.go b/vendor/k8s.io/api/certificates/v1alpha1/doc.go new file mode 100644 index 000000000..d83d0e820 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2022 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:protobuf-gen=package +// +k8s:openapi-gen=true +// +k8s:prerelease-lifecycle-gen=true + +// +groupName=certificates.k8s.io + +package v1alpha1 // import "k8s.io/api/certificates/v1alpha1" diff --git a/vendor/k8s.io/api/certificates/v1alpha1/generated.pb.go b/vendor/k8s.io/api/certificates/v1alpha1/generated.pb.go new file mode 100644 index 000000000..546ecbefb --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/generated.pb.go @@ -0,0 +1,831 @@ +/* +Copyright 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. +*/ + +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: k8s.io/kubernetes/vendor/k8s.io/api/certificates/v1alpha1/generated.proto + +package v1alpha1 + +import ( + fmt "fmt" + + io "io" + + proto "github.com/gogo/protobuf/proto" + + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func (m *ClusterTrustBundle) Reset() { *m = ClusterTrustBundle{} } +func (*ClusterTrustBundle) ProtoMessage() {} +func (*ClusterTrustBundle) Descriptor() ([]byte, []int) { + return fileDescriptor_8915b0d419f9eda6, []int{0} +} +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_8915b0d419f9eda6, []int{1} +} +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_8915b0d419f9eda6, []int{2} +} +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 init() { + proto.RegisterType((*ClusterTrustBundle)(nil), "k8s.io.api.certificates.v1alpha1.ClusterTrustBundle") + proto.RegisterType((*ClusterTrustBundleList)(nil), "k8s.io.api.certificates.v1alpha1.ClusterTrustBundleList") + proto.RegisterType((*ClusterTrustBundleSpec)(nil), "k8s.io.api.certificates.v1alpha1.ClusterTrustBundleSpec") +} + +func init() { + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/certificates/v1alpha1/generated.proto", fileDescriptor_8915b0d419f9eda6) +} + +var fileDescriptor_8915b0d419f9eda6 = []byte{ + // 448 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6b, 0x13, 0x41, + 0x14, 0xc7, 0x77, 0x6a, 0x0b, 0xed, 0x44, 0x41, 0x56, 0x90, 0x90, 0xc3, 0x34, 0xe4, 0xd4, 0x8b, + 0x33, 0x26, 0x54, 0xe9, 0x79, 0x05, 0xa1, 0xe0, 0x0f, 0xd8, 0x7a, 0xb1, 0x78, 0x70, 0x32, 0x79, + 0xdd, 0x8c, 0xc9, 0xee, 0x0e, 0x33, 0xb3, 0x01, 0x6f, 0x82, 0xff, 0x80, 0x7f, 0x56, 0x8e, 0xd5, + 0x53, 0x4f, 0xc5, 0xac, 0xff, 0x88, 0xcc, 0x64, 0x93, 0x5d, 0x5c, 0x25, 0xd2, 0xdb, 0xbe, 0x1f, + 0x9f, 0xef, 0x7b, 0xdf, 0xb7, 0x0c, 0x3e, 0x9f, 0x9d, 0x19, 0x2a, 0x73, 0x36, 0x2b, 0xc6, 0xa0, + 0x33, 0xb0, 0x60, 0xd8, 0x02, 0xb2, 0x49, 0xae, 0x59, 0x55, 0xe0, 0x4a, 0x32, 0x01, 0xda, 0xca, + 0x2b, 0x29, 0xb8, 0x2f, 0x0f, 0xf9, 0x5c, 0x4d, 0xf9, 0x90, 0x25, 0x90, 0x81, 0xe6, 0x16, 0x26, + 0x54, 0xe9, 0xdc, 0xe6, 0x61, 0x7f, 0x4d, 0x50, 0xae, 0x24, 0x6d, 0x12, 0x74, 0x43, 0xf4, 0x9e, + 0x24, 0xd2, 0x4e, 0x8b, 0x31, 0x15, 0x79, 0xca, 0x92, 0x3c, 0xc9, 0x99, 0x07, 0xc7, 0xc5, 0x95, + 0x8f, 0x7c, 0xe0, 0xbf, 0xd6, 0x82, 0xbd, 0xd3, 0x7a, 0x85, 0x94, 0x8b, 0xa9, 0xcc, 0x40, 0x7f, + 0x66, 0x6a, 0x96, 0xb8, 0x84, 0x61, 0x29, 0x58, 0xce, 0x16, 0xad, 0x35, 0x7a, 0xec, 0x5f, 0x94, + 0x2e, 0x32, 0x2b, 0x53, 0x68, 0x01, 0xcf, 0x77, 0x01, 0x46, 0x4c, 0x21, 0xe5, 0x7f, 0x72, 0x83, + 0x1f, 0x08, 0x87, 0x2f, 0xe6, 0x85, 0xb1, 0xa0, 0xdf, 0xe9, 0xc2, 0xd8, 0xa8, 0xc8, 0x26, 0x73, + 0x08, 0x3f, 0xe2, 0x43, 0xb7, 0xda, 0x84, 0x5b, 0xde, 0x45, 0x7d, 0x74, 0xd2, 0x19, 0x3d, 0xa5, + 0xf5, 0x65, 0xb6, 0x13, 0xa8, 0x9a, 0x25, 0x2e, 0x61, 0xa8, 0xeb, 0xa6, 0x8b, 0x21, 0x7d, 0x3b, + 0xfe, 0x04, 0xc2, 0xbe, 0x06, 0xcb, 0xa3, 0x70, 0x79, 0x7b, 0x1c, 0x94, 0xb7, 0xc7, 0xb8, 0xce, + 0xc5, 0x5b, 0xd5, 0xf0, 0x12, 0xef, 0x1b, 0x05, 0xa2, 0xbb, 0xe7, 0xd5, 0xcf, 0xe8, 0xae, 0xbb, + 0xd3, 0xf6, 0x96, 0x17, 0x0a, 0x44, 0x74, 0xbf, 0x9a, 0xb2, 0xef, 0xa2, 0xd8, 0x6b, 0x0e, 0xbe, + 0x23, 0xfc, 0xb8, 0xdd, 0xfe, 0x4a, 0x1a, 0x1b, 0x7e, 0x68, 0x19, 0xa3, 0xff, 0x67, 0xcc, 0xd1, + 0xde, 0xd6, 0xc3, 0x6a, 0xe0, 0xe1, 0x26, 0xd3, 0x30, 0xf5, 0x1e, 0x1f, 0x48, 0x0b, 0xa9, 0xe9, + 0xee, 0xf5, 0xef, 0x9d, 0x74, 0x46, 0xa7, 0x77, 0x71, 0x15, 0x3d, 0xa8, 0x06, 0x1c, 0x9c, 0x3b, + 0xa9, 0x78, 0xad, 0x38, 0xf8, 0xfa, 0x57, 0x4f, 0xce, 0x74, 0x38, 0xc2, 0xd8, 0xc8, 0x24, 0x03, + 0xfd, 0x86, 0xa7, 0xe0, 0x5d, 0x1d, 0xd5, 0xc7, 0xbf, 0xd8, 0x56, 0xe2, 0x46, 0x57, 0xf8, 0x0c, + 0x77, 0x6c, 0x2d, 0xe3, 0xff, 0xc2, 0x51, 0xf4, 0xa8, 0x82, 0x3a, 0x8d, 0x09, 0x71, 0xb3, 0x2f, + 0x7a, 0xb9, 0x5c, 0x91, 0xe0, 0x7a, 0x45, 0x82, 0x9b, 0x15, 0x09, 0xbe, 0x94, 0x04, 0x2d, 0x4b, + 0x82, 0xae, 0x4b, 0x82, 0x6e, 0x4a, 0x82, 0x7e, 0x96, 0x04, 0x7d, 0xfb, 0x45, 0x82, 0xcb, 0xfe, + 0xae, 0x67, 0xf7, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x05, 0xe9, 0xaa, 0x07, 0xb2, 0x03, 0x00, 0x00, +} + +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 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 *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 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 *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() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +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 skipGenerated(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenerated + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenerated + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenerated + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenerated + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group") +) diff --git a/vendor/k8s.io/api/certificates/v1alpha1/generated.proto b/vendor/k8s.io/api/certificates/v1alpha1/generated.proto new file mode 100644 index 000000000..b0ebc4bd4 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/generated.proto @@ -0,0 +1,103 @@ +/* +Copyright 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. +*/ + + +// This file was autogenerated by go-to-protobuf. Do not edit it manually! + +syntax = "proto2"; + +package k8s.io.api.certificates.v1alpha1; + +import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/generated.proto"; +import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; + +// Package-wide variables from generator "generated". +option go_package = "k8s.io/api/certificates/v1alpha1"; + +// 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; +} + diff --git a/vendor/k8s.io/api/certificates/v1alpha1/register.go b/vendor/k8s.io/api/certificates/v1alpha1/register.go new file mode 100644 index 000000000..7288ed9a3 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/register.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "certificates.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + localSchemeBuilder = &SchemeBuilder + + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) + +// Adds the list of known types to the given scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ClusterTrustBundle{}, + &ClusterTrustBundleList{}, + ) + + // Add the watch version that applies + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/vendor/k8s.io/api/certificates/v1alpha1/types.go b/vendor/k8s.io/api/certificates/v1alpha1/types.go new file mode 100644 index 000000000..1a9fda011 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/types.go @@ -0,0 +1,106 @@ +/* +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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:prerelease-lifecycle-gen:introduced=1.26 +// +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.26 +// +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/vendor/k8s.io/api/certificates/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/certificates/v1alpha1/types_swagger_doc_generated.go new file mode 100644 index 000000000..bff649e3c --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/types_swagger_doc_generated.go @@ -0,0 +1,60 @@ +/* +Copyright 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 v1alpha1 + +// This file contains a collection of methods that can be used from go-restful to +// generate Swagger API documentation for its models. Please read this PR for more +// information on the implementation: https://github.com/emicklei/go-restful/pull/215 +// +// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if +// they are on one line! For multiple line or blocks that you want to ignore use ---. +// Any context after a --- is ignored. +// +// Those methods can be generated by using hack/update-codegen.sh + +// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. +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/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..30a4dc1e8 --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,102 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// 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 +} diff --git a/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.prerelease-lifecycle.go new file mode 100644 index 000000000..dfafa656c --- /dev/null +++ b/vendor/k8s.io/api/certificates/v1alpha1/zz_generated.prerelease-lifecycle.go @@ -0,0 +1,58 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by prerelease-lifecycle-gen. DO NOT EDIT. + +package v1alpha1 + +// 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, 26 +} + +// 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, 29 +} + +// 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, 32 +} + +// 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, 26 +} + +// 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, 29 +} + +// 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, 32 +} diff --git a/vendor/k8s.io/api/certificates/v1beta1/generated.proto b/vendor/k8s.io/api/certificates/v1beta1/generated.proto index e246fba02..f70f01ef7 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/generated.proto +++ b/vendor/k8s.io/api/certificates/v1beta1/generated.proto @@ -124,8 +124,10 @@ message CertificateSigningRequestSpec { // allowedUsages specifies a set of usage contexts the key will be // valid for. - // See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 - // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + // See: + // https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + // // Valid values are: // "signing", // "digital signature", diff --git a/vendor/k8s.io/api/certificates/v1beta1/types.go b/vendor/k8s.io/api/certificates/v1beta1/types.go index fe7aab970..7e5a5c198 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/types.go +++ b/vendor/k8s.io/api/certificates/v1beta1/types.go @@ -89,8 +89,10 @@ type CertificateSigningRequestSpec struct { // allowedUsages specifies a set of usage contexts the key will be // valid for. - // See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 - // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + // See: + // https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 + // // Valid values are: // "signing", // "digital signature", @@ -229,8 +231,9 @@ type CertificateSigningRequestList struct { } // KeyUsages specifies valid usage contexts for keys. -// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3 +// See: // +// https://tools.ietf.org/html/rfc5280#section-4.2.1.3 // https://tools.ietf.org/html/rfc5280#section-4.2.1.12 type KeyUsage string diff --git a/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go index d3f318150..f9ab1f13d 100644 --- a/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CertificateSigningRequest = map[string]string{ @@ -55,7 +55,7 @@ var map_CertificateSigningRequestSpec = map[string]string{ "request": "Base64-encoded PKCS#10 CSR data", "signerName": "Requested signer for the request. It is a qualified name in the form: `scope-hostname.io/name`. If empty, it will be defaulted:\n 1. If it's a kubelet client certificate, it is assigned\n \"kubernetes.io/kube-apiserver-client-kubelet\".\n 2. If it's a kubelet serving certificate, it is assigned\n \"kubernetes.io/kubelet-serving\".\n 3. Otherwise, it is assigned \"kubernetes.io/legacy-unknown\".\nDistribution of trust for signers happens out of band. You can select on this field using `spec.signerName`.", "expirationSeconds": "expirationSeconds is the requested duration of validity of the issued certificate. The certificate signer may issue a certificate with a different validity duration so a client must check the delta between the notBefore and and notAfter fields in the issued certificate to determine the actual duration.\n\nThe v1.22+ in-tree implementations of the well-known Kubernetes signers will honor this field as long as the requested duration is not greater than the maximum duration they will honor per the --cluster-signing-duration CLI flag to the Kubernetes controller manager.\n\nCertificate signers may not honor this field for various reasons:\n\n 1. Old signer that is unaware of the field (such as the in-tree\n implementations prior to v1.22)\n 2. Signer whose configured maximum is shorter than the requested duration\n 3. Signer whose configured minimum is longer than the requested duration\n\nThe minimum valid value for expirationSeconds is 600, i.e. 10 minutes.", - "usages": "allowedUsages specifies a set of usage contexts the key will be valid for. See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3\n https://tools.ietf.org/html/rfc5280#section-4.2.1.12\nValid values are:\n \"signing\",\n \"digital signature\",\n \"content commitment\",\n \"key encipherment\",\n \"key agreement\",\n \"data encipherment\",\n \"cert sign\",\n \"crl sign\",\n \"encipher only\",\n \"decipher only\",\n \"any\",\n \"server auth\",\n \"client auth\",\n \"code signing\",\n \"email protection\",\n \"s/mime\",\n \"ipsec end system\",\n \"ipsec tunnel\",\n \"ipsec user\",\n \"timestamping\",\n \"ocsp signing\",\n \"microsoft sgc\",\n \"netscape sgc\"", + "usages": "allowedUsages specifies a set of usage contexts the key will be valid for. See:\n\thttps://tools.ietf.org/html/rfc5280#section-4.2.1.3\n\thttps://tools.ietf.org/html/rfc5280#section-4.2.1.12\n\nValid values are:\n \"signing\",\n \"digital signature\",\n \"content commitment\",\n \"key encipherment\",\n \"key agreement\",\n \"data encipherment\",\n \"cert sign\",\n \"crl sign\",\n \"encipher only\",\n \"decipher only\",\n \"any\",\n \"server auth\",\n \"client auth\",\n \"code signing\",\n \"email protection\",\n \"s/mime\",\n \"ipsec end system\",\n \"ipsec tunnel\",\n \"ipsec user\",\n \"timestamping\",\n \"ocsp signing\",\n \"microsoft sgc\",\n \"netscape sgc\"", "username": "Information about the requesting user. See user.Info interface for details.", "uid": "UID information about the requesting user. See user.Info interface for details.", "groups": "Group information about the requesting user. See user.Info interface for details.", diff --git a/vendor/k8s.io/api/coordination/v1/generated.proto b/vendor/k8s.io/api/coordination/v1/generated.proto index b1efb737f..36fce60f2 100644 --- a/vendor/k8s.io/api/coordination/v1/generated.proto +++ b/vendor/k8s.io/api/coordination/v1/generated.proto @@ -34,7 +34,7 @@ message Lease { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the Lease. + // 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 LeaseSpec spec = 2; @@ -47,7 +47,7 @@ message LeaseList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated Lease items = 2; } @@ -59,7 +59,7 @@ message LeaseSpec { // leaseDurationSeconds is a duration that candidates for a lease need // to wait to force acquire it. This is measure against time of last - // observed RenewTime. + // observed renewTime. // +optional optional int32 leaseDurationSeconds = 2; diff --git a/vendor/k8s.io/api/coordination/v1/types.go b/vendor/k8s.io/api/coordination/v1/types.go index 7a5605ace..b0e1d0682 100644 --- a/vendor/k8s.io/api/coordination/v1/types.go +++ b/vendor/k8s.io/api/coordination/v1/types.go @@ -30,7 +30,7 @@ type Lease struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the Lease. + // 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 LeaseSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -43,7 +43,7 @@ type LeaseSpec struct { HolderIdentity *string `json:"holderIdentity,omitempty" protobuf:"bytes,1,opt,name=holderIdentity"` // leaseDurationSeconds is a duration that candidates for a lease need // to wait to force acquire it. This is measure against time of last - // observed RenewTime. + // observed renewTime. // +optional LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty" protobuf:"varint,2,opt,name=leaseDurationSeconds"` // acquireTime is a time when the current lease was acquired. @@ -69,6 +69,6 @@ type LeaseList struct { // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is a list of schema objects. + // items is a list of schema objects. Items []Lease `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/coordination/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/coordination/v1/types_swagger_doc_generated.go index 0f1440430..f3720eca0 100644 --- a/vendor/k8s.io/api/coordination/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/coordination/v1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Lease = map[string]string{ "": "Lease defines a lease concept.", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "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 (Lease) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (Lease) SwaggerDoc() map[string]string { 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", - "items": "Items is a list of schema objects.", + "items": "items is a list of schema objects.", } func (LeaseList) SwaggerDoc() map[string]string { @@ -50,7 +50,7 @@ func (LeaseList) SwaggerDoc() map[string]string { var map_LeaseSpec = map[string]string{ "": "LeaseSpec is a specification of a Lease.", "holderIdentity": "holderIdentity contains the identity of the holder of a current lease.", - "leaseDurationSeconds": "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed RenewTime.", + "leaseDurationSeconds": "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed renewTime.", "acquireTime": "acquireTime is a time when the current lease was acquired.", "renewTime": "renewTime is a time when the current holder of a lease has last updated the lease.", "leaseTransitions": "leaseTransitions is the number of transitions of a lease between holders.", diff --git a/vendor/k8s.io/api/coordination/v1beta1/generated.proto b/vendor/k8s.io/api/coordination/v1beta1/generated.proto index 85faa3b09..92c8918b8 100644 --- a/vendor/k8s.io/api/coordination/v1beta1/generated.proto +++ b/vendor/k8s.io/api/coordination/v1beta1/generated.proto @@ -34,7 +34,7 @@ message Lease { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the Lease. + // 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 LeaseSpec spec = 2; @@ -47,7 +47,7 @@ message LeaseList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated Lease items = 2; } @@ -59,7 +59,7 @@ message LeaseSpec { // leaseDurationSeconds is a duration that candidates for a lease need // to wait to force acquire it. This is measure against time of last - // observed RenewTime. + // observed renewTime. // +optional optional int32 leaseDurationSeconds = 2; diff --git a/vendor/k8s.io/api/coordination/v1beta1/types.go b/vendor/k8s.io/api/coordination/v1beta1/types.go index 8f300fca8..3a3d5f32e 100644 --- a/vendor/k8s.io/api/coordination/v1beta1/types.go +++ b/vendor/k8s.io/api/coordination/v1beta1/types.go @@ -33,7 +33,7 @@ type Lease struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the Lease. + // 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 LeaseSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -46,7 +46,7 @@ type LeaseSpec struct { HolderIdentity *string `json:"holderIdentity,omitempty" protobuf:"bytes,1,opt,name=holderIdentity"` // leaseDurationSeconds is a duration that candidates for a lease need // to wait to force acquire it. This is measure against time of last - // observed RenewTime. + // observed renewTime. // +optional LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty" protobuf:"varint,2,opt,name=leaseDurationSeconds"` // acquireTime is a time when the current lease was acquired. @@ -75,6 +75,6 @@ type LeaseList struct { // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is a list of schema objects. + // items is a list of schema objects. Items []Lease `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go index f557d265d..78ca4e393 100644 --- a/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Lease = map[string]string{ "": "Lease defines a lease concept.", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "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 (Lease) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (Lease) SwaggerDoc() map[string]string { 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", - "items": "Items is a list of schema objects.", + "items": "items is a list of schema objects.", } func (LeaseList) SwaggerDoc() map[string]string { @@ -50,7 +50,7 @@ func (LeaseList) SwaggerDoc() map[string]string { var map_LeaseSpec = map[string]string{ "": "LeaseSpec is a specification of a Lease.", "holderIdentity": "holderIdentity contains the identity of the holder of a current lease.", - "leaseDurationSeconds": "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed RenewTime.", + "leaseDurationSeconds": "leaseDurationSeconds is a duration that candidates for a lease need to wait to force acquire it. This is measure against time of last observed renewTime.", "acquireTime": "acquireTime is a time when the current lease was acquired.", "renewTime": "renewTime is a time when the current holder of a lease has last updated the lease.", "leaseTransitions": "leaseTransitions is the number of transitions of a lease between holders.", diff --git a/vendor/k8s.io/api/core/v1/annotation_key_constants.go b/vendor/k8s.io/api/core/v1/annotation_key_constants.go index eb9517e1d..61f86f850 100644 --- a/vendor/k8s.io/api/core/v1/annotation_key_constants.go +++ b/vendor/k8s.io/api/core/v1/annotation_key_constants.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This file should be consistent with pkg/api/annotation_key_constants.go. +// This file should be consistent with pkg/apis/core/annotation_key_constants.go. package v1 @@ -144,8 +144,19 @@ const ( // This annotation is beta-level and is only honored when PodDeletionCost feature is enabled. PodDeletionCost = "controller.kubernetes.io/pod-deletion-cost" - // AnnotationTopologyAwareHints can be used to enable or disable Topology - // Aware Hints for a Service. This may be set to "Auto" or "Disabled". Any - // other value is treated as "Disabled". - AnnotationTopologyAwareHints = "service.kubernetes.io/topology-aware-hints" + // DeprecatedAnnotationTopologyAwareHints can be used to enable or disable + // Topology Aware Hints for a Service. This may be set to "Auto" or + // "Disabled". Any other value is treated as "Disabled". This annotation has + // been deprecated in favor of the "service.kubernetes.io/topology-mode" + // annotation. + DeprecatedAnnotationTopologyAwareHints = "service.kubernetes.io/topology-aware-hints" + + // AnnotationTopologyMode can be used to enable or disable Topology Aware + // Routing for a Service. Well known values are "Auto" and "Disabled". + // Implementations may choose to develop new topology approaches, exposing + // them with domain-prefixed values. For example, "example.com/lowest-rtt" + // could be a valid implementation-specific value for this annotation. These + // heuristics will often populate topology hints on EndpointSlices, but that + // is not a requirement. + AnnotationTopologyMode = "service.kubernetes.io/topology-mode" ) diff --git a/vendor/k8s.io/api/core/v1/generated.pb.go b/vendor/k8s.io/api/core/v1/generated.pb.go index a8df2b222..c76646296 100644 --- a/vendor/k8s.io/api/core/v1/generated.pb.go +++ b/vendor/k8s.io/api/core/v1/generated.pb.go @@ -889,10 +889,38 @@ func (m *ContainerPort) XXX_DiscardUnknown() { var xxx_messageInfo_ContainerPort proto.InternalMessageInfo +func (m *ContainerResizePolicy) Reset() { *m = ContainerResizePolicy{} } +func (*ContainerResizePolicy) ProtoMessage() {} +func (*ContainerResizePolicy) Descriptor() ([]byte, []int) { + return fileDescriptor_83c10c24ec417dc9, []int{30} +} +func (m *ContainerResizePolicy) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContainerResizePolicy) 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 *ContainerResizePolicy) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContainerResizePolicy.Merge(m, src) +} +func (m *ContainerResizePolicy) XXX_Size() int { + return m.Size() +} +func (m *ContainerResizePolicy) XXX_DiscardUnknown() { + xxx_messageInfo_ContainerResizePolicy.DiscardUnknown(m) +} + +var xxx_messageInfo_ContainerResizePolicy proto.InternalMessageInfo + func (m *ContainerState) Reset() { *m = ContainerState{} } func (*ContainerState) ProtoMessage() {} func (*ContainerState) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{30} + return fileDescriptor_83c10c24ec417dc9, []int{31} } func (m *ContainerState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -920,7 +948,7 @@ var xxx_messageInfo_ContainerState proto.InternalMessageInfo func (m *ContainerStateRunning) Reset() { *m = ContainerStateRunning{} } func (*ContainerStateRunning) ProtoMessage() {} func (*ContainerStateRunning) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{31} + return fileDescriptor_83c10c24ec417dc9, []int{32} } func (m *ContainerStateRunning) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -948,7 +976,7 @@ var xxx_messageInfo_ContainerStateRunning proto.InternalMessageInfo func (m *ContainerStateTerminated) Reset() { *m = ContainerStateTerminated{} } func (*ContainerStateTerminated) ProtoMessage() {} func (*ContainerStateTerminated) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{32} + return fileDescriptor_83c10c24ec417dc9, []int{33} } func (m *ContainerStateTerminated) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -976,7 +1004,7 @@ var xxx_messageInfo_ContainerStateTerminated proto.InternalMessageInfo func (m *ContainerStateWaiting) Reset() { *m = ContainerStateWaiting{} } func (*ContainerStateWaiting) ProtoMessage() {} func (*ContainerStateWaiting) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{33} + return fileDescriptor_83c10c24ec417dc9, []int{34} } func (m *ContainerStateWaiting) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1004,7 +1032,7 @@ var xxx_messageInfo_ContainerStateWaiting proto.InternalMessageInfo func (m *ContainerStatus) Reset() { *m = ContainerStatus{} } func (*ContainerStatus) ProtoMessage() {} func (*ContainerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{34} + return fileDescriptor_83c10c24ec417dc9, []int{35} } func (m *ContainerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1032,7 +1060,7 @@ var xxx_messageInfo_ContainerStatus proto.InternalMessageInfo func (m *DaemonEndpoint) Reset() { *m = DaemonEndpoint{} } func (*DaemonEndpoint) ProtoMessage() {} func (*DaemonEndpoint) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{35} + return fileDescriptor_83c10c24ec417dc9, []int{36} } func (m *DaemonEndpoint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1060,7 +1088,7 @@ var xxx_messageInfo_DaemonEndpoint proto.InternalMessageInfo func (m *DownwardAPIProjection) Reset() { *m = DownwardAPIProjection{} } func (*DownwardAPIProjection) ProtoMessage() {} func (*DownwardAPIProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{36} + return fileDescriptor_83c10c24ec417dc9, []int{37} } func (m *DownwardAPIProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1088,7 +1116,7 @@ var xxx_messageInfo_DownwardAPIProjection proto.InternalMessageInfo func (m *DownwardAPIVolumeFile) Reset() { *m = DownwardAPIVolumeFile{} } func (*DownwardAPIVolumeFile) ProtoMessage() {} func (*DownwardAPIVolumeFile) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{37} + return fileDescriptor_83c10c24ec417dc9, []int{38} } func (m *DownwardAPIVolumeFile) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1116,7 +1144,7 @@ var xxx_messageInfo_DownwardAPIVolumeFile proto.InternalMessageInfo func (m *DownwardAPIVolumeSource) Reset() { *m = DownwardAPIVolumeSource{} } func (*DownwardAPIVolumeSource) ProtoMessage() {} func (*DownwardAPIVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{38} + return fileDescriptor_83c10c24ec417dc9, []int{39} } func (m *DownwardAPIVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1144,7 +1172,7 @@ var xxx_messageInfo_DownwardAPIVolumeSource proto.InternalMessageInfo func (m *EmptyDirVolumeSource) Reset() { *m = EmptyDirVolumeSource{} } func (*EmptyDirVolumeSource) ProtoMessage() {} func (*EmptyDirVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{39} + return fileDescriptor_83c10c24ec417dc9, []int{40} } func (m *EmptyDirVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1172,7 +1200,7 @@ var xxx_messageInfo_EmptyDirVolumeSource proto.InternalMessageInfo func (m *EndpointAddress) Reset() { *m = EndpointAddress{} } func (*EndpointAddress) ProtoMessage() {} func (*EndpointAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{40} + return fileDescriptor_83c10c24ec417dc9, []int{41} } func (m *EndpointAddress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1200,7 +1228,7 @@ var xxx_messageInfo_EndpointAddress proto.InternalMessageInfo func (m *EndpointPort) Reset() { *m = EndpointPort{} } func (*EndpointPort) ProtoMessage() {} func (*EndpointPort) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{41} + return fileDescriptor_83c10c24ec417dc9, []int{42} } func (m *EndpointPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1228,7 +1256,7 @@ var xxx_messageInfo_EndpointPort proto.InternalMessageInfo func (m *EndpointSubset) Reset() { *m = EndpointSubset{} } func (*EndpointSubset) ProtoMessage() {} func (*EndpointSubset) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{42} + return fileDescriptor_83c10c24ec417dc9, []int{43} } func (m *EndpointSubset) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1256,7 +1284,7 @@ var xxx_messageInfo_EndpointSubset proto.InternalMessageInfo func (m *Endpoints) Reset() { *m = Endpoints{} } func (*Endpoints) ProtoMessage() {} func (*Endpoints) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{43} + return fileDescriptor_83c10c24ec417dc9, []int{44} } func (m *Endpoints) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1284,7 +1312,7 @@ var xxx_messageInfo_Endpoints proto.InternalMessageInfo func (m *EndpointsList) Reset() { *m = EndpointsList{} } func (*EndpointsList) ProtoMessage() {} func (*EndpointsList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{44} + return fileDescriptor_83c10c24ec417dc9, []int{45} } func (m *EndpointsList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1312,7 +1340,7 @@ var xxx_messageInfo_EndpointsList proto.InternalMessageInfo func (m *EnvFromSource) Reset() { *m = EnvFromSource{} } func (*EnvFromSource) ProtoMessage() {} func (*EnvFromSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{45} + return fileDescriptor_83c10c24ec417dc9, []int{46} } func (m *EnvFromSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1340,7 +1368,7 @@ var xxx_messageInfo_EnvFromSource proto.InternalMessageInfo func (m *EnvVar) Reset() { *m = EnvVar{} } func (*EnvVar) ProtoMessage() {} func (*EnvVar) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{46} + return fileDescriptor_83c10c24ec417dc9, []int{47} } func (m *EnvVar) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1368,7 +1396,7 @@ var xxx_messageInfo_EnvVar proto.InternalMessageInfo func (m *EnvVarSource) Reset() { *m = EnvVarSource{} } func (*EnvVarSource) ProtoMessage() {} func (*EnvVarSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{47} + return fileDescriptor_83c10c24ec417dc9, []int{48} } func (m *EnvVarSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1396,7 +1424,7 @@ var xxx_messageInfo_EnvVarSource proto.InternalMessageInfo func (m *EphemeralContainer) Reset() { *m = EphemeralContainer{} } func (*EphemeralContainer) ProtoMessage() {} func (*EphemeralContainer) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{48} + return fileDescriptor_83c10c24ec417dc9, []int{49} } func (m *EphemeralContainer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1424,7 +1452,7 @@ var xxx_messageInfo_EphemeralContainer proto.InternalMessageInfo func (m *EphemeralContainerCommon) Reset() { *m = EphemeralContainerCommon{} } func (*EphemeralContainerCommon) ProtoMessage() {} func (*EphemeralContainerCommon) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{49} + return fileDescriptor_83c10c24ec417dc9, []int{50} } func (m *EphemeralContainerCommon) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1452,7 +1480,7 @@ var xxx_messageInfo_EphemeralContainerCommon proto.InternalMessageInfo func (m *EphemeralVolumeSource) Reset() { *m = EphemeralVolumeSource{} } func (*EphemeralVolumeSource) ProtoMessage() {} func (*EphemeralVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{50} + return fileDescriptor_83c10c24ec417dc9, []int{51} } func (m *EphemeralVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1480,7 +1508,7 @@ var xxx_messageInfo_EphemeralVolumeSource proto.InternalMessageInfo func (m *Event) Reset() { *m = Event{} } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{51} + return fileDescriptor_83c10c24ec417dc9, []int{52} } func (m *Event) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1508,7 +1536,7 @@ var xxx_messageInfo_Event proto.InternalMessageInfo func (m *EventList) Reset() { *m = EventList{} } func (*EventList) ProtoMessage() {} func (*EventList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{52} + return fileDescriptor_83c10c24ec417dc9, []int{53} } func (m *EventList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1536,7 +1564,7 @@ var xxx_messageInfo_EventList proto.InternalMessageInfo func (m *EventSeries) Reset() { *m = EventSeries{} } func (*EventSeries) ProtoMessage() {} func (*EventSeries) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{53} + return fileDescriptor_83c10c24ec417dc9, []int{54} } func (m *EventSeries) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1564,7 +1592,7 @@ var xxx_messageInfo_EventSeries proto.InternalMessageInfo func (m *EventSource) Reset() { *m = EventSource{} } func (*EventSource) ProtoMessage() {} func (*EventSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{54} + return fileDescriptor_83c10c24ec417dc9, []int{55} } func (m *EventSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1592,7 +1620,7 @@ var xxx_messageInfo_EventSource proto.InternalMessageInfo func (m *ExecAction) Reset() { *m = ExecAction{} } func (*ExecAction) ProtoMessage() {} func (*ExecAction) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{55} + return fileDescriptor_83c10c24ec417dc9, []int{56} } func (m *ExecAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1620,7 +1648,7 @@ var xxx_messageInfo_ExecAction proto.InternalMessageInfo func (m *FCVolumeSource) Reset() { *m = FCVolumeSource{} } func (*FCVolumeSource) ProtoMessage() {} func (*FCVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{56} + return fileDescriptor_83c10c24ec417dc9, []int{57} } func (m *FCVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1648,7 +1676,7 @@ var xxx_messageInfo_FCVolumeSource proto.InternalMessageInfo func (m *FlexPersistentVolumeSource) Reset() { *m = FlexPersistentVolumeSource{} } func (*FlexPersistentVolumeSource) ProtoMessage() {} func (*FlexPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{57} + return fileDescriptor_83c10c24ec417dc9, []int{58} } func (m *FlexPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1676,7 +1704,7 @@ var xxx_messageInfo_FlexPersistentVolumeSource proto.InternalMessageInfo func (m *FlexVolumeSource) Reset() { *m = FlexVolumeSource{} } func (*FlexVolumeSource) ProtoMessage() {} func (*FlexVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{58} + return fileDescriptor_83c10c24ec417dc9, []int{59} } func (m *FlexVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1704,7 +1732,7 @@ var xxx_messageInfo_FlexVolumeSource proto.InternalMessageInfo func (m *FlockerVolumeSource) Reset() { *m = FlockerVolumeSource{} } func (*FlockerVolumeSource) ProtoMessage() {} func (*FlockerVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{59} + return fileDescriptor_83c10c24ec417dc9, []int{60} } func (m *FlockerVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1732,7 +1760,7 @@ var xxx_messageInfo_FlockerVolumeSource proto.InternalMessageInfo func (m *GCEPersistentDiskVolumeSource) Reset() { *m = GCEPersistentDiskVolumeSource{} } func (*GCEPersistentDiskVolumeSource) ProtoMessage() {} func (*GCEPersistentDiskVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{60} + return fileDescriptor_83c10c24ec417dc9, []int{61} } func (m *GCEPersistentDiskVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1760,7 +1788,7 @@ var xxx_messageInfo_GCEPersistentDiskVolumeSource proto.InternalMessageInfo func (m *GRPCAction) Reset() { *m = GRPCAction{} } func (*GRPCAction) ProtoMessage() {} func (*GRPCAction) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{61} + return fileDescriptor_83c10c24ec417dc9, []int{62} } func (m *GRPCAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1788,7 +1816,7 @@ var xxx_messageInfo_GRPCAction proto.InternalMessageInfo func (m *GitRepoVolumeSource) Reset() { *m = GitRepoVolumeSource{} } func (*GitRepoVolumeSource) ProtoMessage() {} func (*GitRepoVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{62} + return fileDescriptor_83c10c24ec417dc9, []int{63} } func (m *GitRepoVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1816,7 +1844,7 @@ var xxx_messageInfo_GitRepoVolumeSource proto.InternalMessageInfo func (m *GlusterfsPersistentVolumeSource) Reset() { *m = GlusterfsPersistentVolumeSource{} } func (*GlusterfsPersistentVolumeSource) ProtoMessage() {} func (*GlusterfsPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{63} + return fileDescriptor_83c10c24ec417dc9, []int{64} } func (m *GlusterfsPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1844,7 +1872,7 @@ var xxx_messageInfo_GlusterfsPersistentVolumeSource proto.InternalMessageInfo func (m *GlusterfsVolumeSource) Reset() { *m = GlusterfsVolumeSource{} } func (*GlusterfsVolumeSource) ProtoMessage() {} func (*GlusterfsVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{64} + return fileDescriptor_83c10c24ec417dc9, []int{65} } func (m *GlusterfsVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1872,7 +1900,7 @@ var xxx_messageInfo_GlusterfsVolumeSource proto.InternalMessageInfo func (m *HTTPGetAction) Reset() { *m = HTTPGetAction{} } func (*HTTPGetAction) ProtoMessage() {} func (*HTTPGetAction) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{65} + return fileDescriptor_83c10c24ec417dc9, []int{66} } func (m *HTTPGetAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1900,7 +1928,7 @@ var xxx_messageInfo_HTTPGetAction proto.InternalMessageInfo func (m *HTTPHeader) Reset() { *m = HTTPHeader{} } func (*HTTPHeader) ProtoMessage() {} func (*HTTPHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{66} + return fileDescriptor_83c10c24ec417dc9, []int{67} } func (m *HTTPHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1928,7 +1956,7 @@ var xxx_messageInfo_HTTPHeader proto.InternalMessageInfo func (m *HostAlias) Reset() { *m = HostAlias{} } func (*HostAlias) ProtoMessage() {} func (*HostAlias) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{67} + return fileDescriptor_83c10c24ec417dc9, []int{68} } func (m *HostAlias) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1956,7 +1984,7 @@ var xxx_messageInfo_HostAlias proto.InternalMessageInfo func (m *HostPathVolumeSource) Reset() { *m = HostPathVolumeSource{} } func (*HostPathVolumeSource) ProtoMessage() {} func (*HostPathVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{68} + return fileDescriptor_83c10c24ec417dc9, []int{69} } func (m *HostPathVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1984,7 +2012,7 @@ var xxx_messageInfo_HostPathVolumeSource proto.InternalMessageInfo func (m *ISCSIPersistentVolumeSource) Reset() { *m = ISCSIPersistentVolumeSource{} } func (*ISCSIPersistentVolumeSource) ProtoMessage() {} func (*ISCSIPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{69} + return fileDescriptor_83c10c24ec417dc9, []int{70} } func (m *ISCSIPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2012,7 +2040,7 @@ var xxx_messageInfo_ISCSIPersistentVolumeSource proto.InternalMessageInfo func (m *ISCSIVolumeSource) Reset() { *m = ISCSIVolumeSource{} } func (*ISCSIVolumeSource) ProtoMessage() {} func (*ISCSIVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{70} + return fileDescriptor_83c10c24ec417dc9, []int{71} } func (m *ISCSIVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2040,7 +2068,7 @@ var xxx_messageInfo_ISCSIVolumeSource proto.InternalMessageInfo func (m *KeyToPath) Reset() { *m = KeyToPath{} } func (*KeyToPath) ProtoMessage() {} func (*KeyToPath) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{71} + return fileDescriptor_83c10c24ec417dc9, []int{72} } func (m *KeyToPath) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2068,7 +2096,7 @@ var xxx_messageInfo_KeyToPath proto.InternalMessageInfo func (m *Lifecycle) Reset() { *m = Lifecycle{} } func (*Lifecycle) ProtoMessage() {} func (*Lifecycle) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{72} + return fileDescriptor_83c10c24ec417dc9, []int{73} } func (m *Lifecycle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2096,7 +2124,7 @@ var xxx_messageInfo_Lifecycle proto.InternalMessageInfo func (m *LifecycleHandler) Reset() { *m = LifecycleHandler{} } func (*LifecycleHandler) ProtoMessage() {} func (*LifecycleHandler) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{73} + return fileDescriptor_83c10c24ec417dc9, []int{74} } func (m *LifecycleHandler) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2124,7 +2152,7 @@ var xxx_messageInfo_LifecycleHandler proto.InternalMessageInfo func (m *LimitRange) Reset() { *m = LimitRange{} } func (*LimitRange) ProtoMessage() {} func (*LimitRange) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{74} + return fileDescriptor_83c10c24ec417dc9, []int{75} } func (m *LimitRange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2152,7 +2180,7 @@ var xxx_messageInfo_LimitRange proto.InternalMessageInfo func (m *LimitRangeItem) Reset() { *m = LimitRangeItem{} } func (*LimitRangeItem) ProtoMessage() {} func (*LimitRangeItem) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{75} + return fileDescriptor_83c10c24ec417dc9, []int{76} } func (m *LimitRangeItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2180,7 +2208,7 @@ var xxx_messageInfo_LimitRangeItem proto.InternalMessageInfo func (m *LimitRangeList) Reset() { *m = LimitRangeList{} } func (*LimitRangeList) ProtoMessage() {} func (*LimitRangeList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{76} + return fileDescriptor_83c10c24ec417dc9, []int{77} } func (m *LimitRangeList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2208,7 +2236,7 @@ var xxx_messageInfo_LimitRangeList proto.InternalMessageInfo func (m *LimitRangeSpec) Reset() { *m = LimitRangeSpec{} } func (*LimitRangeSpec) ProtoMessage() {} func (*LimitRangeSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{77} + return fileDescriptor_83c10c24ec417dc9, []int{78} } func (m *LimitRangeSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2236,7 +2264,7 @@ var xxx_messageInfo_LimitRangeSpec proto.InternalMessageInfo func (m *List) Reset() { *m = List{} } func (*List) ProtoMessage() {} func (*List) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{78} + return fileDescriptor_83c10c24ec417dc9, []int{79} } func (m *List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2264,7 +2292,7 @@ var xxx_messageInfo_List proto.InternalMessageInfo func (m *LoadBalancerIngress) Reset() { *m = LoadBalancerIngress{} } func (*LoadBalancerIngress) ProtoMessage() {} func (*LoadBalancerIngress) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{79} + return fileDescriptor_83c10c24ec417dc9, []int{80} } func (m *LoadBalancerIngress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2292,7 +2320,7 @@ var xxx_messageInfo_LoadBalancerIngress proto.InternalMessageInfo func (m *LoadBalancerStatus) Reset() { *m = LoadBalancerStatus{} } func (*LoadBalancerStatus) ProtoMessage() {} func (*LoadBalancerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{80} + return fileDescriptor_83c10c24ec417dc9, []int{81} } func (m *LoadBalancerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2320,7 +2348,7 @@ var xxx_messageInfo_LoadBalancerStatus proto.InternalMessageInfo func (m *LocalObjectReference) Reset() { *m = LocalObjectReference{} } func (*LocalObjectReference) ProtoMessage() {} func (*LocalObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{81} + return fileDescriptor_83c10c24ec417dc9, []int{82} } func (m *LocalObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2348,7 +2376,7 @@ var xxx_messageInfo_LocalObjectReference proto.InternalMessageInfo func (m *LocalVolumeSource) Reset() { *m = LocalVolumeSource{} } func (*LocalVolumeSource) ProtoMessage() {} func (*LocalVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{82} + return fileDescriptor_83c10c24ec417dc9, []int{83} } func (m *LocalVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2376,7 +2404,7 @@ var xxx_messageInfo_LocalVolumeSource proto.InternalMessageInfo func (m *NFSVolumeSource) Reset() { *m = NFSVolumeSource{} } func (*NFSVolumeSource) ProtoMessage() {} func (*NFSVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{83} + return fileDescriptor_83c10c24ec417dc9, []int{84} } func (m *NFSVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2404,7 +2432,7 @@ var xxx_messageInfo_NFSVolumeSource proto.InternalMessageInfo func (m *Namespace) Reset() { *m = Namespace{} } func (*Namespace) ProtoMessage() {} func (*Namespace) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{84} + return fileDescriptor_83c10c24ec417dc9, []int{85} } func (m *Namespace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2432,7 +2460,7 @@ var xxx_messageInfo_Namespace proto.InternalMessageInfo func (m *NamespaceCondition) Reset() { *m = NamespaceCondition{} } func (*NamespaceCondition) ProtoMessage() {} func (*NamespaceCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{85} + return fileDescriptor_83c10c24ec417dc9, []int{86} } func (m *NamespaceCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2460,7 +2488,7 @@ var xxx_messageInfo_NamespaceCondition proto.InternalMessageInfo func (m *NamespaceList) Reset() { *m = NamespaceList{} } func (*NamespaceList) ProtoMessage() {} func (*NamespaceList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{86} + return fileDescriptor_83c10c24ec417dc9, []int{87} } func (m *NamespaceList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2488,7 +2516,7 @@ var xxx_messageInfo_NamespaceList proto.InternalMessageInfo func (m *NamespaceSpec) Reset() { *m = NamespaceSpec{} } func (*NamespaceSpec) ProtoMessage() {} func (*NamespaceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{87} + return fileDescriptor_83c10c24ec417dc9, []int{88} } func (m *NamespaceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2516,7 +2544,7 @@ var xxx_messageInfo_NamespaceSpec proto.InternalMessageInfo func (m *NamespaceStatus) Reset() { *m = NamespaceStatus{} } func (*NamespaceStatus) ProtoMessage() {} func (*NamespaceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{88} + return fileDescriptor_83c10c24ec417dc9, []int{89} } func (m *NamespaceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2544,7 +2572,7 @@ var xxx_messageInfo_NamespaceStatus proto.InternalMessageInfo func (m *Node) Reset() { *m = Node{} } func (*Node) ProtoMessage() {} func (*Node) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{89} + return fileDescriptor_83c10c24ec417dc9, []int{90} } func (m *Node) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2572,7 +2600,7 @@ var xxx_messageInfo_Node proto.InternalMessageInfo func (m *NodeAddress) Reset() { *m = NodeAddress{} } func (*NodeAddress) ProtoMessage() {} func (*NodeAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{90} + return fileDescriptor_83c10c24ec417dc9, []int{91} } func (m *NodeAddress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2600,7 +2628,7 @@ var xxx_messageInfo_NodeAddress proto.InternalMessageInfo func (m *NodeAffinity) Reset() { *m = NodeAffinity{} } func (*NodeAffinity) ProtoMessage() {} func (*NodeAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{91} + return fileDescriptor_83c10c24ec417dc9, []int{92} } func (m *NodeAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2628,7 +2656,7 @@ var xxx_messageInfo_NodeAffinity proto.InternalMessageInfo func (m *NodeCondition) Reset() { *m = NodeCondition{} } func (*NodeCondition) ProtoMessage() {} func (*NodeCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{92} + return fileDescriptor_83c10c24ec417dc9, []int{93} } func (m *NodeCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2656,7 +2684,7 @@ var xxx_messageInfo_NodeCondition proto.InternalMessageInfo func (m *NodeConfigSource) Reset() { *m = NodeConfigSource{} } func (*NodeConfigSource) ProtoMessage() {} func (*NodeConfigSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{93} + return fileDescriptor_83c10c24ec417dc9, []int{94} } func (m *NodeConfigSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2684,7 +2712,7 @@ var xxx_messageInfo_NodeConfigSource proto.InternalMessageInfo func (m *NodeConfigStatus) Reset() { *m = NodeConfigStatus{} } func (*NodeConfigStatus) ProtoMessage() {} func (*NodeConfigStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{94} + return fileDescriptor_83c10c24ec417dc9, []int{95} } func (m *NodeConfigStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2712,7 +2740,7 @@ var xxx_messageInfo_NodeConfigStatus proto.InternalMessageInfo func (m *NodeDaemonEndpoints) Reset() { *m = NodeDaemonEndpoints{} } func (*NodeDaemonEndpoints) ProtoMessage() {} func (*NodeDaemonEndpoints) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{95} + return fileDescriptor_83c10c24ec417dc9, []int{96} } func (m *NodeDaemonEndpoints) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2740,7 +2768,7 @@ var xxx_messageInfo_NodeDaemonEndpoints proto.InternalMessageInfo func (m *NodeList) Reset() { *m = NodeList{} } func (*NodeList) ProtoMessage() {} func (*NodeList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{96} + return fileDescriptor_83c10c24ec417dc9, []int{97} } func (m *NodeList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2768,7 +2796,7 @@ var xxx_messageInfo_NodeList proto.InternalMessageInfo func (m *NodeProxyOptions) Reset() { *m = NodeProxyOptions{} } func (*NodeProxyOptions) ProtoMessage() {} func (*NodeProxyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{97} + return fileDescriptor_83c10c24ec417dc9, []int{98} } func (m *NodeProxyOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2796,7 +2824,7 @@ var xxx_messageInfo_NodeProxyOptions proto.InternalMessageInfo func (m *NodeResources) Reset() { *m = NodeResources{} } func (*NodeResources) ProtoMessage() {} func (*NodeResources) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{98} + return fileDescriptor_83c10c24ec417dc9, []int{99} } func (m *NodeResources) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2824,7 +2852,7 @@ var xxx_messageInfo_NodeResources proto.InternalMessageInfo func (m *NodeSelector) Reset() { *m = NodeSelector{} } func (*NodeSelector) ProtoMessage() {} func (*NodeSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{99} + return fileDescriptor_83c10c24ec417dc9, []int{100} } func (m *NodeSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2852,7 +2880,7 @@ var xxx_messageInfo_NodeSelector proto.InternalMessageInfo func (m *NodeSelectorRequirement) Reset() { *m = NodeSelectorRequirement{} } func (*NodeSelectorRequirement) ProtoMessage() {} func (*NodeSelectorRequirement) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{100} + return fileDescriptor_83c10c24ec417dc9, []int{101} } func (m *NodeSelectorRequirement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2880,7 +2908,7 @@ var xxx_messageInfo_NodeSelectorRequirement proto.InternalMessageInfo func (m *NodeSelectorTerm) Reset() { *m = NodeSelectorTerm{} } func (*NodeSelectorTerm) ProtoMessage() {} func (*NodeSelectorTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{101} + return fileDescriptor_83c10c24ec417dc9, []int{102} } func (m *NodeSelectorTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2908,7 +2936,7 @@ var xxx_messageInfo_NodeSelectorTerm proto.InternalMessageInfo func (m *NodeSpec) Reset() { *m = NodeSpec{} } func (*NodeSpec) ProtoMessage() {} func (*NodeSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{102} + return fileDescriptor_83c10c24ec417dc9, []int{103} } func (m *NodeSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2936,7 +2964,7 @@ var xxx_messageInfo_NodeSpec proto.InternalMessageInfo func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} func (*NodeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{103} + return fileDescriptor_83c10c24ec417dc9, []int{104} } func (m *NodeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2964,7 +2992,7 @@ var xxx_messageInfo_NodeStatus proto.InternalMessageInfo func (m *NodeSystemInfo) Reset() { *m = NodeSystemInfo{} } func (*NodeSystemInfo) ProtoMessage() {} func (*NodeSystemInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{104} + return fileDescriptor_83c10c24ec417dc9, []int{105} } func (m *NodeSystemInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2992,7 +3020,7 @@ var xxx_messageInfo_NodeSystemInfo proto.InternalMessageInfo func (m *ObjectFieldSelector) Reset() { *m = ObjectFieldSelector{} } func (*ObjectFieldSelector) ProtoMessage() {} func (*ObjectFieldSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{105} + return fileDescriptor_83c10c24ec417dc9, []int{106} } func (m *ObjectFieldSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3020,7 +3048,7 @@ var xxx_messageInfo_ObjectFieldSelector proto.InternalMessageInfo func (m *ObjectReference) Reset() { *m = ObjectReference{} } func (*ObjectReference) ProtoMessage() {} func (*ObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{106} + return fileDescriptor_83c10c24ec417dc9, []int{107} } func (m *ObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3048,7 +3076,7 @@ var xxx_messageInfo_ObjectReference proto.InternalMessageInfo func (m *PersistentVolume) Reset() { *m = PersistentVolume{} } func (*PersistentVolume) ProtoMessage() {} func (*PersistentVolume) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{107} + return fileDescriptor_83c10c24ec417dc9, []int{108} } func (m *PersistentVolume) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3076,7 +3104,7 @@ var xxx_messageInfo_PersistentVolume proto.InternalMessageInfo func (m *PersistentVolumeClaim) Reset() { *m = PersistentVolumeClaim{} } func (*PersistentVolumeClaim) ProtoMessage() {} func (*PersistentVolumeClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{108} + return fileDescriptor_83c10c24ec417dc9, []int{109} } func (m *PersistentVolumeClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3104,7 +3132,7 @@ var xxx_messageInfo_PersistentVolumeClaim proto.InternalMessageInfo func (m *PersistentVolumeClaimCondition) Reset() { *m = PersistentVolumeClaimCondition{} } func (*PersistentVolumeClaimCondition) ProtoMessage() {} func (*PersistentVolumeClaimCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{109} + return fileDescriptor_83c10c24ec417dc9, []int{110} } func (m *PersistentVolumeClaimCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3132,7 +3160,7 @@ var xxx_messageInfo_PersistentVolumeClaimCondition proto.InternalMessageInfo func (m *PersistentVolumeClaimList) Reset() { *m = PersistentVolumeClaimList{} } func (*PersistentVolumeClaimList) ProtoMessage() {} func (*PersistentVolumeClaimList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{110} + return fileDescriptor_83c10c24ec417dc9, []int{111} } func (m *PersistentVolumeClaimList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3160,7 +3188,7 @@ var xxx_messageInfo_PersistentVolumeClaimList proto.InternalMessageInfo func (m *PersistentVolumeClaimSpec) Reset() { *m = PersistentVolumeClaimSpec{} } func (*PersistentVolumeClaimSpec) ProtoMessage() {} func (*PersistentVolumeClaimSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{111} + return fileDescriptor_83c10c24ec417dc9, []int{112} } func (m *PersistentVolumeClaimSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3188,7 +3216,7 @@ var xxx_messageInfo_PersistentVolumeClaimSpec proto.InternalMessageInfo func (m *PersistentVolumeClaimStatus) Reset() { *m = PersistentVolumeClaimStatus{} } func (*PersistentVolumeClaimStatus) ProtoMessage() {} func (*PersistentVolumeClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{112} + return fileDescriptor_83c10c24ec417dc9, []int{113} } func (m *PersistentVolumeClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3216,7 +3244,7 @@ var xxx_messageInfo_PersistentVolumeClaimStatus proto.InternalMessageInfo func (m *PersistentVolumeClaimTemplate) Reset() { *m = PersistentVolumeClaimTemplate{} } func (*PersistentVolumeClaimTemplate) ProtoMessage() {} func (*PersistentVolumeClaimTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{113} + return fileDescriptor_83c10c24ec417dc9, []int{114} } func (m *PersistentVolumeClaimTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3244,7 +3272,7 @@ var xxx_messageInfo_PersistentVolumeClaimTemplate proto.InternalMessageInfo func (m *PersistentVolumeClaimVolumeSource) Reset() { *m = PersistentVolumeClaimVolumeSource{} } func (*PersistentVolumeClaimVolumeSource) ProtoMessage() {} func (*PersistentVolumeClaimVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{114} + return fileDescriptor_83c10c24ec417dc9, []int{115} } func (m *PersistentVolumeClaimVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3272,7 +3300,7 @@ var xxx_messageInfo_PersistentVolumeClaimVolumeSource proto.InternalMessageInfo func (m *PersistentVolumeList) Reset() { *m = PersistentVolumeList{} } func (*PersistentVolumeList) ProtoMessage() {} func (*PersistentVolumeList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{115} + return fileDescriptor_83c10c24ec417dc9, []int{116} } func (m *PersistentVolumeList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3300,7 +3328,7 @@ var xxx_messageInfo_PersistentVolumeList proto.InternalMessageInfo func (m *PersistentVolumeSource) Reset() { *m = PersistentVolumeSource{} } func (*PersistentVolumeSource) ProtoMessage() {} func (*PersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{116} + return fileDescriptor_83c10c24ec417dc9, []int{117} } func (m *PersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3328,7 +3356,7 @@ var xxx_messageInfo_PersistentVolumeSource proto.InternalMessageInfo func (m *PersistentVolumeSpec) Reset() { *m = PersistentVolumeSpec{} } func (*PersistentVolumeSpec) ProtoMessage() {} func (*PersistentVolumeSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{117} + return fileDescriptor_83c10c24ec417dc9, []int{118} } func (m *PersistentVolumeSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3356,7 +3384,7 @@ var xxx_messageInfo_PersistentVolumeSpec proto.InternalMessageInfo func (m *PersistentVolumeStatus) Reset() { *m = PersistentVolumeStatus{} } func (*PersistentVolumeStatus) ProtoMessage() {} func (*PersistentVolumeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{118} + return fileDescriptor_83c10c24ec417dc9, []int{119} } func (m *PersistentVolumeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3384,7 +3412,7 @@ var xxx_messageInfo_PersistentVolumeStatus proto.InternalMessageInfo func (m *PhotonPersistentDiskVolumeSource) Reset() { *m = PhotonPersistentDiskVolumeSource{} } func (*PhotonPersistentDiskVolumeSource) ProtoMessage() {} func (*PhotonPersistentDiskVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{119} + return fileDescriptor_83c10c24ec417dc9, []int{120} } func (m *PhotonPersistentDiskVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3412,7 +3440,7 @@ var xxx_messageInfo_PhotonPersistentDiskVolumeSource proto.InternalMessageInfo func (m *Pod) Reset() { *m = Pod{} } func (*Pod) ProtoMessage() {} func (*Pod) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{120} + return fileDescriptor_83c10c24ec417dc9, []int{121} } func (m *Pod) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3440,7 +3468,7 @@ var xxx_messageInfo_Pod proto.InternalMessageInfo func (m *PodAffinity) Reset() { *m = PodAffinity{} } func (*PodAffinity) ProtoMessage() {} func (*PodAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{121} + return fileDescriptor_83c10c24ec417dc9, []int{122} } func (m *PodAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3468,7 +3496,7 @@ var xxx_messageInfo_PodAffinity proto.InternalMessageInfo func (m *PodAffinityTerm) Reset() { *m = PodAffinityTerm{} } func (*PodAffinityTerm) ProtoMessage() {} func (*PodAffinityTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{122} + return fileDescriptor_83c10c24ec417dc9, []int{123} } func (m *PodAffinityTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3496,7 +3524,7 @@ var xxx_messageInfo_PodAffinityTerm proto.InternalMessageInfo func (m *PodAntiAffinity) Reset() { *m = PodAntiAffinity{} } func (*PodAntiAffinity) ProtoMessage() {} func (*PodAntiAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{123} + return fileDescriptor_83c10c24ec417dc9, []int{124} } func (m *PodAntiAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3524,7 +3552,7 @@ var xxx_messageInfo_PodAntiAffinity proto.InternalMessageInfo func (m *PodAttachOptions) Reset() { *m = PodAttachOptions{} } func (*PodAttachOptions) ProtoMessage() {} func (*PodAttachOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{124} + return fileDescriptor_83c10c24ec417dc9, []int{125} } func (m *PodAttachOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3552,7 +3580,7 @@ var xxx_messageInfo_PodAttachOptions proto.InternalMessageInfo func (m *PodCondition) Reset() { *m = PodCondition{} } func (*PodCondition) ProtoMessage() {} func (*PodCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{125} + return fileDescriptor_83c10c24ec417dc9, []int{126} } func (m *PodCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3580,7 +3608,7 @@ var xxx_messageInfo_PodCondition proto.InternalMessageInfo func (m *PodDNSConfig) Reset() { *m = PodDNSConfig{} } func (*PodDNSConfig) ProtoMessage() {} func (*PodDNSConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{126} + return fileDescriptor_83c10c24ec417dc9, []int{127} } func (m *PodDNSConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3608,7 +3636,7 @@ var xxx_messageInfo_PodDNSConfig proto.InternalMessageInfo func (m *PodDNSConfigOption) Reset() { *m = PodDNSConfigOption{} } func (*PodDNSConfigOption) ProtoMessage() {} func (*PodDNSConfigOption) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{127} + return fileDescriptor_83c10c24ec417dc9, []int{128} } func (m *PodDNSConfigOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3636,7 +3664,7 @@ var xxx_messageInfo_PodDNSConfigOption proto.InternalMessageInfo func (m *PodExecOptions) Reset() { *m = PodExecOptions{} } func (*PodExecOptions) ProtoMessage() {} func (*PodExecOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{128} + return fileDescriptor_83c10c24ec417dc9, []int{129} } func (m *PodExecOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3664,7 +3692,7 @@ var xxx_messageInfo_PodExecOptions proto.InternalMessageInfo func (m *PodIP) Reset() { *m = PodIP{} } func (*PodIP) ProtoMessage() {} func (*PodIP) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{129} + return fileDescriptor_83c10c24ec417dc9, []int{130} } func (m *PodIP) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3692,7 +3720,7 @@ var xxx_messageInfo_PodIP proto.InternalMessageInfo func (m *PodList) Reset() { *m = PodList{} } func (*PodList) ProtoMessage() {} func (*PodList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{130} + return fileDescriptor_83c10c24ec417dc9, []int{131} } func (m *PodList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3720,7 +3748,7 @@ var xxx_messageInfo_PodList proto.InternalMessageInfo func (m *PodLogOptions) Reset() { *m = PodLogOptions{} } func (*PodLogOptions) ProtoMessage() {} func (*PodLogOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{131} + return fileDescriptor_83c10c24ec417dc9, []int{132} } func (m *PodLogOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3748,7 +3776,7 @@ var xxx_messageInfo_PodLogOptions proto.InternalMessageInfo func (m *PodOS) Reset() { *m = PodOS{} } func (*PodOS) ProtoMessage() {} func (*PodOS) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{132} + return fileDescriptor_83c10c24ec417dc9, []int{133} } func (m *PodOS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3776,7 +3804,7 @@ var xxx_messageInfo_PodOS proto.InternalMessageInfo func (m *PodPortForwardOptions) Reset() { *m = PodPortForwardOptions{} } func (*PodPortForwardOptions) ProtoMessage() {} func (*PodPortForwardOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{133} + return fileDescriptor_83c10c24ec417dc9, []int{134} } func (m *PodPortForwardOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3804,7 +3832,7 @@ var xxx_messageInfo_PodPortForwardOptions proto.InternalMessageInfo func (m *PodProxyOptions) Reset() { *m = PodProxyOptions{} } func (*PodProxyOptions) ProtoMessage() {} func (*PodProxyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{134} + return fileDescriptor_83c10c24ec417dc9, []int{135} } func (m *PodProxyOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3832,7 +3860,7 @@ var xxx_messageInfo_PodProxyOptions proto.InternalMessageInfo func (m *PodReadinessGate) Reset() { *m = PodReadinessGate{} } func (*PodReadinessGate) ProtoMessage() {} func (*PodReadinessGate) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{135} + return fileDescriptor_83c10c24ec417dc9, []int{136} } func (m *PodReadinessGate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3860,7 +3888,7 @@ var xxx_messageInfo_PodReadinessGate proto.InternalMessageInfo func (m *PodResourceClaim) Reset() { *m = PodResourceClaim{} } func (*PodResourceClaim) ProtoMessage() {} func (*PodResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{136} + return fileDescriptor_83c10c24ec417dc9, []int{137} } func (m *PodResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3888,7 +3916,7 @@ var xxx_messageInfo_PodResourceClaim proto.InternalMessageInfo func (m *PodSchedulingGate) Reset() { *m = PodSchedulingGate{} } func (*PodSchedulingGate) ProtoMessage() {} func (*PodSchedulingGate) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{137} + return fileDescriptor_83c10c24ec417dc9, []int{138} } func (m *PodSchedulingGate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3916,7 +3944,7 @@ var xxx_messageInfo_PodSchedulingGate proto.InternalMessageInfo func (m *PodSecurityContext) Reset() { *m = PodSecurityContext{} } func (*PodSecurityContext) ProtoMessage() {} func (*PodSecurityContext) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{138} + return fileDescriptor_83c10c24ec417dc9, []int{139} } func (m *PodSecurityContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3944,7 +3972,7 @@ var xxx_messageInfo_PodSecurityContext proto.InternalMessageInfo func (m *PodSignature) Reset() { *m = PodSignature{} } func (*PodSignature) ProtoMessage() {} func (*PodSignature) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{139} + return fileDescriptor_83c10c24ec417dc9, []int{140} } func (m *PodSignature) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3972,7 +4000,7 @@ var xxx_messageInfo_PodSignature proto.InternalMessageInfo func (m *PodSpec) Reset() { *m = PodSpec{} } func (*PodSpec) ProtoMessage() {} func (*PodSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{140} + return fileDescriptor_83c10c24ec417dc9, []int{141} } func (m *PodSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4000,7 +4028,7 @@ var xxx_messageInfo_PodSpec proto.InternalMessageInfo func (m *PodStatus) Reset() { *m = PodStatus{} } func (*PodStatus) ProtoMessage() {} func (*PodStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{141} + return fileDescriptor_83c10c24ec417dc9, []int{142} } func (m *PodStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4028,7 +4056,7 @@ var xxx_messageInfo_PodStatus proto.InternalMessageInfo func (m *PodStatusResult) Reset() { *m = PodStatusResult{} } func (*PodStatusResult) ProtoMessage() {} func (*PodStatusResult) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{142} + return fileDescriptor_83c10c24ec417dc9, []int{143} } func (m *PodStatusResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4056,7 +4084,7 @@ var xxx_messageInfo_PodStatusResult proto.InternalMessageInfo func (m *PodTemplate) Reset() { *m = PodTemplate{} } func (*PodTemplate) ProtoMessage() {} func (*PodTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{143} + return fileDescriptor_83c10c24ec417dc9, []int{144} } func (m *PodTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4084,7 +4112,7 @@ var xxx_messageInfo_PodTemplate proto.InternalMessageInfo func (m *PodTemplateList) Reset() { *m = PodTemplateList{} } func (*PodTemplateList) ProtoMessage() {} func (*PodTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{144} + return fileDescriptor_83c10c24ec417dc9, []int{145} } func (m *PodTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4112,7 +4140,7 @@ var xxx_messageInfo_PodTemplateList proto.InternalMessageInfo func (m *PodTemplateSpec) Reset() { *m = PodTemplateSpec{} } func (*PodTemplateSpec) ProtoMessage() {} func (*PodTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{145} + return fileDescriptor_83c10c24ec417dc9, []int{146} } func (m *PodTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4140,7 +4168,7 @@ var xxx_messageInfo_PodTemplateSpec proto.InternalMessageInfo func (m *PortStatus) Reset() { *m = PortStatus{} } func (*PortStatus) ProtoMessage() {} func (*PortStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{146} + return fileDescriptor_83c10c24ec417dc9, []int{147} } func (m *PortStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4168,7 +4196,7 @@ var xxx_messageInfo_PortStatus proto.InternalMessageInfo func (m *PortworxVolumeSource) Reset() { *m = PortworxVolumeSource{} } func (*PortworxVolumeSource) ProtoMessage() {} func (*PortworxVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{147} + return fileDescriptor_83c10c24ec417dc9, []int{148} } func (m *PortworxVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4196,7 +4224,7 @@ var xxx_messageInfo_PortworxVolumeSource proto.InternalMessageInfo func (m *Preconditions) Reset() { *m = Preconditions{} } func (*Preconditions) ProtoMessage() {} func (*Preconditions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{148} + return fileDescriptor_83c10c24ec417dc9, []int{149} } func (m *Preconditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4224,7 +4252,7 @@ var xxx_messageInfo_Preconditions proto.InternalMessageInfo func (m *PreferAvoidPodsEntry) Reset() { *m = PreferAvoidPodsEntry{} } func (*PreferAvoidPodsEntry) ProtoMessage() {} func (*PreferAvoidPodsEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{149} + return fileDescriptor_83c10c24ec417dc9, []int{150} } func (m *PreferAvoidPodsEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4252,7 +4280,7 @@ var xxx_messageInfo_PreferAvoidPodsEntry proto.InternalMessageInfo func (m *PreferredSchedulingTerm) Reset() { *m = PreferredSchedulingTerm{} } func (*PreferredSchedulingTerm) ProtoMessage() {} func (*PreferredSchedulingTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{150} + return fileDescriptor_83c10c24ec417dc9, []int{151} } func (m *PreferredSchedulingTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4280,7 +4308,7 @@ var xxx_messageInfo_PreferredSchedulingTerm proto.InternalMessageInfo func (m *Probe) Reset() { *m = Probe{} } func (*Probe) ProtoMessage() {} func (*Probe) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{151} + return fileDescriptor_83c10c24ec417dc9, []int{152} } func (m *Probe) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4308,7 +4336,7 @@ var xxx_messageInfo_Probe proto.InternalMessageInfo func (m *ProbeHandler) Reset() { *m = ProbeHandler{} } func (*ProbeHandler) ProtoMessage() {} func (*ProbeHandler) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{152} + return fileDescriptor_83c10c24ec417dc9, []int{153} } func (m *ProbeHandler) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4336,7 +4364,7 @@ var xxx_messageInfo_ProbeHandler proto.InternalMessageInfo func (m *ProjectedVolumeSource) Reset() { *m = ProjectedVolumeSource{} } func (*ProjectedVolumeSource) ProtoMessage() {} func (*ProjectedVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{153} + return fileDescriptor_83c10c24ec417dc9, []int{154} } func (m *ProjectedVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4364,7 +4392,7 @@ var xxx_messageInfo_ProjectedVolumeSource proto.InternalMessageInfo func (m *QuobyteVolumeSource) Reset() { *m = QuobyteVolumeSource{} } func (*QuobyteVolumeSource) ProtoMessage() {} func (*QuobyteVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{154} + return fileDescriptor_83c10c24ec417dc9, []int{155} } func (m *QuobyteVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4392,7 +4420,7 @@ var xxx_messageInfo_QuobyteVolumeSource proto.InternalMessageInfo func (m *RBDPersistentVolumeSource) Reset() { *m = RBDPersistentVolumeSource{} } func (*RBDPersistentVolumeSource) ProtoMessage() {} func (*RBDPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{155} + return fileDescriptor_83c10c24ec417dc9, []int{156} } func (m *RBDPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4420,7 +4448,7 @@ var xxx_messageInfo_RBDPersistentVolumeSource proto.InternalMessageInfo func (m *RBDVolumeSource) Reset() { *m = RBDVolumeSource{} } func (*RBDVolumeSource) ProtoMessage() {} func (*RBDVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{156} + return fileDescriptor_83c10c24ec417dc9, []int{157} } func (m *RBDVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4448,7 +4476,7 @@ var xxx_messageInfo_RBDVolumeSource proto.InternalMessageInfo func (m *RangeAllocation) Reset() { *m = RangeAllocation{} } func (*RangeAllocation) ProtoMessage() {} func (*RangeAllocation) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{157} + return fileDescriptor_83c10c24ec417dc9, []int{158} } func (m *RangeAllocation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4476,7 +4504,7 @@ var xxx_messageInfo_RangeAllocation proto.InternalMessageInfo func (m *ReplicationController) Reset() { *m = ReplicationController{} } func (*ReplicationController) ProtoMessage() {} func (*ReplicationController) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{158} + return fileDescriptor_83c10c24ec417dc9, []int{159} } func (m *ReplicationController) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4504,7 +4532,7 @@ var xxx_messageInfo_ReplicationController proto.InternalMessageInfo func (m *ReplicationControllerCondition) Reset() { *m = ReplicationControllerCondition{} } func (*ReplicationControllerCondition) ProtoMessage() {} func (*ReplicationControllerCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{159} + return fileDescriptor_83c10c24ec417dc9, []int{160} } func (m *ReplicationControllerCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4532,7 +4560,7 @@ var xxx_messageInfo_ReplicationControllerCondition proto.InternalMessageInfo func (m *ReplicationControllerList) Reset() { *m = ReplicationControllerList{} } func (*ReplicationControllerList) ProtoMessage() {} func (*ReplicationControllerList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{160} + return fileDescriptor_83c10c24ec417dc9, []int{161} } func (m *ReplicationControllerList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4560,7 +4588,7 @@ var xxx_messageInfo_ReplicationControllerList proto.InternalMessageInfo func (m *ReplicationControllerSpec) Reset() { *m = ReplicationControllerSpec{} } func (*ReplicationControllerSpec) ProtoMessage() {} func (*ReplicationControllerSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{161} + return fileDescriptor_83c10c24ec417dc9, []int{162} } func (m *ReplicationControllerSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4588,7 +4616,7 @@ var xxx_messageInfo_ReplicationControllerSpec proto.InternalMessageInfo func (m *ReplicationControllerStatus) Reset() { *m = ReplicationControllerStatus{} } func (*ReplicationControllerStatus) ProtoMessage() {} func (*ReplicationControllerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{162} + return fileDescriptor_83c10c24ec417dc9, []int{163} } func (m *ReplicationControllerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4616,7 +4644,7 @@ var xxx_messageInfo_ReplicationControllerStatus proto.InternalMessageInfo func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } func (*ResourceClaim) ProtoMessage() {} func (*ResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{163} + return fileDescriptor_83c10c24ec417dc9, []int{164} } func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4644,7 +4672,7 @@ var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo func (m *ResourceFieldSelector) Reset() { *m = ResourceFieldSelector{} } func (*ResourceFieldSelector) ProtoMessage() {} func (*ResourceFieldSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{164} + return fileDescriptor_83c10c24ec417dc9, []int{165} } func (m *ResourceFieldSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4672,7 +4700,7 @@ var xxx_messageInfo_ResourceFieldSelector proto.InternalMessageInfo func (m *ResourceQuota) Reset() { *m = ResourceQuota{} } func (*ResourceQuota) ProtoMessage() {} func (*ResourceQuota) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{165} + return fileDescriptor_83c10c24ec417dc9, []int{166} } func (m *ResourceQuota) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4700,7 +4728,7 @@ var xxx_messageInfo_ResourceQuota proto.InternalMessageInfo func (m *ResourceQuotaList) Reset() { *m = ResourceQuotaList{} } func (*ResourceQuotaList) ProtoMessage() {} func (*ResourceQuotaList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{166} + return fileDescriptor_83c10c24ec417dc9, []int{167} } func (m *ResourceQuotaList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4728,7 +4756,7 @@ var xxx_messageInfo_ResourceQuotaList proto.InternalMessageInfo func (m *ResourceQuotaSpec) Reset() { *m = ResourceQuotaSpec{} } func (*ResourceQuotaSpec) ProtoMessage() {} func (*ResourceQuotaSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{167} + return fileDescriptor_83c10c24ec417dc9, []int{168} } func (m *ResourceQuotaSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4756,7 +4784,7 @@ var xxx_messageInfo_ResourceQuotaSpec proto.InternalMessageInfo func (m *ResourceQuotaStatus) Reset() { *m = ResourceQuotaStatus{} } func (*ResourceQuotaStatus) ProtoMessage() {} func (*ResourceQuotaStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{168} + return fileDescriptor_83c10c24ec417dc9, []int{169} } func (m *ResourceQuotaStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4784,7 +4812,7 @@ var xxx_messageInfo_ResourceQuotaStatus proto.InternalMessageInfo func (m *ResourceRequirements) Reset() { *m = ResourceRequirements{} } func (*ResourceRequirements) ProtoMessage() {} func (*ResourceRequirements) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{169} + return fileDescriptor_83c10c24ec417dc9, []int{170} } func (m *ResourceRequirements) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4812,7 +4840,7 @@ var xxx_messageInfo_ResourceRequirements proto.InternalMessageInfo func (m *SELinuxOptions) Reset() { *m = SELinuxOptions{} } func (*SELinuxOptions) ProtoMessage() {} func (*SELinuxOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{170} + return fileDescriptor_83c10c24ec417dc9, []int{171} } func (m *SELinuxOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4840,7 +4868,7 @@ var xxx_messageInfo_SELinuxOptions proto.InternalMessageInfo func (m *ScaleIOPersistentVolumeSource) Reset() { *m = ScaleIOPersistentVolumeSource{} } func (*ScaleIOPersistentVolumeSource) ProtoMessage() {} func (*ScaleIOPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{171} + return fileDescriptor_83c10c24ec417dc9, []int{172} } func (m *ScaleIOPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4868,7 +4896,7 @@ var xxx_messageInfo_ScaleIOPersistentVolumeSource proto.InternalMessageInfo func (m *ScaleIOVolumeSource) Reset() { *m = ScaleIOVolumeSource{} } func (*ScaleIOVolumeSource) ProtoMessage() {} func (*ScaleIOVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{172} + return fileDescriptor_83c10c24ec417dc9, []int{173} } func (m *ScaleIOVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4896,7 +4924,7 @@ var xxx_messageInfo_ScaleIOVolumeSource proto.InternalMessageInfo func (m *ScopeSelector) Reset() { *m = ScopeSelector{} } func (*ScopeSelector) ProtoMessage() {} func (*ScopeSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{173} + return fileDescriptor_83c10c24ec417dc9, []int{174} } func (m *ScopeSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4924,7 +4952,7 @@ var xxx_messageInfo_ScopeSelector proto.InternalMessageInfo func (m *ScopedResourceSelectorRequirement) Reset() { *m = ScopedResourceSelectorRequirement{} } func (*ScopedResourceSelectorRequirement) ProtoMessage() {} func (*ScopedResourceSelectorRequirement) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{174} + return fileDescriptor_83c10c24ec417dc9, []int{175} } func (m *ScopedResourceSelectorRequirement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4952,7 +4980,7 @@ var xxx_messageInfo_ScopedResourceSelectorRequirement proto.InternalMessageInfo func (m *SeccompProfile) Reset() { *m = SeccompProfile{} } func (*SeccompProfile) ProtoMessage() {} func (*SeccompProfile) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{175} + return fileDescriptor_83c10c24ec417dc9, []int{176} } func (m *SeccompProfile) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4980,7 +5008,7 @@ var xxx_messageInfo_SeccompProfile proto.InternalMessageInfo func (m *Secret) Reset() { *m = Secret{} } func (*Secret) ProtoMessage() {} func (*Secret) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{176} + return fileDescriptor_83c10c24ec417dc9, []int{177} } func (m *Secret) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5008,7 +5036,7 @@ var xxx_messageInfo_Secret proto.InternalMessageInfo func (m *SecretEnvSource) Reset() { *m = SecretEnvSource{} } func (*SecretEnvSource) ProtoMessage() {} func (*SecretEnvSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{177} + return fileDescriptor_83c10c24ec417dc9, []int{178} } func (m *SecretEnvSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5036,7 +5064,7 @@ var xxx_messageInfo_SecretEnvSource proto.InternalMessageInfo func (m *SecretKeySelector) Reset() { *m = SecretKeySelector{} } func (*SecretKeySelector) ProtoMessage() {} func (*SecretKeySelector) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{178} + return fileDescriptor_83c10c24ec417dc9, []int{179} } func (m *SecretKeySelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5064,7 +5092,7 @@ var xxx_messageInfo_SecretKeySelector proto.InternalMessageInfo func (m *SecretList) Reset() { *m = SecretList{} } func (*SecretList) ProtoMessage() {} func (*SecretList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{179} + return fileDescriptor_83c10c24ec417dc9, []int{180} } func (m *SecretList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5092,7 +5120,7 @@ var xxx_messageInfo_SecretList proto.InternalMessageInfo func (m *SecretProjection) Reset() { *m = SecretProjection{} } func (*SecretProjection) ProtoMessage() {} func (*SecretProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{180} + return fileDescriptor_83c10c24ec417dc9, []int{181} } func (m *SecretProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5120,7 +5148,7 @@ var xxx_messageInfo_SecretProjection proto.InternalMessageInfo func (m *SecretReference) Reset() { *m = SecretReference{} } func (*SecretReference) ProtoMessage() {} func (*SecretReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{181} + return fileDescriptor_83c10c24ec417dc9, []int{182} } func (m *SecretReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5148,7 +5176,7 @@ var xxx_messageInfo_SecretReference proto.InternalMessageInfo func (m *SecretVolumeSource) Reset() { *m = SecretVolumeSource{} } func (*SecretVolumeSource) ProtoMessage() {} func (*SecretVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{182} + return fileDescriptor_83c10c24ec417dc9, []int{183} } func (m *SecretVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5176,7 +5204,7 @@ var xxx_messageInfo_SecretVolumeSource proto.InternalMessageInfo func (m *SecurityContext) Reset() { *m = SecurityContext{} } func (*SecurityContext) ProtoMessage() {} func (*SecurityContext) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{183} + return fileDescriptor_83c10c24ec417dc9, []int{184} } func (m *SecurityContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5204,7 +5232,7 @@ var xxx_messageInfo_SecurityContext proto.InternalMessageInfo func (m *SerializedReference) Reset() { *m = SerializedReference{} } func (*SerializedReference) ProtoMessage() {} func (*SerializedReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{184} + return fileDescriptor_83c10c24ec417dc9, []int{185} } func (m *SerializedReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5232,7 +5260,7 @@ var xxx_messageInfo_SerializedReference proto.InternalMessageInfo func (m *Service) Reset() { *m = Service{} } func (*Service) ProtoMessage() {} func (*Service) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{185} + return fileDescriptor_83c10c24ec417dc9, []int{186} } func (m *Service) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5260,7 +5288,7 @@ var xxx_messageInfo_Service proto.InternalMessageInfo func (m *ServiceAccount) Reset() { *m = ServiceAccount{} } func (*ServiceAccount) ProtoMessage() {} func (*ServiceAccount) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{186} + return fileDescriptor_83c10c24ec417dc9, []int{187} } func (m *ServiceAccount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5288,7 +5316,7 @@ var xxx_messageInfo_ServiceAccount proto.InternalMessageInfo func (m *ServiceAccountList) Reset() { *m = ServiceAccountList{} } func (*ServiceAccountList) ProtoMessage() {} func (*ServiceAccountList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{187} + return fileDescriptor_83c10c24ec417dc9, []int{188} } func (m *ServiceAccountList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5316,7 +5344,7 @@ var xxx_messageInfo_ServiceAccountList proto.InternalMessageInfo func (m *ServiceAccountTokenProjection) Reset() { *m = ServiceAccountTokenProjection{} } func (*ServiceAccountTokenProjection) ProtoMessage() {} func (*ServiceAccountTokenProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{188} + return fileDescriptor_83c10c24ec417dc9, []int{189} } func (m *ServiceAccountTokenProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5344,7 +5372,7 @@ var xxx_messageInfo_ServiceAccountTokenProjection proto.InternalMessageInfo func (m *ServiceList) Reset() { *m = ServiceList{} } func (*ServiceList) ProtoMessage() {} func (*ServiceList) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{189} + return fileDescriptor_83c10c24ec417dc9, []int{190} } func (m *ServiceList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5372,7 +5400,7 @@ var xxx_messageInfo_ServiceList proto.InternalMessageInfo func (m *ServicePort) Reset() { *m = ServicePort{} } func (*ServicePort) ProtoMessage() {} func (*ServicePort) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{190} + return fileDescriptor_83c10c24ec417dc9, []int{191} } func (m *ServicePort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5400,7 +5428,7 @@ var xxx_messageInfo_ServicePort proto.InternalMessageInfo func (m *ServiceProxyOptions) Reset() { *m = ServiceProxyOptions{} } func (*ServiceProxyOptions) ProtoMessage() {} func (*ServiceProxyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{191} + return fileDescriptor_83c10c24ec417dc9, []int{192} } func (m *ServiceProxyOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5428,7 +5456,7 @@ var xxx_messageInfo_ServiceProxyOptions proto.InternalMessageInfo func (m *ServiceSpec) Reset() { *m = ServiceSpec{} } func (*ServiceSpec) ProtoMessage() {} func (*ServiceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{192} + return fileDescriptor_83c10c24ec417dc9, []int{193} } func (m *ServiceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5456,7 +5484,7 @@ var xxx_messageInfo_ServiceSpec proto.InternalMessageInfo func (m *ServiceStatus) Reset() { *m = ServiceStatus{} } func (*ServiceStatus) ProtoMessage() {} func (*ServiceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{193} + return fileDescriptor_83c10c24ec417dc9, []int{194} } func (m *ServiceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5484,7 +5512,7 @@ var xxx_messageInfo_ServiceStatus proto.InternalMessageInfo func (m *SessionAffinityConfig) Reset() { *m = SessionAffinityConfig{} } func (*SessionAffinityConfig) ProtoMessage() {} func (*SessionAffinityConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{194} + return fileDescriptor_83c10c24ec417dc9, []int{195} } func (m *SessionAffinityConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5512,7 +5540,7 @@ var xxx_messageInfo_SessionAffinityConfig proto.InternalMessageInfo func (m *StorageOSPersistentVolumeSource) Reset() { *m = StorageOSPersistentVolumeSource{} } func (*StorageOSPersistentVolumeSource) ProtoMessage() {} func (*StorageOSPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{195} + return fileDescriptor_83c10c24ec417dc9, []int{196} } func (m *StorageOSPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5540,7 +5568,7 @@ var xxx_messageInfo_StorageOSPersistentVolumeSource proto.InternalMessageInfo func (m *StorageOSVolumeSource) Reset() { *m = StorageOSVolumeSource{} } func (*StorageOSVolumeSource) ProtoMessage() {} func (*StorageOSVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{196} + return fileDescriptor_83c10c24ec417dc9, []int{197} } func (m *StorageOSVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5568,7 +5596,7 @@ var xxx_messageInfo_StorageOSVolumeSource proto.InternalMessageInfo func (m *Sysctl) Reset() { *m = Sysctl{} } func (*Sysctl) ProtoMessage() {} func (*Sysctl) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{197} + return fileDescriptor_83c10c24ec417dc9, []int{198} } func (m *Sysctl) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5596,7 +5624,7 @@ var xxx_messageInfo_Sysctl proto.InternalMessageInfo func (m *TCPSocketAction) Reset() { *m = TCPSocketAction{} } func (*TCPSocketAction) ProtoMessage() {} func (*TCPSocketAction) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{198} + return fileDescriptor_83c10c24ec417dc9, []int{199} } func (m *TCPSocketAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5624,7 +5652,7 @@ var xxx_messageInfo_TCPSocketAction proto.InternalMessageInfo func (m *Taint) Reset() { *m = Taint{} } func (*Taint) ProtoMessage() {} func (*Taint) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{199} + return fileDescriptor_83c10c24ec417dc9, []int{200} } func (m *Taint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5652,7 +5680,7 @@ var xxx_messageInfo_Taint proto.InternalMessageInfo func (m *Toleration) Reset() { *m = Toleration{} } func (*Toleration) ProtoMessage() {} func (*Toleration) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{200} + return fileDescriptor_83c10c24ec417dc9, []int{201} } func (m *Toleration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5680,7 +5708,7 @@ var xxx_messageInfo_Toleration proto.InternalMessageInfo func (m *TopologySelectorLabelRequirement) Reset() { *m = TopologySelectorLabelRequirement{} } func (*TopologySelectorLabelRequirement) ProtoMessage() {} func (*TopologySelectorLabelRequirement) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{201} + return fileDescriptor_83c10c24ec417dc9, []int{202} } func (m *TopologySelectorLabelRequirement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5708,7 +5736,7 @@ var xxx_messageInfo_TopologySelectorLabelRequirement proto.InternalMessageInfo func (m *TopologySelectorTerm) Reset() { *m = TopologySelectorTerm{} } func (*TopologySelectorTerm) ProtoMessage() {} func (*TopologySelectorTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{202} + return fileDescriptor_83c10c24ec417dc9, []int{203} } func (m *TopologySelectorTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5736,7 +5764,7 @@ var xxx_messageInfo_TopologySelectorTerm proto.InternalMessageInfo func (m *TopologySpreadConstraint) Reset() { *m = TopologySpreadConstraint{} } func (*TopologySpreadConstraint) ProtoMessage() {} func (*TopologySpreadConstraint) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{203} + return fileDescriptor_83c10c24ec417dc9, []int{204} } func (m *TopologySpreadConstraint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5764,7 +5792,7 @@ var xxx_messageInfo_TopologySpreadConstraint proto.InternalMessageInfo func (m *TypedLocalObjectReference) Reset() { *m = TypedLocalObjectReference{} } func (*TypedLocalObjectReference) ProtoMessage() {} func (*TypedLocalObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{204} + return fileDescriptor_83c10c24ec417dc9, []int{205} } func (m *TypedLocalObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5792,7 +5820,7 @@ var xxx_messageInfo_TypedLocalObjectReference proto.InternalMessageInfo func (m *TypedObjectReference) Reset() { *m = TypedObjectReference{} } func (*TypedObjectReference) ProtoMessage() {} func (*TypedObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{205} + return fileDescriptor_83c10c24ec417dc9, []int{206} } func (m *TypedObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5820,7 +5848,7 @@ var xxx_messageInfo_TypedObjectReference proto.InternalMessageInfo func (m *Volume) Reset() { *m = Volume{} } func (*Volume) ProtoMessage() {} func (*Volume) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{206} + return fileDescriptor_83c10c24ec417dc9, []int{207} } func (m *Volume) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5848,7 +5876,7 @@ var xxx_messageInfo_Volume proto.InternalMessageInfo func (m *VolumeDevice) Reset() { *m = VolumeDevice{} } func (*VolumeDevice) ProtoMessage() {} func (*VolumeDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{207} + return fileDescriptor_83c10c24ec417dc9, []int{208} } func (m *VolumeDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5876,7 +5904,7 @@ var xxx_messageInfo_VolumeDevice proto.InternalMessageInfo func (m *VolumeMount) Reset() { *m = VolumeMount{} } func (*VolumeMount) ProtoMessage() {} func (*VolumeMount) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{208} + return fileDescriptor_83c10c24ec417dc9, []int{209} } func (m *VolumeMount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5904,7 +5932,7 @@ var xxx_messageInfo_VolumeMount proto.InternalMessageInfo func (m *VolumeNodeAffinity) Reset() { *m = VolumeNodeAffinity{} } func (*VolumeNodeAffinity) ProtoMessage() {} func (*VolumeNodeAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{209} + return fileDescriptor_83c10c24ec417dc9, []int{210} } func (m *VolumeNodeAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5932,7 +5960,7 @@ var xxx_messageInfo_VolumeNodeAffinity proto.InternalMessageInfo func (m *VolumeProjection) Reset() { *m = VolumeProjection{} } func (*VolumeProjection) ProtoMessage() {} func (*VolumeProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{210} + return fileDescriptor_83c10c24ec417dc9, []int{211} } func (m *VolumeProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5960,7 +5988,7 @@ var xxx_messageInfo_VolumeProjection proto.InternalMessageInfo func (m *VolumeSource) Reset() { *m = VolumeSource{} } func (*VolumeSource) ProtoMessage() {} func (*VolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{211} + return fileDescriptor_83c10c24ec417dc9, []int{212} } func (m *VolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5988,7 +6016,7 @@ var xxx_messageInfo_VolumeSource proto.InternalMessageInfo func (m *VsphereVirtualDiskVolumeSource) Reset() { *m = VsphereVirtualDiskVolumeSource{} } func (*VsphereVirtualDiskVolumeSource) ProtoMessage() {} func (*VsphereVirtualDiskVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{212} + return fileDescriptor_83c10c24ec417dc9, []int{213} } func (m *VsphereVirtualDiskVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6016,7 +6044,7 @@ var xxx_messageInfo_VsphereVirtualDiskVolumeSource proto.InternalMessageInfo func (m *WeightedPodAffinityTerm) Reset() { *m = WeightedPodAffinityTerm{} } func (*WeightedPodAffinityTerm) ProtoMessage() {} func (*WeightedPodAffinityTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{213} + return fileDescriptor_83c10c24ec417dc9, []int{214} } func (m *WeightedPodAffinityTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6044,7 +6072,7 @@ var xxx_messageInfo_WeightedPodAffinityTerm proto.InternalMessageInfo func (m *WindowsSecurityContextOptions) Reset() { *m = WindowsSecurityContextOptions{} } func (*WindowsSecurityContextOptions) ProtoMessage() {} func (*WindowsSecurityContextOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_83c10c24ec417dc9, []int{214} + return fileDescriptor_83c10c24ec417dc9, []int{215} } func (m *WindowsSecurityContextOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6104,11 +6132,13 @@ func init() { proto.RegisterType((*Container)(nil), "k8s.io.api.core.v1.Container") proto.RegisterType((*ContainerImage)(nil), "k8s.io.api.core.v1.ContainerImage") proto.RegisterType((*ContainerPort)(nil), "k8s.io.api.core.v1.ContainerPort") + proto.RegisterType((*ContainerResizePolicy)(nil), "k8s.io.api.core.v1.ContainerResizePolicy") proto.RegisterType((*ContainerState)(nil), "k8s.io.api.core.v1.ContainerState") proto.RegisterType((*ContainerStateRunning)(nil), "k8s.io.api.core.v1.ContainerStateRunning") proto.RegisterType((*ContainerStateTerminated)(nil), "k8s.io.api.core.v1.ContainerStateTerminated") proto.RegisterType((*ContainerStateWaiting)(nil), "k8s.io.api.core.v1.ContainerStateWaiting") proto.RegisterType((*ContainerStatus)(nil), "k8s.io.api.core.v1.ContainerStatus") + proto.RegisterMapType((ResourceList)(nil), "k8s.io.api.core.v1.ContainerStatus.AllocatedResourcesEntry") proto.RegisterType((*DaemonEndpoint)(nil), "k8s.io.api.core.v1.DaemonEndpoint") proto.RegisterType((*DownwardAPIProjection)(nil), "k8s.io.api.core.v1.DownwardAPIProjection") proto.RegisterType((*DownwardAPIVolumeFile)(nil), "k8s.io.api.core.v1.DownwardAPIVolumeFile") @@ -6320,917 +6350,925 @@ func init() { } var fileDescriptor_83c10c24ec417dc9 = []byte{ - // 14547 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x69, 0x8c, 0x24, 0xd7, - 0x79, 0x98, 0xaa, 0x7b, 0xae, 0xfe, 0xe6, 0x7e, 0xb3, 0xbb, 0x9c, 0x1d, 0x72, 0x77, 0x96, 0x45, - 0x72, 0xb9, 0x14, 0xc9, 0x19, 0x2d, 0x0f, 0x89, 0x26, 0x25, 0x5a, 0x73, 0xee, 0x36, 0x77, 0x67, - 0xb6, 0xf9, 0x7a, 0x76, 0x57, 0x07, 0x25, 0xa8, 0xa6, 0xfb, 0xcd, 0x4c, 0x69, 0xba, 0xab, 0x9a, - 0x55, 0xd5, 0xb3, 0x3b, 0x8c, 0x84, 0x38, 0xf2, 0x29, 0xdb, 0x09, 0x84, 0xc0, 0x39, 0x20, 0x1b, - 0x46, 0xe0, 0x38, 0xb6, 0x15, 0xe5, 0x52, 0xe4, 0xd8, 0x8e, 0xe5, 0xd8, 0xce, 0xed, 0x04, 0x81, - 0xe3, 0x18, 0x88, 0x65, 0xc0, 0xc8, 0xc4, 0x5e, 0x07, 0x30, 0x04, 0x24, 0xb6, 0x73, 0x01, 0xc9, - 0xc4, 0x89, 0x83, 0x77, 0xd6, 0x7b, 0x75, 0x74, 0xf7, 0x2c, 0x67, 0x47, 0x94, 0xc0, 0x7f, 0xdd, - 0xdf, 0xf7, 0xbd, 0xef, 0xbd, 0x7a, 0xe7, 0xf7, 0xbe, 0xef, 0x7b, 0xdf, 0x07, 0xaf, 0xec, 0xbe, - 0x14, 0xce, 0xb9, 0xfe, 0xfc, 0x6e, 0x7b, 0x93, 0x04, 0x1e, 0x89, 0x48, 0x38, 0xbf, 0x47, 0xbc, - 0xba, 0x1f, 0xcc, 0x0b, 0x84, 0xd3, 0x72, 0xe7, 0x6b, 0x7e, 0x40, 0xe6, 0xf7, 0x2e, 0xcf, 0x6f, - 0x13, 0x8f, 0x04, 0x4e, 0x44, 0xea, 0x73, 0xad, 0xc0, 0x8f, 0x7c, 0x84, 0x38, 0xcd, 0x9c, 0xd3, - 0x72, 0xe7, 0x28, 0xcd, 0xdc, 0xde, 0xe5, 0x99, 0x67, 0xb7, 0xdd, 0x68, 0xa7, 0xbd, 0x39, 0x57, - 0xf3, 0x9b, 0xf3, 0xdb, 0xfe, 0xb6, 0x3f, 0xcf, 0x48, 0x37, 0xdb, 0x5b, 0xec, 0x1f, 0xfb, 0xc3, - 0x7e, 0x71, 0x16, 0x33, 0x2f, 0xc4, 0xd5, 0x34, 0x9d, 0xda, 0x8e, 0xeb, 0x91, 0x60, 0x7f, 0xbe, - 0xb5, 0xbb, 0xcd, 0xea, 0x0d, 0x48, 0xe8, 0xb7, 0x83, 0x1a, 0x49, 0x56, 0xdc, 0xb1, 0x54, 0x38, - 0xdf, 0x24, 0x91, 0x93, 0xd1, 0xdc, 0x99, 0xf9, 0xbc, 0x52, 0x41, 0xdb, 0x8b, 0xdc, 0x66, 0xba, - 0x9a, 0xf7, 0x77, 0x2b, 0x10, 0xd6, 0x76, 0x48, 0xd3, 0x49, 0x95, 0x7b, 0x3e, 0xaf, 0x5c, 0x3b, - 0x72, 0x1b, 0xf3, 0xae, 0x17, 0x85, 0x51, 0x90, 0x2c, 0x64, 0x7f, 0xdd, 0x82, 0x0b, 0x0b, 0xb7, - 0xab, 0x2b, 0x0d, 0x27, 0x8c, 0xdc, 0xda, 0x62, 0xc3, 0xaf, 0xed, 0x56, 0x23, 0x3f, 0x20, 0xb7, - 0xfc, 0x46, 0xbb, 0x49, 0xaa, 0xac, 0x23, 0xd0, 0x33, 0x30, 0xb4, 0xc7, 0xfe, 0x97, 0x97, 0xa7, - 0xad, 0x0b, 0xd6, 0xa5, 0xd2, 0xe2, 0xc4, 0xaf, 0x1d, 0xcc, 0xbe, 0xe7, 0xde, 0xc1, 0xec, 0xd0, - 0x2d, 0x01, 0xc7, 0x8a, 0x02, 0x5d, 0x84, 0x81, 0xad, 0x70, 0x63, 0xbf, 0x45, 0xa6, 0x0b, 0x8c, - 0x76, 0x4c, 0xd0, 0x0e, 0xac, 0x56, 0x29, 0x14, 0x0b, 0x2c, 0x9a, 0x87, 0x52, 0xcb, 0x09, 0x22, - 0x37, 0x72, 0x7d, 0x6f, 0xba, 0x78, 0xc1, 0xba, 0xd4, 0xbf, 0x38, 0x29, 0x48, 0x4b, 0x15, 0x89, - 0xc0, 0x31, 0x0d, 0x6d, 0x46, 0x40, 0x9c, 0xfa, 0x0d, 0xaf, 0xb1, 0x3f, 0xdd, 0x77, 0xc1, 0xba, - 0x34, 0x14, 0x37, 0x03, 0x0b, 0x38, 0x56, 0x14, 0xf6, 0x17, 0x0b, 0x30, 0xb4, 0xb0, 0xb5, 0xe5, - 0x7a, 0x6e, 0xb4, 0x8f, 0x6e, 0xc1, 0x88, 0xe7, 0xd7, 0x89, 0xfc, 0xcf, 0xbe, 0x62, 0xf8, 0xb9, - 0x0b, 0x73, 0xe9, 0xa9, 0x34, 0xb7, 0xae, 0xd1, 0x2d, 0x4e, 0xdc, 0x3b, 0x98, 0x1d, 0xd1, 0x21, - 0xd8, 0xe0, 0x83, 0x30, 0x0c, 0xb7, 0xfc, 0xba, 0x62, 0x5b, 0x60, 0x6c, 0x67, 0xb3, 0xd8, 0x56, - 0x62, 0xb2, 0xc5, 0xf1, 0x7b, 0x07, 0xb3, 0xc3, 0x1a, 0x00, 0xeb, 0x4c, 0xd0, 0x26, 0x8c, 0xd3, - 0xbf, 0x5e, 0xe4, 0x2a, 0xbe, 0x45, 0xc6, 0xf7, 0xb1, 0x3c, 0xbe, 0x1a, 0xe9, 0xe2, 0xd4, 0xbd, - 0x83, 0xd9, 0xf1, 0x04, 0x10, 0x27, 0x19, 0xda, 0x6f, 0xc1, 0xd8, 0x42, 0x14, 0x39, 0xb5, 0x1d, - 0x52, 0xe7, 0x23, 0x88, 0x5e, 0x80, 0x3e, 0xcf, 0x69, 0x12, 0x31, 0xbe, 0x17, 0x44, 0xc7, 0xf6, - 0xad, 0x3b, 0x4d, 0x72, 0x78, 0x30, 0x3b, 0x71, 0xd3, 0x73, 0xdf, 0x6c, 0x8b, 0x59, 0x41, 0x61, - 0x98, 0x51, 0xa3, 0xe7, 0x00, 0xea, 0x64, 0xcf, 0xad, 0x91, 0x8a, 0x13, 0xed, 0x88, 0xf1, 0x46, - 0xa2, 0x2c, 0x2c, 0x2b, 0x0c, 0xd6, 0xa8, 0xec, 0xbb, 0x50, 0x5a, 0xd8, 0xf3, 0xdd, 0x7a, 0xc5, - 0xaf, 0x87, 0x68, 0x17, 0xc6, 0x5b, 0x01, 0xd9, 0x22, 0x81, 0x02, 0x4d, 0x5b, 0x17, 0x8a, 0x97, - 0x86, 0x9f, 0xbb, 0x94, 0xf9, 0xb1, 0x26, 0xe9, 0x8a, 0x17, 0x05, 0xfb, 0x8b, 0x0f, 0x89, 0xfa, - 0xc6, 0x13, 0x58, 0x9c, 0xe4, 0x6c, 0xff, 0xb3, 0x02, 0x9c, 0x5e, 0x78, 0xab, 0x1d, 0x90, 0x65, - 0x37, 0xdc, 0x4d, 0xce, 0xf0, 0xba, 0x1b, 0xee, 0xae, 0xc7, 0x3d, 0xa0, 0xa6, 0xd6, 0xb2, 0x80, - 0x63, 0x45, 0x81, 0x9e, 0x85, 0x41, 0xfa, 0xfb, 0x26, 0x2e, 0x8b, 0x4f, 0x9e, 0x12, 0xc4, 0xc3, - 0xcb, 0x4e, 0xe4, 0x2c, 0x73, 0x14, 0x96, 0x34, 0x68, 0x0d, 0x86, 0x6b, 0x6c, 0x41, 0x6e, 0xaf, - 0xf9, 0x75, 0xc2, 0x06, 0xb3, 0xb4, 0xf8, 0x34, 0x25, 0x5f, 0x8a, 0xc1, 0x87, 0x07, 0xb3, 0xd3, - 0xbc, 0x6d, 0x82, 0x85, 0x86, 0xc3, 0x7a, 0x79, 0x64, 0xab, 0xf5, 0xd5, 0xc7, 0x38, 0x41, 0xc6, - 0xda, 0xba, 0xa4, 0x2d, 0x95, 0x7e, 0xb6, 0x54, 0x46, 0xb2, 0x97, 0x09, 0xba, 0x0c, 0x7d, 0xbb, - 0xae, 0x57, 0x9f, 0x1e, 0x60, 0xbc, 0xce, 0xd1, 0x31, 0xbf, 0xe6, 0x7a, 0xf5, 0xc3, 0x83, 0xd9, - 0x49, 0xa3, 0x39, 0x14, 0x88, 0x19, 0xa9, 0xfd, 0xdf, 0x2d, 0x98, 0x65, 0xb8, 0x55, 0xb7, 0x41, - 0x2a, 0x24, 0x08, 0xdd, 0x30, 0x22, 0x5e, 0x64, 0x74, 0xe8, 0x73, 0x00, 0x21, 0xa9, 0x05, 0x24, - 0xd2, 0xba, 0x54, 0x4d, 0x8c, 0xaa, 0xc2, 0x60, 0x8d, 0x8a, 0x6e, 0x08, 0xe1, 0x8e, 0x13, 0xb0, - 0xf9, 0x25, 0x3a, 0x56, 0x6d, 0x08, 0x55, 0x89, 0xc0, 0x31, 0x8d, 0xb1, 0x21, 0x14, 0xbb, 0x6d, - 0x08, 0xe8, 0x43, 0x30, 0x1e, 0x57, 0x16, 0xb6, 0x9c, 0x9a, 0xec, 0x40, 0xb6, 0x64, 0xaa, 0x26, - 0x0a, 0x27, 0x69, 0xed, 0xbf, 0x69, 0x89, 0xc9, 0x43, 0xbf, 0xfa, 0x1d, 0xfe, 0xad, 0xf6, 0x2f, - 0x58, 0x30, 0xb8, 0xe8, 0x7a, 0x75, 0xd7, 0xdb, 0x46, 0x9f, 0x82, 0x21, 0x7a, 0x36, 0xd5, 0x9d, - 0xc8, 0x11, 0xfb, 0xde, 0xfb, 0xb4, 0xb5, 0xa5, 0x8e, 0x8a, 0xb9, 0xd6, 0xee, 0x36, 0x05, 0x84, - 0x73, 0x94, 0x9a, 0xae, 0xb6, 0x1b, 0x9b, 0x9f, 0x26, 0xb5, 0x68, 0x8d, 0x44, 0x4e, 0xfc, 0x39, - 0x31, 0x0c, 0x2b, 0xae, 0xe8, 0x1a, 0x0c, 0x44, 0x4e, 0xb0, 0x4d, 0x22, 0xb1, 0x01, 0x66, 0x6e, - 0x54, 0xbc, 0x24, 0xa6, 0x2b, 0x92, 0x78, 0x35, 0x12, 0x1f, 0x0b, 0x1b, 0xac, 0x28, 0x16, 0x2c, - 0xec, 0xff, 0x3b, 0x08, 0x67, 0x97, 0xaa, 0xe5, 0x9c, 0x79, 0x75, 0x11, 0x06, 0xea, 0x81, 0xbb, - 0x47, 0x02, 0xd1, 0xcf, 0x8a, 0xcb, 0x32, 0x83, 0x62, 0x81, 0x45, 0x2f, 0xc1, 0x08, 0x3f, 0x90, - 0xae, 0x3a, 0x5e, 0xbd, 0x21, 0xbb, 0xf8, 0x94, 0xa0, 0x1e, 0xb9, 0xa5, 0xe1, 0xb0, 0x41, 0x79, - 0xc4, 0x49, 0x75, 0x31, 0xb1, 0x18, 0xf3, 0x0e, 0xbb, 0xcf, 0x5b, 0x30, 0xc1, 0xab, 0x59, 0x88, - 0xa2, 0xc0, 0xdd, 0x6c, 0x47, 0x24, 0x9c, 0xee, 0x67, 0x3b, 0xdd, 0x52, 0x56, 0x6f, 0xe5, 0xf6, - 0xc0, 0xdc, 0xad, 0x04, 0x17, 0xbe, 0x09, 0x4e, 0x8b, 0x7a, 0x27, 0x92, 0x68, 0x9c, 0xaa, 0x16, - 0x7d, 0xb7, 0x05, 0x33, 0x35, 0xdf, 0x8b, 0x02, 0xbf, 0xd1, 0x20, 0x41, 0xa5, 0xbd, 0xd9, 0x70, - 0xc3, 0x1d, 0x3e, 0x4f, 0x31, 0xd9, 0x62, 0x3b, 0x41, 0xce, 0x18, 0x2a, 0x22, 0x31, 0x86, 0xe7, - 0xef, 0x1d, 0xcc, 0xce, 0x2c, 0xe5, 0xb2, 0xc2, 0x1d, 0xaa, 0x41, 0xbb, 0x80, 0xe8, 0x51, 0x5a, - 0x8d, 0x9c, 0x6d, 0x12, 0x57, 0x3e, 0xd8, 0x7b, 0xe5, 0x67, 0xee, 0x1d, 0xcc, 0xa2, 0xf5, 0x14, - 0x0b, 0x9c, 0xc1, 0x16, 0xbd, 0x09, 0xa7, 0x28, 0x34, 0xf5, 0xad, 0x43, 0xbd, 0x57, 0x37, 0x7d, - 0xef, 0x60, 0xf6, 0xd4, 0x7a, 0x06, 0x13, 0x9c, 0xc9, 0x1a, 0x7d, 0x97, 0x05, 0x67, 0xe3, 0xcf, - 0x5f, 0xb9, 0xdb, 0x72, 0xbc, 0x7a, 0x5c, 0x71, 0xa9, 0xf7, 0x8a, 0xe9, 0x9e, 0x7c, 0x76, 0x29, - 0x8f, 0x13, 0xce, 0xaf, 0x04, 0x79, 0x30, 0x45, 0x9b, 0x96, 0xac, 0x1b, 0x7a, 0xaf, 0xfb, 0xa1, - 0x7b, 0x07, 0xb3, 0x53, 0xeb, 0x69, 0x1e, 0x38, 0x8b, 0xf1, 0xcc, 0x12, 0x9c, 0xce, 0x9c, 0x9d, - 0x68, 0x02, 0x8a, 0xbb, 0x84, 0x4b, 0x5d, 0x25, 0x4c, 0x7f, 0xa2, 0x53, 0xd0, 0xbf, 0xe7, 0x34, - 0xda, 0x62, 0x61, 0x62, 0xfe, 0xe7, 0xe5, 0xc2, 0x4b, 0x96, 0xfd, 0xcf, 0x8b, 0x30, 0xbe, 0x54, - 0x2d, 0xdf, 0xd7, 0xaa, 0xd7, 0x8f, 0xbd, 0x42, 0xc7, 0x63, 0x2f, 0x3e, 0x44, 0x8b, 0xb9, 0x87, - 0xe8, 0x9f, 0xcd, 0x58, 0xb2, 0x7d, 0x6c, 0xc9, 0x7e, 0x47, 0xce, 0x92, 0x3d, 0xe6, 0x85, 0xba, - 0x97, 0x33, 0x6b, 0xfb, 0xd9, 0x00, 0x66, 0x4a, 0x48, 0xd7, 0xfd, 0x9a, 0xd3, 0x48, 0x6e, 0xb5, - 0x47, 0x9c, 0xba, 0xc7, 0x33, 0x8e, 0x35, 0x18, 0x59, 0x72, 0x5a, 0xce, 0xa6, 0xdb, 0x70, 0x23, - 0x97, 0x84, 0xe8, 0x49, 0x28, 0x3a, 0xf5, 0x3a, 0x93, 0xee, 0x4a, 0x8b, 0xa7, 0xef, 0x1d, 0xcc, - 0x16, 0x17, 0xea, 0x54, 0xcc, 0x00, 0x45, 0xb5, 0x8f, 0x29, 0x05, 0x7a, 0x2f, 0xf4, 0xd5, 0x03, - 0xbf, 0x35, 0x5d, 0x60, 0x94, 0x74, 0x95, 0xf7, 0x2d, 0x07, 0x7e, 0x2b, 0x41, 0xca, 0x68, 0xec, - 0x5f, 0x2d, 0xc0, 0x23, 0x4b, 0xa4, 0xb5, 0xb3, 0x5a, 0xcd, 0x39, 0x2f, 0x2e, 0xc1, 0x50, 0xd3, - 0xf7, 0xdc, 0xc8, 0x0f, 0x42, 0x51, 0x35, 0x9b, 0x11, 0x6b, 0x02, 0x86, 0x15, 0x16, 0x5d, 0x80, - 0xbe, 0x56, 0x2c, 0xc4, 0x8e, 0x48, 0x01, 0x98, 0x89, 0xaf, 0x0c, 0x43, 0x29, 0xda, 0x21, 0x09, - 0xc4, 0x8c, 0x51, 0x14, 0x37, 0x43, 0x12, 0x60, 0x86, 0x89, 0x25, 0x01, 0x2a, 0x23, 0x88, 0x13, - 0x21, 0x21, 0x09, 0x50, 0x0c, 0xd6, 0xa8, 0x50, 0x05, 0x4a, 0x61, 0x62, 0x64, 0x7b, 0x5a, 0x9a, - 0xa3, 0x4c, 0x54, 0x50, 0x23, 0x19, 0x33, 0x31, 0x4e, 0xb0, 0x81, 0xae, 0xa2, 0xc2, 0xd7, 0x0a, - 0x80, 0x78, 0x17, 0x7e, 0x8b, 0x75, 0xdc, 0xcd, 0x74, 0xc7, 0xf5, 0xbe, 0x24, 0x8e, 0xab, 0xf7, - 0xfe, 0x87, 0x05, 0x8f, 0x2c, 0xb9, 0x5e, 0x9d, 0x04, 0x39, 0x13, 0xf0, 0xc1, 0xdc, 0x9d, 0x8f, - 0x26, 0xa4, 0x18, 0x53, 0xac, 0xef, 0x18, 0xa6, 0x98, 0xfd, 0x47, 0x16, 0x20, 0xfe, 0xd9, 0xef, - 0xb8, 0x8f, 0xbd, 0x99, 0xfe, 0xd8, 0x63, 0x98, 0x16, 0xf6, 0xdf, 0xb5, 0x60, 0x78, 0xa9, 0xe1, - 0xb8, 0x4d, 0xf1, 0xa9, 0x4b, 0x30, 0x29, 0x15, 0x45, 0x0c, 0xac, 0xc9, 0xfe, 0x74, 0x73, 0x9b, - 0xc4, 0x49, 0x24, 0x4e, 0xd3, 0xa3, 0x8f, 0xc3, 0x59, 0x03, 0xb8, 0x41, 0x9a, 0xad, 0x86, 0x13, - 0xe9, 0xb7, 0x02, 0x76, 0xfa, 0xe3, 0x3c, 0x22, 0x9c, 0x5f, 0xde, 0xbe, 0x0e, 0x63, 0x4b, 0x0d, - 0x97, 0x78, 0x51, 0xb9, 0xb2, 0xe4, 0x7b, 0x5b, 0xee, 0x36, 0x7a, 0x19, 0xc6, 0x22, 0xb7, 0x49, - 0xfc, 0x76, 0x54, 0x25, 0x35, 0xdf, 0x63, 0x77, 0x6d, 0xeb, 0x52, 0xff, 0x22, 0xba, 0x77, 0x30, - 0x3b, 0xb6, 0x61, 0x60, 0x70, 0x82, 0xd2, 0xfe, 0x1d, 0x3a, 0xe2, 0x7e, 0xb3, 0xe5, 0x7b, 0xc4, - 0x8b, 0x96, 0x7c, 0xaf, 0xce, 0x75, 0x32, 0x2f, 0x43, 0x5f, 0x44, 0x47, 0x90, 0x7f, 0xf9, 0x45, - 0xb9, 0xb4, 0xe9, 0xb8, 0x1d, 0x1e, 0xcc, 0x9e, 0x49, 0x97, 0x60, 0x23, 0xcb, 0xca, 0xa0, 0xef, - 0x80, 0x81, 0x30, 0x72, 0xa2, 0x76, 0x28, 0x3e, 0xf5, 0x51, 0x39, 0xfe, 0x55, 0x06, 0x3d, 0x3c, - 0x98, 0x1d, 0x57, 0xc5, 0x38, 0x08, 0x8b, 0x02, 0xe8, 0x29, 0x18, 0x6c, 0x92, 0x30, 0x74, 0xb6, - 0xe5, 0xf9, 0x3d, 0x2e, 0xca, 0x0e, 0xae, 0x71, 0x30, 0x96, 0x78, 0xf4, 0x18, 0xf4, 0x93, 0x20, - 0xf0, 0x03, 0xb1, 0xab, 0x8c, 0x0a, 0xc2, 0xfe, 0x15, 0x0a, 0xc4, 0x1c, 0x67, 0xff, 0x5b, 0x0b, - 0xc6, 0x55, 0x5b, 0x79, 0x5d, 0x27, 0x70, 0x6f, 0xfa, 0x18, 0x40, 0x4d, 0x7e, 0x60, 0xc8, 0xce, - 0xbb, 0xe1, 0xe7, 0x2e, 0x66, 0x8a, 0x16, 0xa9, 0x6e, 0x8c, 0x39, 0x2b, 0x50, 0x88, 0x35, 0x6e, - 0xf6, 0x3f, 0xb2, 0x60, 0x2a, 0xf1, 0x45, 0xd7, 0xdd, 0x30, 0x42, 0x6f, 0xa4, 0xbe, 0x6a, 0xae, - 0xb7, 0xaf, 0xa2, 0xa5, 0xd9, 0x37, 0xa9, 0xc5, 0x27, 0x21, 0xda, 0x17, 0x5d, 0x85, 0x7e, 0x37, - 0x22, 0x4d, 0xf9, 0x31, 0x8f, 0x75, 0xfc, 0x18, 0xde, 0xaa, 0x78, 0x44, 0xca, 0xb4, 0x24, 0xe6, - 0x0c, 0xec, 0x5f, 0x2d, 0x42, 0x89, 0x4f, 0xdb, 0x35, 0xa7, 0x75, 0x02, 0x63, 0xf1, 0x34, 0x94, - 0xdc, 0x66, 0xb3, 0x1d, 0x39, 0x9b, 0xe2, 0x00, 0x1a, 0xe2, 0x9b, 0x41, 0x59, 0x02, 0x71, 0x8c, - 0x47, 0x65, 0xe8, 0x63, 0x4d, 0xe1, 0x5f, 0xf9, 0x64, 0xf6, 0x57, 0x8a, 0xb6, 0xcf, 0x2d, 0x3b, - 0x91, 0xc3, 0x65, 0x3f, 0x75, 0xf2, 0x51, 0x10, 0x66, 0x2c, 0x90, 0x03, 0xb0, 0xe9, 0x7a, 0x4e, - 0xb0, 0x4f, 0x61, 0xd3, 0x45, 0xc6, 0xf0, 0xd9, 0xce, 0x0c, 0x17, 0x15, 0x3d, 0x67, 0xab, 0x3e, - 0x2c, 0x46, 0x60, 0x8d, 0xe9, 0xcc, 0x07, 0xa0, 0xa4, 0x88, 0x8f, 0x22, 0xc2, 0xcd, 0x7c, 0x08, - 0xc6, 0x13, 0x75, 0x75, 0x2b, 0x3e, 0xa2, 0x4b, 0x80, 0xbf, 0xc8, 0xb6, 0x0c, 0xd1, 0xea, 0x15, - 0x6f, 0x4f, 0xec, 0x9c, 0x6f, 0xc1, 0xa9, 0x46, 0xc6, 0xde, 0x2b, 0xc6, 0xb5, 0xf7, 0xbd, 0xfa, - 0x11, 0xf1, 0xd9, 0xa7, 0xb2, 0xb0, 0x38, 0xb3, 0x0e, 0x2a, 0xd5, 0xf8, 0x2d, 0xba, 0x40, 0x9c, - 0x86, 0x7e, 0x41, 0xb8, 0x21, 0x60, 0x58, 0x61, 0xe9, 0x7e, 0x77, 0x4a, 0x35, 0xfe, 0x1a, 0xd9, - 0xaf, 0x92, 0x06, 0xa9, 0x45, 0x7e, 0xf0, 0x4d, 0x6d, 0xfe, 0x39, 0xde, 0xfb, 0x7c, 0xbb, 0x1c, - 0x16, 0x0c, 0x8a, 0xd7, 0xc8, 0x3e, 0x1f, 0x0a, 0xfd, 0xeb, 0x8a, 0x1d, 0xbf, 0xee, 0x2b, 0x16, - 0x8c, 0xaa, 0xaf, 0x3b, 0x81, 0x7d, 0x61, 0xd1, 0xdc, 0x17, 0xce, 0x75, 0x9c, 0xe0, 0x39, 0x3b, - 0xc2, 0xd7, 0x0a, 0x70, 0x56, 0xd1, 0xd0, 0xdb, 0x0c, 0xff, 0x23, 0x66, 0xd5, 0x3c, 0x94, 0x3c, - 0xa5, 0xd7, 0xb3, 0x4c, 0x85, 0x5a, 0xac, 0xd5, 0x8b, 0x69, 0xa8, 0x50, 0xea, 0xc5, 0xc7, 0xec, - 0x88, 0xae, 0xf0, 0x16, 0xca, 0xed, 0x45, 0x28, 0xb6, 0xdd, 0xba, 0x38, 0x60, 0xde, 0x27, 0x7b, - 0xfb, 0x66, 0x79, 0xf9, 0xf0, 0x60, 0xf6, 0xd1, 0x3c, 0x63, 0x0b, 0x3d, 0xd9, 0xc2, 0xb9, 0x9b, - 0xe5, 0x65, 0x4c, 0x0b, 0xa3, 0x05, 0x18, 0x97, 0x27, 0xf4, 0x2d, 0x2a, 0x20, 0xfa, 0x9e, 0x38, - 0x87, 0x94, 0xd6, 0x1a, 0x9b, 0x68, 0x9c, 0xa4, 0x47, 0xcb, 0x30, 0xb1, 0xdb, 0xde, 0x24, 0x0d, - 0x12, 0xf1, 0x0f, 0xbe, 0x46, 0xb8, 0x4e, 0xb7, 0x14, 0xdf, 0x25, 0xaf, 0x25, 0xf0, 0x38, 0x55, - 0xc2, 0xfe, 0x53, 0x76, 0x1e, 0x88, 0xde, 0xab, 0x04, 0x3e, 0x9d, 0x58, 0x94, 0xfb, 0x37, 0x73, - 0x3a, 0xf7, 0x32, 0x2b, 0xae, 0x91, 0xfd, 0x0d, 0x9f, 0xde, 0x25, 0xb2, 0x67, 0x85, 0x31, 0xe7, - 0xfb, 0x3a, 0xce, 0xf9, 0x9f, 0x2d, 0xc0, 0x69, 0xd5, 0x03, 0x86, 0xd8, 0xfa, 0xad, 0xde, 0x07, - 0x97, 0x61, 0xb8, 0x4e, 0xb6, 0x9c, 0x76, 0x23, 0x52, 0x06, 0x86, 0x7e, 0x6e, 0x64, 0x5a, 0x8e, - 0xc1, 0x58, 0xa7, 0x39, 0x42, 0xb7, 0xfd, 0xcf, 0x61, 0x76, 0x10, 0x47, 0x0e, 0x9d, 0xe3, 0x6a, - 0xd5, 0x58, 0xb9, 0xab, 0xe6, 0x31, 0xe8, 0x77, 0x9b, 0x54, 0x30, 0x2b, 0x98, 0xf2, 0x56, 0x99, - 0x02, 0x31, 0xc7, 0xa1, 0x27, 0x60, 0xb0, 0xe6, 0x37, 0x9b, 0x8e, 0x57, 0x67, 0x47, 0x5e, 0x69, - 0x71, 0x98, 0xca, 0x6e, 0x4b, 0x1c, 0x84, 0x25, 0x0e, 0x3d, 0x02, 0x7d, 0x4e, 0xb0, 0xcd, 0xb5, - 0x2e, 0xa5, 0xc5, 0x21, 0x5a, 0xd3, 0x42, 0xb0, 0x1d, 0x62, 0x06, 0xa5, 0x97, 0xc6, 0x3b, 0x7e, - 0xb0, 0xeb, 0x7a, 0xdb, 0xcb, 0x6e, 0x20, 0x96, 0x84, 0x3a, 0x0b, 0x6f, 0x2b, 0x0c, 0xd6, 0xa8, - 0xd0, 0x2a, 0xf4, 0xb7, 0xfc, 0x20, 0x0a, 0xa7, 0x07, 0x58, 0x77, 0x3f, 0x9a, 0xb3, 0x11, 0xf1, - 0xaf, 0xad, 0xf8, 0x41, 0x14, 0x7f, 0x00, 0xfd, 0x17, 0x62, 0x5e, 0x1c, 0x5d, 0x87, 0x41, 0xe2, - 0xed, 0xad, 0x06, 0x7e, 0x73, 0x7a, 0x2a, 0x9f, 0xd3, 0x0a, 0x27, 0xe1, 0xd3, 0x2c, 0x96, 0x51, - 0x05, 0x18, 0x4b, 0x16, 0xe8, 0x3b, 0xa0, 0x48, 0xbc, 0xbd, 0xe9, 0x41, 0xc6, 0x69, 0x26, 0x87, - 0xd3, 0x2d, 0x27, 0x88, 0xf7, 0xfc, 0x15, 0x6f, 0x0f, 0xd3, 0x32, 0xe8, 0xa3, 0x50, 0x92, 0x1b, - 0x46, 0x28, 0xd4, 0x99, 0x99, 0x13, 0x56, 0x6e, 0x33, 0x98, 0xbc, 0xd9, 0x76, 0x03, 0xd2, 0x24, - 0x5e, 0x14, 0xc6, 0x3b, 0xa4, 0xc4, 0x86, 0x38, 0xe6, 0x86, 0x3e, 0x2a, 0x75, 0xe8, 0x6b, 0x7e, - 0xdb, 0x8b, 0xc2, 0xe9, 0x12, 0x6b, 0x5e, 0xa6, 0x75, 0xf3, 0x56, 0x4c, 0x97, 0x54, 0xb2, 0xf3, - 0xc2, 0xd8, 0x60, 0x85, 0x3e, 0x01, 0xa3, 0xfc, 0x3f, 0xb7, 0x11, 0x86, 0xd3, 0xa7, 0x19, 0xef, - 0x0b, 0xf9, 0xbc, 0x39, 0xe1, 0xe2, 0x69, 0xc1, 0x7c, 0x54, 0x87, 0x86, 0xd8, 0xe4, 0x86, 0x30, - 0x8c, 0x36, 0xdc, 0x3d, 0xe2, 0x91, 0x30, 0xac, 0x04, 0xfe, 0x26, 0x11, 0x2a, 0xcf, 0xb3, 0xd9, - 0x36, 0x45, 0x7f, 0x93, 0x2c, 0x4e, 0x52, 0x9e, 0xd7, 0xf5, 0x32, 0xd8, 0x64, 0x81, 0x6e, 0xc2, - 0x18, 0xbd, 0x63, 0xba, 0x31, 0xd3, 0xe1, 0x6e, 0x4c, 0xd9, 0xbd, 0x0a, 0x1b, 0x85, 0x70, 0x82, - 0x09, 0xba, 0x01, 0x23, 0x61, 0xe4, 0x04, 0x51, 0xbb, 0xc5, 0x99, 0x9e, 0xe9, 0xc6, 0x94, 0x99, - 0xa4, 0xab, 0x5a, 0x11, 0x6c, 0x30, 0x40, 0xaf, 0x41, 0xa9, 0xe1, 0x6e, 0x91, 0xda, 0x7e, 0xad, - 0x41, 0xa6, 0x47, 0x18, 0xb7, 0xcc, 0x4d, 0xe5, 0xba, 0x24, 0xe2, 0x72, 0xae, 0xfa, 0x8b, 0xe3, - 0xe2, 0xe8, 0x16, 0x9c, 0x89, 0x48, 0xd0, 0x74, 0x3d, 0x87, 0x6e, 0x06, 0xe2, 0x6a, 0xc5, 0x4c, - 0xbd, 0xa3, 0x6c, 0xb5, 0x9d, 0x17, 0xa3, 0x71, 0x66, 0x23, 0x93, 0x0a, 0xe7, 0x94, 0x46, 0x77, - 0x61, 0x3a, 0x03, 0xe3, 0x37, 0xdc, 0xda, 0xfe, 0xf4, 0x29, 0xc6, 0xf9, 0x83, 0x82, 0xf3, 0xf4, - 0x46, 0x0e, 0xdd, 0x61, 0x07, 0x1c, 0xce, 0xe5, 0x8e, 0x6e, 0xc0, 0x38, 0xdb, 0x81, 0x2a, 0xed, - 0x46, 0x43, 0x54, 0x38, 0xc6, 0x2a, 0x7c, 0x42, 0x9e, 0xc7, 0x65, 0x13, 0x7d, 0x78, 0x30, 0x0b, - 0xf1, 0x3f, 0x9c, 0x2c, 0x8d, 0x36, 0x99, 0x55, 0xb1, 0x1d, 0xb8, 0xd1, 0x3e, 0xdd, 0x37, 0xc8, - 0xdd, 0x68, 0x7a, 0xbc, 0xa3, 0x86, 0x45, 0x27, 0x55, 0xa6, 0x47, 0x1d, 0x88, 0x93, 0x0c, 0xe9, - 0x96, 0x1a, 0x46, 0x75, 0xd7, 0x9b, 0x9e, 0xe0, 0xf7, 0x12, 0xb9, 0x23, 0x55, 0x29, 0x10, 0x73, - 0x1c, 0xb3, 0x28, 0xd2, 0x1f, 0x37, 0xe8, 0xc9, 0x35, 0xc9, 0x08, 0x63, 0x8b, 0xa2, 0x44, 0xe0, - 0x98, 0x86, 0x0a, 0x93, 0x51, 0xb4, 0x3f, 0x8d, 0x18, 0xa9, 0xda, 0x58, 0x36, 0x36, 0x3e, 0x8a, - 0x29, 0xdc, 0xde, 0x84, 0x31, 0xb5, 0x11, 0xb2, 0x3e, 0x41, 0xb3, 0xd0, 0xcf, 0xc4, 0x27, 0xa1, - 0x0f, 0x2c, 0xd1, 0x26, 0x30, 0xd1, 0x0a, 0x73, 0x38, 0x6b, 0x82, 0xfb, 0x16, 0x59, 0xdc, 0x8f, - 0x08, 0xbf, 0xd3, 0x17, 0xb5, 0x26, 0x48, 0x04, 0x8e, 0x69, 0xec, 0xff, 0xc7, 0xc5, 0xd0, 0x78, - 0xb7, 0xed, 0xe1, 0x7c, 0x79, 0x06, 0x86, 0x76, 0xfc, 0x30, 0xa2, 0xd4, 0xac, 0x8e, 0xfe, 0x58, - 0xf0, 0xbc, 0x2a, 0xe0, 0x58, 0x51, 0xa0, 0x57, 0x60, 0xb4, 0xa6, 0x57, 0x20, 0x0e, 0x47, 0xb5, - 0x8d, 0x18, 0xb5, 0x63, 0x93, 0x16, 0xbd, 0x04, 0x43, 0xcc, 0x4b, 0xa6, 0xe6, 0x37, 0x84, 0xd4, - 0x26, 0x4f, 0xf8, 0xa1, 0x8a, 0x80, 0x1f, 0x6a, 0xbf, 0xb1, 0xa2, 0x46, 0x17, 0x61, 0x80, 0x36, - 0xa1, 0x5c, 0x11, 0xc7, 0x92, 0x52, 0x6d, 0x5d, 0x65, 0x50, 0x2c, 0xb0, 0xf6, 0x5f, 0x2c, 0x68, - 0xbd, 0x4c, 0xef, 0xc3, 0x04, 0x55, 0x60, 0xf0, 0x8e, 0xe3, 0x46, 0xae, 0xb7, 0x2d, 0xe4, 0x8f, - 0xa7, 0x3a, 0x9e, 0x51, 0xac, 0xd0, 0x6d, 0x5e, 0x80, 0x9f, 0xa2, 0xe2, 0x0f, 0x96, 0x6c, 0x28, - 0xc7, 0xa0, 0xed, 0x79, 0x94, 0x63, 0xa1, 0x57, 0x8e, 0x98, 0x17, 0xe0, 0x1c, 0xc5, 0x1f, 0x2c, - 0xd9, 0xa0, 0x37, 0x00, 0xe4, 0x0a, 0x23, 0x75, 0xe1, 0x9d, 0xf2, 0x4c, 0x77, 0xa6, 0x1b, 0xaa, - 0xcc, 0xe2, 0x18, 0x3d, 0xa3, 0xe3, 0xff, 0x58, 0xe3, 0x67, 0x47, 0x4c, 0x4e, 0x4b, 0x37, 0x06, - 0x7d, 0x9c, 0x4e, 0x71, 0x27, 0x88, 0x48, 0x7d, 0x21, 0x12, 0x9d, 0xf3, 0xde, 0xde, 0x2e, 0x29, - 0x1b, 0x6e, 0x93, 0xe8, 0xcb, 0x41, 0x30, 0xc1, 0x31, 0x3f, 0xfb, 0xe7, 0x8b, 0x30, 0x9d, 0xd7, - 0x5c, 0x3a, 0xe9, 0xc8, 0x5d, 0x37, 0x5a, 0xa2, 0xe2, 0x95, 0x65, 0x4e, 0xba, 0x15, 0x01, 0xc7, - 0x8a, 0x82, 0x8e, 0x7e, 0xe8, 0x6e, 0xcb, 0x3b, 0x66, 0x7f, 0x3c, 0xfa, 0x55, 0x06, 0xc5, 0x02, - 0x4b, 0xe9, 0x02, 0xe2, 0x84, 0xc2, 0xfd, 0x49, 0x9b, 0x25, 0x98, 0x41, 0xb1, 0xc0, 0xea, 0xda, - 0xae, 0xbe, 0x2e, 0xda, 0x2e, 0xa3, 0x8b, 0xfa, 0x8f, 0xb7, 0x8b, 0xd0, 0x27, 0x01, 0xb6, 0x5c, - 0xcf, 0x0d, 0x77, 0x18, 0xf7, 0x81, 0x23, 0x73, 0x57, 0xc2, 0xd9, 0xaa, 0xe2, 0x82, 0x35, 0x8e, - 0xe8, 0x45, 0x18, 0x56, 0x0b, 0xb0, 0xbc, 0xcc, 0x6c, 0xc1, 0x9a, 0x6f, 0x4d, 0xbc, 0x1b, 0x2d, - 0x63, 0x9d, 0xce, 0xfe, 0x74, 0x72, 0xbe, 0x88, 0x15, 0xa0, 0xf5, 0xaf, 0xd5, 0x6b, 0xff, 0x16, - 0x3a, 0xf7, 0xaf, 0xfd, 0x8d, 0x22, 0x8c, 0x1b, 0x95, 0xb5, 0xc3, 0x1e, 0xf6, 0xac, 0x2b, 0x74, - 0x03, 0x77, 0x22, 0x22, 0xd6, 0x9f, 0xdd, 0x7d, 0xa9, 0xe8, 0x9b, 0x3c, 0x5d, 0x01, 0xbc, 0x3c, - 0xfa, 0x24, 0x94, 0x1a, 0x4e, 0xc8, 0x34, 0x67, 0x44, 0xac, 0xbb, 0x5e, 0x98, 0xc5, 0x17, 0x13, - 0x27, 0x8c, 0xb4, 0x53, 0x93, 0xf3, 0x8e, 0x59, 0xd2, 0x93, 0x86, 0xca, 0x27, 0xd2, 0xbf, 0x4e, - 0x35, 0x82, 0x0a, 0x31, 0xfb, 0x98, 0xe3, 0xd0, 0x4b, 0x30, 0x12, 0x10, 0x36, 0x2b, 0x96, 0xa8, - 0x34, 0xc7, 0xa6, 0x59, 0x7f, 0x2c, 0xf6, 0x61, 0x0d, 0x87, 0x0d, 0xca, 0xf8, 0x6e, 0x30, 0xd0, - 0xe1, 0x6e, 0xf0, 0x14, 0x0c, 0xb2, 0x1f, 0x6a, 0x06, 0xa8, 0xd1, 0x28, 0x73, 0x30, 0x96, 0xf8, - 0xe4, 0x84, 0x19, 0xea, 0x6d, 0xc2, 0xd0, 0xdb, 0x87, 0x98, 0xd4, 0xcc, 0x0e, 0x3f, 0xc4, 0x77, - 0x39, 0x31, 0xe5, 0xb1, 0xc4, 0xd9, 0xef, 0x85, 0xb1, 0x65, 0x87, 0x34, 0x7d, 0x6f, 0xc5, 0xab, - 0xb7, 0x7c, 0xd7, 0x8b, 0xd0, 0x34, 0xf4, 0xb1, 0x43, 0x84, 0x6f, 0x01, 0x7d, 0xb4, 0x22, 0xcc, - 0x20, 0xf6, 0x36, 0x9c, 0x5e, 0xf6, 0xef, 0x78, 0x77, 0x9c, 0xa0, 0xbe, 0x50, 0x29, 0x6b, 0xf7, - 0xeb, 0x75, 0x79, 0xbf, 0xe3, 0x6e, 0x6d, 0x99, 0x5b, 0xaf, 0x56, 0x92, 0x8b, 0xb5, 0xab, 0x6e, - 0x83, 0xe4, 0x68, 0x41, 0xfe, 0x4a, 0xc1, 0xa8, 0x29, 0xa6, 0x57, 0x76, 0x38, 0x2b, 0xd7, 0x0e, - 0xf7, 0x3a, 0x0c, 0x6d, 0xb9, 0xa4, 0x51, 0xc7, 0x64, 0x4b, 0xcc, 0xc4, 0x27, 0xf3, 0x3d, 0x75, - 0x56, 0x29, 0xa5, 0xd4, 0x7a, 0xf1, 0xdb, 0xe1, 0xaa, 0x28, 0x8c, 0x15, 0x1b, 0xb4, 0x0b, 0x13, - 0xf2, 0xc2, 0x20, 0xb1, 0x62, 0x5e, 0x3e, 0xd5, 0xe9, 0x16, 0x62, 0x32, 0x3f, 0x75, 0xef, 0x60, - 0x76, 0x02, 0x27, 0xd8, 0xe0, 0x14, 0x63, 0x7a, 0x1d, 0x6c, 0xd2, 0x1d, 0xb8, 0x8f, 0x75, 0x3f, - 0xbb, 0x0e, 0xb2, 0x9b, 0x2d, 0x83, 0xda, 0x3f, 0x66, 0xc1, 0x43, 0xa9, 0x9e, 0x11, 0x37, 0xfc, - 0x63, 0x1e, 0x85, 0xe4, 0x8d, 0xbb, 0xd0, 0xfd, 0xc6, 0x6d, 0xff, 0x2d, 0x0b, 0x4e, 0xad, 0x34, - 0x5b, 0xd1, 0xfe, 0xb2, 0x6b, 0x1a, 0xcd, 0x3e, 0x00, 0x03, 0x4d, 0x52, 0x77, 0xdb, 0x4d, 0x31, - 0x72, 0xb3, 0x72, 0x97, 0x5a, 0x63, 0xd0, 0xc3, 0x83, 0xd9, 0xd1, 0x6a, 0xe4, 0x07, 0xce, 0x36, - 0xe1, 0x00, 0x2c, 0xc8, 0xd9, 0x5e, 0xef, 0xbe, 0x45, 0xae, 0xbb, 0x4d, 0x57, 0x7a, 0x5e, 0x75, - 0xd4, 0xd9, 0xcd, 0xc9, 0x0e, 0x9d, 0x7b, 0xbd, 0xed, 0x78, 0x91, 0x1b, 0xed, 0x0b, 0x7b, 0x97, - 0x64, 0x82, 0x63, 0x7e, 0xf6, 0xd7, 0x2d, 0x18, 0x97, 0xf3, 0x7e, 0xa1, 0x5e, 0x0f, 0x48, 0x18, - 0xa2, 0x19, 0x28, 0xb8, 0x2d, 0xd1, 0x4a, 0x10, 0xad, 0x2c, 0x94, 0x2b, 0xb8, 0xe0, 0xb6, 0xa4, - 0x58, 0xc6, 0x36, 0xc2, 0xa2, 0x69, 0xfa, 0xbb, 0x2a, 0xe0, 0x58, 0x51, 0xa0, 0x4b, 0x30, 0xe4, - 0xf9, 0x75, 0x6e, 0xe7, 0xe2, 0x47, 0x1a, 0x9b, 0x60, 0xeb, 0x02, 0x86, 0x15, 0x16, 0x55, 0xa0, - 0xc4, 0x1d, 0xc3, 0xe2, 0x49, 0xdb, 0x93, 0x7b, 0x19, 0xfb, 0xb2, 0x0d, 0x59, 0x12, 0xc7, 0x4c, - 0xec, 0x5f, 0xb1, 0x60, 0x44, 0x7e, 0x59, 0x8f, 0x32, 0x27, 0x5d, 0x5a, 0xb1, 0xbc, 0x19, 0x2f, - 0x2d, 0x2a, 0x33, 0x32, 0x8c, 0x21, 0x2a, 0x16, 0x8f, 0x24, 0x2a, 0x5e, 0x86, 0x61, 0xa7, 0xd5, - 0xaa, 0x98, 0x72, 0x26, 0x9b, 0x4a, 0x0b, 0x31, 0x18, 0xeb, 0x34, 0xf6, 0x8f, 0x16, 0x60, 0x4c, - 0x7e, 0x41, 0xb5, 0xbd, 0x19, 0x92, 0x08, 0x6d, 0x40, 0xc9, 0xe1, 0xa3, 0x44, 0xe4, 0x24, 0x7f, - 0x2c, 0x5b, 0x8f, 0x60, 0x0c, 0x69, 0x7c, 0xe0, 0x2f, 0xc8, 0xd2, 0x38, 0x66, 0x84, 0x1a, 0x30, - 0xe9, 0xf9, 0x11, 0xdb, 0xfc, 0x15, 0xbe, 0x93, 0x69, 0x27, 0xc9, 0xfd, 0xac, 0xe0, 0x3e, 0xb9, - 0x9e, 0xe4, 0x82, 0xd3, 0x8c, 0xd1, 0x8a, 0xd4, 0xcd, 0x14, 0xf3, 0x95, 0x01, 0xfa, 0xc0, 0x65, - 0xab, 0x66, 0xec, 0x5f, 0xb2, 0xa0, 0x24, 0xc9, 0x4e, 0xc2, 0x8a, 0xb7, 0x06, 0x83, 0x21, 0x1b, - 0x04, 0xd9, 0x35, 0x76, 0xa7, 0x86, 0xf3, 0xf1, 0x8a, 0xcf, 0x34, 0xfe, 0x3f, 0xc4, 0x92, 0x07, - 0x53, 0xcd, 0xab, 0xe6, 0xbf, 0x43, 0x54, 0xf3, 0xaa, 0x3d, 0x39, 0x87, 0xd2, 0x1f, 0xb0, 0x36, - 0x6b, 0xba, 0x2e, 0x2a, 0x7a, 0xb5, 0x02, 0xb2, 0xe5, 0xde, 0x4d, 0x8a, 0x5e, 0x15, 0x06, 0xc5, - 0x02, 0x8b, 0xde, 0x80, 0x91, 0x9a, 0xd4, 0xc9, 0xc6, 0x2b, 0xfc, 0x62, 0x47, 0xfb, 0x80, 0x32, - 0x25, 0x71, 0x5d, 0xc8, 0x92, 0x56, 0x1e, 0x1b, 0xdc, 0x4c, 0xc7, 0x87, 0x62, 0x37, 0xc7, 0x87, - 0x98, 0x6f, 0xbe, 0x1b, 0xc0, 0x8f, 0x5b, 0x30, 0xc0, 0x75, 0x71, 0xbd, 0xa9, 0x42, 0x35, 0xcb, - 0x5a, 0xdc, 0x77, 0xb7, 0x28, 0x50, 0x58, 0xca, 0xd0, 0x1a, 0x94, 0xd8, 0x0f, 0xa6, 0x4b, 0x2c, - 0xe6, 0xbf, 0x4b, 0xe0, 0xb5, 0xea, 0x0d, 0xbc, 0x25, 0x8b, 0xe1, 0x98, 0x83, 0xfd, 0x23, 0x45, - 0xba, 0xbb, 0xc5, 0xa4, 0xc6, 0xa1, 0x6f, 0x3d, 0xb8, 0x43, 0xbf, 0xf0, 0xa0, 0x0e, 0xfd, 0x6d, - 0x18, 0xaf, 0x69, 0x76, 0xb8, 0x78, 0x24, 0x2f, 0x75, 0x9c, 0x24, 0x9a, 0xc9, 0x8e, 0x6b, 0x59, - 0x96, 0x4c, 0x26, 0x38, 0xc9, 0x15, 0x7d, 0x1c, 0x46, 0xf8, 0x38, 0x8b, 0x5a, 0xb8, 0xef, 0xc8, - 0x13, 0xf9, 0xf3, 0x45, 0xaf, 0x82, 0x6b, 0xe5, 0xb4, 0xe2, 0xd8, 0x60, 0x66, 0xff, 0xb1, 0x05, - 0x68, 0xa5, 0xb5, 0x43, 0x9a, 0x24, 0x70, 0x1a, 0xb1, 0x3a, 0xfd, 0x07, 0x2d, 0x98, 0x26, 0x29, - 0xf0, 0x92, 0xdf, 0x6c, 0x8a, 0x4b, 0x4b, 0xce, 0xbd, 0x7a, 0x25, 0xa7, 0x8c, 0x7a, 0xb8, 0x31, - 0x9d, 0x47, 0x81, 0x73, 0xeb, 0x43, 0x6b, 0x30, 0xc5, 0x4f, 0x49, 0x85, 0xd0, 0xfc, 0x50, 0x1e, - 0x16, 0x8c, 0xa7, 0x36, 0xd2, 0x24, 0x38, 0xab, 0x9c, 0xfd, 0x3d, 0x23, 0x90, 0xdb, 0x8a, 0x77, - 0xed, 0x08, 0xef, 0xda, 0x11, 0xde, 0xb5, 0x23, 0xbc, 0x6b, 0x47, 0x78, 0xd7, 0x8e, 0xf0, 0x6d, - 0x6f, 0x47, 0xf8, 0x4b, 0x16, 0x9c, 0x56, 0xc7, 0x80, 0x71, 0xf1, 0xfd, 0x0c, 0x4c, 0xf1, 0xe5, - 0x66, 0xf8, 0x2e, 0x8a, 0x63, 0xef, 0x72, 0xe6, 0xcc, 0x4d, 0xf8, 0xd8, 0x1a, 0x05, 0xf9, 0x63, - 0x85, 0x0c, 0x04, 0xce, 0xaa, 0xc6, 0xfe, 0xf9, 0x21, 0xe8, 0x5f, 0xd9, 0x23, 0x5e, 0x74, 0x02, - 0x57, 0x84, 0x1a, 0x8c, 0xb9, 0xde, 0x9e, 0xdf, 0xd8, 0x23, 0x75, 0x8e, 0x3f, 0xca, 0x4d, 0xf6, - 0x8c, 0x60, 0x3d, 0x56, 0x36, 0x58, 0xe0, 0x04, 0xcb, 0x07, 0xa1, 0x4d, 0xbe, 0x02, 0x03, 0x7c, - 0x13, 0x17, 0xaa, 0xe4, 0xcc, 0x3d, 0x9b, 0x75, 0xa2, 0x38, 0x9a, 0x62, 0x4d, 0x37, 0x3f, 0x24, - 0x44, 0x71, 0xf4, 0x69, 0x18, 0xdb, 0x72, 0x83, 0x30, 0xda, 0x70, 0x9b, 0x24, 0x8c, 0x9c, 0x66, - 0xeb, 0x3e, 0xb4, 0xc7, 0xaa, 0x1f, 0x56, 0x0d, 0x4e, 0x38, 0xc1, 0x19, 0x6d, 0xc3, 0x68, 0xc3, - 0xd1, 0xab, 0x1a, 0x3c, 0x72, 0x55, 0xea, 0x74, 0xb8, 0xae, 0x33, 0xc2, 0x26, 0x5f, 0xba, 0x9c, - 0x6a, 0x4c, 0x01, 0x3a, 0xc4, 0xd4, 0x02, 0x6a, 0x39, 0x71, 0xcd, 0x27, 0xc7, 0x51, 0x41, 0x87, - 0x39, 0xc8, 0x96, 0x4c, 0x41, 0x47, 0x73, 0x83, 0xfd, 0x14, 0x94, 0x08, 0xed, 0x42, 0xca, 0x58, - 0x1c, 0x30, 0xf3, 0xbd, 0xb5, 0x75, 0xcd, 0xad, 0x05, 0xbe, 0xa9, 0xb7, 0x5f, 0x91, 0x9c, 0x70, - 0xcc, 0x14, 0x2d, 0xc1, 0x40, 0x48, 0x02, 0x97, 0x84, 0xe2, 0xa8, 0xe9, 0x30, 0x8c, 0x8c, 0x8c, - 0xbf, 0x86, 0xe1, 0xbf, 0xb1, 0x28, 0x4a, 0xa7, 0x97, 0xc3, 0x54, 0x9a, 0xec, 0x30, 0xd0, 0xa6, - 0xd7, 0x02, 0x83, 0x62, 0x81, 0x45, 0xaf, 0xc1, 0x60, 0x40, 0x1a, 0xcc, 0x30, 0x34, 0xda, 0xfb, - 0x24, 0xe7, 0x76, 0x26, 0x5e, 0x0e, 0x4b, 0x06, 0xe8, 0x1a, 0xa0, 0x80, 0x50, 0x41, 0xc9, 0xf5, - 0xb6, 0x95, 0xdb, 0xa8, 0xd8, 0x68, 0x95, 0x40, 0x8a, 0x63, 0x0a, 0xf9, 0x10, 0x0a, 0x67, 0x14, - 0x43, 0x57, 0x60, 0x52, 0x41, 0xcb, 0x5e, 0x18, 0x39, 0x74, 0x83, 0x1b, 0x67, 0xbc, 0x94, 0x9e, - 0x02, 0x27, 0x09, 0x70, 0xba, 0x8c, 0xfd, 0x25, 0x0b, 0x78, 0x3f, 0x9f, 0xc0, 0xed, 0xfc, 0x55, - 0xf3, 0x76, 0x7e, 0x36, 0x77, 0xe4, 0x72, 0x6e, 0xe6, 0x5f, 0xb2, 0x60, 0x58, 0x1b, 0xd9, 0x78, - 0xce, 0x5a, 0x1d, 0xe6, 0x6c, 0x1b, 0x26, 0xe8, 0x4c, 0xbf, 0xb1, 0x19, 0x92, 0x60, 0x8f, 0xd4, - 0xd9, 0xc4, 0x2c, 0xdc, 0xdf, 0xc4, 0x54, 0x2e, 0x6a, 0xd7, 0x13, 0x0c, 0x71, 0xaa, 0x0a, 0xfb, - 0x53, 0xb2, 0xa9, 0xca, 0xa3, 0xaf, 0xa6, 0xc6, 0x3c, 0xe1, 0xd1, 0xa7, 0x46, 0x15, 0xc7, 0x34, - 0x74, 0xa9, 0xed, 0xf8, 0x61, 0x94, 0xf4, 0xe8, 0xbb, 0xea, 0x87, 0x11, 0x66, 0x18, 0xfb, 0x79, - 0x80, 0x95, 0xbb, 0xa4, 0xc6, 0x67, 0xac, 0x7e, 0x79, 0xb0, 0xf2, 0x2f, 0x0f, 0xf6, 0x6f, 0x5a, - 0x30, 0xb6, 0xba, 0x64, 0x9c, 0x5c, 0x73, 0x00, 0xfc, 0xc6, 0x73, 0xfb, 0xf6, 0xba, 0x34, 0x87, - 0x73, 0x8b, 0xa6, 0x82, 0x62, 0x8d, 0x02, 0x9d, 0x85, 0x62, 0xa3, 0xed, 0x09, 0xf5, 0xe1, 0x20, - 0x3d, 0x1e, 0xaf, 0xb7, 0x3d, 0x4c, 0x61, 0xda, 0x23, 0x88, 0x62, 0xcf, 0x8f, 0x20, 0xba, 0x06, - 0x3f, 0x40, 0xb3, 0xd0, 0x7f, 0xe7, 0x8e, 0x5b, 0xe7, 0x4f, 0x4c, 0x85, 0xa9, 0xfe, 0xf6, 0xed, - 0xf2, 0x72, 0x88, 0x39, 0xdc, 0xfe, 0x42, 0x11, 0x66, 0x56, 0x1b, 0xe4, 0xee, 0xdb, 0x7c, 0x66, - 0xdb, 0xeb, 0x13, 0x8e, 0xa3, 0x29, 0x62, 0x8e, 0xfa, 0x4c, 0xa7, 0x7b, 0x7f, 0x6c, 0xc1, 0x20, - 0x77, 0x68, 0x93, 0x8f, 0x6e, 0x5f, 0xc9, 0xaa, 0x3d, 0xbf, 0x43, 0xe6, 0xb8, 0x63, 0x9c, 0x78, - 0xc3, 0xa7, 0x0e, 0x4c, 0x01, 0xc5, 0x92, 0xf9, 0xcc, 0xcb, 0x30, 0xa2, 0x53, 0x1e, 0xe9, 0xc1, - 0xdc, 0x9f, 0x2b, 0xc2, 0x04, 0x6d, 0xc1, 0x03, 0x1d, 0x88, 0x9b, 0xe9, 0x81, 0x38, 0xee, 0x47, - 0x53, 0xdd, 0x47, 0xe3, 0x8d, 0xe4, 0x68, 0x5c, 0xce, 0x1b, 0x8d, 0x93, 0x1e, 0x83, 0xef, 0xb6, - 0x60, 0x6a, 0xb5, 0xe1, 0xd7, 0x76, 0x13, 0x0f, 0x9b, 0x5e, 0x84, 0x61, 0xba, 0x1d, 0x87, 0xc6, - 0x1b, 0x7f, 0x23, 0xea, 0x83, 0x40, 0x61, 0x9d, 0x4e, 0x2b, 0x76, 0xf3, 0x66, 0x79, 0x39, 0x2b, - 0x58, 0x84, 0x40, 0x61, 0x9d, 0xce, 0xfe, 0x75, 0x0b, 0xce, 0x5d, 0x59, 0x5a, 0x89, 0xa7, 0x62, - 0x2a, 0x5e, 0xc5, 0x45, 0x18, 0x68, 0xd5, 0xb5, 0xa6, 0xc4, 0xea, 0xd5, 0x65, 0xd6, 0x0a, 0x81, - 0x7d, 0xa7, 0xc4, 0x62, 0xb9, 0x09, 0x70, 0x05, 0x57, 0x96, 0xc4, 0xbe, 0x2b, 0xad, 0x29, 0x56, - 0xae, 0x35, 0xe5, 0x09, 0x18, 0xa4, 0xe7, 0x82, 0x5b, 0x93, 0xed, 0xe6, 0x06, 0x5a, 0x0e, 0xc2, - 0x12, 0x67, 0xff, 0x8c, 0x05, 0x53, 0x57, 0xdc, 0x88, 0x1e, 0xda, 0xc9, 0x80, 0x0c, 0xf4, 0xd4, - 0x0e, 0xdd, 0xc8, 0x0f, 0xf6, 0x93, 0x01, 0x19, 0xb0, 0xc2, 0x60, 0x8d, 0x8a, 0x7f, 0xd0, 0x9e, - 0xcb, 0x3c, 0xb4, 0x0b, 0xa6, 0xfd, 0x0a, 0x0b, 0x38, 0x56, 0x14, 0xb4, 0xbf, 0xea, 0x6e, 0xc0, - 0x54, 0x7f, 0xfb, 0x62, 0xe3, 0x56, 0xfd, 0xb5, 0x2c, 0x11, 0x38, 0xa6, 0xb1, 0xff, 0xd0, 0x82, - 0xd9, 0x2b, 0x8d, 0x76, 0x18, 0x91, 0x60, 0x2b, 0xcc, 0xd9, 0x74, 0x9f, 0x87, 0x12, 0x91, 0x8a, - 0x76, 0xf9, 0x94, 0x4c, 0x0a, 0xa2, 0x4a, 0x03, 0xcf, 0xe3, 0x42, 0x28, 0xba, 0x1e, 0x5e, 0x5f, - 0x1e, 0xed, 0xf9, 0xdc, 0x2a, 0x20, 0xa2, 0xd7, 0xa5, 0x07, 0xca, 0x60, 0x2f, 0xee, 0x57, 0x52, - 0x58, 0x9c, 0x51, 0xc2, 0xfe, 0x31, 0x0b, 0x4e, 0xab, 0x0f, 0x7e, 0xc7, 0x7d, 0xa6, 0xfd, 0xd5, - 0x02, 0x8c, 0x5e, 0xdd, 0xd8, 0xa8, 0x5c, 0x21, 0x91, 0x36, 0x2b, 0x3b, 0x9b, 0xcf, 0xb1, 0x66, - 0x05, 0xec, 0x74, 0x47, 0x6c, 0x47, 0x6e, 0x63, 0x8e, 0xc7, 0x5b, 0x9a, 0x2b, 0x7b, 0xd1, 0x8d, - 0xa0, 0x1a, 0x05, 0xae, 0xb7, 0x9d, 0x39, 0xd3, 0xa5, 0xcc, 0x52, 0xcc, 0x93, 0x59, 0xd0, 0xf3, - 0x30, 0xc0, 0x02, 0x3e, 0xc9, 0x41, 0x78, 0x58, 0x5d, 0xb1, 0x18, 0xf4, 0xf0, 0x60, 0xb6, 0x74, - 0x13, 0x97, 0xf9, 0x1f, 0x2c, 0x48, 0xd1, 0x4d, 0x18, 0xde, 0x89, 0xa2, 0xd6, 0x55, 0xe2, 0xd4, - 0x49, 0x20, 0x77, 0xd9, 0xf3, 0x59, 0xbb, 0x2c, 0xed, 0x04, 0x4e, 0x16, 0x6f, 0x4c, 0x31, 0x2c, - 0xc4, 0x3a, 0x1f, 0xbb, 0x0a, 0x10, 0xe3, 0x8e, 0xc9, 0x00, 0x62, 0x6f, 0x40, 0x89, 0x7e, 0xee, - 0x42, 0xc3, 0x75, 0x3a, 0x9b, 0x98, 0x9f, 0x86, 0x92, 0x34, 0x20, 0x87, 0xe2, 0x75, 0x38, 0x3b, - 0x91, 0xa4, 0x7d, 0x39, 0xc4, 0x31, 0xde, 0xde, 0x82, 0x53, 0xcc, 0x1d, 0xd0, 0x89, 0x76, 0x8c, - 0xd9, 0xd7, 0x7d, 0x98, 0x9f, 0x11, 0x37, 0x36, 0xde, 0xe6, 0x69, 0xed, 0x39, 0xe3, 0x88, 0xe4, - 0x18, 0xdf, 0xde, 0xec, 0x6f, 0xf4, 0xc1, 0xc3, 0xe5, 0x6a, 0x7e, 0xc0, 0x92, 0x97, 0x60, 0x84, - 0x0b, 0x82, 0x74, 0xd0, 0x9d, 0x86, 0xa8, 0x57, 0xe9, 0x36, 0x37, 0x34, 0x1c, 0x36, 0x28, 0xd1, - 0x39, 0x28, 0xba, 0x6f, 0x7a, 0xc9, 0xc7, 0x3e, 0xe5, 0xd7, 0xd7, 0x31, 0x85, 0x53, 0x34, 0x95, - 0x29, 0xf9, 0x66, 0xad, 0xd0, 0x4a, 0xae, 0x7c, 0x15, 0xc6, 0xdc, 0xb0, 0x16, 0xba, 0x65, 0x8f, - 0xae, 0x40, 0x6d, 0x0d, 0x2b, 0x6d, 0x02, 0x6d, 0xb4, 0xc2, 0xe2, 0x04, 0xb5, 0x76, 0x72, 0xf4, - 0xf7, 0x2c, 0x97, 0x76, 0x7d, 0x2e, 0x4d, 0x37, 0xf6, 0x16, 0xfb, 0xba, 0x90, 0x29, 0xa9, 0xc5, - 0xc6, 0xce, 0x3f, 0x38, 0xc4, 0x12, 0x47, 0xaf, 0x6a, 0xb5, 0x1d, 0xa7, 0xb5, 0xd0, 0x8e, 0x76, - 0x96, 0xdd, 0xb0, 0xe6, 0xef, 0x91, 0x60, 0x9f, 0xdd, 0xb2, 0x87, 0xe2, 0xab, 0x9a, 0x42, 0x2c, - 0x5d, 0x5d, 0xa8, 0x50, 0x4a, 0x9c, 0x2e, 0x83, 0x16, 0x60, 0x5c, 0x02, 0xab, 0x24, 0x64, 0x9b, - 0xfb, 0x30, 0x63, 0xa3, 0x9e, 0xdf, 0x08, 0xb0, 0x62, 0x92, 0xa4, 0x37, 0x45, 0x57, 0x38, 0x0e, - 0xd1, 0xf5, 0x03, 0x30, 0xea, 0x7a, 0x6e, 0xe4, 0x3a, 0x91, 0xcf, 0x2d, 0x2c, 0xfc, 0x42, 0xcd, - 0x54, 0xc7, 0x65, 0x1d, 0x81, 0x4d, 0x3a, 0xfb, 0x3f, 0xf5, 0xc1, 0x24, 0x1b, 0xb6, 0x77, 0x67, - 0xd8, 0xb7, 0xd3, 0x0c, 0xbb, 0x99, 0x9e, 0x61, 0xc7, 0x21, 0x93, 0xdf, 0xf7, 0x34, 0xfb, 0x34, - 0x94, 0xd4, 0x8b, 0x23, 0xf9, 0xe4, 0xd0, 0xca, 0x79, 0x72, 0xd8, 0xfd, 0x5c, 0x96, 0x4e, 0x5b, - 0xc5, 0x4c, 0xa7, 0xad, 0x2f, 0x5b, 0x10, 0x9b, 0x0c, 0xd0, 0xeb, 0x50, 0x6a, 0xf9, 0xcc, 0x17, - 0x31, 0x90, 0x0e, 0xbe, 0x8f, 0x77, 0xb4, 0x39, 0xf0, 0x98, 0x4d, 0x01, 0xef, 0x85, 0x8a, 0x2c, - 0x8a, 0x63, 0x2e, 0xe8, 0x1a, 0x0c, 0xb6, 0x02, 0x52, 0x8d, 0x58, 0x40, 0x91, 0xde, 0x19, 0xf2, - 0x59, 0xc3, 0x0b, 0x62, 0xc9, 0xc1, 0xfe, 0xcf, 0x16, 0x4c, 0x24, 0x49, 0xd1, 0x07, 0xa1, 0x8f, - 0xdc, 0x25, 0x35, 0xd1, 0xde, 0xcc, 0x43, 0x36, 0x56, 0x3a, 0xf0, 0x0e, 0xa0, 0xff, 0x31, 0x2b, - 0x85, 0xae, 0xc2, 0x20, 0x3d, 0x61, 0xaf, 0xa8, 0xe0, 0x59, 0x8f, 0xe6, 0x9d, 0xd2, 0x4a, 0x54, - 0xe1, 0x8d, 0x13, 0x20, 0x2c, 0x8b, 0x33, 0x4f, 0xa9, 0x5a, 0xab, 0x4a, 0x2f, 0x2f, 0x51, 0xa7, - 0x3b, 0xf6, 0xc6, 0x52, 0x85, 0x13, 0x09, 0x6e, 0xdc, 0x53, 0x4a, 0x02, 0x71, 0xcc, 0xc4, 0xfe, - 0x59, 0x0b, 0x80, 0x3b, 0x86, 0x39, 0xde, 0x36, 0x39, 0x01, 0x3d, 0xf9, 0x32, 0xf4, 0x85, 0x2d, - 0x52, 0xeb, 0xe4, 0x26, 0x1b, 0xb7, 0xa7, 0xda, 0x22, 0xb5, 0x78, 0xc6, 0xd1, 0x7f, 0x98, 0x95, - 0xb6, 0xbf, 0x17, 0x60, 0x2c, 0x26, 0x2b, 0x47, 0xa4, 0x89, 0x9e, 0x35, 0xc2, 0x14, 0x9c, 0x4d, - 0x84, 0x29, 0x28, 0x31, 0x6a, 0x4d, 0x25, 0xfb, 0x69, 0x28, 0x36, 0x9d, 0xbb, 0x42, 0xe7, 0xf6, - 0x74, 0xe7, 0x66, 0x50, 0xfe, 0x73, 0x6b, 0xce, 0x5d, 0x7e, 0x2d, 0x7d, 0x5a, 0xae, 0x90, 0x35, - 0xe7, 0xee, 0x21, 0x77, 0x86, 0x65, 0xbb, 0xf4, 0x75, 0x37, 0x8c, 0x3e, 0xf7, 0x1f, 0xe3, 0xff, - 0x6c, 0xdd, 0xd1, 0x4a, 0x58, 0x5d, 0xae, 0x27, 0x7c, 0x9e, 0x7a, 0xaa, 0xcb, 0xf5, 0x92, 0x75, - 0xb9, 0x5e, 0x0f, 0x75, 0xb9, 0x1e, 0x7a, 0x0b, 0x06, 0x85, 0x4b, 0xa2, 0x08, 0x64, 0x34, 0xdf, - 0x43, 0x7d, 0xc2, 0xa3, 0x91, 0xd7, 0x39, 0x2f, 0xaf, 0xdd, 0x02, 0xda, 0xb5, 0x5e, 0x59, 0x21, - 0xfa, 0xcb, 0x16, 0x8c, 0x89, 0xdf, 0x98, 0xbc, 0xd9, 0x26, 0x61, 0x24, 0xc4, 0xd2, 0xf7, 0xf7, - 0xde, 0x06, 0x51, 0x90, 0x37, 0xe5, 0xfd, 0xf2, 0x9c, 0x31, 0x91, 0x5d, 0x5b, 0x94, 0x68, 0x05, - 0xfa, 0x3b, 0x16, 0x9c, 0x6a, 0x3a, 0x77, 0x79, 0x8d, 0x1c, 0x86, 0x9d, 0xc8, 0xf5, 0x85, 0x69, - 0xff, 0x83, 0xbd, 0x0d, 0x7f, 0xaa, 0x38, 0x6f, 0xa4, 0xb4, 0x3f, 0x9e, 0xca, 0x22, 0xe9, 0xda, - 0xd4, 0xcc, 0x76, 0xcd, 0x6c, 0xc1, 0x90, 0x9c, 0x6f, 0x19, 0xca, 0x8d, 0x65, 0x5d, 0xe6, 0x3e, - 0xb2, 0x47, 0xa8, 0xfe, 0xfc, 0x9f, 0xd6, 0x23, 0xe6, 0xda, 0x03, 0xad, 0xe7, 0xd3, 0x30, 0xa2, - 0xcf, 0xb1, 0x07, 0x5a, 0xd7, 0x9b, 0x30, 0x95, 0x31, 0x97, 0x1e, 0x68, 0x95, 0x77, 0xe0, 0x6c, - 0xee, 0xfc, 0x78, 0x90, 0x15, 0xdb, 0x5f, 0xb5, 0xf4, 0x7d, 0xf0, 0x04, 0x8c, 0x15, 0x4b, 0xa6, - 0xb1, 0xe2, 0x7c, 0xe7, 0x95, 0x93, 0x63, 0xb1, 0x78, 0x43, 0x6f, 0x34, 0xdd, 0xd5, 0xd1, 0x6b, - 0x30, 0xd0, 0xa0, 0x10, 0xe9, 0xd8, 0x6a, 0x77, 0x5f, 0x91, 0xb1, 0x30, 0xc9, 0xe0, 0x21, 0x16, - 0x1c, 0xec, 0x5f, 0xb0, 0xa0, 0xef, 0x04, 0x7a, 0x02, 0x9b, 0x3d, 0xf1, 0x6c, 0x2e, 0x6b, 0x11, - 0xd3, 0x79, 0x0e, 0x3b, 0x77, 0x56, 0xee, 0x46, 0xc4, 0x0b, 0xd9, 0x89, 0x9c, 0xd9, 0x31, 0x3f, - 0x69, 0xc1, 0xd4, 0x75, 0xdf, 0xa9, 0x2f, 0x3a, 0x0d, 0xc7, 0xab, 0x91, 0xa0, 0xec, 0x6d, 0x1f, - 0xc9, 0x2b, 0xbb, 0xd0, 0xd5, 0x2b, 0x7b, 0x49, 0x3a, 0x35, 0xf5, 0xe5, 0x8f, 0x1f, 0x95, 0xa4, - 0x93, 0x81, 0x5b, 0x0c, 0xf7, 0xdb, 0x1d, 0x40, 0x7a, 0x2b, 0xc5, 0x1b, 0x19, 0x0c, 0x83, 0x2e, - 0x6f, 0xaf, 0x18, 0xc4, 0x27, 0xb3, 0x25, 0xdc, 0xd4, 0xe7, 0x69, 0xaf, 0x3f, 0x38, 0x00, 0x4b, - 0x46, 0xf6, 0x4b, 0x90, 0xf9, 0xd0, 0xbe, 0xbb, 0x5e, 0xc2, 0xfe, 0x28, 0x4c, 0xb2, 0x92, 0x47, - 0xd4, 0x0c, 0xd8, 0x09, 0x6d, 0x6a, 0x46, 0xd0, 0x40, 0xfb, 0xf3, 0x16, 0x8c, 0xaf, 0x27, 0x62, - 0xa9, 0x5d, 0x64, 0xf6, 0xd7, 0x0c, 0x25, 0x7e, 0x95, 0x41, 0xb1, 0xc0, 0x1e, 0xbb, 0x92, 0xeb, - 0x4f, 0x2d, 0x88, 0x63, 0x5f, 0x9c, 0x80, 0xf8, 0xb6, 0x64, 0x88, 0x6f, 0x99, 0x82, 0xac, 0x6a, - 0x4e, 0x9e, 0xf4, 0x86, 0xae, 0xa9, 0xa8, 0x50, 0x1d, 0x64, 0xd8, 0x98, 0x0d, 0x9f, 0x8a, 0x63, - 0x66, 0xe8, 0x28, 0x19, 0x27, 0xca, 0xfe, 0xad, 0x02, 0x20, 0x45, 0xdb, 0x73, 0xd4, 0xaa, 0x74, - 0x89, 0xe3, 0x89, 0x5a, 0xb5, 0x07, 0x88, 0x79, 0x10, 0x04, 0x8e, 0x17, 0x72, 0xb6, 0xae, 0x50, - 0xeb, 0x1d, 0xcd, 0x3d, 0x61, 0x46, 0x54, 0x89, 0xae, 0xa7, 0xb8, 0xe1, 0x8c, 0x1a, 0x34, 0xcf, - 0x90, 0xfe, 0x5e, 0x3d, 0x43, 0x06, 0xba, 0xbc, 0x83, 0xfb, 0x8a, 0x05, 0xa3, 0xaa, 0x9b, 0xde, - 0x21, 0x5e, 0xea, 0xaa, 0x3d, 0x39, 0x1b, 0x68, 0x45, 0x6b, 0x32, 0x3b, 0x58, 0xbe, 0x93, 0xbd, - 0x67, 0x74, 0x1a, 0xee, 0x5b, 0x44, 0x45, 0x39, 0x9c, 0x15, 0xef, 0x13, 0x05, 0xf4, 0xf0, 0x60, - 0x76, 0x54, 0xfd, 0xe3, 0x51, 0x9c, 0xe3, 0x22, 0x74, 0x4b, 0x1e, 0x4f, 0x4c, 0x45, 0xf4, 0x22, - 0xf4, 0xb7, 0x76, 0x9c, 0x90, 0x24, 0x5e, 0xf3, 0xf4, 0x57, 0x28, 0xf0, 0xf0, 0x60, 0x76, 0x4c, - 0x15, 0x60, 0x10, 0xcc, 0xa9, 0x7b, 0x8f, 0x05, 0x96, 0x9e, 0x9c, 0x5d, 0x63, 0x81, 0xfd, 0xb1, - 0x05, 0x7d, 0xeb, 0x7e, 0xfd, 0x24, 0xb6, 0x80, 0x57, 0x8d, 0x2d, 0xe0, 0x91, 0xbc, 0x00, 0xfb, - 0xb9, 0xab, 0x7f, 0x35, 0xb1, 0xfa, 0xcf, 0xe7, 0x72, 0xe8, 0xbc, 0xf0, 0x9b, 0x30, 0xcc, 0xc2, - 0xf6, 0x8b, 0x97, 0x4b, 0xcf, 0x1b, 0x0b, 0x7e, 0x36, 0xb1, 0xe0, 0xc7, 0x35, 0x52, 0x6d, 0xa5, - 0x3f, 0x05, 0x83, 0xe2, 0x29, 0x4c, 0xf2, 0x59, 0xa8, 0xa0, 0xc5, 0x12, 0x6f, 0xff, 0x78, 0x11, - 0x8c, 0x34, 0x01, 0xe8, 0x97, 0x2c, 0x98, 0x0b, 0xb8, 0x8b, 0x6c, 0x7d, 0xb9, 0x1d, 0xb8, 0xde, - 0x76, 0xb5, 0xb6, 0x43, 0xea, 0xed, 0x86, 0xeb, 0x6d, 0x97, 0xb7, 0x3d, 0x5f, 0x81, 0x57, 0xee, - 0x92, 0x5a, 0x9b, 0x99, 0xdd, 0xba, 0xe4, 0x24, 0x50, 0xae, 0xe6, 0xcf, 0xdd, 0x3b, 0x98, 0x9d, - 0xc3, 0x47, 0xe2, 0x8d, 0x8f, 0xd8, 0x16, 0xf4, 0xeb, 0x16, 0xcc, 0xf3, 0xe8, 0xf9, 0xbd, 0xb7, - 0xbf, 0xc3, 0x6d, 0xb9, 0x22, 0x59, 0xc5, 0x4c, 0x36, 0x48, 0xd0, 0x5c, 0xfc, 0x80, 0xe8, 0xd0, - 0xf9, 0xca, 0xd1, 0xea, 0xc2, 0x47, 0x6d, 0x9c, 0xfd, 0x8f, 0x8b, 0x30, 0x2a, 0x62, 0x46, 0x89, - 0x33, 0xe0, 0x45, 0x63, 0x4a, 0x3c, 0x9a, 0x98, 0x12, 0x93, 0x06, 0xf1, 0xf1, 0x6c, 0xff, 0x21, - 0x4c, 0xd2, 0xcd, 0xf9, 0x2a, 0x71, 0x82, 0x68, 0x93, 0x38, 0xdc, 0xe1, 0xab, 0x78, 0xe4, 0xdd, - 0x5f, 0xe9, 0x27, 0xaf, 0x27, 0x99, 0xe1, 0x34, 0xff, 0x6f, 0xa7, 0x33, 0xc7, 0x83, 0x89, 0x54, - 0xd8, 0xaf, 0x8f, 0x41, 0x49, 0xbd, 0xe3, 0x10, 0x9b, 0x4e, 0xe7, 0xe8, 0x79, 0x49, 0x0e, 0x5c, - 0xfd, 0x15, 0xbf, 0x21, 0x8a, 0xd9, 0xd9, 0x7f, 0xaf, 0x60, 0x54, 0xc8, 0x07, 0x71, 0x1d, 0x86, - 0x9c, 0x30, 0x74, 0xb7, 0x3d, 0x52, 0xef, 0xa4, 0xa1, 0x4c, 0x55, 0xc3, 0xde, 0xd2, 0x2c, 0x88, - 0x92, 0x58, 0xf1, 0x40, 0x57, 0xb9, 0x5b, 0xdd, 0x1e, 0xe9, 0xa4, 0x9e, 0x4c, 0x71, 0x03, 0xe9, - 0x78, 0xb7, 0x47, 0xb0, 0x28, 0x8f, 0x3e, 0xc1, 0xfd, 0x1e, 0xaf, 0x79, 0xfe, 0x1d, 0xef, 0x8a, - 0xef, 0xcb, 0xb8, 0x0c, 0xbd, 0x31, 0x9c, 0x94, 0xde, 0x8e, 0xaa, 0x38, 0x36, 0xb9, 0xf5, 0x16, - 0x47, 0xf3, 0x33, 0xc0, 0xa2, 0x85, 0x9b, 0xcf, 0xa6, 0x43, 0x44, 0x60, 0x5c, 0x04, 0x24, 0x93, - 0x30, 0xd1, 0x77, 0x99, 0x57, 0x39, 0xb3, 0x74, 0xac, 0x48, 0xbf, 0x66, 0xb2, 0xc0, 0x49, 0x9e, - 0xf6, 0x4f, 0x5b, 0xc0, 0x9e, 0x90, 0x9e, 0x80, 0x3c, 0xf2, 0x21, 0x53, 0x1e, 0x99, 0xce, 0xeb, - 0xe4, 0x1c, 0x51, 0xe4, 0x05, 0x3e, 0xb3, 0x2a, 0x81, 0x7f, 0x77, 0x5f, 0x38, 0xab, 0x74, 0xbf, - 0x7f, 0xd8, 0xff, 0xc7, 0xe2, 0x9b, 0x98, 0x7a, 0x65, 0x81, 0x3e, 0x0b, 0x43, 0x35, 0xa7, 0xe5, - 0xd4, 0x78, 0x4e, 0x9b, 0x5c, 0x8d, 0x9e, 0x51, 0x68, 0x6e, 0x49, 0x94, 0xe0, 0x1a, 0x2a, 0x19, - 0xd8, 0x6e, 0x48, 0x82, 0xbb, 0x6a, 0xa5, 0x54, 0x95, 0x33, 0xbb, 0x30, 0x6a, 0x30, 0x7b, 0xa0, - 0xea, 0x8c, 0xcf, 0xf2, 0x23, 0x56, 0x05, 0x62, 0x6c, 0xc2, 0xa4, 0xa7, 0xfd, 0xa7, 0x07, 0x8a, - 0xbc, 0x5c, 0x3e, 0xde, 0xed, 0x10, 0x65, 0xa7, 0x8f, 0xf6, 0x3a, 0x35, 0xc1, 0x06, 0xa7, 0x39, - 0xdb, 0x3f, 0x61, 0xc1, 0x43, 0x3a, 0xa1, 0xf6, 0x00, 0xa6, 0x9b, 0x91, 0x64, 0x19, 0x86, 0xfc, - 0x16, 0x09, 0x9c, 0xc8, 0x0f, 0xc4, 0xa9, 0x71, 0x49, 0x76, 0xfa, 0x0d, 0x01, 0x3f, 0x14, 0x11, - 0xda, 0x25, 0x77, 0x09, 0xc7, 0xaa, 0x24, 0xbd, 0x7d, 0xb2, 0xce, 0x08, 0xc5, 0x53, 0x27, 0xb6, - 0x07, 0x30, 0x4b, 0x7a, 0x88, 0x05, 0xc6, 0xfe, 0x86, 0xc5, 0x27, 0x96, 0xde, 0x74, 0xf4, 0x26, - 0x4c, 0x34, 0x9d, 0xa8, 0xb6, 0xb3, 0x72, 0xb7, 0x15, 0x70, 0x93, 0x93, 0xec, 0xa7, 0xa7, 0xbb, - 0xf5, 0x93, 0xf6, 0x91, 0xb1, 0x2b, 0xe7, 0x5a, 0x82, 0x19, 0x4e, 0xb1, 0x47, 0x9b, 0x30, 0xcc, - 0x60, 0xec, 0x15, 0x5f, 0xd8, 0x49, 0x34, 0xc8, 0xab, 0x4d, 0x39, 0x23, 0xac, 0xc5, 0x7c, 0xb0, - 0xce, 0xd4, 0xfe, 0x72, 0x91, 0xaf, 0x76, 0x26, 0xca, 0x3f, 0x05, 0x83, 0x2d, 0xbf, 0xbe, 0x54, - 0x5e, 0xc6, 0x62, 0x14, 0xd4, 0x31, 0x52, 0xe1, 0x60, 0x2c, 0xf1, 0xe8, 0x12, 0x0c, 0x89, 0x9f, - 0xd2, 0x44, 0xc8, 0xf6, 0x66, 0x41, 0x17, 0x62, 0x85, 0x45, 0xcf, 0x01, 0xb4, 0x02, 0x7f, 0xcf, - 0xad, 0xb3, 0xe8, 0x12, 0x45, 0xd3, 0x8f, 0xa8, 0xa2, 0x30, 0x58, 0xa3, 0x42, 0xaf, 0xc0, 0x68, - 0xdb, 0x0b, 0xb9, 0x38, 0xa2, 0xc5, 0x92, 0x55, 0x1e, 0x2e, 0x37, 0x75, 0x24, 0x36, 0x69, 0xd1, - 0x02, 0x0c, 0x44, 0x0e, 0xf3, 0x8b, 0xe9, 0xcf, 0x77, 0xf7, 0xdd, 0xa0, 0x14, 0x7a, 0xfa, 0x14, - 0x5a, 0x00, 0x8b, 0x82, 0xe8, 0x63, 0xf2, 0x41, 0x2d, 0xdf, 0xd8, 0x85, 0x9f, 0x7d, 0x6f, 0x87, - 0x80, 0xf6, 0x9c, 0x56, 0xf8, 0xef, 0x1b, 0xbc, 0xd0, 0xcb, 0x00, 0xe4, 0x6e, 0x44, 0x02, 0xcf, - 0x69, 0x28, 0x6f, 0x36, 0x25, 0x17, 0x2c, 0xfb, 0xeb, 0x7e, 0x74, 0x33, 0x24, 0x2b, 0x8a, 0x02, - 0x6b, 0xd4, 0xf6, 0xaf, 0x97, 0x00, 0x62, 0xb9, 0x1d, 0xbd, 0x95, 0xda, 0xb8, 0x9e, 0xe9, 0x2c, - 0xe9, 0x1f, 0xdf, 0xae, 0x85, 0xbe, 0xcf, 0x82, 0x61, 0xa7, 0xd1, 0xf0, 0x6b, 0x0e, 0x8f, 0xf6, - 0x5b, 0xe8, 0xbc, 0x71, 0x8a, 0xfa, 0x17, 0xe2, 0x12, 0xbc, 0x09, 0xcf, 0xcb, 0x19, 0xaa, 0x61, - 0xba, 0xb6, 0x42, 0xaf, 0x18, 0xbd, 0x4f, 0x5e, 0x15, 0x8b, 0x46, 0x57, 0xaa, 0xab, 0x62, 0x89, - 0x9d, 0x11, 0xfa, 0x2d, 0xf1, 0xa6, 0x71, 0x4b, 0xec, 0xcb, 0x7f, 0x31, 0x68, 0x88, 0xaf, 0xdd, - 0x2e, 0x88, 0xa8, 0xa2, 0x47, 0x0f, 0xe8, 0xcf, 0x7f, 0x9e, 0xa7, 0xdd, 0x93, 0xba, 0x44, 0x0e, - 0xf8, 0x34, 0x8c, 0xd7, 0x4d, 0x21, 0x40, 0xcc, 0xc4, 0x27, 0xf3, 0xf8, 0x26, 0x64, 0x86, 0xf8, - 0xd8, 0x4f, 0x20, 0x70, 0x92, 0x31, 0xaa, 0xf0, 0x60, 0x12, 0x65, 0x6f, 0xcb, 0x17, 0x6f, 0x3d, - 0xec, 0xdc, 0xb1, 0xdc, 0x0f, 0x23, 0xd2, 0xa4, 0x94, 0xf1, 0xe9, 0xbe, 0x2e, 0xca, 0x62, 0xc5, - 0x05, 0xbd, 0x06, 0x03, 0xec, 0x7d, 0x56, 0x38, 0x3d, 0x94, 0xaf, 0x71, 0x36, 0xa3, 0xa3, 0xc5, - 0x0b, 0x92, 0xfd, 0x0d, 0xb1, 0xe0, 0x80, 0xae, 0xca, 0xd7, 0x8f, 0x61, 0xd9, 0xbb, 0x19, 0x12, - 0xf6, 0xfa, 0xb1, 0xb4, 0xf8, 0x78, 0xfc, 0xb0, 0x91, 0xc3, 0x33, 0x93, 0xac, 0x19, 0x25, 0xa9, - 0x14, 0x25, 0xfe, 0xcb, 0xdc, 0x6d, 0xd3, 0x90, 0xdf, 0x3c, 0x33, 0xbf, 0x5b, 0xdc, 0x9d, 0xb7, - 0x4c, 0x16, 0x38, 0xc9, 0x93, 0x4a, 0xa4, 0x7c, 0xd5, 0x8b, 0xd7, 0x22, 0xdd, 0xf6, 0x0e, 0x7e, - 0x11, 0x67, 0xa7, 0x11, 0x87, 0x60, 0x51, 0xfe, 0x44, 0xc5, 0x83, 0x19, 0x0f, 0x26, 0x92, 0x4b, - 0xf4, 0x81, 0x8a, 0x23, 0xbf, 0xdf, 0x07, 0x63, 0xe6, 0x94, 0x42, 0xf3, 0x50, 0x12, 0x4c, 0x54, - 0xfe, 0x03, 0xb5, 0x4a, 0xd6, 0x24, 0x02, 0xc7, 0x34, 0x2c, 0xed, 0x05, 0x2b, 0xae, 0xb9, 0x07, - 0xc7, 0x69, 0x2f, 0x14, 0x06, 0x6b, 0x54, 0xf4, 0x62, 0xb5, 0xe9, 0xfb, 0x91, 0x3a, 0x90, 0xd4, - 0xbc, 0x5b, 0x64, 0x50, 0x2c, 0xb0, 0xf4, 0x20, 0xda, 0x25, 0x81, 0x47, 0x1a, 0x66, 0xdc, 0x61, - 0x75, 0x10, 0x5d, 0xd3, 0x91, 0xd8, 0xa4, 0xa5, 0xc7, 0xa9, 0x1f, 0xb2, 0x89, 0x2c, 0xae, 0x6f, - 0xb1, 0xbb, 0x75, 0x95, 0x3f, 0xc0, 0x96, 0x78, 0xf4, 0x51, 0x78, 0x48, 0xc5, 0x56, 0xc2, 0xdc, - 0x9a, 0x21, 0x6b, 0x1c, 0x30, 0xb4, 0x2d, 0x0f, 0x2d, 0x65, 0x93, 0xe1, 0xbc, 0xf2, 0xe8, 0x55, - 0x18, 0x13, 0x22, 0xbe, 0xe4, 0x38, 0x68, 0x7a, 0x18, 0x5d, 0x33, 0xb0, 0x38, 0x41, 0x2d, 0x23, - 0x27, 0x33, 0x29, 0x5b, 0x72, 0x18, 0x4a, 0x47, 0x4e, 0xd6, 0xf1, 0x38, 0x55, 0x02, 0x2d, 0xc0, - 0x38, 0x97, 0xc1, 0x5c, 0x6f, 0x9b, 0x8f, 0x89, 0x78, 0xcc, 0xa5, 0x96, 0xd4, 0x0d, 0x13, 0x8d, - 0x93, 0xf4, 0xe8, 0x25, 0x18, 0x71, 0x82, 0xda, 0x8e, 0x1b, 0x91, 0x5a, 0xd4, 0x0e, 0xf8, 0x2b, - 0x2f, 0xcd, 0x45, 0x6b, 0x41, 0xc3, 0x61, 0x83, 0xd2, 0x7e, 0x0b, 0xa6, 0x32, 0x22, 0x33, 0xd0, - 0x89, 0xe3, 0xb4, 0x5c, 0xf9, 0x4d, 0x09, 0x0f, 0xe7, 0x85, 0x4a, 0x59, 0x7e, 0x8d, 0x46, 0x45, - 0x67, 0x27, 0x8b, 0xe0, 0xa0, 0xa5, 0x6a, 0x54, 0xb3, 0x73, 0x55, 0x22, 0x70, 0x4c, 0x63, 0xff, - 0xb7, 0x02, 0x8c, 0x67, 0xd8, 0x56, 0x58, 0xba, 0xc0, 0xc4, 0x25, 0x25, 0xce, 0x0e, 0x68, 0x06, - 0xe2, 0x2e, 0x1c, 0x21, 0x10, 0x77, 0xb1, 0x5b, 0x20, 0xee, 0xbe, 0xb7, 0x13, 0x88, 0xdb, 0xec, - 0xb1, 0xfe, 0x9e, 0x7a, 0x2c, 0x23, 0x78, 0xf7, 0xc0, 0x11, 0x83, 0x77, 0x1b, 0x9d, 0x3e, 0xd8, - 0x43, 0xa7, 0xff, 0x48, 0x01, 0x26, 0x92, 0xae, 0xa4, 0x27, 0xa0, 0xb7, 0x7d, 0xcd, 0xd0, 0xdb, - 0x5e, 0xea, 0xe5, 0xf1, 0x6d, 0xae, 0x0e, 0x17, 0x27, 0x74, 0xb8, 0xef, 0xed, 0x89, 0x5b, 0x67, - 0x7d, 0xee, 0x5f, 0x2f, 0xc0, 0xe9, 0xcc, 0xd7, 0xbf, 0x27, 0xd0, 0x37, 0x37, 0x8c, 0xbe, 0x79, - 0xb6, 0xe7, 0x87, 0xc9, 0xb9, 0x1d, 0x74, 0x3b, 0xd1, 0x41, 0xf3, 0xbd, 0xb3, 0xec, 0xdc, 0x4b, - 0x5f, 0x2f, 0xc2, 0xf9, 0xcc, 0x72, 0xb1, 0xda, 0x73, 0xd5, 0x50, 0x7b, 0x3e, 0x97, 0x50, 0x7b, - 0xda, 0x9d, 0x4b, 0x1f, 0x8f, 0x1e, 0x54, 0x3c, 0xd0, 0x65, 0x61, 0x06, 0xee, 0x53, 0x07, 0x6a, - 0x3c, 0xd0, 0x55, 0x8c, 0xb0, 0xc9, 0xf7, 0xdb, 0x49, 0xf7, 0xf9, 0xaf, 0x2c, 0x38, 0x9b, 0x39, - 0x36, 0x27, 0xa0, 0xeb, 0x5a, 0x37, 0x75, 0x5d, 0x4f, 0xf5, 0x3c, 0x5b, 0x73, 0x94, 0x5f, 0x3f, - 0xd5, 0x9f, 0xf3, 0x2d, 0xec, 0x26, 0x7f, 0x03, 0x86, 0x9d, 0x5a, 0x8d, 0x84, 0xe1, 0x9a, 0x5f, - 0x57, 0xb1, 0x86, 0x9f, 0x65, 0xf7, 0xac, 0x18, 0x7c, 0x78, 0x30, 0x3b, 0x93, 0x64, 0x11, 0xa3, - 0xb1, 0xce, 0x01, 0x7d, 0x02, 0x86, 0x42, 0x71, 0x6e, 0x8a, 0xb1, 0x7f, 0xbe, 0xc7, 0xce, 0x71, - 0x36, 0x49, 0xc3, 0x0c, 0x86, 0xa4, 0x34, 0x15, 0x8a, 0xa5, 0x19, 0x38, 0xa5, 0x70, 0xac, 0x81, - 0x53, 0x9e, 0x03, 0xd8, 0x53, 0x97, 0x81, 0xa4, 0xfe, 0x41, 0xbb, 0x26, 0x68, 0x54, 0xe8, 0xc3, - 0x30, 0x11, 0xf2, 0x68, 0x81, 0x4b, 0x0d, 0x27, 0x64, 0xef, 0x68, 0xc4, 0x2c, 0x64, 0x01, 0x97, - 0xaa, 0x09, 0x1c, 0x4e, 0x51, 0xa3, 0x55, 0x59, 0x2b, 0x0b, 0x6d, 0xc8, 0x27, 0xe6, 0xc5, 0xb8, - 0x46, 0x91, 0xac, 0xf8, 0x54, 0xb2, 0xfb, 0x59, 0xc7, 0x6b, 0x25, 0xd1, 0x27, 0x00, 0xe8, 0xf4, - 0x11, 0x7a, 0x88, 0xc1, 0xfc, 0xcd, 0x93, 0xee, 0x2a, 0xf5, 0x4c, 0xe7, 0x66, 0xf6, 0xa6, 0x76, - 0x59, 0x31, 0xc1, 0x1a, 0x43, 0xe4, 0xc0, 0x68, 0xfc, 0x2f, 0xce, 0xe5, 0x79, 0x29, 0xb7, 0x86, - 0x24, 0x73, 0xa6, 0xf2, 0x5e, 0xd6, 0x59, 0x60, 0x93, 0xa3, 0xfd, 0x63, 0x83, 0xf0, 0x70, 0x87, - 0x6d, 0x18, 0x2d, 0x98, 0xa6, 0xde, 0xa7, 0x93, 0xf7, 0xf7, 0x99, 0xcc, 0xc2, 0xc6, 0x85, 0x3e, - 0x31, 0xdb, 0x0b, 0x6f, 0x7b, 0xb6, 0xff, 0x90, 0xa5, 0x69, 0x56, 0xb8, 0x53, 0xe9, 0x87, 0x8e, - 0x78, 0xbc, 0x1c, 0xa3, 0xaa, 0x65, 0x2b, 0x43, 0x5f, 0xf1, 0x5c, 0xcf, 0xcd, 0xe9, 0x5d, 0x81, - 0xf1, 0x55, 0x0b, 0x90, 0xd0, 0xac, 0x90, 0xba, 0x5a, 0x4b, 0x42, 0x95, 0x71, 0xe5, 0xa8, 0xdf, - 0xbf, 0x90, 0xe2, 0xc4, 0x7b, 0xe2, 0x65, 0x79, 0x0e, 0xa4, 0x09, 0xba, 0xf6, 0x49, 0x46, 0xf3, - 0xd0, 0x47, 0x59, 0x20, 0x5d, 0xf7, 0x2d, 0x21, 0xfc, 0x88, 0xb5, 0xf6, 0xa2, 0x08, 0xa2, 0xab, - 0xe0, 0x54, 0xca, 0xcd, 0x6c, 0xae, 0x4e, 0x84, 0x0d, 0x56, 0x27, 0x7b, 0xf5, 0x6e, 0xc3, 0x43, - 0x39, 0x5d, 0xf6, 0x40, 0x6f, 0xe0, 0xbf, 0x69, 0xc1, 0xb9, 0x8e, 0x11, 0x61, 0xbe, 0x05, 0x65, - 0x43, 0xfb, 0x73, 0x16, 0x64, 0x0f, 0xb6, 0xe1, 0x51, 0x36, 0x0f, 0xa5, 0x5a, 0x22, 0xeb, 0x60, - 0x1c, 0x1b, 0x41, 0x65, 0x1c, 0x8c, 0x69, 0x0c, 0xc7, 0xb1, 0x42, 0x57, 0xc7, 0xb1, 0x5f, 0xb1, - 0x20, 0xb5, 0xbf, 0x9f, 0x80, 0xa0, 0x51, 0x36, 0x05, 0x8d, 0xc7, 0x7b, 0xe9, 0xcd, 0x1c, 0x19, - 0xe3, 0x8f, 0xc6, 0xe1, 0x4c, 0xce, 0x8b, 0xbc, 0x3d, 0x98, 0xdc, 0xae, 0x11, 0xf3, 0x71, 0x75, - 0xa7, 0xa0, 0x43, 0x1d, 0x5f, 0x62, 0xf3, 0x64, 0x8f, 0x29, 0x12, 0x9c, 0xae, 0x02, 0x7d, 0xce, - 0x82, 0x53, 0xce, 0x9d, 0x70, 0x85, 0x0a, 0x8c, 0x6e, 0x6d, 0xb1, 0xe1, 0xd7, 0x76, 0xe9, 0x69, - 0x2c, 0x17, 0xc2, 0x0b, 0x99, 0x4a, 0xbc, 0xdb, 0xd5, 0x14, 0xbd, 0x51, 0x3d, 0x4b, 0xed, 0x9b, - 0x45, 0x85, 0x33, 0xeb, 0x42, 0x58, 0x64, 0x4f, 0xa0, 0xd7, 0xd1, 0x0e, 0xcf, 0xff, 0xb3, 0x9e, - 0x4e, 0x72, 0x09, 0x48, 0x62, 0xb0, 0xe2, 0x83, 0x3e, 0x05, 0xa5, 0x6d, 0xf9, 0xd2, 0x37, 0x43, - 0xc2, 0x8a, 0x3b, 0xb2, 0xf3, 0xfb, 0x67, 0x6e, 0x89, 0x57, 0x44, 0x38, 0x66, 0x8a, 0x5e, 0x85, - 0xa2, 0xb7, 0x15, 0x76, 0xca, 0x8e, 0x9b, 0x70, 0xb9, 0xe4, 0x41, 0x36, 0xd6, 0x57, 0xab, 0x98, - 0x16, 0x44, 0x57, 0xa1, 0x18, 0x6c, 0xd6, 0x85, 0x06, 0x3a, 0x73, 0x91, 0xe2, 0xc5, 0xe5, 0x9c, - 0x56, 0x31, 0x4e, 0x78, 0x71, 0x19, 0x53, 0x16, 0xa8, 0x02, 0xfd, 0xec, 0x19, 0x9b, 0x90, 0x67, - 0x32, 0x6f, 0x6e, 0x1d, 0x9e, 0x83, 0xf2, 0x48, 0x1c, 0x8c, 0x00, 0x73, 0x46, 0x68, 0x03, 0x06, - 0x6a, 0x2c, 0x93, 0xaa, 0x10, 0x60, 0xde, 0x97, 0xa9, 0x6b, 0xee, 0x90, 0x62, 0x56, 0xa8, 0x5e, - 0x19, 0x05, 0x16, 0xbc, 0x18, 0x57, 0xd2, 0xda, 0xd9, 0x0a, 0x45, 0xa6, 0xf1, 0x6c, 0xae, 0x1d, - 0x32, 0x27, 0x0b, 0xae, 0x8c, 0x02, 0x0b, 0x5e, 0xe8, 0x65, 0x28, 0x6c, 0xd5, 0xc4, 0x13, 0xb5, - 0x4c, 0xa5, 0xb3, 0x19, 0x27, 0x65, 0x71, 0xe0, 0xde, 0xc1, 0x6c, 0x61, 0x75, 0x09, 0x17, 0xb6, - 0x6a, 0x68, 0x1d, 0x06, 0xb7, 0x78, 0x64, 0x05, 0xa1, 0x57, 0x7e, 0x32, 0x3b, 0xe8, 0x43, 0x2a, - 0xf8, 0x02, 0x7f, 0xee, 0x24, 0x10, 0x58, 0x32, 0x61, 0xc9, 0x08, 0x54, 0x84, 0x08, 0x11, 0xa0, - 0x6e, 0xee, 0x68, 0x51, 0x3d, 0xb8, 0x7c, 0x19, 0xc7, 0x99, 0xc0, 0x1a, 0x47, 0x3a, 0xab, 0x9d, - 0xb7, 0xda, 0x01, 0x8b, 0x02, 0x2e, 0x22, 0x19, 0x65, 0xce, 0xea, 0x05, 0x49, 0xd4, 0x69, 0x56, - 0x2b, 0x22, 0x1c, 0x33, 0x45, 0xbb, 0x30, 0xba, 0x17, 0xb6, 0x76, 0x88, 0x5c, 0xd2, 0x2c, 0xb0, - 0x51, 0x8e, 0x7c, 0x74, 0x4b, 0x10, 0xba, 0x41, 0xd4, 0x76, 0x1a, 0xa9, 0x5d, 0x88, 0xc9, 0xb2, - 0xb7, 0x74, 0x66, 0xd8, 0xe4, 0x4d, 0xbb, 0xff, 0xcd, 0xb6, 0xbf, 0xb9, 0x1f, 0x11, 0x11, 0x57, - 0x2e, 0xb3, 0xfb, 0x5f, 0xe7, 0x24, 0xe9, 0xee, 0x17, 0x08, 0x2c, 0x99, 0xa0, 0x5b, 0xa2, 0x7b, - 0xd8, 0xee, 0x39, 0x91, 0x1f, 0xfc, 0x75, 0x41, 0x12, 0xe5, 0x74, 0x0a, 0xdb, 0x2d, 0x63, 0x56, - 0x6c, 0x97, 0x6c, 0xed, 0xf8, 0x91, 0xef, 0x25, 0x76, 0xe8, 0xc9, 0xfc, 0x5d, 0xb2, 0x92, 0x41, - 0x9f, 0xde, 0x25, 0xb3, 0xa8, 0x70, 0x66, 0x5d, 0xa8, 0x0e, 0x63, 0x2d, 0x3f, 0x88, 0xee, 0xf8, - 0x81, 0x9c, 0x5f, 0xa8, 0x83, 0x5e, 0xcc, 0xa0, 0x14, 0x35, 0xb2, 0x90, 0x8d, 0x26, 0x06, 0x27, - 0x78, 0xa2, 0x8f, 0xc0, 0x60, 0x58, 0x73, 0x1a, 0xa4, 0x7c, 0x63, 0x7a, 0x2a, 0xff, 0xf8, 0xa9, - 0x72, 0x92, 0x9c, 0xd9, 0xc5, 0x03, 0x63, 0x70, 0x12, 0x2c, 0xd9, 0xa1, 0x55, 0xe8, 0x67, 0xc9, - 0xe6, 0x58, 0x10, 0xc4, 0x9c, 0x18, 0xb6, 0x29, 0x07, 0x78, 0xbe, 0x37, 0x31, 0x30, 0xe6, 0xc5, - 0xe9, 0x1a, 0x10, 0xd7, 0x43, 0x3f, 0x9c, 0x3e, 0x9d, 0xbf, 0x06, 0xc4, 0xad, 0xf2, 0x46, 0xb5, - 0xd3, 0x1a, 0x50, 0x44, 0x38, 0x66, 0x4a, 0x77, 0x66, 0xba, 0x9b, 0x9e, 0xe9, 0xe0, 0xb9, 0x95, - 0xbb, 0x97, 0xb2, 0x9d, 0x99, 0xee, 0xa4, 0x94, 0x85, 0xfd, 0xbb, 0x83, 0x69, 0x99, 0x85, 0x29, - 0x14, 0xbe, 0xc7, 0x4a, 0xd9, 0x9a, 0xdf, 0xdf, 0xab, 0x7e, 0xf3, 0x18, 0xaf, 0x42, 0x9f, 0xb3, - 0xe0, 0x4c, 0x2b, 0xf3, 0x43, 0x84, 0x00, 0xd0, 0x9b, 0x9a, 0x94, 0x7f, 0xba, 0x0a, 0x98, 0x99, - 0x8d, 0xc7, 0x39, 0x35, 0x25, 0xaf, 0x9b, 0xc5, 0xb7, 0x7d, 0xdd, 0x5c, 0x83, 0xa1, 0x1a, 0xbf, - 0x8a, 0x74, 0xcc, 0x2c, 0x9e, 0xbc, 0x7b, 0x33, 0x51, 0x42, 0xdc, 0x61, 0xb6, 0xb0, 0x62, 0x81, - 0x7e, 0xd8, 0x82, 0x73, 0xc9, 0xa6, 0x63, 0xc2, 0xd0, 0x22, 0xca, 0x26, 0xd7, 0x65, 0xac, 0x8a, - 0xef, 0x4f, 0xc9, 0xff, 0x06, 0xf1, 0x61, 0x37, 0x02, 0xdc, 0xb9, 0x32, 0xb4, 0x9c, 0xa1, 0x4c, - 0x19, 0x30, 0x0d, 0x48, 0x3d, 0x28, 0x54, 0x5e, 0x80, 0x91, 0xa6, 0xdf, 0xf6, 0x22, 0xe1, 0xe8, - 0x25, 0x9c, 0x4e, 0x98, 0xb3, 0xc5, 0x9a, 0x06, 0xc7, 0x06, 0x55, 0x42, 0x0d, 0x33, 0x74, 0xdf, - 0x6a, 0x98, 0x37, 0x60, 0xc4, 0xd3, 0x3c, 0x93, 0x85, 0x3c, 0x70, 0x31, 0x3f, 0x42, 0xae, 0xee, - 0xc7, 0xcc, 0x5b, 0xa9, 0x43, 0xb0, 0xc1, 0xed, 0x64, 0x3d, 0xc0, 0xbe, 0x64, 0x65, 0x08, 0xf5, - 0x5c, 0x15, 0xf3, 0x41, 0x53, 0x15, 0x73, 0x31, 0xa9, 0x8a, 0x49, 0x19, 0x0f, 0x0c, 0x2d, 0x4c, - 0xef, 0x09, 0x80, 0x7a, 0x8d, 0xb2, 0x69, 0x37, 0xe0, 0x42, 0xb7, 0x63, 0x89, 0x79, 0xfc, 0xd5, - 0x95, 0xa9, 0x38, 0xf6, 0xf8, 0xab, 0x97, 0x97, 0x31, 0xc3, 0xf4, 0x1a, 0xbf, 0xc9, 0xfe, 0x2f, - 0x16, 0x14, 0x2b, 0x7e, 0xfd, 0x04, 0x2e, 0xbc, 0x1f, 0x32, 0x2e, 0xbc, 0x0f, 0x67, 0x1f, 0x88, - 0xf5, 0x5c, 0xd3, 0xc7, 0x4a, 0xc2, 0xf4, 0x71, 0x2e, 0x8f, 0x41, 0x67, 0x43, 0xc7, 0x4f, 0x16, - 0x61, 0xb8, 0xe2, 0xd7, 0x95, 0xbb, 0xfd, 0x3f, 0xbd, 0x1f, 0x77, 0xfb, 0xdc, 0x34, 0x16, 0x1a, - 0x67, 0xe6, 0x28, 0x28, 0x5f, 0x1a, 0x7f, 0x8b, 0x79, 0xdd, 0xdf, 0x26, 0xee, 0xf6, 0x4e, 0x44, - 0xea, 0xc9, 0xcf, 0x39, 0x39, 0xaf, 0xfb, 0xdf, 0x2d, 0xc0, 0x78, 0xa2, 0x76, 0xd4, 0x80, 0xd1, - 0x86, 0xae, 0x58, 0x17, 0xf3, 0xf4, 0xbe, 0x74, 0xf2, 0xc2, 0x6b, 0x59, 0x03, 0x61, 0x93, 0x39, - 0x9a, 0x03, 0x50, 0x96, 0x66, 0xa9, 0x5e, 0x65, 0x52, 0xbf, 0x32, 0x45, 0x87, 0x58, 0xa3, 0x40, - 0x2f, 0xc2, 0x70, 0xe4, 0xb7, 0xfc, 0x86, 0xbf, 0xbd, 0x7f, 0x8d, 0xc8, 0xd0, 0x5e, 0xca, 0x17, - 0x71, 0x23, 0x46, 0x61, 0x9d, 0x0e, 0xdd, 0x85, 0x49, 0xc5, 0xa4, 0x7a, 0x0c, 0xc6, 0x06, 0xa6, - 0x55, 0x58, 0x4f, 0x72, 0xc4, 0xe9, 0x4a, 0xec, 0x9f, 0x29, 0xf2, 0x2e, 0xf6, 0x22, 0xf7, 0xdd, - 0xd5, 0xf0, 0xce, 0x5e, 0x0d, 0x5f, 0xb7, 0x60, 0x82, 0xd6, 0xce, 0x1c, 0xad, 0xe4, 0x31, 0xaf, - 0x62, 0x72, 0x5b, 0x1d, 0x62, 0x72, 0x5f, 0xa4, 0xbb, 0x66, 0xdd, 0x6f, 0x47, 0x42, 0x77, 0xa7, - 0x6d, 0x8b, 0x14, 0x8a, 0x05, 0x56, 0xd0, 0x91, 0x20, 0x10, 0x8f, 0x43, 0x75, 0x3a, 0x12, 0x04, - 0x58, 0x60, 0x65, 0xc8, 0xee, 0xbe, 0xec, 0x90, 0xdd, 0x3c, 0xf2, 0xaa, 0x70, 0xc9, 0x11, 0x02, - 0x97, 0x16, 0x79, 0x55, 0xfa, 0xea, 0xc4, 0x34, 0xf6, 0x57, 0x8b, 0x30, 0x52, 0xf1, 0xeb, 0xb1, - 0x95, 0xf9, 0x05, 0xc3, 0xca, 0x7c, 0x21, 0x61, 0x65, 0x9e, 0xd0, 0x69, 0xdf, 0xb5, 0x29, 0x7f, - 0xb3, 0x6c, 0xca, 0xbf, 0x6c, 0xb1, 0x51, 0x5b, 0x5e, 0xaf, 0x72, 0xbf, 0x3d, 0x74, 0x19, 0x86, - 0xd9, 0x06, 0xc3, 0x5e, 0x23, 0x4b, 0xd3, 0x2b, 0x4b, 0x45, 0xb5, 0x1e, 0x83, 0xb1, 0x4e, 0x83, - 0x2e, 0xc1, 0x50, 0x48, 0x9c, 0xa0, 0xb6, 0xa3, 0x76, 0x57, 0x61, 0x27, 0xe5, 0x30, 0xac, 0xb0, - 0xe8, 0xf5, 0x38, 0xe8, 0x67, 0x31, 0xff, 0x75, 0xa3, 0xde, 0x1e, 0xbe, 0x44, 0xf2, 0x23, 0x7d, - 0xda, 0xb7, 0x01, 0xa5, 0xe9, 0x7b, 0x08, 0x4b, 0x37, 0x6b, 0x86, 0xa5, 0x2b, 0xa5, 0x42, 0xd2, - 0xfd, 0x89, 0x05, 0x63, 0x15, 0xbf, 0x4e, 0x97, 0xee, 0xb7, 0xd3, 0x3a, 0xd5, 0x23, 0x1e, 0x0f, - 0x74, 0x88, 0x78, 0xfc, 0x18, 0xf4, 0x57, 0xfc, 0x7a, 0xb9, 0xd2, 0x29, 0xb4, 0x80, 0xfd, 0x37, - 0x2c, 0x18, 0xac, 0xf8, 0xf5, 0x13, 0x30, 0x0b, 0x7c, 0xd0, 0x34, 0x0b, 0x3c, 0x94, 0x33, 0x6f, - 0x72, 0x2c, 0x01, 0x7f, 0xad, 0x0f, 0x46, 0x69, 0x3b, 0xfd, 0x6d, 0x39, 0x94, 0x46, 0xb7, 0x59, - 0x3d, 0x74, 0x1b, 0x95, 0xc2, 0xfd, 0x46, 0xc3, 0xbf, 0x93, 0x1c, 0xd6, 0x55, 0x06, 0xc5, 0x02, - 0x8b, 0x9e, 0x81, 0xa1, 0x56, 0x40, 0xf6, 0x5c, 0x5f, 0x88, 0xb7, 0x9a, 0x91, 0xa5, 0x22, 0xe0, - 0x58, 0x51, 0xd0, 0x6b, 0x61, 0xe8, 0x7a, 0xf4, 0x28, 0xaf, 0xf9, 0x5e, 0x9d, 0x6b, 0xce, 0x8b, - 0x22, 0x2d, 0x87, 0x06, 0xc7, 0x06, 0x15, 0xba, 0x0d, 0x25, 0xf6, 0x9f, 0x6d, 0x3b, 0x47, 0x4f, - 0xf0, 0x2a, 0x12, 0xfe, 0x09, 0x06, 0x38, 0xe6, 0x85, 0x9e, 0x03, 0x88, 0x64, 0x68, 0xfb, 0x50, - 0x04, 0x5a, 0x53, 0x57, 0x01, 0x15, 0xf4, 0x3e, 0xc4, 0x1a, 0x15, 0x7a, 0x1a, 0x4a, 0x91, 0xe3, - 0x36, 0xae, 0xbb, 0x1e, 0x09, 0x99, 0x46, 0xbc, 0x28, 0xf3, 0xee, 0x09, 0x20, 0x8e, 0xf1, 0x54, - 0x14, 0x63, 0x41, 0x38, 0x78, 0x7a, 0xe8, 0x21, 0x46, 0xcd, 0x44, 0xb1, 0xeb, 0x0a, 0x8a, 0x35, - 0x0a, 0xb4, 0x03, 0x8f, 0xb8, 0x1e, 0x4b, 0x61, 0x41, 0xaa, 0xbb, 0x6e, 0x6b, 0xe3, 0x7a, 0xf5, - 0x16, 0x09, 0xdc, 0xad, 0xfd, 0x45, 0xa7, 0xb6, 0x4b, 0x3c, 0x99, 0xba, 0xf3, 0x71, 0xd1, 0xc4, - 0x47, 0xca, 0x1d, 0x68, 0x71, 0x47, 0x4e, 0xf6, 0xf3, 0x6c, 0xbe, 0xdf, 0xa8, 0xa2, 0xf7, 0x1a, - 0x5b, 0xc7, 0x19, 0x7d, 0xeb, 0x38, 0x3c, 0x98, 0x1d, 0xb8, 0x51, 0xd5, 0x62, 0x48, 0xbc, 0x04, - 0xa7, 0x2b, 0x7e, 0xbd, 0xe2, 0x07, 0xd1, 0xaa, 0x1f, 0xdc, 0x71, 0x82, 0xba, 0x9c, 0x5e, 0xb3, - 0x32, 0x8a, 0x06, 0xdd, 0x3f, 0xfb, 0xf9, 0xee, 0x62, 0x44, 0xc8, 0x78, 0x9e, 0x49, 0x6c, 0x47, - 0x7c, 0xfb, 0x55, 0x63, 0xb2, 0x83, 0x4a, 0x02, 0x73, 0xc5, 0x89, 0x08, 0xba, 0xc1, 0x92, 0x5b, - 0xc7, 0xc7, 0xa8, 0x28, 0xfe, 0x94, 0x96, 0xdc, 0x3a, 0x46, 0x66, 0x9e, 0xbb, 0x66, 0x79, 0xfb, - 0xb3, 0xa2, 0x12, 0x7e, 0x07, 0xe7, 0xfe, 0x75, 0xbd, 0x64, 0xb7, 0x95, 0x59, 0x22, 0x0a, 0xf9, - 0xe9, 0x05, 0xb8, 0xd5, 0xb3, 0x63, 0x96, 0x08, 0xfb, 0x45, 0x98, 0xa4, 0x57, 0x3f, 0x25, 0x47, - 0xb1, 0x8f, 0xec, 0x1e, 0xcd, 0xe3, 0xbf, 0xf6, 0xb3, 0x73, 0x20, 0x91, 0xfe, 0x04, 0x7d, 0x12, - 0xc6, 0x42, 0x72, 0xdd, 0xf5, 0xda, 0x77, 0xa5, 0xe2, 0xa5, 0xc3, 0x9b, 0xc3, 0xea, 0x8a, 0x4e, - 0xc9, 0xd5, 0xb7, 0x26, 0x0c, 0x27, 0xb8, 0xa1, 0x26, 0x8c, 0xdd, 0x71, 0xbd, 0xba, 0x7f, 0x27, - 0x94, 0xfc, 0x87, 0xf2, 0xb5, 0xb8, 0xb7, 0x39, 0x65, 0xa2, 0x8d, 0x46, 0x75, 0xb7, 0x0d, 0x66, - 0x38, 0xc1, 0x9c, 0xae, 0xb5, 0xa0, 0xed, 0x2d, 0x84, 0x37, 0x43, 0x12, 0x88, 0xe4, 0xea, 0x6c, - 0xad, 0x61, 0x09, 0xc4, 0x31, 0x9e, 0xae, 0x35, 0xf6, 0xe7, 0x4a, 0xe0, 0xb7, 0x79, 0xae, 0x0d, - 0xb1, 0xd6, 0xb0, 0x82, 0x62, 0x8d, 0x82, 0xee, 0x45, 0xec, 0xdf, 0xba, 0xef, 0x61, 0xdf, 0x8f, - 0xe4, 0xee, 0xc5, 0x3c, 0x11, 0x34, 0x38, 0x36, 0xa8, 0xd0, 0x2a, 0xa0, 0xb0, 0xdd, 0x6a, 0x35, - 0x98, 0x33, 0x93, 0xd3, 0x60, 0xac, 0xb8, 0x97, 0x47, 0x91, 0xc7, 0x0a, 0xae, 0xa6, 0xb0, 0x38, - 0xa3, 0x04, 0x3d, 0x96, 0xb6, 0x44, 0x53, 0xfb, 0x59, 0x53, 0xb9, 0xc5, 0xa7, 0xca, 0xdb, 0x29, - 0x71, 0x68, 0x05, 0x06, 0xc3, 0xfd, 0xb0, 0x16, 0x89, 0xd0, 0x8e, 0x39, 0x19, 0xae, 0xaa, 0x8c, - 0x44, 0x4b, 0xb0, 0xc8, 0x8b, 0x60, 0x59, 0x16, 0xd5, 0x60, 0x4a, 0x70, 0x5c, 0xda, 0x71, 0x3c, - 0x95, 0x2f, 0x88, 0xfb, 0x74, 0x5f, 0xbe, 0x77, 0x30, 0x3b, 0x25, 0x6a, 0xd6, 0xd1, 0x87, 0x07, - 0xb3, 0x67, 0x2a, 0x7e, 0x3d, 0x03, 0x83, 0xb3, 0xb8, 0xf1, 0xc9, 0x57, 0xab, 0xf9, 0xcd, 0x56, - 0x25, 0xf0, 0xb7, 0xdc, 0x06, 0xe9, 0x64, 0x35, 0xab, 0x1a, 0x94, 0x62, 0xf2, 0x19, 0x30, 0x9c, - 0xe0, 0x66, 0x7f, 0x96, 0x89, 0x6e, 0x2c, 0x9f, 0x78, 0xd4, 0x0e, 0x08, 0x6a, 0xc2, 0x68, 0x8b, - 0x2d, 0x6e, 0x91, 0x01, 0x43, 0xcc, 0xf5, 0x17, 0x7a, 0xd4, 0xfe, 0xdc, 0xa1, 0x27, 0x9e, 0xe9, - 0x19, 0x55, 0xd1, 0xd9, 0x61, 0x93, 0xbb, 0xfd, 0x6f, 0xce, 0xb2, 0xc3, 0xbf, 0xca, 0x55, 0x3a, - 0x83, 0xe2, 0x09, 0x89, 0xb8, 0x45, 0xce, 0xe4, 0xeb, 0x16, 0xe3, 0x61, 0x11, 0xcf, 0x50, 0xb0, - 0x2c, 0x8b, 0x3e, 0x01, 0x63, 0xf4, 0x52, 0xa6, 0x0e, 0xe0, 0x70, 0xfa, 0x54, 0x7e, 0xa8, 0x0f, - 0x45, 0xa5, 0x67, 0xc7, 0xd1, 0x0b, 0xe3, 0x04, 0x33, 0xf4, 0x3a, 0xf3, 0x44, 0x92, 0xac, 0x0b, - 0xbd, 0xb0, 0xd6, 0x9d, 0x8e, 0x24, 0x5b, 0x8d, 0x09, 0x6a, 0xc3, 0x54, 0x3a, 0x97, 0x5e, 0x38, - 0x6d, 0xe7, 0x4b, 0xb7, 0xe9, 0x74, 0x78, 0x71, 0x1a, 0x93, 0x34, 0x2e, 0xc4, 0x59, 0xfc, 0xd1, - 0x75, 0x18, 0x15, 0x49, 0xb5, 0xc5, 0xcc, 0x2d, 0x1a, 0x2a, 0xcf, 0x51, 0xac, 0x23, 0x0f, 0x93, - 0x00, 0x6c, 0x16, 0x46, 0xdb, 0x70, 0x4e, 0x4b, 0x72, 0x75, 0x25, 0x70, 0x98, 0xdf, 0x82, 0xcb, - 0xb6, 0x53, 0x4d, 0x2c, 0x79, 0xf4, 0xde, 0xc1, 0xec, 0xb9, 0x8d, 0x4e, 0x84, 0xb8, 0x33, 0x1f, - 0x74, 0x03, 0x4e, 0xf3, 0x87, 0xea, 0xcb, 0xc4, 0xa9, 0x37, 0x5c, 0x4f, 0xc9, 0x3d, 0x7c, 0xc9, - 0x9f, 0xbd, 0x77, 0x30, 0x7b, 0x7a, 0x21, 0x8b, 0x00, 0x67, 0x97, 0x43, 0x1f, 0x84, 0x52, 0xdd, - 0x0b, 0x45, 0x1f, 0x0c, 0x18, 0x79, 0xc4, 0x4a, 0xcb, 0xeb, 0x55, 0xf5, 0xfd, 0xf1, 0x1f, 0x1c, - 0x17, 0x40, 0xdb, 0x5c, 0x2d, 0xae, 0x94, 0x35, 0x83, 0xa9, 0x40, 0x5d, 0x49, 0x7d, 0xa6, 0xf1, - 0x54, 0x95, 0xdb, 0x83, 0xd4, 0x0b, 0x0e, 0xe3, 0x15, 0xab, 0xc1, 0x18, 0xbd, 0x06, 0x48, 0xc4, - 0xab, 0x5f, 0xa8, 0xb1, 0xf4, 0x2a, 0xcc, 0x8a, 0x30, 0x64, 0x3e, 0x9e, 0xac, 0xa6, 0x28, 0x70, - 0x46, 0x29, 0x74, 0x95, 0xee, 0x2a, 0x3a, 0x54, 0xec, 0x5a, 0x2a, 0xeb, 0xe3, 0x32, 0x69, 0x05, - 0x84, 0xf9, 0x61, 0x99, 0x1c, 0x71, 0xa2, 0x1c, 0xaa, 0xc3, 0x23, 0x4e, 0x3b, 0xf2, 0x99, 0xc5, - 0xc1, 0x24, 0xdd, 0xf0, 0x77, 0x89, 0xc7, 0x8c, 0x7d, 0x43, 0x8b, 0x17, 0xa8, 0x60, 0xb5, 0xd0, - 0x81, 0x0e, 0x77, 0xe4, 0x42, 0x05, 0x62, 0x95, 0xe6, 0x19, 0xcc, 0xf0, 0x63, 0x19, 0xa9, 0x9e, - 0x5f, 0x84, 0xe1, 0x1d, 0x3f, 0x8c, 0xd6, 0x49, 0x74, 0xc7, 0x0f, 0x76, 0x45, 0x18, 0xdd, 0x38, - 0x28, 0x79, 0x8c, 0xc2, 0x3a, 0x1d, 0xbd, 0xf1, 0x32, 0x57, 0x94, 0xf2, 0x32, 0xf3, 0x02, 0x18, - 0x8a, 0xf7, 0x98, 0xab, 0x1c, 0x8c, 0x25, 0x5e, 0x92, 0x96, 0x2b, 0x4b, 0xcc, 0xa2, 0x9f, 0x20, - 0x2d, 0x57, 0x96, 0xb0, 0xc4, 0xd3, 0xe9, 0x1a, 0xee, 0x38, 0x01, 0xa9, 0x04, 0x7e, 0x8d, 0x84, - 0x5a, 0x28, 0xfc, 0x87, 0x79, 0x90, 0x60, 0x3a, 0x5d, 0xab, 0x59, 0x04, 0x38, 0xbb, 0x1c, 0x22, - 0xe9, 0x04, 0x6f, 0x63, 0xf9, 0xa6, 0x98, 0xb4, 0x3c, 0xd3, 0x63, 0x8e, 0x37, 0x0f, 0x26, 0x54, - 0x6a, 0x39, 0x1e, 0x16, 0x38, 0x9c, 0x1e, 0x67, 0x73, 0xbb, 0xf7, 0x98, 0xc2, 0xca, 0xb8, 0x55, - 0x4e, 0x70, 0xc2, 0x29, 0xde, 0x46, 0x84, 0xb9, 0x89, 0xae, 0x11, 0xe6, 0xe6, 0xa1, 0x14, 0xb6, - 0x37, 0xeb, 0x7e, 0xd3, 0x71, 0x3d, 0x66, 0xd1, 0xd7, 0xae, 0x5e, 0x55, 0x89, 0xc0, 0x31, 0x0d, - 0x5a, 0x85, 0x21, 0x47, 0x5a, 0xae, 0x50, 0x7e, 0x4c, 0x21, 0x65, 0xaf, 0xe2, 0x61, 0x36, 0xa4, - 0xad, 0x4a, 0x95, 0x45, 0xaf, 0xc0, 0xa8, 0x78, 0x68, 0x2d, 0xb2, 0x9a, 0x4e, 0x99, 0xaf, 0xe1, - 0xaa, 0x3a, 0x12, 0x9b, 0xb4, 0xe8, 0x26, 0x0c, 0x47, 0x7e, 0x83, 0x3d, 0xe9, 0xa2, 0x62, 0xde, - 0x99, 0xfc, 0xe8, 0x78, 0x1b, 0x8a, 0x4c, 0x57, 0x1a, 0xab, 0xa2, 0x58, 0xe7, 0x83, 0x36, 0xf8, - 0x7c, 0x67, 0x81, 0xef, 0x49, 0x38, 0xfd, 0x50, 0xfe, 0x99, 0xa4, 0xe2, 0xe3, 0x9b, 0xcb, 0x41, - 0x94, 0xc4, 0x3a, 0x1b, 0x74, 0x05, 0x26, 0x5b, 0x81, 0xeb, 0xb3, 0x39, 0xa1, 0x8c, 0x96, 0xd3, - 0x66, 0x9a, 0xab, 0x4a, 0x92, 0x00, 0xa7, 0xcb, 0xb0, 0x77, 0xf2, 0x02, 0x38, 0x7d, 0x96, 0xa7, - 0xea, 0xe0, 0x37, 0x59, 0x0e, 0xc3, 0x0a, 0x8b, 0xd6, 0xd8, 0x4e, 0xcc, 0x95, 0x30, 0xd3, 0x33, - 0xf9, 0x61, 0x8c, 0x74, 0x65, 0x0d, 0x17, 0x5e, 0xd5, 0x5f, 0x1c, 0x73, 0x40, 0x75, 0x2d, 0x43, - 0x26, 0xbd, 0x02, 0x84, 0xd3, 0x8f, 0x74, 0xf0, 0x07, 0x4c, 0x5c, 0x8a, 0x62, 0x81, 0xc0, 0x00, - 0x87, 0x38, 0xc1, 0x13, 0x7d, 0x18, 0x26, 0x44, 0xf0, 0xc5, 0xb8, 0x9b, 0xce, 0xc5, 0x8e, 0xf2, - 0x38, 0x81, 0xc3, 0x29, 0x6a, 0x9e, 0x2a, 0xc3, 0xd9, 0x6c, 0x10, 0xb1, 0xf5, 0x5d, 0x77, 0xbd, - 0xdd, 0x70, 0xfa, 0x3c, 0xdb, 0x1f, 0x44, 0xaa, 0x8c, 0x24, 0x16, 0x67, 0x94, 0x40, 0x1b, 0x30, - 0xd1, 0x0a, 0x08, 0x69, 0x32, 0x41, 0x5f, 0x9c, 0x67, 0xb3, 0x3c, 0x4c, 0x04, 0x6d, 0x49, 0x25, - 0x81, 0x3b, 0xcc, 0x80, 0xe1, 0x14, 0x07, 0x74, 0x07, 0x86, 0xfc, 0x3d, 0x12, 0xec, 0x10, 0xa7, - 0x3e, 0x7d, 0xa1, 0xc3, 0xc3, 0x0d, 0x71, 0xb8, 0xdd, 0x10, 0xb4, 0x09, 0x47, 0x07, 0x09, 0xee, - 0xee, 0xe8, 0x20, 0x2b, 0x43, 0x7f, 0xde, 0x82, 0xb3, 0xd2, 0x36, 0x52, 0x6d, 0xd1, 0x5e, 0x5f, - 0xf2, 0xbd, 0x30, 0x0a, 0x78, 0x60, 0x83, 0x47, 0xf3, 0x1f, 0xfb, 0x6f, 0xe4, 0x14, 0x52, 0x7a, - 0xe0, 0xb3, 0x79, 0x14, 0x21, 0xce, 0xaf, 0x11, 0x2d, 0xc1, 0x64, 0x48, 0x22, 0xb9, 0x19, 0x2d, - 0x84, 0xab, 0xaf, 0x2f, 0xaf, 0x4f, 0x3f, 0xc6, 0xa3, 0x32, 0xd0, 0xc5, 0x50, 0x4d, 0x22, 0x71, - 0x9a, 0x1e, 0x5d, 0x86, 0x82, 0x1f, 0x4e, 0x3f, 0xde, 0x21, 0xa9, 0xaa, 0x5f, 0xbf, 0x51, 0xe5, - 0x0e, 0x6f, 0x37, 0xaa, 0xb8, 0xe0, 0x87, 0x32, 0x5d, 0x05, 0xbd, 0x8f, 0x85, 0xd3, 0x4f, 0x70, - 0xad, 0xa1, 0x4c, 0x57, 0xc1, 0x80, 0x38, 0xc6, 0xa3, 0x1d, 0x18, 0x0f, 0x8d, 0x7b, 0x6f, 0x38, - 0x7d, 0x91, 0xf5, 0xd4, 0x13, 0x79, 0x83, 0x66, 0x50, 0x6b, 0xd1, 0xe6, 0x4d, 0x2e, 0x38, 0xc9, - 0x96, 0xaf, 0x2e, 0xed, 0x82, 0x1f, 0x4e, 0x3f, 0xd9, 0x65, 0x75, 0x69, 0xc4, 0xfa, 0xea, 0xd2, - 0x79, 0xe0, 0x04, 0xcf, 0x99, 0xef, 0x84, 0xc9, 0x94, 0xb8, 0x74, 0x94, 0x4c, 0x4c, 0x33, 0xbb, - 0x30, 0x6a, 0x4c, 0xc9, 0x07, 0xea, 0x58, 0xf0, 0x2f, 0x06, 0xa1, 0xa4, 0x8c, 0xce, 0x68, 0xde, - 0xf4, 0x25, 0x38, 0x9b, 0xf4, 0x25, 0x18, 0xaa, 0xf8, 0x75, 0xc3, 0x7d, 0x60, 0x23, 0x23, 0x76, - 0x5f, 0xde, 0x06, 0xd8, 0xfb, 0x9b, 0x06, 0x4d, 0x93, 0x5f, 0xec, 0xd9, 0x29, 0xa1, 0xaf, 0xa3, - 0x71, 0xe0, 0x0a, 0x4c, 0x7a, 0x3e, 0x93, 0xd1, 0x49, 0x5d, 0x0a, 0x60, 0x4c, 0xce, 0x2a, 0xe9, - 0xc1, 0x70, 0x12, 0x04, 0x38, 0x5d, 0x86, 0x56, 0xc8, 0x05, 0xa5, 0xa4, 0x35, 0x82, 0xcb, 0x51, - 0x58, 0x60, 0xd1, 0x63, 0xd0, 0xdf, 0xf2, 0xeb, 0xe5, 0x8a, 0x90, 0xcf, 0xb5, 0x88, 0xb1, 0xf5, - 0x72, 0x05, 0x73, 0x1c, 0x5a, 0x80, 0x01, 0xf6, 0x23, 0x9c, 0x1e, 0xc9, 0x8f, 0x7a, 0xc2, 0x4a, - 0x68, 0x79, 0xae, 0x58, 0x01, 0x2c, 0x0a, 0x32, 0xad, 0x28, 0xbd, 0xd4, 0x30, 0xad, 0xe8, 0xe0, - 0x7d, 0x6a, 0x45, 0x25, 0x03, 0x1c, 0xf3, 0x42, 0x77, 0xe1, 0xb4, 0x71, 0x91, 0xe4, 0x53, 0x84, - 0x84, 0x22, 0xf2, 0xc2, 0x63, 0x1d, 0x6f, 0x90, 0xc2, 0x89, 0xe1, 0x9c, 0x68, 0xf4, 0xe9, 0x72, - 0x16, 0x27, 0x9c, 0x5d, 0x01, 0x6a, 0xc0, 0x64, 0x2d, 0x55, 0xeb, 0x50, 0xef, 0xb5, 0xaa, 0x01, - 0x4d, 0xd7, 0x98, 0x66, 0x8c, 0x5e, 0x81, 0xa1, 0x37, 0xfd, 0x90, 0x9d, 0x6d, 0xe2, 0x4e, 0x21, - 0x9f, 0xed, 0x0f, 0xbd, 0x7e, 0xa3, 0xca, 0xe0, 0x87, 0x07, 0xb3, 0xc3, 0x15, 0xbf, 0x2e, 0xff, - 0x62, 0x55, 0x00, 0x7d, 0xbf, 0x05, 0x33, 0xe9, 0x9b, 0xaa, 0x6a, 0xf4, 0x68, 0xef, 0x8d, 0xb6, - 0x45, 0xa5, 0x33, 0x2b, 0xb9, 0xec, 0x70, 0x87, 0xaa, 0xec, 0x5f, 0xb4, 0x98, 0x6e, 0x55, 0x18, - 0x07, 0x49, 0xd8, 0x6e, 0x9c, 0x44, 0x7a, 0xdf, 0x15, 0xc3, 0x6e, 0x79, 0xdf, 0x4e, 0x2d, 0xff, - 0xc4, 0x62, 0x4e, 0x2d, 0x27, 0xf8, 0x7a, 0xe5, 0x75, 0x18, 0x8a, 0x64, 0xda, 0xe5, 0x0e, 0x19, - 0x89, 0xb5, 0x46, 0x31, 0xc7, 0x1e, 0x25, 0xe1, 0xab, 0x0c, 0xcb, 0x8a, 0x8d, 0xfd, 0x0f, 0xf8, - 0x08, 0x48, 0xcc, 0x09, 0x98, 0x87, 0x96, 0x4d, 0xf3, 0xd0, 0x6c, 0x97, 0x2f, 0xc8, 0x31, 0x13, - 0xfd, 0x7d, 0xb3, 0xdd, 0x4c, 0xb3, 0xf5, 0x4e, 0xf7, 0xa6, 0xb2, 0x3f, 0x6f, 0x01, 0xc4, 0x01, - 0xb9, 0x7b, 0x48, 0xac, 0xf7, 0x12, 0x95, 0xe9, 0xfd, 0xc8, 0xaf, 0xf9, 0x0d, 0x61, 0xfc, 0x7c, - 0x24, 0xb6, 0x50, 0x71, 0xf8, 0xa1, 0xf6, 0x1b, 0x2b, 0x6a, 0x34, 0x2b, 0xc3, 0xff, 0x15, 0x63, - 0x9b, 0xa9, 0x11, 0xfa, 0xef, 0x8b, 0x16, 0x9c, 0xca, 0x72, 0x85, 0xa6, 0x37, 0x44, 0xae, 0xe3, - 0x53, 0x9e, 0x6e, 0x6a, 0x34, 0x6f, 0x09, 0x38, 0x56, 0x14, 0x3d, 0x67, 0x2c, 0x3c, 0x5a, 0x24, - 0xec, 0x1b, 0x30, 0x5a, 0x09, 0x88, 0x76, 0xb8, 0xbe, 0xca, 0x43, 0x4a, 0xf0, 0xf6, 0x3c, 0x73, - 0xe4, 0x70, 0x12, 0xf6, 0x97, 0x0b, 0x70, 0x8a, 0x3b, 0x8c, 0x2c, 0xec, 0xf9, 0x6e, 0xbd, 0xe2, - 0xd7, 0xc5, 0x83, 0xb7, 0x8f, 0xc1, 0x48, 0x4b, 0x53, 0xcc, 0x76, 0x8a, 0xea, 0xaa, 0x2b, 0x70, - 0x63, 0x55, 0x92, 0x0e, 0xc5, 0x06, 0x2f, 0x54, 0x87, 0x11, 0xb2, 0xe7, 0xd6, 0x94, 0xd7, 0x41, - 0xe1, 0xc8, 0x07, 0x9d, 0xaa, 0x65, 0x45, 0xe3, 0x83, 0x0d, 0xae, 0x0f, 0x20, 0x8f, 0xb8, 0xfd, - 0xa3, 0x16, 0x3c, 0x94, 0x13, 0x03, 0x96, 0x56, 0x77, 0x87, 0xb9, 0xe6, 0x88, 0x69, 0xab, 0xaa, - 0xe3, 0x0e, 0x3b, 0x58, 0x60, 0xd1, 0x47, 0x00, 0xb8, 0xc3, 0x0d, 0xf1, 0x6a, 0x5d, 0x83, 0x65, - 0x1a, 0x71, 0xfe, 0xb4, 0x90, 0x6d, 0xb2, 0x3c, 0xd6, 0x78, 0xd9, 0x5f, 0xec, 0x83, 0x7e, 0xe6, - 0xe0, 0x81, 0x2a, 0x30, 0xb8, 0xc3, 0xb3, 0xfa, 0x74, 0x1c, 0x37, 0x4a, 0x2b, 0x13, 0x05, 0xc5, - 0xe3, 0xa6, 0x41, 0xb1, 0x64, 0x83, 0xd6, 0x60, 0x8a, 0x27, 0x57, 0x6a, 0x2c, 0x93, 0x86, 0xb3, - 0x2f, 0x75, 0x9e, 0x3c, 0x13, 0xb0, 0xd2, 0xfd, 0x96, 0xd3, 0x24, 0x38, 0xab, 0x1c, 0x7a, 0x15, - 0xc6, 0xe8, 0x1d, 0xd4, 0x6f, 0x47, 0x92, 0x13, 0x4f, 0xab, 0xa4, 0xc4, 0xf2, 0x0d, 0x03, 0x8b, - 0x13, 0xd4, 0xe8, 0x15, 0x18, 0x6d, 0xa5, 0xb4, 0xbb, 0xfd, 0xb1, 0x1a, 0xc4, 0xd4, 0xe8, 0x9a, - 0xb4, 0xcc, 0x1b, 0xba, 0xcd, 0x7c, 0xbf, 0x37, 0x76, 0x02, 0x12, 0xee, 0xf8, 0x8d, 0x3a, 0x13, - 0xff, 0xfa, 0x35, 0x6f, 0xe8, 0x04, 0x1e, 0xa7, 0x4a, 0x50, 0x2e, 0x5b, 0x8e, 0xdb, 0x68, 0x07, - 0x24, 0xe6, 0x32, 0x60, 0x72, 0x59, 0x4d, 0xe0, 0x71, 0xaa, 0x44, 0x77, 0xb5, 0xf5, 0xe0, 0xf1, - 0xa8, 0xad, 0xed, 0x9f, 0x2a, 0x80, 0x31, 0xb4, 0xdf, 0xbe, 0xe9, 0x9e, 0xe8, 0x97, 0x6d, 0x07, - 0xad, 0x9a, 0x70, 0x66, 0xca, 0xfc, 0xb2, 0x38, 0x8b, 0x2b, 0xff, 0x32, 0xfa, 0x1f, 0xb3, 0x52, - 0x74, 0x8d, 0x9f, 0xae, 0x04, 0x3e, 0x3d, 0xe4, 0x64, 0xd0, 0x31, 0xf5, 0xe8, 0x60, 0x50, 0x3e, - 0xc8, 0xee, 0x10, 0x9e, 0x53, 0xb8, 0x65, 0x73, 0x0e, 0x86, 0xdf, 0x4f, 0x55, 0x44, 0x46, 0x90, - 0x5c, 0xd0, 0x65, 0x18, 0x16, 0x39, 0x7c, 0x98, 0x6f, 0x3c, 0x5f, 0x4c, 0xcc, 0x4f, 0x69, 0x39, - 0x06, 0x63, 0x9d, 0xc6, 0xfe, 0x81, 0x02, 0x4c, 0x65, 0x3c, 0x6e, 0xe2, 0xc7, 0xc8, 0xb6, 0x1b, - 0x46, 0x2a, 0x51, 0xac, 0x76, 0x8c, 0x70, 0x38, 0x56, 0x14, 0x74, 0xaf, 0xe2, 0x07, 0x55, 0xf2, - 0x70, 0x12, 0x8f, 0x07, 0x04, 0xf6, 0x88, 0x29, 0x57, 0x2f, 0x40, 0x5f, 0x3b, 0x24, 0x32, 0xb0, - 0xae, 0x3a, 0xb6, 0x99, 0x4d, 0x97, 0x61, 0xe8, 0x35, 0x6a, 0x5b, 0x99, 0x47, 0xb5, 0x6b, 0x14, - 0x37, 0x90, 0x72, 0x1c, 0x6d, 0x5c, 0x44, 0x3c, 0xc7, 0x8b, 0xc4, 0x65, 0x2b, 0x8e, 0x10, 0xc9, - 0xa0, 0x58, 0x60, 0xed, 0x2f, 0x14, 0xe1, 0x6c, 0xee, 0x73, 0x47, 0xda, 0xf4, 0xa6, 0xef, 0xb9, - 0x91, 0xaf, 0x1c, 0xc0, 0x78, 0x54, 0x48, 0xd2, 0xda, 0x59, 0x13, 0x70, 0xac, 0x28, 0xd0, 0x45, - 0xe8, 0x67, 0x1a, 0xe1, 0x54, 0xca, 0xdc, 0xc5, 0x65, 0x1e, 0x26, 0x8c, 0xa3, 0x7b, 0xce, 0x72, - 0xfe, 0x18, 0x95, 0x60, 0xfc, 0x46, 0xf2, 0x40, 0xa1, 0xcd, 0xf5, 0xfd, 0x06, 0x66, 0x48, 0xf4, - 0x84, 0xe8, 0xaf, 0x84, 0xc7, 0x13, 0x76, 0xea, 0x7e, 0xa8, 0x75, 0xda, 0x53, 0x30, 0xb8, 0x4b, - 0xf6, 0x03, 0xd7, 0xdb, 0x4e, 0x7a, 0xc2, 0x5d, 0xe3, 0x60, 0x2c, 0xf1, 0x66, 0x8e, 0xc7, 0xc1, - 0xe3, 0x4e, 0x4f, 0x3e, 0xd4, 0x55, 0x3c, 0xf9, 0xa1, 0x22, 0x8c, 0xe3, 0xc5, 0xe5, 0x77, 0x07, - 0xe2, 0x66, 0x7a, 0x20, 0x8e, 0x3b, 0x3d, 0x79, 0xf7, 0xd1, 0xf8, 0x39, 0x0b, 0xc6, 0x59, 0x26, - 0x21, 0x11, 0xd4, 0xc0, 0xf5, 0xbd, 0x13, 0xb8, 0x0a, 0x3c, 0x06, 0xfd, 0x01, 0xad, 0x34, 0x99, - 0x2b, 0x97, 0xb5, 0x04, 0x73, 0x1c, 0x7a, 0x04, 0xfa, 0x58, 0x13, 0xe8, 0xe0, 0x8d, 0xf0, 0x2d, - 0x78, 0xd9, 0x89, 0x1c, 0xcc, 0xa0, 0x2c, 0x48, 0x16, 0x26, 0xad, 0x86, 0xcb, 0x1b, 0x1d, 0xdb, - 0xeb, 0xdf, 0x19, 0x81, 0x10, 0x32, 0x9b, 0xf6, 0xf6, 0x82, 0x64, 0x65, 0xb3, 0xec, 0x7c, 0xcd, - 0xfe, 0xc3, 0x02, 0x9c, 0xcf, 0x2c, 0xd7, 0x73, 0x90, 0xac, 0xce, 0xa5, 0x1f, 0x64, 0xae, 0x98, - 0xe2, 0x09, 0xfa, 0x19, 0xf7, 0xf5, 0x2a, 0xfd, 0xf7, 0xf7, 0x10, 0xbb, 0x2a, 0xb3, 0xcb, 0xde, - 0x21, 0xb1, 0xab, 0x32, 0xdb, 0x96, 0xa3, 0x26, 0xf8, 0xd3, 0x42, 0xce, 0xb7, 0x30, 0x85, 0xc1, - 0x25, 0xba, 0xcf, 0x30, 0x64, 0x28, 0x2f, 0xe1, 0x7c, 0x8f, 0xe1, 0x30, 0xac, 0xb0, 0x68, 0x01, - 0xc6, 0x9b, 0xae, 0x47, 0x37, 0x9f, 0x7d, 0x53, 0x14, 0x57, 0x8a, 0xfc, 0x35, 0x13, 0x8d, 0x93, - 0xf4, 0xc8, 0xd5, 0xe2, 0x5a, 0xf1, 0xaf, 0x7b, 0xe5, 0x48, 0xab, 0x6e, 0xce, 0xf4, 0x65, 0x50, - 0xbd, 0x98, 0x11, 0xe3, 0x6a, 0x4d, 0xd3, 0x13, 0x15, 0x7b, 0xd7, 0x13, 0x8d, 0x64, 0xeb, 0x88, - 0x66, 0x5e, 0x81, 0xd1, 0xfb, 0x36, 0x0c, 0xd8, 0x5f, 0x2f, 0xc2, 0xc3, 0x1d, 0x96, 0x3d, 0xdf, - 0xeb, 0x8d, 0x31, 0xd0, 0xf6, 0xfa, 0xd4, 0x38, 0x54, 0xe0, 0xd4, 0x56, 0xbb, 0xd1, 0xd8, 0x67, - 0xcf, 0x6f, 0x48, 0x5d, 0x52, 0x08, 0x99, 0x52, 0x2a, 0x47, 0x4e, 0xad, 0x66, 0xd0, 0xe0, 0xcc, - 0x92, 0xf4, 0x8a, 0x45, 0x4f, 0x92, 0x7d, 0xc5, 0x2a, 0x71, 0xc5, 0xc2, 0x3a, 0x12, 0x9b, 0xb4, - 0xe8, 0x0a, 0x4c, 0x3a, 0x7b, 0x8e, 0xcb, 0x83, 0x83, 0x4b, 0x06, 0xfc, 0x8e, 0xa5, 0xf4, 0xb9, - 0x0b, 0x49, 0x02, 0x9c, 0x2e, 0x83, 0x5e, 0x03, 0xe4, 0x6f, 0x32, 0x27, 0xfd, 0xfa, 0x15, 0xe2, - 0x09, 0x93, 0x33, 0x1b, 0xbb, 0x62, 0xbc, 0x25, 0xdc, 0x48, 0x51, 0xe0, 0x8c, 0x52, 0x89, 0x20, - 0x4e, 0x03, 0xf9, 0x41, 0x9c, 0x3a, 0xef, 0x8b, 0x5d, 0xd3, 0x14, 0x5d, 0x86, 0xd1, 0x23, 0xba, - 0x9e, 0xda, 0xff, 0xc1, 0xa2, 0x27, 0x1e, 0x2f, 0x63, 0x46, 0x48, 0x7d, 0x85, 0xf9, 0xc6, 0x72, - 0xf5, 0xb0, 0x16, 0x25, 0xe7, 0xb4, 0xe6, 0x1b, 0x1b, 0x23, 0xb1, 0x49, 0xcb, 0xe7, 0x90, 0xe6, - 0xd3, 0x6a, 0xdc, 0x0a, 0x44, 0x18, 0x37, 0x45, 0x81, 0x3e, 0x0a, 0x83, 0x75, 0x77, 0xcf, 0x0d, - 0x85, 0x72, 0xec, 0xc8, 0x96, 0xa8, 0x78, 0xeb, 0x5c, 0xe6, 0x6c, 0xb0, 0xe4, 0x67, 0xff, 0x50, - 0x21, 0xee, 0x93, 0xd7, 0xdb, 0x7e, 0xe4, 0x9c, 0xc0, 0x49, 0x7e, 0xc5, 0x38, 0xc9, 0x9f, 0xe8, - 0x14, 0xcb, 0x8e, 0x35, 0x29, 0xf7, 0x04, 0xbf, 0x91, 0x38, 0xc1, 0x9f, 0xec, 0xce, 0xaa, 0xf3, - 0xc9, 0xfd, 0x0f, 0x2d, 0x98, 0x34, 0xe8, 0x4f, 0xe0, 0x00, 0x59, 0x35, 0x0f, 0x90, 0x47, 0xbb, - 0x7e, 0x43, 0xce, 0xc1, 0xf1, 0xbd, 0xc5, 0x44, 0xdb, 0xd9, 0x81, 0xf1, 0x26, 0xf4, 0xed, 0x38, - 0x41, 0xbd, 0x53, 0xee, 0x8e, 0x54, 0xa1, 0xb9, 0xab, 0x4e, 0x20, 0xcc, 0xf4, 0xcf, 0xc8, 0x5e, - 0xa7, 0xa0, 0xae, 0x26, 0x7a, 0x56, 0x15, 0x7a, 0x09, 0x06, 0xc2, 0x9a, 0xdf, 0x52, 0xef, 0x75, - 0x2e, 0xb0, 0x8e, 0x66, 0x90, 0xc3, 0x83, 0x59, 0x64, 0x56, 0x47, 0xc1, 0x58, 0xd0, 0xa3, 0x8f, - 0xc1, 0x28, 0xfb, 0xa5, 0x7c, 0xe6, 0x8a, 0xf9, 0x1a, 0x8c, 0xaa, 0x4e, 0xc8, 0x1d, 0x4a, 0x0d, - 0x10, 0x36, 0x59, 0xcd, 0x6c, 0x43, 0x49, 0x7d, 0xd6, 0x03, 0x35, 0xf5, 0xfe, 0xbb, 0x22, 0x4c, - 0x65, 0xcc, 0x39, 0x14, 0x1a, 0x23, 0x71, 0xb9, 0xc7, 0xa9, 0xfa, 0x36, 0xc7, 0x22, 0x64, 0x17, - 0xa8, 0xba, 0x98, 0x5b, 0x3d, 0x57, 0x7a, 0x33, 0x24, 0xc9, 0x4a, 0x29, 0xa8, 0x7b, 0xa5, 0xb4, - 0xb2, 0x13, 0xeb, 0x6a, 0x5a, 0x91, 0x6a, 0xe9, 0x03, 0x1d, 0xd3, 0x5f, 0xee, 0x83, 0x53, 0x59, - 0xe1, 0x35, 0xd1, 0x67, 0x12, 0x99, 0x63, 0x5f, 0xe8, 0x35, 0x30, 0x27, 0x4f, 0x27, 0x2b, 0xc2, - 0xfe, 0xcd, 0x99, 0xb9, 0x64, 0xbb, 0x76, 0xb3, 0xa8, 0x93, 0x05, 0x1e, 0x09, 0x78, 0xc6, 0x5f, - 0xb9, 0x7d, 0xbc, 0xbf, 0xe7, 0x06, 0x88, 0x54, 0xc1, 0x61, 0xc2, 0x1f, 0x47, 0x82, 0xbb, 0xfb, - 0xe3, 0xc8, 0x9a, 0x51, 0x19, 0x06, 0x6a, 0xdc, 0xd1, 0xa3, 0xd8, 0x7d, 0x0b, 0xe3, 0x5e, 0x1e, - 0x6a, 0x03, 0x16, 0xde, 0x1d, 0x82, 0xc1, 0x8c, 0x0b, 0xc3, 0x5a, 0xc7, 0x3c, 0xd0, 0xc9, 0xb3, - 0x4b, 0x0f, 0x3e, 0xad, 0x0b, 0x1e, 0xe8, 0x04, 0xfa, 0x51, 0x0b, 0x12, 0xaf, 0x3d, 0x94, 0x52, - 0xce, 0xca, 0x55, 0xca, 0x5d, 0x80, 0xbe, 0xc0, 0x6f, 0x90, 0x64, 0xb6, 0x56, 0xec, 0x37, 0x08, - 0x66, 0x18, 0x4a, 0x11, 0xc5, 0xaa, 0x96, 0x11, 0xfd, 0x1a, 0x29, 0x2e, 0x88, 0x8f, 0x41, 0x7f, - 0x83, 0xec, 0x91, 0x46, 0x32, 0xa9, 0xd6, 0x75, 0x0a, 0xc4, 0x1c, 0x67, 0xff, 0x5c, 0x1f, 0x9c, - 0xeb, 0x18, 0x05, 0x88, 0x5e, 0xc6, 0xb6, 0x9d, 0x88, 0xdc, 0x71, 0xf6, 0x93, 0xd9, 0x6f, 0xae, - 0x70, 0x30, 0x96, 0x78, 0xf6, 0xf4, 0x90, 0x07, 0xb1, 0x4f, 0xa8, 0x30, 0x45, 0xec, 0x7a, 0x81, - 0x35, 0x55, 0x62, 0xc5, 0xe3, 0x50, 0x89, 0x3d, 0x07, 0x10, 0x86, 0x0d, 0xee, 0x13, 0x57, 0x17, - 0x6f, 0x1a, 0xe3, 0x64, 0x07, 0xd5, 0xeb, 0x02, 0x83, 0x35, 0x2a, 0xb4, 0x0c, 0x13, 0xad, 0xc0, - 0x8f, 0xb8, 0x46, 0x78, 0x99, 0xbb, 0x8d, 0xf6, 0x9b, 0x01, 0x58, 0x2a, 0x09, 0x3c, 0x4e, 0x95, - 0x40, 0x2f, 0xc2, 0xb0, 0x08, 0xca, 0x52, 0xf1, 0xfd, 0x86, 0x50, 0x42, 0x29, 0x4f, 0xca, 0x6a, - 0x8c, 0xc2, 0x3a, 0x9d, 0x56, 0x8c, 0xa9, 0x99, 0x07, 0x33, 0x8b, 0x71, 0x55, 0xb3, 0x46, 0x97, - 0x88, 0xda, 0x3b, 0xd4, 0x53, 0xd4, 0xde, 0x58, 0x2d, 0x57, 0xea, 0xd9, 0xea, 0x09, 0x5d, 0x15, - 0x59, 0x5f, 0xe9, 0x83, 0x29, 0x31, 0x71, 0x1e, 0xf4, 0x74, 0xb9, 0x99, 0x9e, 0x2e, 0xc7, 0xa1, - 0xb8, 0x7b, 0x77, 0xce, 0x9c, 0xf4, 0x9c, 0xf9, 0x61, 0x0b, 0x4c, 0x49, 0x0d, 0xfd, 0x99, 0xdc, - 0xf4, 0x61, 0x2f, 0xe6, 0x4a, 0x7e, 0xca, 0x6b, 0xf0, 0x6d, 0x26, 0x12, 0xb3, 0xff, 0xbd, 0x05, - 0x8f, 0x76, 0xe5, 0x88, 0x56, 0xa0, 0xc4, 0xc4, 0x49, 0xed, 0xa2, 0xf7, 0xa4, 0x72, 0x2b, 0x97, - 0x88, 0x1c, 0xe9, 0x36, 0x2e, 0x89, 0x56, 0x52, 0x79, 0xda, 0x9e, 0xca, 0xc8, 0xd3, 0x76, 0xda, - 0xe8, 0x9e, 0xfb, 0x4c, 0xd4, 0xf6, 0x83, 0xf4, 0xc4, 0x31, 0x9e, 0x74, 0xa1, 0xf7, 0x1b, 0x4a, - 0x47, 0x3b, 0xa1, 0x74, 0x44, 0x26, 0xb5, 0x76, 0x86, 0x7c, 0x18, 0x26, 0x58, 0xb4, 0x36, 0xf6, - 0xc8, 0x41, 0x3c, 0x36, 0x2b, 0xc4, 0x8e, 0xcc, 0xd7, 0x13, 0x38, 0x9c, 0xa2, 0xb6, 0xff, 0xa0, - 0x08, 0x03, 0x7c, 0xf9, 0x9d, 0xc0, 0xf5, 0xf2, 0x69, 0x28, 0xb9, 0xcd, 0x66, 0x9b, 0xa7, 0xde, - 0xea, 0x8f, 0xdd, 0x62, 0xcb, 0x12, 0x88, 0x63, 0x3c, 0x5a, 0x15, 0xfa, 0xee, 0x0e, 0x01, 0x61, - 0x79, 0xc3, 0xe7, 0x96, 0x9d, 0xc8, 0xe1, 0xb2, 0x92, 0x3a, 0x67, 0x63, 0xcd, 0x38, 0xfa, 0x24, - 0x40, 0x18, 0x05, 0xae, 0xb7, 0x4d, 0x61, 0x22, 0x0e, 0xf5, 0x7b, 0x3b, 0x70, 0xab, 0x2a, 0x62, - 0xce, 0x33, 0xde, 0x73, 0x14, 0x02, 0x6b, 0x1c, 0xd1, 0x9c, 0x71, 0xd2, 0xcf, 0x24, 0xc6, 0x0e, - 0x38, 0xd7, 0x78, 0xcc, 0x66, 0x3e, 0x00, 0x25, 0xc5, 0xbc, 0x9b, 0xf6, 0x6b, 0x44, 0x17, 0x8b, - 0x3e, 0x04, 0xe3, 0x89, 0xb6, 0x1d, 0x49, 0x79, 0xf6, 0xf3, 0x16, 0x8c, 0xf3, 0xc6, 0xac, 0x78, - 0x7b, 0xe2, 0x34, 0x78, 0x0b, 0x4e, 0x35, 0x32, 0x76, 0x65, 0x31, 0xfc, 0xbd, 0xef, 0xe2, 0x4a, - 0x59, 0x96, 0x85, 0xc5, 0x99, 0x75, 0xa0, 0x4b, 0x74, 0xc5, 0xd1, 0x5d, 0xd7, 0x69, 0x88, 0xb7, - 0xf5, 0x23, 0x7c, 0xb5, 0x71, 0x18, 0x56, 0x58, 0xfb, 0xb7, 0x2d, 0x98, 0xe4, 0x2d, 0xbf, 0x46, - 0xf6, 0xd5, 0xde, 0xf4, 0xcd, 0x6c, 0xbb, 0x48, 0xfa, 0x58, 0xc8, 0x49, 0xfa, 0xa8, 0x7f, 0x5a, - 0xb1, 0xe3, 0xa7, 0x7d, 0xd9, 0x02, 0x31, 0x43, 0x4e, 0x40, 0x9f, 0xf1, 0x9d, 0xa6, 0x3e, 0x63, - 0x26, 0x7f, 0x11, 0xe4, 0x28, 0x32, 0xfe, 0xc4, 0x82, 0x09, 0x4e, 0x10, 0xdb, 0xea, 0xbf, 0xa9, - 0xe3, 0xd0, 0x4b, 0x6a, 0xf8, 0x6b, 0x64, 0x7f, 0xc3, 0xaf, 0x38, 0xd1, 0x4e, 0xf6, 0x47, 0x19, - 0x83, 0xd5, 0xd7, 0x71, 0xb0, 0xea, 0x72, 0x01, 0x19, 0x39, 0x91, 0xba, 0xbc, 0x90, 0x3f, 0x6a, - 0x4e, 0x24, 0xfb, 0x1b, 0x16, 0x20, 0x5e, 0x8d, 0x21, 0xb8, 0x51, 0x71, 0x88, 0x41, 0xb5, 0x83, - 0x2e, 0xde, 0x9a, 0x14, 0x06, 0x6b, 0x54, 0xc7, 0xd2, 0x3d, 0x09, 0x87, 0x8b, 0x62, 0x77, 0x87, - 0x8b, 0x23, 0xf4, 0xe8, 0xbf, 0x1c, 0x80, 0xe4, 0xb3, 0x36, 0x74, 0x0b, 0x46, 0x6a, 0x4e, 0xcb, - 0xd9, 0x74, 0x1b, 0x6e, 0xe4, 0x92, 0xb0, 0x93, 0x37, 0xd6, 0x92, 0x46, 0x27, 0x4c, 0xe4, 0x1a, - 0x04, 0x1b, 0x7c, 0xd0, 0x1c, 0x40, 0x2b, 0x70, 0xf7, 0xdc, 0x06, 0xd9, 0x66, 0x6a, 0x17, 0x16, - 0xcd, 0x83, 0xbb, 0x86, 0x49, 0x28, 0xd6, 0x28, 0x32, 0x62, 0x08, 0x14, 0x1f, 0x70, 0x0c, 0x01, - 0x38, 0xb1, 0x18, 0x02, 0x7d, 0x47, 0x8a, 0x21, 0x30, 0x74, 0xe4, 0x18, 0x02, 0xfd, 0x3d, 0xc5, - 0x10, 0xc0, 0x70, 0x46, 0xca, 0x9e, 0xf4, 0xff, 0xaa, 0xdb, 0x20, 0xe2, 0xc2, 0xc1, 0x43, 0x90, - 0xcc, 0xdc, 0x3b, 0x98, 0x3d, 0x83, 0x33, 0x29, 0x70, 0x4e, 0x49, 0xf4, 0x11, 0x98, 0x76, 0x1a, - 0x0d, 0xff, 0x8e, 0x1a, 0xd4, 0x95, 0xb0, 0xe6, 0x34, 0xb8, 0x09, 0x64, 0x90, 0x71, 0x7d, 0xe4, - 0xde, 0xc1, 0xec, 0xf4, 0x42, 0x0e, 0x0d, 0xce, 0x2d, 0x8d, 0x3e, 0x08, 0xa5, 0x56, 0xe0, 0xd7, - 0xd6, 0xb4, 0xb7, 0xb7, 0xe7, 0x69, 0x07, 0x56, 0x24, 0xf0, 0xf0, 0x60, 0x76, 0x54, 0xfd, 0x61, - 0x07, 0x7e, 0x5c, 0x20, 0x23, 0x28, 0xc0, 0xf0, 0xb1, 0x06, 0x05, 0xd8, 0x85, 0xa9, 0x2a, 0x09, - 0x5c, 0xa7, 0xe1, 0xbe, 0x45, 0xe5, 0x65, 0xb9, 0x3f, 0x6d, 0x40, 0x29, 0x48, 0xec, 0xc8, 0x3d, - 0x05, 0x69, 0xd5, 0x92, 0xd3, 0xc8, 0x1d, 0x38, 0x66, 0x64, 0xff, 0x6f, 0x0b, 0x06, 0xc5, 0x33, - 0xb6, 0x13, 0x90, 0x1a, 0x17, 0x0c, 0xa3, 0xc4, 0x6c, 0x76, 0x87, 0xb1, 0xc6, 0xe4, 0x9a, 0x23, - 0xca, 0x09, 0x73, 0xc4, 0xa3, 0x9d, 0x98, 0x74, 0x36, 0x44, 0xfc, 0xd5, 0x22, 0x95, 0xde, 0x8d, - 0x07, 0xd5, 0x0f, 0xbe, 0x0b, 0xd6, 0x61, 0x30, 0x14, 0x0f, 0x7a, 0x0b, 0xf9, 0x2f, 0x2a, 0x92, - 0x83, 0x18, 0x7b, 0xd1, 0x89, 0x27, 0xbc, 0x92, 0x49, 0xe6, 0x4b, 0xe1, 0xe2, 0x03, 0x7c, 0x29, - 0xdc, 0xed, 0xc9, 0x79, 0xdf, 0x71, 0x3c, 0x39, 0xb7, 0xbf, 0xc6, 0x4e, 0x4e, 0x1d, 0x7e, 0x02, - 0x42, 0xd5, 0x15, 0xf3, 0x8c, 0xb5, 0x3b, 0xcc, 0x2c, 0xd1, 0xa8, 0x1c, 0xe1, 0xea, 0x67, 0x2d, - 0x38, 0x97, 0xf1, 0x55, 0x9a, 0xa4, 0xf5, 0x0c, 0x0c, 0x39, 0xed, 0xba, 0xab, 0xd6, 0xb2, 0x66, - 0x9a, 0x5c, 0x10, 0x70, 0xac, 0x28, 0xd0, 0x12, 0x4c, 0x92, 0xbb, 0x2d, 0x97, 0x1b, 0x72, 0x75, - 0xe7, 0xe3, 0x22, 0x7f, 0xfb, 0xb8, 0x92, 0x44, 0xe2, 0x34, 0xbd, 0x0a, 0x4e, 0x54, 0xcc, 0x0d, - 0x4e, 0xf4, 0xb7, 0x2d, 0x18, 0x56, 0x4f, 0x5a, 0x1f, 0x78, 0x6f, 0x7f, 0xd8, 0xec, 0xed, 0x87, - 0x3b, 0xf4, 0x76, 0x4e, 0x37, 0xff, 0x66, 0x41, 0xb5, 0xb7, 0xe2, 0x07, 0x51, 0x0f, 0x12, 0xdc, - 0xfd, 0x3f, 0x9c, 0xb8, 0x0c, 0xc3, 0x4e, 0xab, 0x25, 0x11, 0xd2, 0x03, 0x8e, 0x85, 0xdc, 0x8e, - 0xc1, 0x58, 0xa7, 0x51, 0xef, 0x38, 0x8a, 0xb9, 0xef, 0x38, 0xea, 0x00, 0x91, 0x13, 0x6c, 0x93, - 0x88, 0xc2, 0x84, 0xc3, 0x6e, 0xfe, 0x7e, 0xd3, 0x8e, 0xdc, 0xc6, 0x9c, 0xeb, 0x45, 0x61, 0x14, - 0xcc, 0x95, 0xbd, 0xe8, 0x46, 0xc0, 0xaf, 0x90, 0x5a, 0x78, 0x2f, 0xc5, 0x0b, 0x6b, 0x7c, 0x65, - 0xf8, 0x06, 0x56, 0x47, 0xbf, 0xe9, 0x4a, 0xb1, 0x2e, 0xe0, 0x58, 0x51, 0xd8, 0x1f, 0x60, 0xa7, - 0x0f, 0xeb, 0xd3, 0xa3, 0x85, 0xb6, 0xfa, 0xf2, 0x88, 0x1a, 0x0d, 0x66, 0x14, 0x5d, 0xd6, 0x03, - 0x68, 0x75, 0xde, 0xec, 0x69, 0xc5, 0xfa, 0xab, 0xc2, 0x38, 0xca, 0x16, 0xfa, 0x78, 0xca, 0x3d, - 0xe6, 0xd9, 0x2e, 0xa7, 0xc6, 0x11, 0x1c, 0x62, 0x58, 0xfe, 0x1d, 0x96, 0x9d, 0xa4, 0x5c, 0x11, - 0xeb, 0x42, 0xcb, 0xbf, 0x23, 0x10, 0x38, 0xa6, 0xa1, 0xc2, 0x94, 0xfa, 0x13, 0x4e, 0xa3, 0x38, - 0x0e, 0xad, 0xa2, 0x0e, 0xb1, 0x46, 0x81, 0xe6, 0x85, 0x42, 0x81, 0xdb, 0x05, 0x1e, 0x4e, 0x28, - 0x14, 0x64, 0x77, 0x69, 0x5a, 0xa0, 0xcb, 0x30, 0xac, 0xb2, 0xad, 0x57, 0x78, 0xe6, 0x2b, 0x31, - 0xcd, 0x56, 0x62, 0x30, 0xd6, 0x69, 0xd0, 0x06, 0x8c, 0x87, 0x5c, 0xcf, 0xa6, 0x82, 0x83, 0x73, - 0x7d, 0xe5, 0x7b, 0xd5, 0x63, 0x62, 0x13, 0x7d, 0xc8, 0x40, 0x7c, 0x77, 0x92, 0x21, 0x16, 0x92, - 0x2c, 0xd0, 0xab, 0x30, 0xd6, 0xf0, 0x9d, 0xfa, 0xa2, 0xd3, 0x70, 0xbc, 0x1a, 0xeb, 0x9f, 0x21, - 0x33, 0x69, 0xef, 0x75, 0x03, 0x8b, 0x13, 0xd4, 0x54, 0x78, 0xd3, 0x21, 0x22, 0x44, 0x98, 0xe3, - 0x6d, 0x93, 0x50, 0xe4, 0xce, 0x66, 0xc2, 0xdb, 0xf5, 0x1c, 0x1a, 0x9c, 0x5b, 0x1a, 0xbd, 0x04, - 0x23, 0xf2, 0xf3, 0xb5, 0x88, 0x24, 0xf1, 0x93, 0x18, 0x0d, 0x87, 0x0d, 0x4a, 0x74, 0x07, 0x4e, - 0xcb, 0xff, 0x1b, 0x81, 0xb3, 0xb5, 0xe5, 0xd6, 0xc4, 0x33, 0x7d, 0xfe, 0x76, 0x76, 0x41, 0x3e, - 0xf0, 0x5c, 0xc9, 0x22, 0x3a, 0x3c, 0x98, 0xbd, 0x20, 0x7a, 0x2d, 0x13, 0xcf, 0x06, 0x31, 0x9b, - 0x3f, 0x5a, 0x83, 0xa9, 0x1d, 0xe2, 0x34, 0xa2, 0x9d, 0xa5, 0x1d, 0x52, 0xdb, 0x95, 0x8b, 0x8e, - 0xc5, 0x39, 0xd1, 0x9e, 0x8f, 0x5c, 0x4d, 0x93, 0xe0, 0xac, 0x72, 0xe8, 0x0d, 0x98, 0x6e, 0xb5, - 0x37, 0x1b, 0x6e, 0xb8, 0xb3, 0xee, 0x47, 0xcc, 0x11, 0x49, 0x25, 0x6f, 0x17, 0x01, 0x51, 0x54, - 0x24, 0x99, 0x4a, 0x0e, 0x1d, 0xce, 0xe5, 0x80, 0xde, 0x82, 0xd3, 0x89, 0xc9, 0x20, 0x42, 0x42, - 0x8c, 0xe5, 0xa7, 0x07, 0xa9, 0x66, 0x15, 0x10, 0xd1, 0x55, 0xb2, 0x50, 0x38, 0xbb, 0x0a, 0xf4, - 0x32, 0x80, 0xdb, 0x5a, 0x75, 0x9a, 0x6e, 0x83, 0x5e, 0x17, 0xa7, 0xd8, 0x3c, 0xa1, 0x57, 0x07, - 0x28, 0x57, 0x24, 0x94, 0xee, 0xcf, 0xe2, 0xdf, 0x3e, 0xd6, 0xa8, 0xd1, 0x75, 0x18, 0x13, 0xff, - 0xf6, 0xc5, 0xb0, 0xf2, 0xc8, 0x24, 0x8f, 0xb3, 0xb0, 0x52, 0x15, 0x1d, 0x73, 0x98, 0x82, 0xe0, - 0x44, 0x59, 0xb4, 0x0d, 0xe7, 0x64, 0xaa, 0x37, 0x7d, 0x8e, 0xca, 0x31, 0x08, 0x59, 0x4e, 0x8e, - 0x21, 0xfe, 0x32, 0x65, 0xa1, 0x13, 0x21, 0xee, 0xcc, 0x87, 0x9e, 0xed, 0xfa, 0x54, 0xe7, 0x6f, - 0x77, 0x4f, 0x73, 0x2f, 0x27, 0x7a, 0xb6, 0x5f, 0x4f, 0x22, 0x71, 0x9a, 0x1e, 0x85, 0x70, 0xda, - 0xf5, 0xb2, 0x66, 0xf6, 0x19, 0xc6, 0xe8, 0x43, 0xfc, 0xd9, 0x72, 0xe7, 0x59, 0x9d, 0x89, 0xe7, - 0xb3, 0x3a, 0x93, 0xf7, 0xdb, 0xf3, 0xff, 0xfb, 0x2d, 0x8b, 0x96, 0xd6, 0xa4, 0x74, 0xf4, 0x29, - 0x18, 0xd1, 0x3f, 0x4c, 0x48, 0x1c, 0x17, 0xb3, 0x85, 0x58, 0x6d, 0x6f, 0xe0, 0x32, 0xbe, 0x5a, - 0xff, 0x3a, 0x0e, 0x1b, 0x1c, 0x51, 0x2d, 0xe3, 0x81, 0xff, 0x7c, 0x6f, 0x12, 0x4d, 0xef, 0xee, - 0x6f, 0x04, 0xb2, 0xa7, 0x3c, 0xba, 0x0e, 0x43, 0xb5, 0x86, 0x4b, 0xbc, 0xa8, 0x5c, 0xe9, 0x14, - 0xc2, 0x70, 0x49, 0xd0, 0x88, 0x35, 0x24, 0x52, 0x6c, 0x70, 0x18, 0x56, 0x1c, 0xec, 0x5f, 0x2d, - 0xc0, 0x6c, 0x97, 0x7c, 0x2d, 0x09, 0x73, 0x94, 0xd5, 0x93, 0x39, 0x6a, 0x01, 0xc6, 0xe3, 0x7f, - 0xba, 0xa6, 0x4b, 0x79, 0xb4, 0xde, 0x32, 0xd1, 0x38, 0x49, 0xdf, 0xf3, 0xe3, 0x04, 0xdd, 0xa2, - 0xd5, 0xd7, 0xf5, 0x79, 0x8d, 0x61, 0xc9, 0xee, 0xef, 0xfd, 0xfa, 0x9b, 0x6b, 0x95, 0xb4, 0xbf, - 0x56, 0x80, 0xd3, 0xaa, 0x0b, 0xbf, 0x7d, 0x3b, 0xee, 0x66, 0xba, 0xe3, 0x8e, 0xc1, 0xa6, 0x6b, - 0xdf, 0x80, 0x01, 0x1e, 0x93, 0xb1, 0x07, 0xb1, 0xfb, 0x31, 0x33, 0x52, 0xb3, 0x92, 0xf4, 0x8c, - 0x68, 0xcd, 0xdf, 0x6f, 0xc1, 0x78, 0xe2, 0x95, 0x1b, 0xc2, 0xda, 0x53, 0xe8, 0xfb, 0x11, 0x8d, - 0xb3, 0x84, 0xee, 0x0b, 0xd0, 0xb7, 0xe3, 0x87, 0x51, 0xd2, 0xe1, 0xe3, 0xaa, 0x1f, 0x46, 0x98, - 0x61, 0xec, 0xdf, 0xb1, 0xa0, 0x7f, 0xc3, 0x71, 0xbd, 0x48, 0x1a, 0x07, 0xac, 0x1c, 0xe3, 0x40, - 0x2f, 0xdf, 0x85, 0x5e, 0x84, 0x01, 0xb2, 0xb5, 0x45, 0x6a, 0x91, 0x18, 0x55, 0x19, 0x47, 0x62, - 0x60, 0x85, 0x41, 0xa9, 0x1c, 0xc8, 0x2a, 0xe3, 0x7f, 0xb1, 0x20, 0x46, 0xb7, 0xa1, 0x14, 0xb9, - 0x4d, 0xb2, 0x50, 0xaf, 0x0b, 0x93, 0xf9, 0x7d, 0xc4, 0xc2, 0xd8, 0x90, 0x0c, 0x70, 0xcc, 0xcb, - 0xfe, 0x42, 0x01, 0x20, 0x0e, 0x66, 0xd5, 0xed, 0x13, 0x17, 0x53, 0xc6, 0xd4, 0x8b, 0x19, 0xc6, - 0x54, 0x14, 0x33, 0xcc, 0xb0, 0xa4, 0xaa, 0x6e, 0x2a, 0xf6, 0xd4, 0x4d, 0x7d, 0x47, 0xe9, 0xa6, - 0x25, 0x98, 0x8c, 0x83, 0x71, 0x99, 0xb1, 0x08, 0xd9, 0xf1, 0xb9, 0x91, 0x44, 0xe2, 0x34, 0xbd, - 0x4d, 0xe0, 0x82, 0x8a, 0x49, 0x24, 0x4e, 0x34, 0xe6, 0x0f, 0xae, 0x1b, 0xa7, 0xbb, 0xf4, 0x53, - 0x6c, 0x2d, 0x2e, 0xe4, 0x5a, 0x8b, 0x7f, 0xc2, 0x82, 0x53, 0xc9, 0x7a, 0xd8, 0xe3, 0xe9, 0xcf, - 0x5b, 0x70, 0x9a, 0xd9, 0xcc, 0x59, 0xad, 0x69, 0x0b, 0xfd, 0x0b, 0x1d, 0xe3, 0x2c, 0xe5, 0xb4, - 0x38, 0x0e, 0x58, 0xb2, 0x96, 0xc5, 0x1a, 0x67, 0xd7, 0x68, 0xff, 0xaf, 0x3e, 0x98, 0xce, 0x0b, - 0xd0, 0xc4, 0x9e, 0x8b, 0x38, 0x77, 0xab, 0xbb, 0xe4, 0x8e, 0x70, 0xca, 0x8f, 0x9f, 0x8b, 0x70, - 0x30, 0x96, 0xf8, 0x64, 0x0a, 0x8e, 0x42, 0x8f, 0x29, 0x38, 0x76, 0x60, 0xf2, 0xce, 0x0e, 0xf1, - 0x6e, 0x7a, 0xa1, 0x13, 0xb9, 0xe1, 0x96, 0xcb, 0xec, 0xcb, 0x7c, 0xde, 0xc8, 0xbc, 0xbd, 0x93, - 0xb7, 0x93, 0x04, 0x87, 0x07, 0xb3, 0xe7, 0x0c, 0x40, 0xdc, 0x64, 0xbe, 0x91, 0xe0, 0x34, 0xd3, - 0x74, 0x06, 0x93, 0xbe, 0x07, 0x9c, 0xc1, 0xa4, 0xe9, 0x0a, 0xaf, 0x14, 0xf9, 0x16, 0x80, 0xdd, - 0x1c, 0xd7, 0x14, 0x14, 0x6b, 0x14, 0xe8, 0x13, 0x80, 0xf4, 0x0c, 0x4d, 0x46, 0x7c, 0xcc, 0x67, - 0xef, 0x1d, 0xcc, 0xa2, 0xf5, 0x14, 0xf6, 0xf0, 0x60, 0x76, 0x8a, 0x42, 0xcb, 0x1e, 0xbd, 0x81, - 0xc6, 0x41, 0xc5, 0x32, 0x18, 0xa1, 0xdb, 0x30, 0x41, 0xa1, 0x6c, 0x45, 0xc9, 0xe0, 0x9b, 0xfc, - 0xd6, 0xf8, 0xf4, 0xbd, 0x83, 0xd9, 0x89, 0xf5, 0x04, 0x2e, 0x8f, 0x75, 0x8a, 0x09, 0x7a, 0x19, - 0xc6, 0xe2, 0x79, 0x75, 0x8d, 0xec, 0xf3, 0x60, 0x37, 0x25, 0xae, 0xf8, 0x5e, 0x33, 0x30, 0x38, - 0x41, 0x69, 0x7f, 0xde, 0x82, 0xb3, 0xb9, 0x59, 0xc4, 0xd1, 0x25, 0x18, 0x72, 0x5a, 0x2e, 0x37, - 0x63, 0x88, 0xa3, 0x86, 0xa9, 0xcb, 0x2a, 0x65, 0x6e, 0xc4, 0x50, 0x58, 0xba, 0xc3, 0xef, 0xba, - 0x5e, 0x3d, 0xb9, 0xc3, 0x5f, 0x73, 0xbd, 0x3a, 0x66, 0x18, 0x75, 0x64, 0x15, 0x73, 0x9f, 0x24, - 0x7c, 0x85, 0xae, 0xd5, 0x8c, 0x7c, 0xe3, 0x27, 0xdb, 0x0c, 0xf4, 0xb4, 0x6e, 0x72, 0x14, 0xde, - 0x85, 0xb9, 0xe6, 0xc6, 0xef, 0xb3, 0x40, 0x3c, 0x61, 0xee, 0xe1, 0x4c, 0xfe, 0x18, 0x8c, 0xec, - 0xa5, 0xb3, 0xd7, 0x5d, 0xc8, 0x7f, 0xd3, 0x2d, 0xa2, 0x7e, 0x2b, 0x41, 0xdb, 0xc8, 0x54, 0x67, - 0xf0, 0xb2, 0xeb, 0x20, 0xb0, 0xcb, 0x84, 0x19, 0x16, 0xba, 0xb7, 0xe6, 0x39, 0x80, 0x3a, 0xa3, - 0x65, 0x29, 0x6d, 0x0b, 0xa6, 0xc4, 0xb5, 0xac, 0x30, 0x58, 0xa3, 0xb2, 0xff, 0x75, 0x01, 0x86, - 0x65, 0xb6, 0xb4, 0xb6, 0xd7, 0x8b, 0xfa, 0xef, 0x48, 0xe9, 0x93, 0xd1, 0x3c, 0x94, 0x98, 0x7e, - 0xba, 0x12, 0x6b, 0x4d, 0x95, 0x76, 0x68, 0x4d, 0x22, 0x70, 0x4c, 0x43, 0x77, 0xc7, 0xb0, 0xbd, - 0xc9, 0xc8, 0x13, 0x0f, 0x6e, 0xab, 0x1c, 0x8c, 0x25, 0x1e, 0x7d, 0x04, 0x26, 0x78, 0xb9, 0xc0, - 0x6f, 0x39, 0xdb, 0xdc, 0xa6, 0xd5, 0xaf, 0xa2, 0x98, 0x4c, 0xac, 0x25, 0x70, 0x87, 0x07, 0xb3, - 0xa7, 0x92, 0x30, 0x66, 0xac, 0x4d, 0x71, 0x61, 0xae, 0x6b, 0xbc, 0x12, 0xba, 0xab, 0xa7, 0x3c, - 0xde, 0x62, 0x14, 0xd6, 0xe9, 0xec, 0x4f, 0x01, 0x4a, 0xe7, 0x8d, 0x43, 0xaf, 0x71, 0xd7, 0x67, - 0x37, 0x20, 0xf5, 0x4e, 0xc6, 0x5b, 0x3d, 0x56, 0x87, 0x7c, 0x2b, 0xc7, 0x4b, 0x61, 0x55, 0xde, - 0xfe, 0x0b, 0x45, 0x98, 0x48, 0x46, 0x07, 0x40, 0x57, 0x61, 0x80, 0x8b, 0x94, 0x82, 0x7d, 0x07, - 0xdf, 0x20, 0x2d, 0xa6, 0x00, 0x3b, 0x5c, 0x85, 0x54, 0x2a, 0xca, 0xa3, 0x37, 0x60, 0xb8, 0xee, - 0xdf, 0xf1, 0xee, 0x38, 0x41, 0x7d, 0xa1, 0x52, 0x16, 0xd3, 0x39, 0x53, 0x59, 0xb1, 0x1c, 0x93, - 0xe9, 0x71, 0x0a, 0x98, 0x1d, 0x3c, 0x46, 0x61, 0x9d, 0x1d, 0xda, 0x60, 0xc9, 0x26, 0xb6, 0xdc, - 0xed, 0x35, 0xa7, 0xd5, 0xe9, 0x1d, 0xcc, 0x92, 0x24, 0xd2, 0x38, 0x8f, 0x8a, 0x8c, 0x14, 0x1c, - 0x81, 0x63, 0x46, 0xe8, 0x33, 0x30, 0x15, 0xe6, 0x98, 0x50, 0xf2, 0xd2, 0x88, 0x76, 0xb2, 0x2a, - 0x2c, 0x3e, 0x74, 0xef, 0x60, 0x76, 0x2a, 0xcb, 0xd8, 0x92, 0x55, 0x8d, 0xfd, 0xc5, 0x53, 0x60, - 0x2c, 0x62, 0x23, 0xab, 0xb4, 0x75, 0x4c, 0x59, 0xa5, 0x31, 0x0c, 0x91, 0x66, 0x2b, 0xda, 0x5f, - 0x76, 0x03, 0x31, 0x26, 0x99, 0x3c, 0x57, 0x04, 0x4d, 0x9a, 0xa7, 0xc4, 0x60, 0xc5, 0x27, 0x3b, - 0xf5, 0x77, 0xf1, 0x9b, 0x98, 0xfa, 0xbb, 0xef, 0x04, 0x53, 0x7f, 0xaf, 0xc3, 0xe0, 0xb6, 0x1b, - 0x61, 0xd2, 0xf2, 0xc5, 0x65, 0x2e, 0x73, 0x1e, 0x5e, 0xe1, 0x24, 0xe9, 0x24, 0xb3, 0x02, 0x81, - 0x25, 0x13, 0xf4, 0x9a, 0x5a, 0x81, 0x03, 0xf9, 0x0a, 0x97, 0xb4, 0x13, 0x4b, 0xe6, 0x1a, 0x14, - 0x09, 0xbe, 0x07, 0xef, 0x37, 0xc1, 0xf7, 0xaa, 0x4c, 0xcb, 0x3d, 0x94, 0xff, 0x68, 0x8d, 0x65, - 0xdd, 0xee, 0x92, 0x8c, 0xfb, 0x96, 0x9e, 0xca, 0xbc, 0x94, 0xbf, 0x13, 0xa8, 0x2c, 0xe5, 0x3d, - 0x26, 0x30, 0xff, 0x3e, 0x0b, 0x4e, 0xb7, 0xb2, 0xb2, 0xfa, 0x0b, 0x7f, 0x8f, 0x17, 0x7b, 0xc9, - 0xfd, 0xca, 0x0a, 0x18, 0x15, 0x32, 0x3d, 0x69, 0x26, 0x19, 0xce, 0xae, 0x8e, 0x76, 0x74, 0xb0, - 0x59, 0x17, 0x7e, 0x07, 0x8f, 0xe5, 0x64, 0x42, 0xef, 0x90, 0xff, 0x7c, 0x23, 0x23, 0xeb, 0xf6, - 0xe3, 0x79, 0x59, 0xb7, 0x7b, 0xce, 0xb5, 0xfd, 0x9a, 0xca, 0x81, 0x3e, 0x9a, 0x3f, 0x95, 0x78, - 0x86, 0xf3, 0xae, 0x99, 0xcf, 0x5f, 0x53, 0x99, 0xcf, 0x3b, 0x84, 0xd7, 0xe6, 0x79, 0xcd, 0xbb, - 0xe6, 0x3b, 0xd7, 0x72, 0x96, 0x8f, 0x1f, 0x4f, 0xce, 0x72, 0xe3, 0xa8, 0xe1, 0x69, 0xb3, 0x9f, - 0xee, 0x72, 0xd4, 0x18, 0x7c, 0x3b, 0x1f, 0x36, 0x3c, 0x3f, 0xfb, 0xe4, 0x7d, 0xe5, 0x67, 0xbf, - 0xa5, 0xe7, 0x3b, 0x47, 0x5d, 0x12, 0x7a, 0x53, 0xa2, 0x1e, 0xb3, 0x9c, 0xdf, 0xd2, 0x0f, 0xc0, - 0xa9, 0x7c, 0xbe, 0xea, 0x9c, 0x4b, 0xf3, 0xcd, 0x3c, 0x02, 0x53, 0xd9, 0xd3, 0x4f, 0x9d, 0x4c, - 0xf6, 0xf4, 0xd3, 0xc7, 0x9e, 0x3d, 0xfd, 0xcc, 0x09, 0x64, 0x4f, 0x7f, 0xe8, 0x04, 0xb3, 0xa7, - 0xdf, 0x62, 0x4e, 0x52, 0x3c, 0x10, 0x94, 0x08, 0x07, 0xfe, 0x54, 0x4e, 0x1c, 0xb5, 0x74, 0xb4, - 0x28, 0xfe, 0x71, 0x0a, 0x85, 0x63, 0x56, 0x19, 0x59, 0xd9, 0xa7, 0x1f, 0x40, 0x56, 0xf6, 0xf5, - 0x38, 0x2b, 0xfb, 0xd9, 0xfc, 0xa1, 0xce, 0x78, 0x56, 0x93, 0x93, 0x8b, 0xfd, 0x96, 0x9e, 0x43, - 0xfd, 0xe1, 0x0e, 0x96, 0xb0, 0x2c, 0x85, 0x72, 0x87, 0xcc, 0xe9, 0xaf, 0xf2, 0xcc, 0xe9, 0x8f, - 0xe4, 0xef, 0xe4, 0xc9, 0xe3, 0xce, 0xc8, 0x97, 0x4e, 0xdb, 0xa5, 0x02, 0xa9, 0xb2, 0xc0, 0xe7, - 0x39, 0xed, 0x52, 0x91, 0x58, 0xd3, 0xed, 0x52, 0x28, 0x1c, 0xb3, 0xb2, 0x7f, 0xa0, 0x00, 0xe7, - 0x3b, 0xaf, 0xb7, 0x58, 0x4b, 0x5e, 0x89, 0x1d, 0x03, 0x12, 0x5a, 0x72, 0x7e, 0x67, 0x8b, 0xa9, - 0x7a, 0x8e, 0x0b, 0x79, 0x05, 0x26, 0xd5, 0x7b, 0x9c, 0x86, 0x5b, 0xdb, 0x5f, 0x8f, 0xaf, 0xc9, - 0x2a, 0x82, 0x42, 0x35, 0x49, 0x80, 0xd3, 0x65, 0xd0, 0x02, 0x8c, 0x1b, 0xc0, 0xf2, 0xb2, 0xb8, - 0x9b, 0xc5, 0xa1, 0xb6, 0x4d, 0x34, 0x4e, 0xd2, 0xdb, 0x5f, 0xb2, 0xe0, 0xa1, 0x9c, 0xb4, 0xa3, - 0x3d, 0x87, 0x3d, 0xdc, 0x82, 0xf1, 0x96, 0x59, 0xb4, 0x4b, 0xa4, 0x56, 0x23, 0xb9, 0xa9, 0x6a, - 0x6b, 0x02, 0x81, 0x93, 0x4c, 0xed, 0x9f, 0x2e, 0xc0, 0xb9, 0x8e, 0x0e, 0xa6, 0x08, 0xc3, 0x99, - 0xed, 0x66, 0xe8, 0x2c, 0x05, 0xa4, 0x4e, 0xbc, 0xc8, 0x75, 0x1a, 0xd5, 0x16, 0xa9, 0x69, 0x76, - 0x0e, 0xe6, 0xa9, 0x79, 0x65, 0xad, 0xba, 0x90, 0xa6, 0xc0, 0x39, 0x25, 0xd1, 0x2a, 0xa0, 0x34, - 0x46, 0x8c, 0x30, 0x0b, 0xa1, 0x9f, 0xe6, 0x87, 0x33, 0x4a, 0xa0, 0x0f, 0xc0, 0xa8, 0x72, 0x5c, - 0xd5, 0x46, 0x9c, 0x6d, 0xec, 0x58, 0x47, 0x60, 0x93, 0x0e, 0x5d, 0xe6, 0x39, 0x18, 0x44, 0xb6, - 0x0e, 0x61, 0x14, 0x19, 0x97, 0x09, 0x16, 0x04, 0x18, 0xeb, 0x34, 0x8b, 0x2f, 0xfd, 0xda, 0xef, - 0x9d, 0x7f, 0xcf, 0x6f, 0xfc, 0xde, 0xf9, 0xf7, 0xfc, 0xf6, 0xef, 0x9d, 0x7f, 0xcf, 0x77, 0xdd, - 0x3b, 0x6f, 0xfd, 0xda, 0xbd, 0xf3, 0xd6, 0x6f, 0xdc, 0x3b, 0x6f, 0xfd, 0xf6, 0xbd, 0xf3, 0xd6, - 0xef, 0xde, 0x3b, 0x6f, 0x7d, 0xe1, 0xf7, 0xcf, 0xbf, 0xe7, 0x63, 0x28, 0x0e, 0x24, 0x3a, 0x4f, - 0x47, 0x67, 0x7e, 0xef, 0xf2, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x52, 0x56, 0xa0, 0x3b, 0xf7, - 0x0c, 0x01, 0x00, + // 14685 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x69, 0x90, 0x5c, 0xd7, + 0x75, 0x18, 0xac, 0xd7, 0x3d, 0x5b, 0x9f, 0xd9, 0xef, 0x00, 0xe0, 0x60, 0x48, 0xa0, 0xc1, 0x47, + 0x12, 0x04, 0x45, 0x72, 0x20, 0x70, 0x91, 0x28, 0x52, 0xa2, 0x35, 0x2b, 0x30, 0x04, 0x66, 0xd0, + 0xbc, 0x3d, 0x00, 0x24, 0x8a, 0x52, 0xe9, 0x4d, 0xf7, 0x9d, 0x99, 0xa7, 0xe9, 0x7e, 0xaf, 0xf9, + 0xde, 0xeb, 0x01, 0x06, 0x9f, 0x54, 0x9f, 0x2d, 0xc7, 0x8b, 0x6c, 0x27, 0xa5, 0x4a, 0x39, 0x4b, + 0xc9, 0x2e, 0x57, 0xca, 0x76, 0x6c, 0x2b, 0xca, 0xa6, 0xc8, 0xb1, 0x1d, 0xcb, 0x5b, 0xb6, 0x8a, + 0x93, 0x4a, 0x39, 0x8e, 0xab, 0x62, 0xb9, 0xe2, 0xca, 0xc4, 0x82, 0x53, 0xe5, 0x52, 0x55, 0x62, + 0x3b, 0xcb, 0x8f, 0x64, 0xe2, 0xc4, 0xa9, 0xbb, 0xbe, 0x7b, 0xdf, 0xd2, 0xdd, 0x03, 0x0e, 0x46, + 0x94, 0x8a, 0xff, 0xba, 0xcf, 0x39, 0xf7, 0xdc, 0xfb, 0xee, 0x7a, 0xee, 0x39, 0xe7, 0x9e, 0x03, + 0xaf, 0xec, 0xbc, 0x14, 0xce, 0xba, 0xfe, 0xc5, 0x9d, 0xf6, 0x06, 0x09, 0x3c, 0x12, 0x91, 0xf0, + 0xe2, 0x2e, 0xf1, 0xea, 0x7e, 0x70, 0x51, 0x20, 0x9c, 0x96, 0x7b, 0xb1, 0xe6, 0x07, 0xe4, 0xe2, + 0xee, 0xa5, 0x8b, 0x5b, 0xc4, 0x23, 0x81, 0x13, 0x91, 0xfa, 0x6c, 0x2b, 0xf0, 0x23, 0x1f, 0x21, + 0x4e, 0x33, 0xeb, 0xb4, 0xdc, 0x59, 0x4a, 0x33, 0xbb, 0x7b, 0x69, 0xe6, 0xd9, 0x2d, 0x37, 0xda, + 0x6e, 0x6f, 0xcc, 0xd6, 0xfc, 0xe6, 0xc5, 0x2d, 0x7f, 0xcb, 0xbf, 0xc8, 0x48, 0x37, 0xda, 0x9b, + 0xec, 0x1f, 0xfb, 0xc3, 0x7e, 0x71, 0x16, 0x33, 0x2f, 0xc4, 0xd5, 0x34, 0x9d, 0xda, 0xb6, 0xeb, + 0x91, 0x60, 0xef, 0x62, 0x6b, 0x67, 0x8b, 0xd5, 0x1b, 0x90, 0xd0, 0x6f, 0x07, 0x35, 0x92, 0xac, + 0xb8, 0x63, 0xa9, 0xf0, 0x62, 0x93, 0x44, 0x4e, 0x46, 0x73, 0x67, 0x2e, 0xe6, 0x95, 0x0a, 0xda, + 0x5e, 0xe4, 0x36, 0xd3, 0xd5, 0xbc, 0xbf, 0x5b, 0x81, 0xb0, 0xb6, 0x4d, 0x9a, 0x4e, 0xaa, 0xdc, + 0xf3, 0x79, 0xe5, 0xda, 0x91, 0xdb, 0xb8, 0xe8, 0x7a, 0x51, 0x18, 0x05, 0xc9, 0x42, 0xf6, 0xd7, + 0x2d, 0x38, 0x37, 0x77, 0xab, 0xba, 0xd4, 0x70, 0xc2, 0xc8, 0xad, 0xcd, 0x37, 0xfc, 0xda, 0x4e, + 0x35, 0xf2, 0x03, 0x72, 0xd3, 0x6f, 0xb4, 0x9b, 0xa4, 0xca, 0x3a, 0x02, 0x3d, 0x03, 0x43, 0xbb, + 0xec, 0xff, 0xca, 0xe2, 0xb4, 0x75, 0xce, 0xba, 0x50, 0x9a, 0x9f, 0xf8, 0xcd, 0xfd, 0xf2, 0x7b, + 0xee, 0xed, 0x97, 0x87, 0x6e, 0x0a, 0x38, 0x56, 0x14, 0xe8, 0x3c, 0x0c, 0x6c, 0x86, 0xeb, 0x7b, + 0x2d, 0x32, 0x5d, 0x60, 0xb4, 0x63, 0x82, 0x76, 0x60, 0xb9, 0x4a, 0xa1, 0x58, 0x60, 0xd1, 0x45, + 0x28, 0xb5, 0x9c, 0x20, 0x72, 0x23, 0xd7, 0xf7, 0xa6, 0x8b, 0xe7, 0xac, 0x0b, 0xfd, 0xf3, 0x93, + 0x82, 0xb4, 0x54, 0x91, 0x08, 0x1c, 0xd3, 0xd0, 0x66, 0x04, 0xc4, 0xa9, 0x5f, 0xf7, 0x1a, 0x7b, + 0xd3, 0x7d, 0xe7, 0xac, 0x0b, 0x43, 0x71, 0x33, 0xb0, 0x80, 0x63, 0x45, 0x61, 0x7f, 0xb1, 0x00, + 0x43, 0x73, 0x9b, 0x9b, 0xae, 0xe7, 0x46, 0x7b, 0xe8, 0x26, 0x8c, 0x78, 0x7e, 0x9d, 0xc8, 0xff, + 0xec, 0x2b, 0x86, 0x9f, 0x3b, 0x37, 0x9b, 0x9e, 0x4a, 0xb3, 0x6b, 0x1a, 0xdd, 0xfc, 0xc4, 0xbd, + 0xfd, 0xf2, 0x88, 0x0e, 0xc1, 0x06, 0x1f, 0x84, 0x61, 0xb8, 0xe5, 0xd7, 0x15, 0xdb, 0x02, 0x63, + 0x5b, 0xce, 0x62, 0x5b, 0x89, 0xc9, 0xe6, 0xc7, 0xef, 0xed, 0x97, 0x87, 0x35, 0x00, 0xd6, 0x99, + 0xa0, 0x0d, 0x18, 0xa7, 0x7f, 0xbd, 0xc8, 0x55, 0x7c, 0x8b, 0x8c, 0xef, 0x63, 0x79, 0x7c, 0x35, + 0xd2, 0xf9, 0xa9, 0x7b, 0xfb, 0xe5, 0xf1, 0x04, 0x10, 0x27, 0x19, 0xda, 0x77, 0x61, 0x6c, 0x2e, + 0x8a, 0x9c, 0xda, 0x36, 0xa9, 0xf3, 0x11, 0x44, 0x2f, 0x40, 0x9f, 0xe7, 0x34, 0x89, 0x18, 0xdf, + 0x73, 0xa2, 0x63, 0xfb, 0xd6, 0x9c, 0x26, 0x39, 0xd8, 0x2f, 0x4f, 0xdc, 0xf0, 0xdc, 0xb7, 0xda, + 0x62, 0x56, 0x50, 0x18, 0x66, 0xd4, 0xe8, 0x39, 0x80, 0x3a, 0xd9, 0x75, 0x6b, 0xa4, 0xe2, 0x44, + 0xdb, 0x62, 0xbc, 0x91, 0x28, 0x0b, 0x8b, 0x0a, 0x83, 0x35, 0x2a, 0xfb, 0x0e, 0x94, 0xe6, 0x76, + 0x7d, 0xb7, 0x5e, 0xf1, 0xeb, 0x21, 0xda, 0x81, 0xf1, 0x56, 0x40, 0x36, 0x49, 0xa0, 0x40, 0xd3, + 0xd6, 0xb9, 0xe2, 0x85, 0xe1, 0xe7, 0x2e, 0x64, 0x7e, 0xac, 0x49, 0xba, 0xe4, 0x45, 0xc1, 0xde, + 0xfc, 0x43, 0xa2, 0xbe, 0xf1, 0x04, 0x16, 0x27, 0x39, 0xdb, 0xff, 0xac, 0x00, 0x27, 0xe7, 0xee, + 0xb6, 0x03, 0xb2, 0xe8, 0x86, 0x3b, 0xc9, 0x19, 0x5e, 0x77, 0xc3, 0x9d, 0xb5, 0xb8, 0x07, 0xd4, + 0xd4, 0x5a, 0x14, 0x70, 0xac, 0x28, 0xd0, 0xb3, 0x30, 0x48, 0x7f, 0xdf, 0xc0, 0x2b, 0xe2, 0x93, + 0xa7, 0x04, 0xf1, 0xf0, 0xa2, 0x13, 0x39, 0x8b, 0x1c, 0x85, 0x25, 0x0d, 0x5a, 0x85, 0xe1, 0x1a, + 0x5b, 0x90, 0x5b, 0xab, 0x7e, 0x9d, 0xb0, 0xc1, 0x2c, 0xcd, 0x3f, 0x4d, 0xc9, 0x17, 0x62, 0xf0, + 0xc1, 0x7e, 0x79, 0x9a, 0xb7, 0x4d, 0xb0, 0xd0, 0x70, 0x58, 0x2f, 0x8f, 0x6c, 0xb5, 0xbe, 0xfa, + 0x18, 0x27, 0xc8, 0x58, 0x5b, 0x17, 0xb4, 0xa5, 0xd2, 0xcf, 0x96, 0xca, 0x48, 0xf6, 0x32, 0x41, + 0x97, 0xa0, 0x6f, 0xc7, 0xf5, 0xea, 0xd3, 0x03, 0x8c, 0xd7, 0x19, 0x3a, 0xe6, 0x57, 0x5d, 0xaf, + 0x7e, 0xb0, 0x5f, 0x9e, 0x34, 0x9a, 0x43, 0x81, 0x98, 0x91, 0xda, 0xff, 0xdd, 0x82, 0x32, 0xc3, + 0x2d, 0xbb, 0x0d, 0x52, 0x21, 0x41, 0xe8, 0x86, 0x11, 0xf1, 0x22, 0xa3, 0x43, 0x9f, 0x03, 0x08, + 0x49, 0x2d, 0x20, 0x91, 0xd6, 0xa5, 0x6a, 0x62, 0x54, 0x15, 0x06, 0x6b, 0x54, 0x74, 0x43, 0x08, + 0xb7, 0x9d, 0x80, 0xcd, 0x2f, 0xd1, 0xb1, 0x6a, 0x43, 0xa8, 0x4a, 0x04, 0x8e, 0x69, 0x8c, 0x0d, + 0xa1, 0xd8, 0x6d, 0x43, 0x40, 0x1f, 0x86, 0xf1, 0xb8, 0xb2, 0xb0, 0xe5, 0xd4, 0x64, 0x07, 0xb2, + 0x25, 0x53, 0x35, 0x51, 0x38, 0x49, 0x6b, 0xff, 0x2d, 0x4b, 0x4c, 0x1e, 0xfa, 0xd5, 0xef, 0xf0, + 0x6f, 0xb5, 0x7f, 0xc9, 0x82, 0xc1, 0x79, 0xd7, 0xab, 0xbb, 0xde, 0x16, 0xfa, 0x14, 0x0c, 0xd1, + 0xb3, 0xa9, 0xee, 0x44, 0x8e, 0xd8, 0xf7, 0xde, 0xa7, 0xad, 0x2d, 0x75, 0x54, 0xcc, 0xb6, 0x76, + 0xb6, 0x28, 0x20, 0x9c, 0xa5, 0xd4, 0x74, 0xb5, 0x5d, 0xdf, 0xf8, 0x34, 0xa9, 0x45, 0xab, 0x24, + 0x72, 0xe2, 0xcf, 0x89, 0x61, 0x58, 0x71, 0x45, 0x57, 0x61, 0x20, 0x72, 0x82, 0x2d, 0x12, 0x89, + 0x0d, 0x30, 0x73, 0xa3, 0xe2, 0x25, 0x31, 0x5d, 0x91, 0xc4, 0xab, 0x91, 0xf8, 0x58, 0x58, 0x67, + 0x45, 0xb1, 0x60, 0x61, 0xff, 0x9f, 0x41, 0x38, 0xbd, 0x50, 0x5d, 0xc9, 0x99, 0x57, 0xe7, 0x61, + 0xa0, 0x1e, 0xb8, 0xbb, 0x24, 0x10, 0xfd, 0xac, 0xb8, 0x2c, 0x32, 0x28, 0x16, 0x58, 0xf4, 0x12, + 0x8c, 0xf0, 0x03, 0xe9, 0x8a, 0xe3, 0xd5, 0x1b, 0xb2, 0x8b, 0x4f, 0x08, 0xea, 0x91, 0x9b, 0x1a, + 0x0e, 0x1b, 0x94, 0x87, 0x9c, 0x54, 0xe7, 0x13, 0x8b, 0x31, 0xef, 0xb0, 0xfb, 0xbc, 0x05, 0x13, + 0xbc, 0x9a, 0xb9, 0x28, 0x0a, 0xdc, 0x8d, 0x76, 0x44, 0xc2, 0xe9, 0x7e, 0xb6, 0xd3, 0x2d, 0x64, + 0xf5, 0x56, 0x6e, 0x0f, 0xcc, 0xde, 0x4c, 0x70, 0xe1, 0x9b, 0xe0, 0xb4, 0xa8, 0x77, 0x22, 0x89, + 0xc6, 0xa9, 0x6a, 0xd1, 0xf7, 0x5a, 0x30, 0x53, 0xf3, 0xbd, 0x28, 0xf0, 0x1b, 0x0d, 0x12, 0x54, + 0xda, 0x1b, 0x0d, 0x37, 0xdc, 0xe6, 0xf3, 0x14, 0x93, 0x4d, 0xb6, 0x13, 0xe4, 0x8c, 0xa1, 0x22, + 0x12, 0x63, 0x78, 0xf6, 0xde, 0x7e, 0x79, 0x66, 0x21, 0x97, 0x15, 0xee, 0x50, 0x0d, 0xda, 0x01, + 0x44, 0x8f, 0xd2, 0x6a, 0xe4, 0x6c, 0x91, 0xb8, 0xf2, 0xc1, 0xde, 0x2b, 0x3f, 0x75, 0x6f, 0xbf, + 0x8c, 0xd6, 0x52, 0x2c, 0x70, 0x06, 0x5b, 0xf4, 0x16, 0x9c, 0xa0, 0xd0, 0xd4, 0xb7, 0x0e, 0xf5, + 0x5e, 0xdd, 0xf4, 0xbd, 0xfd, 0xf2, 0x89, 0xb5, 0x0c, 0x26, 0x38, 0x93, 0x35, 0xfa, 0x6e, 0x0b, + 0x4e, 0xc7, 0x9f, 0xbf, 0x74, 0xa7, 0xe5, 0x78, 0xf5, 0xb8, 0xe2, 0x52, 0xef, 0x15, 0xd3, 0x3d, + 0xf9, 0xf4, 0x42, 0x1e, 0x27, 0x9c, 0x5f, 0x09, 0xf2, 0x60, 0x8a, 0x36, 0x2d, 0x59, 0x37, 0xf4, + 0x5e, 0xf7, 0x43, 0xf7, 0xf6, 0xcb, 0x53, 0x6b, 0x69, 0x1e, 0x38, 0x8b, 0xf1, 0xcc, 0x02, 0x9c, + 0xcc, 0x9c, 0x9d, 0x68, 0x02, 0x8a, 0x3b, 0x84, 0x4b, 0x5d, 0x25, 0x4c, 0x7f, 0xa2, 0x13, 0xd0, + 0xbf, 0xeb, 0x34, 0xda, 0x62, 0x61, 0x62, 0xfe, 0xe7, 0xe5, 0xc2, 0x4b, 0x96, 0xfd, 0xcf, 0x8b, + 0x30, 0xbe, 0x50, 0x5d, 0xb9, 0xaf, 0x55, 0xaf, 0x1f, 0x7b, 0x85, 0x8e, 0xc7, 0x5e, 0x7c, 0x88, + 0x16, 0x73, 0x0f, 0xd1, 0xff, 0x3f, 0x63, 0xc9, 0xf6, 0xb1, 0x25, 0xfb, 0xc1, 0x9c, 0x25, 0x7b, + 0xc4, 0x0b, 0x75, 0x37, 0x67, 0xd6, 0xf6, 0xb3, 0x01, 0xcc, 0x94, 0x90, 0xae, 0xf9, 0x35, 0xa7, + 0x91, 0xdc, 0x6a, 0x0f, 0x39, 0x75, 0x8f, 0x66, 0x1c, 0x6b, 0x30, 0xb2, 0xe0, 0xb4, 0x9c, 0x0d, + 0xb7, 0xe1, 0x46, 0x2e, 0x09, 0xd1, 0x93, 0x50, 0x74, 0xea, 0x75, 0x26, 0xdd, 0x95, 0xe6, 0x4f, + 0xde, 0xdb, 0x2f, 0x17, 0xe7, 0xea, 0x54, 0xcc, 0x00, 0x45, 0xb5, 0x87, 0x29, 0x05, 0x7a, 0x2f, + 0xf4, 0xd5, 0x03, 0xbf, 0x35, 0x5d, 0x60, 0x94, 0x74, 0x95, 0xf7, 0x2d, 0x06, 0x7e, 0x2b, 0x41, + 0xca, 0x68, 0xec, 0xdf, 0x28, 0xc0, 0x23, 0x0b, 0xa4, 0xb5, 0xbd, 0x5c, 0xcd, 0x39, 0x2f, 0x2e, + 0xc0, 0x50, 0xd3, 0xf7, 0xdc, 0xc8, 0x0f, 0x42, 0x51, 0x35, 0x9b, 0x11, 0xab, 0x02, 0x86, 0x15, + 0x16, 0x9d, 0x83, 0xbe, 0x56, 0x2c, 0xc4, 0x8e, 0x48, 0x01, 0x98, 0x89, 0xaf, 0x0c, 0x43, 0x29, + 0xda, 0x21, 0x09, 0xc4, 0x8c, 0x51, 0x14, 0x37, 0x42, 0x12, 0x60, 0x86, 0x89, 0x25, 0x01, 0x2a, + 0x23, 0x88, 0x13, 0x21, 0x21, 0x09, 0x50, 0x0c, 0xd6, 0xa8, 0x50, 0x05, 0x4a, 0x61, 0x62, 0x64, + 0x7b, 0x5a, 0x9a, 0xa3, 0x4c, 0x54, 0x50, 0x23, 0x19, 0x33, 0x31, 0x4e, 0xb0, 0x81, 0xae, 0xa2, + 0xc2, 0xd7, 0x0a, 0x80, 0x78, 0x17, 0x7e, 0x9b, 0x75, 0xdc, 0x8d, 0x74, 0xc7, 0xf5, 0xbe, 0x24, + 0x8e, 0xaa, 0xf7, 0xfe, 0x87, 0x05, 0x8f, 0x2c, 0xb8, 0x5e, 0x9d, 0x04, 0x39, 0x13, 0xf0, 0xc1, + 0xdc, 0x9d, 0x0f, 0x27, 0xa4, 0x18, 0x53, 0xac, 0xef, 0x08, 0xa6, 0x98, 0xfd, 0x27, 0x16, 0x20, + 0xfe, 0xd9, 0xef, 0xb8, 0x8f, 0xbd, 0x91, 0xfe, 0xd8, 0x23, 0x98, 0x16, 0xf6, 0xdf, 0xb3, 0x60, + 0x78, 0xa1, 0xe1, 0xb8, 0x4d, 0xf1, 0xa9, 0x0b, 0x30, 0x29, 0x15, 0x45, 0x0c, 0xac, 0xc9, 0xfe, + 0x74, 0x73, 0x9b, 0xc4, 0x49, 0x24, 0x4e, 0xd3, 0xa3, 0x8f, 0xc3, 0x69, 0x03, 0xb8, 0x4e, 0x9a, + 0xad, 0x86, 0x13, 0xe9, 0xb7, 0x02, 0x76, 0xfa, 0xe3, 0x3c, 0x22, 0x9c, 0x5f, 0xde, 0xbe, 0x06, + 0x63, 0x0b, 0x0d, 0x97, 0x78, 0xd1, 0x4a, 0x65, 0xc1, 0xf7, 0x36, 0xdd, 0x2d, 0xf4, 0x32, 0x8c, + 0x45, 0x6e, 0x93, 0xf8, 0xed, 0xa8, 0x4a, 0x6a, 0xbe, 0xc7, 0xee, 0xda, 0xd6, 0x85, 0xfe, 0x79, + 0x74, 0x6f, 0xbf, 0x3c, 0xb6, 0x6e, 0x60, 0x70, 0x82, 0xd2, 0xfe, 0x7d, 0x3a, 0xe2, 0x7e, 0xb3, + 0xe5, 0x7b, 0xc4, 0x8b, 0x16, 0x7c, 0xaf, 0xce, 0x75, 0x32, 0x2f, 0x43, 0x5f, 0x44, 0x47, 0x90, + 0x7f, 0xf9, 0x79, 0xb9, 0xb4, 0xe9, 0xb8, 0x1d, 0xec, 0x97, 0x4f, 0xa5, 0x4b, 0xb0, 0x91, 0x65, + 0x65, 0xd0, 0x07, 0x61, 0x20, 0x8c, 0x9c, 0xa8, 0x1d, 0x8a, 0x4f, 0x7d, 0x54, 0x8e, 0x7f, 0x95, + 0x41, 0x0f, 0xf6, 0xcb, 0xe3, 0xaa, 0x18, 0x07, 0x61, 0x51, 0x00, 0x3d, 0x05, 0x83, 0x4d, 0x12, + 0x86, 0xce, 0x96, 0x3c, 0xbf, 0xc7, 0x45, 0xd9, 0xc1, 0x55, 0x0e, 0xc6, 0x12, 0x8f, 0x1e, 0x83, + 0x7e, 0x12, 0x04, 0x7e, 0x20, 0x76, 0x95, 0x51, 0x41, 0xd8, 0xbf, 0x44, 0x81, 0x98, 0xe3, 0xec, + 0x7f, 0x63, 0xc1, 0xb8, 0x6a, 0x2b, 0xaf, 0xeb, 0x18, 0xee, 0x4d, 0x6f, 0x00, 0xd4, 0xe4, 0x07, + 0x86, 0xec, 0xbc, 0x1b, 0x7e, 0xee, 0x7c, 0xa6, 0x68, 0x91, 0xea, 0xc6, 0x98, 0xb3, 0x02, 0x85, + 0x58, 0xe3, 0x66, 0xff, 0xaa, 0x05, 0x53, 0x89, 0x2f, 0xba, 0xe6, 0x86, 0x11, 0x7a, 0x33, 0xf5, + 0x55, 0xb3, 0xbd, 0x7d, 0x15, 0x2d, 0xcd, 0xbe, 0x49, 0x2d, 0x3e, 0x09, 0xd1, 0xbe, 0xe8, 0x0a, + 0xf4, 0xbb, 0x11, 0x69, 0xca, 0x8f, 0x79, 0xac, 0xe3, 0xc7, 0xf0, 0x56, 0xc5, 0x23, 0xb2, 0x42, + 0x4b, 0x62, 0xce, 0xc0, 0xfe, 0x8d, 0x22, 0x94, 0xf8, 0xb4, 0x5d, 0x75, 0x5a, 0xc7, 0x30, 0x16, + 0x4f, 0x43, 0xc9, 0x6d, 0x36, 0xdb, 0x91, 0xb3, 0x21, 0x0e, 0xa0, 0x21, 0xbe, 0x19, 0xac, 0x48, + 0x20, 0x8e, 0xf1, 0x68, 0x05, 0xfa, 0x58, 0x53, 0xf8, 0x57, 0x3e, 0x99, 0xfd, 0x95, 0xa2, 0xed, + 0xb3, 0x8b, 0x4e, 0xe4, 0x70, 0xd9, 0x4f, 0x9d, 0x7c, 0x14, 0x84, 0x19, 0x0b, 0xe4, 0x00, 0x6c, + 0xb8, 0x9e, 0x13, 0xec, 0x51, 0xd8, 0x74, 0x91, 0x31, 0x7c, 0xb6, 0x33, 0xc3, 0x79, 0x45, 0xcf, + 0xd9, 0xaa, 0x0f, 0x8b, 0x11, 0x58, 0x63, 0x3a, 0xf3, 0x01, 0x28, 0x29, 0xe2, 0xc3, 0x88, 0x70, + 0x33, 0x1f, 0x86, 0xf1, 0x44, 0x5d, 0xdd, 0x8a, 0x8f, 0xe8, 0x12, 0xe0, 0x2f, 0xb3, 0x2d, 0x43, + 0xb4, 0x7a, 0xc9, 0xdb, 0x15, 0x3b, 0xe7, 0x5d, 0x38, 0xd1, 0xc8, 0xd8, 0x7b, 0xc5, 0xb8, 0xf6, + 0xbe, 0x57, 0x3f, 0x22, 0x3e, 0xfb, 0x44, 0x16, 0x16, 0x67, 0xd6, 0x41, 0xa5, 0x1a, 0xbf, 0x45, + 0x17, 0x88, 0xd3, 0xd0, 0x2f, 0x08, 0xd7, 0x05, 0x0c, 0x2b, 0x2c, 0xdd, 0xef, 0x4e, 0xa8, 0xc6, + 0x5f, 0x25, 0x7b, 0x55, 0xd2, 0x20, 0xb5, 0xc8, 0x0f, 0xbe, 0xa5, 0xcd, 0x3f, 0xc3, 0x7b, 0x9f, + 0x6f, 0x97, 0xc3, 0x82, 0x41, 0xf1, 0x2a, 0xd9, 0xe3, 0x43, 0xa1, 0x7f, 0x5d, 0xb1, 0xe3, 0xd7, + 0x7d, 0xc5, 0x82, 0x51, 0xf5, 0x75, 0xc7, 0xb0, 0x2f, 0xcc, 0x9b, 0xfb, 0xc2, 0x99, 0x8e, 0x13, + 0x3c, 0x67, 0x47, 0xf8, 0x5a, 0x01, 0x4e, 0x2b, 0x1a, 0x7a, 0x9b, 0xe1, 0x7f, 0xc4, 0xac, 0xba, + 0x08, 0x25, 0x4f, 0xe9, 0xf5, 0x2c, 0x53, 0xa1, 0x16, 0x6b, 0xf5, 0x62, 0x1a, 0x2a, 0x94, 0x7a, + 0xf1, 0x31, 0x3b, 0xa2, 0x2b, 0xbc, 0x85, 0x72, 0x7b, 0x1e, 0x8a, 0x6d, 0xb7, 0x2e, 0x0e, 0x98, + 0xf7, 0xc9, 0xde, 0xbe, 0xb1, 0xb2, 0x78, 0xb0, 0x5f, 0x7e, 0x34, 0xcf, 0xd8, 0x42, 0x4f, 0xb6, + 0x70, 0xf6, 0xc6, 0xca, 0x22, 0xa6, 0x85, 0xd1, 0x1c, 0x8c, 0xcb, 0x13, 0xfa, 0x26, 0x15, 0x10, + 0x7d, 0x4f, 0x9c, 0x43, 0x4a, 0x6b, 0x8d, 0x4d, 0x34, 0x4e, 0xd2, 0xa3, 0x45, 0x98, 0xd8, 0x69, + 0x6f, 0x90, 0x06, 0x89, 0xf8, 0x07, 0x5f, 0x25, 0x5c, 0xa7, 0x5b, 0x8a, 0xef, 0x92, 0x57, 0x13, + 0x78, 0x9c, 0x2a, 0x61, 0xff, 0x39, 0x3b, 0x0f, 0x44, 0xef, 0x55, 0x02, 0x9f, 0x4e, 0x2c, 0xca, + 0xfd, 0x5b, 0x39, 0x9d, 0x7b, 0x99, 0x15, 0x57, 0xc9, 0xde, 0xba, 0x4f, 0xef, 0x12, 0xd9, 0xb3, + 0xc2, 0x98, 0xf3, 0x7d, 0x1d, 0xe7, 0xfc, 0xcf, 0x17, 0xe0, 0xa4, 0xea, 0x01, 0x43, 0x6c, 0xfd, + 0x76, 0xef, 0x83, 0x4b, 0x30, 0x5c, 0x27, 0x9b, 0x4e, 0xbb, 0x11, 0x29, 0x03, 0x43, 0x3f, 0x37, + 0x32, 0x2d, 0xc6, 0x60, 0xac, 0xd3, 0x1c, 0xa2, 0xdb, 0xfe, 0xfd, 0x08, 0x3b, 0x88, 0x23, 0x87, + 0xce, 0x71, 0xb5, 0x6a, 0xac, 0xdc, 0x55, 0xf3, 0x18, 0xf4, 0xbb, 0x4d, 0x2a, 0x98, 0x15, 0x4c, + 0x79, 0x6b, 0x85, 0x02, 0x31, 0xc7, 0xa1, 0x27, 0x60, 0xb0, 0xe6, 0x37, 0x9b, 0x8e, 0x57, 0x67, + 0x47, 0x5e, 0x69, 0x7e, 0x98, 0xca, 0x6e, 0x0b, 0x1c, 0x84, 0x25, 0x0e, 0x3d, 0x02, 0x7d, 0x4e, + 0xb0, 0xc5, 0xb5, 0x2e, 0xa5, 0xf9, 0x21, 0x5a, 0xd3, 0x5c, 0xb0, 0x15, 0x62, 0x06, 0xa5, 0x97, + 0xc6, 0xdb, 0x7e, 0xb0, 0xe3, 0x7a, 0x5b, 0x8b, 0x6e, 0x20, 0x96, 0x84, 0x3a, 0x0b, 0x6f, 0x29, + 0x0c, 0xd6, 0xa8, 0xd0, 0x32, 0xf4, 0xb7, 0xfc, 0x20, 0x0a, 0xa7, 0x07, 0x58, 0x77, 0x3f, 0x9a, + 0xb3, 0x11, 0xf1, 0xaf, 0xad, 0xf8, 0x41, 0x14, 0x7f, 0x00, 0xfd, 0x17, 0x62, 0x5e, 0x1c, 0x5d, + 0x83, 0x41, 0xe2, 0xed, 0x2e, 0x07, 0x7e, 0x73, 0x7a, 0x2a, 0x9f, 0xd3, 0x12, 0x27, 0xe1, 0xd3, + 0x2c, 0x96, 0x51, 0x05, 0x18, 0x4b, 0x16, 0xe8, 0x83, 0x50, 0x24, 0xde, 0xee, 0xf4, 0x20, 0xe3, + 0x34, 0x93, 0xc3, 0xe9, 0xa6, 0x13, 0xc4, 0x7b, 0xfe, 0x92, 0xb7, 0x8b, 0x69, 0x19, 0xf4, 0x31, + 0x28, 0xc9, 0x0d, 0x23, 0x14, 0xea, 0xcc, 0xcc, 0x09, 0x2b, 0xb7, 0x19, 0x4c, 0xde, 0x6a, 0xbb, + 0x01, 0x69, 0x12, 0x2f, 0x0a, 0xe3, 0x1d, 0x52, 0x62, 0x43, 0x1c, 0x73, 0x43, 0x35, 0x18, 0x09, + 0x48, 0xe8, 0xde, 0x25, 0x15, 0xbf, 0xe1, 0xd6, 0xf6, 0xa6, 0x1f, 0x62, 0xcd, 0x7b, 0xaa, 0x63, + 0x97, 0x61, 0xad, 0x40, 0xac, 0x6e, 0xd7, 0xa1, 0xd8, 0x60, 0x8a, 0x3e, 0x26, 0x15, 0xf5, 0xab, + 0x7e, 0xdb, 0x8b, 0xc2, 0xe9, 0x12, 0xab, 0x24, 0xd3, 0x84, 0x7a, 0x33, 0xa6, 0x4b, 0x6a, 0xf2, + 0x79, 0x61, 0x6c, 0xb0, 0x42, 0x9f, 0x80, 0x51, 0xfe, 0x9f, 0x1b, 0x22, 0xc3, 0xe9, 0x93, 0x8c, + 0xf7, 0xb9, 0x7c, 0xde, 0x9c, 0x70, 0xfe, 0xa4, 0x60, 0x3e, 0xaa, 0x43, 0x43, 0x6c, 0x72, 0x43, + 0x18, 0x46, 0x1b, 0xee, 0x2e, 0xf1, 0x48, 0x18, 0x56, 0x02, 0x7f, 0x83, 0x08, 0xbd, 0xea, 0xe9, + 0x6c, 0xc3, 0xa5, 0xbf, 0x41, 0xe6, 0x27, 0x29, 0xcf, 0x6b, 0x7a, 0x19, 0x6c, 0xb2, 0x40, 0x37, + 0x60, 0x8c, 0x5e, 0x64, 0xdd, 0x98, 0xe9, 0x70, 0x37, 0xa6, 0xec, 0xf2, 0x86, 0x8d, 0x42, 0x38, + 0xc1, 0x04, 0x5d, 0x87, 0x91, 0x30, 0x72, 0x82, 0xa8, 0xdd, 0xe2, 0x4c, 0x4f, 0x75, 0x63, 0xca, + 0xec, 0xde, 0x55, 0xad, 0x08, 0x36, 0x18, 0xa0, 0xd7, 0xa0, 0xd4, 0x70, 0x37, 0x49, 0x6d, 0xaf, + 0xd6, 0x20, 0xd3, 0x23, 0x8c, 0x5b, 0xe6, 0xce, 0x75, 0x4d, 0x12, 0x71, 0x61, 0x5a, 0xfd, 0xc5, + 0x71, 0x71, 0x74, 0x13, 0x4e, 0x45, 0x24, 0x68, 0xba, 0x9e, 0x43, 0x77, 0x1c, 0x71, 0x7f, 0x63, + 0xf6, 0xe4, 0x51, 0xb6, 0xa4, 0xcf, 0x8a, 0xd1, 0x38, 0xb5, 0x9e, 0x49, 0x85, 0x73, 0x4a, 0xa3, + 0x3b, 0x30, 0x9d, 0x81, 0xe1, 0x53, 0xf9, 0x04, 0xe3, 0xfc, 0x21, 0xc1, 0x79, 0x7a, 0x3d, 0x87, + 0xee, 0xa0, 0x03, 0x0e, 0xe7, 0x72, 0x47, 0xd7, 0x61, 0x9c, 0x6d, 0x73, 0x95, 0x76, 0xa3, 0x21, + 0x2a, 0x1c, 0x63, 0x15, 0x3e, 0x21, 0x0f, 0xfd, 0x15, 0x13, 0x7d, 0xb0, 0x5f, 0x86, 0xf8, 0x1f, + 0x4e, 0x96, 0x46, 0x1b, 0xcc, 0x74, 0xd9, 0x0e, 0xdc, 0x68, 0x8f, 0xae, 0x34, 0x72, 0x27, 0x9a, + 0x1e, 0xef, 0xa8, 0xc6, 0xd1, 0x49, 0x95, 0x7d, 0x53, 0x07, 0xe2, 0x24, 0x43, 0xba, 0x6f, 0x87, + 0x51, 0xdd, 0xf5, 0xa6, 0x27, 0xf8, 0xe5, 0x47, 0x6e, 0x7b, 0x55, 0x0a, 0xc4, 0x1c, 0xc7, 0xcc, + 0x96, 0xf4, 0xc7, 0x75, 0x7a, 0x3c, 0x4e, 0x32, 0xc2, 0xd8, 0x6c, 0x29, 0x11, 0x38, 0xa6, 0xa1, + 0x12, 0x6b, 0x14, 0xed, 0x4d, 0x23, 0x46, 0xaa, 0x76, 0xaf, 0xf5, 0xf5, 0x8f, 0x61, 0x0a, 0xb7, + 0x37, 0x60, 0x4c, 0x6d, 0x1d, 0xac, 0x4f, 0x50, 0x19, 0xfa, 0x99, 0x8c, 0x26, 0x94, 0x8e, 0x25, + 0xda, 0x04, 0x26, 0xbf, 0x61, 0x0e, 0x67, 0x4d, 0x70, 0xef, 0x92, 0xf9, 0xbd, 0x88, 0x70, 0xc5, + 0x41, 0x51, 0x6b, 0x82, 0x44, 0xe0, 0x98, 0xc6, 0xfe, 0xbf, 0x5c, 0xd6, 0x8d, 0xb7, 0xf4, 0x1e, + 0x0e, 0xb1, 0x67, 0x60, 0x68, 0xdb, 0x0f, 0x23, 0x4a, 0xcd, 0xea, 0xe8, 0x8f, 0xa5, 0xdb, 0x2b, + 0x02, 0x8e, 0x15, 0x05, 0x7a, 0x05, 0x46, 0x6b, 0x7a, 0x05, 0xe2, 0x04, 0x56, 0xdb, 0x88, 0x51, + 0x3b, 0x36, 0x69, 0xd1, 0x4b, 0x30, 0xc4, 0x5c, 0x71, 0x6a, 0x7e, 0x43, 0x88, 0x86, 0x52, 0x8c, + 0x18, 0xaa, 0x08, 0xf8, 0x81, 0xf6, 0x1b, 0x2b, 0x6a, 0x74, 0x1e, 0x06, 0x68, 0x13, 0x56, 0x2a, + 0xe2, 0xec, 0x53, 0xfa, 0xb3, 0x2b, 0x0c, 0x8a, 0x05, 0xd6, 0xfe, 0x55, 0x8b, 0x09, 0x3e, 0xe9, + 0x0d, 0x1a, 0x5d, 0x61, 0x3b, 0x3c, 0xdb, 0xee, 0x35, 0xfd, 0xd5, 0xe3, 0xda, 0xb6, 0xad, 0x70, + 0x07, 0x89, 0xff, 0xd8, 0x28, 0x89, 0xde, 0x80, 0xd1, 0x80, 0xb0, 0x2d, 0x42, 0x4c, 0x78, 0x7e, + 0xfa, 0xbf, 0x20, 0xbb, 0x00, 0xeb, 0xc8, 0x83, 0xfd, 0xf2, 0xc3, 0xf1, 0x79, 0x44, 0xdb, 0x63, + 0xa0, 0xb1, 0xc9, 0xca, 0xfe, 0xcb, 0x05, 0x6d, 0x96, 0x54, 0x23, 0x27, 0x22, 0xa8, 0x02, 0x83, + 0xb7, 0x1d, 0x37, 0x72, 0xbd, 0x2d, 0x21, 0xa4, 0x75, 0x3e, 0x95, 0x58, 0xa1, 0x5b, 0xbc, 0x00, + 0x17, 0x35, 0xc4, 0x1f, 0x2c, 0xd9, 0x50, 0x8e, 0x41, 0xdb, 0xf3, 0x28, 0xc7, 0x42, 0xaf, 0x1c, + 0x31, 0x2f, 0xc0, 0x39, 0x8a, 0x3f, 0x58, 0xb2, 0x41, 0x6f, 0x02, 0xc8, 0x1d, 0x82, 0xd4, 0x85, + 0x0b, 0xcf, 0x33, 0xdd, 0x99, 0xae, 0xab, 0x32, 0xf3, 0x63, 0x54, 0x90, 0x89, 0xff, 0x63, 0x8d, + 0x9f, 0x1d, 0x69, 0x63, 0xaa, 0x37, 0x06, 0x7d, 0x9c, 0x2e, 0x51, 0x27, 0x88, 0x48, 0x7d, 0x2e, + 0x12, 0x9d, 0xf3, 0xde, 0xde, 0x6e, 0x72, 0xeb, 0x6e, 0x93, 0xe8, 0xcb, 0x59, 0x30, 0xc1, 0x31, + 0x3f, 0xfb, 0x17, 0x8b, 0x30, 0x9d, 0xd7, 0x5c, 0xba, 0x68, 0xc8, 0x1d, 0x37, 0x5a, 0xa0, 0x32, + 0xa8, 0x65, 0x2e, 0x9a, 0x25, 0x01, 0xc7, 0x8a, 0x82, 0xce, 0xde, 0xd0, 0xdd, 0x92, 0x17, 0xf1, + 0xfe, 0x78, 0xf6, 0x56, 0x19, 0x14, 0x0b, 0x2c, 0xa5, 0x0b, 0x88, 0x13, 0x0a, 0x1f, 0x31, 0x6d, + 0x96, 0x63, 0x06, 0xc5, 0x02, 0xab, 0xab, 0x04, 0xfb, 0xba, 0xa8, 0x04, 0x8d, 0x2e, 0xea, 0x3f, + 0xda, 0x2e, 0x42, 0x9f, 0x04, 0xd8, 0x74, 0x3d, 0x37, 0xdc, 0x66, 0xdc, 0x07, 0x0e, 0xcd, 0x5d, + 0x49, 0xb0, 0xcb, 0x8a, 0x0b, 0xd6, 0x38, 0xa2, 0x17, 0x61, 0x58, 0x6d, 0x20, 0x2b, 0x8b, 0xcc, + 0x60, 0xae, 0x39, 0x20, 0xc5, 0xbb, 0xe9, 0x22, 0xd6, 0xe9, 0xec, 0x4f, 0x27, 0xe7, 0x8b, 0x58, + 0x01, 0x5a, 0xff, 0x5a, 0xbd, 0xf6, 0x6f, 0xa1, 0x73, 0xff, 0xda, 0xdf, 0x18, 0x80, 0x71, 0xa3, + 0xb2, 0x76, 0xd8, 0xc3, 0x9e, 0x7b, 0x99, 0x1e, 0x40, 0x4e, 0x44, 0xc4, 0xfa, 0xb3, 0xbb, 0x2f, + 0x15, 0xfd, 0x90, 0xa2, 0x2b, 0x80, 0x97, 0x47, 0x9f, 0x84, 0x52, 0xc3, 0x09, 0x99, 0x7a, 0x91, + 0x88, 0x75, 0xd7, 0x0b, 0xb3, 0xf8, 0xf6, 0xe6, 0x84, 0x91, 0x76, 0xea, 0x73, 0xde, 0x31, 0x4b, + 0x7a, 0x52, 0x52, 0xf9, 0x4a, 0x3a, 0x21, 0xaa, 0x46, 0x50, 0x21, 0x6c, 0x0f, 0x73, 0x1c, 0x7a, + 0x89, 0x6d, 0xad, 0x74, 0x56, 0x2c, 0x50, 0x69, 0x94, 0x4d, 0xb3, 0x7e, 0x43, 0x22, 0x56, 0x38, + 0x6c, 0x50, 0xc6, 0x17, 0xa8, 0x81, 0x0e, 0x17, 0xa8, 0xa7, 0x60, 0x90, 0xfd, 0x50, 0x33, 0x40, + 0x8d, 0xc6, 0x0a, 0x07, 0x63, 0x89, 0x4f, 0x4e, 0x98, 0xa1, 0xde, 0x26, 0x0c, 0xbd, 0xa2, 0x89, + 0x49, 0xcd, 0x9c, 0x15, 0x86, 0xf8, 0x2e, 0x27, 0xa6, 0x3c, 0x96, 0x38, 0xf4, 0xb3, 0x16, 0x20, + 0xa7, 0x41, 0xaf, 0xb6, 0x14, 0xac, 0x6e, 0x22, 0xc0, 0x44, 0xed, 0x57, 0xba, 0x76, 0x7b, 0x3b, + 0x9c, 0x9d, 0x4b, 0x95, 0xe6, 0x6a, 0xcd, 0x97, 0x45, 0x13, 0x51, 0x9a, 0x40, 0x3f, 0x8c, 0xae, + 0xb9, 0x61, 0xf4, 0xb9, 0xff, 0x98, 0x38, 0x9c, 0x32, 0x9a, 0x84, 0x6e, 0xe8, 0x37, 0xa5, 0xe1, + 0x43, 0xde, 0x94, 0x46, 0xf3, 0x6e, 0x49, 0x33, 0x6d, 0x78, 0x28, 0xe7, 0x0b, 0x32, 0x94, 0xa5, + 0x8b, 0xba, 0xb2, 0xb4, 0x8b, 0x8a, 0x6d, 0x56, 0xd6, 0x31, 0xfb, 0x7a, 0xdb, 0xf1, 0x22, 0x37, + 0xda, 0xd3, 0x95, 0xab, 0xef, 0x85, 0xb1, 0x45, 0x87, 0x34, 0x7d, 0x6f, 0xc9, 0xab, 0xb7, 0x7c, + 0xd7, 0x8b, 0xd0, 0x34, 0xf4, 0x31, 0xe1, 0x83, 0x6f, 0xbd, 0x7d, 0xb4, 0xf7, 0x30, 0x83, 0xd8, + 0x5b, 0x70, 0x72, 0xd1, 0xbf, 0xed, 0xdd, 0x76, 0x82, 0xfa, 0x5c, 0x65, 0x45, 0x53, 0xfe, 0xac, + 0x49, 0xe5, 0x83, 0x95, 0x7f, 0xb5, 0xd3, 0x4a, 0xf2, 0xeb, 0xd0, 0xb2, 0xdb, 0x20, 0x39, 0x2a, + 0xba, 0xbf, 0x56, 0x30, 0x6a, 0x8a, 0xe9, 0x95, 0x91, 0xd8, 0xca, 0x35, 0x12, 0xbf, 0x0e, 0x43, + 0x9b, 0x2e, 0x69, 0xd4, 0x31, 0xd9, 0x14, 0xbd, 0xf3, 0x64, 0xbe, 0x1b, 0xd9, 0x32, 0xa5, 0x94, + 0x2a, 0x59, 0xae, 0xba, 0x58, 0x16, 0x85, 0xb1, 0x62, 0x83, 0x76, 0x60, 0x42, 0xf6, 0xa1, 0xc4, + 0x8a, 0xfd, 0xe0, 0xa9, 0x4e, 0x03, 0x6f, 0x32, 0x3f, 0x71, 0x6f, 0xbf, 0x3c, 0x81, 0x13, 0x6c, + 0x70, 0x8a, 0x31, 0x7a, 0x04, 0xfa, 0x9a, 0xf4, 0xe4, 0xeb, 0x63, 0xdd, 0xcf, 0x74, 0x15, 0x4c, + 0xed, 0xc2, 0xa0, 0xf6, 0x8f, 0x5b, 0xf0, 0x50, 0xaa, 0x67, 0x84, 0xfa, 0xe9, 0x88, 0x47, 0x21, + 0xa9, 0x0e, 0x2a, 0x74, 0x57, 0x07, 0xd9, 0x7f, 0xdb, 0x82, 0x13, 0x4b, 0xcd, 0x56, 0xb4, 0xb7, + 0xe8, 0x9a, 0x16, 0xdd, 0x0f, 0xc0, 0x40, 0x93, 0xd4, 0xdd, 0x76, 0x53, 0x8c, 0x5c, 0x59, 0x9e, + 0x0e, 0xab, 0x0c, 0x7a, 0xb0, 0x5f, 0x1e, 0xad, 0x46, 0x7e, 0xe0, 0x6c, 0x11, 0x0e, 0xc0, 0x82, + 0x9c, 0x9d, 0xb1, 0xee, 0x5d, 0x72, 0xcd, 0x6d, 0xba, 0xd1, 0xfd, 0xcd, 0x76, 0x61, 0x8c, 0x95, + 0x4c, 0x70, 0xcc, 0xcf, 0xfe, 0xba, 0x05, 0xe3, 0x72, 0xde, 0xcf, 0xd5, 0xeb, 0x01, 0x09, 0x43, + 0x34, 0x03, 0x05, 0xb7, 0x25, 0x5a, 0x09, 0xa2, 0x95, 0x85, 0x95, 0x0a, 0x2e, 0xb8, 0x2d, 0x29, + 0xce, 0xb3, 0x03, 0xa8, 0x68, 0xda, 0xa5, 0xaf, 0x08, 0x38, 0x56, 0x14, 0xe8, 0x02, 0x0c, 0x79, + 0x7e, 0x9d, 0x4b, 0xc4, 0x5c, 0x94, 0x60, 0x13, 0x6c, 0x4d, 0xc0, 0xb0, 0xc2, 0xa2, 0x0a, 0x94, + 0xb8, 0xd7, 0x62, 0x3c, 0x69, 0x7b, 0xf2, 0x7d, 0x64, 0x5f, 0xb6, 0x2e, 0x4b, 0xe2, 0x98, 0x89, + 0xfd, 0xeb, 0x16, 0x8c, 0xc8, 0x2f, 0xeb, 0xf1, 0xae, 0x42, 0x97, 0x56, 0x7c, 0x4f, 0x89, 0x97, + 0x16, 0xbd, 0x6b, 0x30, 0x8c, 0x71, 0xc5, 0x28, 0x1e, 0xea, 0x8a, 0x71, 0x09, 0x86, 0x9d, 0x56, + 0xab, 0x62, 0xde, 0x4f, 0xd8, 0x54, 0x9a, 0x8b, 0xc1, 0x58, 0xa7, 0xb1, 0x7f, 0xac, 0x00, 0x63, + 0xf2, 0x0b, 0xaa, 0xed, 0x8d, 0x90, 0x44, 0x68, 0x1d, 0x4a, 0x0e, 0x1f, 0x25, 0x22, 0x27, 0xf9, + 0x63, 0xd9, 0x4a, 0x2e, 0x63, 0x48, 0x63, 0x41, 0x6b, 0x4e, 0x96, 0xc6, 0x31, 0x23, 0xd4, 0x80, + 0x49, 0xcf, 0x8f, 0xd8, 0xa1, 0xab, 0xf0, 0x9d, 0xec, 0x8e, 0x49, 0xee, 0xa7, 0x05, 0xf7, 0xc9, + 0xb5, 0x24, 0x17, 0x9c, 0x66, 0x8c, 0x96, 0xa4, 0xe2, 0xb0, 0x98, 0xaf, 0x44, 0xd2, 0x07, 0x2e, + 0x5b, 0x6f, 0x68, 0xff, 0x8a, 0x05, 0x25, 0x49, 0x76, 0x1c, 0x26, 0xe6, 0x55, 0x18, 0x0c, 0xd9, + 0x20, 0xc8, 0xae, 0xb1, 0x3b, 0x35, 0x9c, 0x8f, 0x57, 0x2c, 0x4b, 0xf0, 0xff, 0x21, 0x96, 0x3c, + 0x98, 0xdd, 0x48, 0x35, 0xff, 0x1d, 0x62, 0x37, 0x52, 0xed, 0xc9, 0x39, 0x94, 0xfe, 0x88, 0xb5, + 0x59, 0x53, 0xc4, 0x52, 0x91, 0xb7, 0x15, 0x90, 0x4d, 0xf7, 0x4e, 0x52, 0xe4, 0xad, 0x30, 0x28, + 0x16, 0x58, 0xf4, 0x26, 0x8c, 0xd4, 0xa4, 0xc1, 0x20, 0x5e, 0xe1, 0xe7, 0x3b, 0x1a, 0xaf, 0x94, + 0x9d, 0x93, 0xeb, 0xd0, 0x16, 0xb4, 0xf2, 0xd8, 0xe0, 0x66, 0x7a, 0xe5, 0x14, 0xbb, 0x79, 0xe5, + 0xc4, 0x7c, 0xf3, 0x7d, 0x54, 0x7e, 0xc2, 0x82, 0x01, 0xae, 0x28, 0xee, 0x4d, 0x4f, 0xaf, 0x99, + 0x7d, 0xe3, 0xbe, 0xbb, 0x49, 0x81, 0x42, 0xd2, 0x40, 0xab, 0x50, 0x62, 0x3f, 0x98, 0xa2, 0xbb, + 0x98, 0xff, 0x68, 0x86, 0xd7, 0xaa, 0x37, 0xf0, 0xa6, 0x2c, 0x86, 0x63, 0x0e, 0xf6, 0x8f, 0x16, + 0xe9, 0xee, 0x16, 0x93, 0x1a, 0x87, 0xbe, 0xf5, 0xe0, 0x0e, 0xfd, 0xc2, 0x83, 0x3a, 0xf4, 0xb7, + 0x60, 0xbc, 0xa6, 0x19, 0x89, 0xe3, 0x91, 0xbc, 0xd0, 0x71, 0x92, 0x68, 0xf6, 0x64, 0xae, 0x9d, + 0x5b, 0x30, 0x99, 0xe0, 0x24, 0x57, 0xf4, 0x71, 0x18, 0xe1, 0xe3, 0x2c, 0x6a, 0xe1, 0x8e, 0x4d, + 0x4f, 0xe4, 0xcf, 0x17, 0xbd, 0x0a, 0xae, 0xcd, 0xd5, 0x8a, 0x63, 0x83, 0x99, 0xfd, 0xa7, 0x16, + 0xa0, 0xa5, 0xd6, 0x36, 0x69, 0x92, 0xc0, 0x69, 0xc4, 0xb6, 0x9e, 0x1f, 0xb2, 0x60, 0x9a, 0xa4, + 0xc0, 0x0b, 0x7e, 0xb3, 0x29, 0x2e, 0x8b, 0x39, 0xfa, 0x8c, 0xa5, 0x9c, 0x32, 0xea, 0x55, 0xd1, + 0x74, 0x1e, 0x05, 0xce, 0xad, 0x0f, 0xad, 0xc2, 0x14, 0x3f, 0x25, 0x15, 0x42, 0x73, 0x92, 0x7a, + 0x58, 0x30, 0x9e, 0x5a, 0x4f, 0x93, 0xe0, 0xac, 0x72, 0xf6, 0x37, 0x47, 0x20, 0xb7, 0x15, 0xef, + 0x1a, 0xb9, 0xde, 0x35, 0x72, 0xbd, 0x6b, 0xe4, 0x7a, 0xd7, 0xc8, 0xf5, 0xae, 0x91, 0xeb, 0x5d, + 0x23, 0xd7, 0x51, 0x18, 0xb9, 0xfe, 0x8a, 0x05, 0x27, 0xd5, 0x59, 0x63, 0xdc, 0xae, 0x3f, 0x03, + 0x53, 0x7c, 0xb9, 0x19, 0xde, 0xbb, 0xe2, 0x6c, 0xbd, 0x94, 0x39, 0x73, 0x13, 0x5e, 0xe6, 0x46, + 0x41, 0xfe, 0x5c, 0x27, 0x03, 0x81, 0xb3, 0xaa, 0xb1, 0x7f, 0x71, 0x08, 0xfa, 0x97, 0x76, 0x89, + 0x17, 0x1d, 0xc3, 0x3d, 0xa4, 0x06, 0x63, 0xae, 0xb7, 0xeb, 0x37, 0x76, 0x49, 0x9d, 0xe3, 0x0f, + 0x73, 0x5d, 0x3e, 0x25, 0x58, 0x8f, 0xad, 0x18, 0x2c, 0x70, 0x82, 0xe5, 0x83, 0x30, 0x15, 0x5c, + 0x86, 0x01, 0x7e, 0x52, 0x08, 0x3b, 0x41, 0xe6, 0x9e, 0xcd, 0x3a, 0x51, 0x9c, 0x7f, 0xb1, 0x19, + 0x83, 0x9f, 0x44, 0xa2, 0x38, 0xfa, 0x34, 0x8c, 0x6d, 0xba, 0x41, 0x18, 0xad, 0xbb, 0x4d, 0x12, + 0x46, 0x4e, 0xb3, 0x75, 0x1f, 0xa6, 0x01, 0xd5, 0x0f, 0xcb, 0x06, 0x27, 0x9c, 0xe0, 0x8c, 0xb6, + 0x60, 0xb4, 0xe1, 0xe8, 0x55, 0x0d, 0x1e, 0xba, 0x2a, 0x75, 0x3a, 0x5c, 0xd3, 0x19, 0x61, 0x93, + 0x2f, 0x5d, 0x4e, 0x35, 0xa6, 0xdd, 0x1e, 0x62, 0xba, 0x07, 0xb5, 0x9c, 0xb8, 0x5a, 0x9b, 0xe3, + 0xa8, 0x34, 0xc5, 0x5c, 0xc4, 0x4b, 0xa6, 0x34, 0xa5, 0x39, 0x82, 0x7f, 0x0a, 0x4a, 0x84, 0x76, + 0x21, 0x65, 0x2c, 0x0e, 0x98, 0x8b, 0xbd, 0xb5, 0x75, 0xd5, 0xad, 0x05, 0xbe, 0x69, 0x94, 0x59, + 0x92, 0x9c, 0x70, 0xcc, 0x14, 0x2d, 0xc0, 0x40, 0x48, 0x02, 0x57, 0x29, 0x7e, 0x3b, 0x0c, 0x23, + 0x23, 0xe3, 0xef, 0xc1, 0xf8, 0x6f, 0x2c, 0x8a, 0xd2, 0xe9, 0xe5, 0x30, 0xbd, 0x29, 0x3b, 0x0c, + 0xb4, 0xe9, 0x35, 0xc7, 0xa0, 0x58, 0x60, 0xd1, 0x6b, 0x30, 0x18, 0x90, 0x06, 0xb3, 0xfa, 0x8d, + 0xf6, 0x3e, 0xc9, 0xb9, 0x11, 0x91, 0x97, 0xc3, 0x92, 0x01, 0xba, 0x0a, 0x28, 0x20, 0x54, 0x1a, + 0x73, 0xbd, 0x2d, 0xe5, 0x38, 0x2d, 0x36, 0x5a, 0x25, 0xf5, 0xe2, 0x98, 0x42, 0x3e, 0x05, 0xc4, + 0x19, 0xc5, 0xd0, 0x65, 0x98, 0x54, 0xd0, 0x15, 0x2f, 0x8c, 0x1c, 0xba, 0xc1, 0x8d, 0x33, 0x5e, + 0x4a, 0x19, 0x82, 0x93, 0x04, 0x38, 0x5d, 0xc6, 0xfe, 0x92, 0x05, 0xbc, 0x9f, 0x8f, 0x41, 0x05, + 0xf0, 0xaa, 0xa9, 0x02, 0x38, 0x9d, 0x3b, 0x72, 0x39, 0xd7, 0xff, 0x2f, 0x59, 0x30, 0xac, 0x8d, + 0x6c, 0x3c, 0x67, 0xad, 0x0e, 0x73, 0xb6, 0x0d, 0x13, 0x74, 0xa6, 0x5f, 0xdf, 0x08, 0x49, 0xb0, + 0x4b, 0xea, 0x6c, 0x62, 0x16, 0xee, 0x6f, 0x62, 0x2a, 0x27, 0xcd, 0x6b, 0x09, 0x86, 0x38, 0x55, + 0x85, 0xfd, 0x29, 0xd9, 0x54, 0xe5, 0xd3, 0x5a, 0x53, 0x63, 0x9e, 0xf0, 0x69, 0x55, 0xa3, 0x8a, + 0x63, 0x1a, 0xba, 0xd4, 0xb6, 0xfd, 0x30, 0x4a, 0xfa, 0xb4, 0x5e, 0xf1, 0xc3, 0x08, 0x33, 0x8c, + 0xfd, 0x3c, 0xc0, 0xd2, 0x1d, 0x52, 0xe3, 0x33, 0x56, 0xbf, 0xa1, 0x58, 0xf9, 0x37, 0x14, 0xfb, + 0x77, 0x2c, 0x18, 0x5b, 0x5e, 0x30, 0x4e, 0xae, 0x59, 0x00, 0x7e, 0xad, 0xba, 0x75, 0x6b, 0x4d, + 0xfa, 0x6a, 0x70, 0x73, 0xb5, 0x82, 0x62, 0x8d, 0x02, 0x9d, 0x86, 0x62, 0xa3, 0xed, 0x09, 0x1d, + 0xe5, 0x20, 0x3d, 0x1e, 0xaf, 0xb5, 0x3d, 0x4c, 0x61, 0xda, 0x33, 0xa0, 0x62, 0xcf, 0xcf, 0x80, + 0xba, 0x86, 0xff, 0x40, 0x65, 0xe8, 0xbf, 0x7d, 0xdb, 0xad, 0xf3, 0x47, 0xd6, 0xc2, 0x8f, 0xe4, + 0xd6, 0xad, 0x95, 0xc5, 0x10, 0x73, 0xb8, 0xfd, 0x85, 0x22, 0xcc, 0x2c, 0x37, 0xc8, 0x9d, 0xb7, + 0xf9, 0xd0, 0xbc, 0xd7, 0x47, 0x4c, 0x87, 0xd3, 0xf6, 0x1c, 0xf6, 0xa1, 0x5a, 0xf7, 0xfe, 0xd8, + 0x84, 0x41, 0xee, 0xd2, 0x29, 0x9f, 0x9d, 0x67, 0xda, 0xe6, 0xf2, 0x3b, 0x64, 0x96, 0xbb, 0x86, + 0x0a, 0xdb, 0x9c, 0x3a, 0x30, 0x05, 0x14, 0x4b, 0xe6, 0x33, 0x2f, 0xc3, 0x88, 0x4e, 0x79, 0xa8, + 0x27, 0xa3, 0xdf, 0x53, 0x84, 0x09, 0xda, 0x82, 0x07, 0x3a, 0x10, 0x37, 0xd2, 0x03, 0x71, 0xd4, + 0xcf, 0x06, 0xbb, 0x8f, 0xc6, 0x9b, 0xc9, 0xd1, 0xb8, 0x94, 0x37, 0x1a, 0xc7, 0x3d, 0x06, 0xdf, + 0x6b, 0xc1, 0xd4, 0x72, 0xc3, 0xaf, 0xed, 0x24, 0x9e, 0xf6, 0xbd, 0x08, 0xc3, 0x74, 0x3b, 0x0e, + 0x8d, 0x28, 0x17, 0x46, 0xdc, 0x13, 0x81, 0xc2, 0x3a, 0x9d, 0x56, 0xec, 0xc6, 0x8d, 0x95, 0xc5, + 0xac, 0x70, 0x29, 0x02, 0x85, 0x75, 0x3a, 0xfb, 0xb7, 0x2c, 0x38, 0x73, 0x79, 0x61, 0x29, 0x9e, + 0x8a, 0xa9, 0x88, 0x2d, 0xe7, 0x61, 0xa0, 0x55, 0xd7, 0x9a, 0x12, 0xeb, 0x70, 0x17, 0x59, 0x2b, + 0x04, 0xf6, 0x9d, 0x12, 0x8d, 0xe8, 0x06, 0xc0, 0x65, 0x5c, 0x59, 0x10, 0xfb, 0xae, 0x34, 0xd9, + 0x58, 0xb9, 0x26, 0x9b, 0x27, 0x60, 0x90, 0x9e, 0x0b, 0x6e, 0x4d, 0xb6, 0x9b, 0x5b, 0xdf, 0x39, + 0x08, 0x4b, 0x9c, 0xfd, 0x73, 0x16, 0x4c, 0x5d, 0x76, 0x23, 0x7a, 0x68, 0x27, 0x43, 0x92, 0xd0, + 0x53, 0x3b, 0x74, 0x23, 0x3f, 0xd8, 0x4b, 0x86, 0x24, 0xc1, 0x0a, 0x83, 0x35, 0x2a, 0xfe, 0x41, + 0xbb, 0x2e, 0x7b, 0xa3, 0x50, 0x30, 0x8d, 0x64, 0x58, 0xc0, 0xb1, 0xa2, 0xa0, 0xfd, 0x55, 0x77, + 0x03, 0xa6, 0x5f, 0xdc, 0x13, 0x1b, 0xb7, 0xea, 0xaf, 0x45, 0x89, 0xc0, 0x31, 0x8d, 0xfd, 0xc7, + 0x16, 0x94, 0x2f, 0x37, 0xda, 0x61, 0x44, 0x82, 0xcd, 0x30, 0x67, 0xd3, 0x7d, 0x1e, 0x4a, 0x44, + 0x6a, 0xf3, 0xe5, 0x63, 0x4a, 0x29, 0x88, 0x2a, 0x35, 0x3f, 0x8f, 0x8c, 0xa2, 0xe8, 0x7a, 0x78, + 0x7f, 0x7c, 0xb8, 0x07, 0xa4, 0xcb, 0x80, 0x88, 0x5e, 0x97, 0x1e, 0x2a, 0x86, 0xc5, 0x9c, 0x58, + 0x4a, 0x61, 0x71, 0x46, 0x09, 0xfb, 0xc7, 0x2d, 0x38, 0xa9, 0x3e, 0xf8, 0x1d, 0xf7, 0x99, 0xf6, + 0x57, 0x0b, 0x30, 0x7a, 0x65, 0x7d, 0xbd, 0x72, 0x99, 0x44, 0xda, 0xac, 0xec, 0x6c, 0xa3, 0xc7, + 0x9a, 0xa9, 0xb1, 0xd3, 0x1d, 0xb1, 0x1d, 0xb9, 0x8d, 0x59, 0x1e, 0x71, 0x6c, 0x76, 0xc5, 0x8b, + 0xae, 0x07, 0xd5, 0x28, 0x70, 0xbd, 0xad, 0xcc, 0x99, 0x2e, 0x65, 0x96, 0x62, 0x9e, 0xcc, 0x82, + 0x9e, 0x87, 0x01, 0x16, 0xf2, 0x4c, 0x0e, 0xc2, 0xc3, 0xea, 0x8a, 0xc5, 0xa0, 0x07, 0xfb, 0xe5, + 0xd2, 0x0d, 0xbc, 0xc2, 0xff, 0x60, 0x41, 0x8a, 0x6e, 0xc0, 0xf0, 0x76, 0x14, 0xb5, 0xae, 0x10, + 0xa7, 0x4e, 0x02, 0xb9, 0xcb, 0x9e, 0xcd, 0xda, 0x65, 0x69, 0x27, 0x70, 0xb2, 0x78, 0x63, 0x8a, + 0x61, 0x21, 0xd6, 0xf9, 0xd8, 0x55, 0x80, 0x18, 0x77, 0x44, 0x56, 0x16, 0x7b, 0x1d, 0x4a, 0xf4, + 0x73, 0xe7, 0x1a, 0xae, 0xd3, 0xd9, 0x8e, 0xfd, 0x34, 0x94, 0xa4, 0x95, 0x3a, 0x14, 0xf1, 0x11, + 0xd8, 0x89, 0x24, 0x8d, 0xd8, 0x21, 0x8e, 0xf1, 0xf6, 0x26, 0x9c, 0x60, 0xbe, 0xaa, 0x4e, 0xb4, + 0x6d, 0xcc, 0xbe, 0xee, 0xc3, 0xfc, 0x8c, 0xb8, 0xb1, 0xf1, 0x36, 0x4f, 0x6b, 0x0f, 0x7a, 0x47, + 0x24, 0xc7, 0xf8, 0xf6, 0x66, 0x7f, 0xb3, 0x0f, 0x1e, 0x5e, 0xa9, 0xe6, 0x87, 0xec, 0x79, 0x09, + 0x46, 0xb8, 0x20, 0x48, 0x07, 0xdd, 0x69, 0x88, 0x7a, 0x95, 0x6e, 0x73, 0x5d, 0xc3, 0x61, 0x83, + 0x12, 0x9d, 0x81, 0xa2, 0xfb, 0x96, 0x97, 0x7c, 0xee, 0xb6, 0xf2, 0xfa, 0x1a, 0xa6, 0x70, 0x8a, + 0xa6, 0x32, 0x25, 0xdf, 0xac, 0x15, 0x5a, 0xc9, 0x95, 0xaf, 0xc2, 0x98, 0x1b, 0xd6, 0x42, 0x77, + 0xc5, 0xa3, 0x2b, 0x50, 0x5b, 0xc3, 0x4a, 0x9b, 0x40, 0x1b, 0xad, 0xb0, 0x38, 0x41, 0xad, 0x9d, + 0x1c, 0xfd, 0x3d, 0xcb, 0xa5, 0x5d, 0x03, 0x06, 0xd0, 0x8d, 0xbd, 0xc5, 0xbe, 0x2e, 0x64, 0x9a, + 0x70, 0xb1, 0xb1, 0xf3, 0x0f, 0x0e, 0xb1, 0xc4, 0xd1, 0xab, 0x5a, 0x6d, 0xdb, 0x69, 0xcd, 0xb5, + 0xa3, 0xed, 0x45, 0x37, 0xac, 0xf9, 0xbb, 0x24, 0xd8, 0x63, 0xb7, 0xec, 0xa1, 0xf8, 0xaa, 0xa6, + 0x10, 0x0b, 0x57, 0xe6, 0x2a, 0x94, 0x12, 0xa7, 0xcb, 0xa0, 0x39, 0x18, 0x97, 0xc0, 0x2a, 0x09, + 0xd9, 0xe6, 0x3e, 0xcc, 0xd8, 0xa8, 0x07, 0x68, 0x02, 0xac, 0x98, 0x24, 0xe9, 0x4d, 0xd1, 0x15, + 0x8e, 0x42, 0x74, 0xfd, 0x00, 0x8c, 0xba, 0x9e, 0x1b, 0xb9, 0x4e, 0xe4, 0x73, 0x33, 0x0e, 0xbf, + 0x50, 0x33, 0xd5, 0xf1, 0x8a, 0x8e, 0xc0, 0x26, 0x9d, 0xfd, 0x9f, 0xfa, 0x60, 0x92, 0x0d, 0xdb, + 0xbb, 0x33, 0xec, 0x3b, 0x69, 0x86, 0xdd, 0x48, 0xcf, 0xb0, 0xa3, 0x90, 0xc9, 0xef, 0x7b, 0x9a, + 0x7d, 0x1a, 0x4a, 0xea, 0xcd, 0x9d, 0x7c, 0x74, 0x6b, 0xe5, 0x3c, 0xba, 0xed, 0x7e, 0x2e, 0x4b, + 0xcf, 0xb0, 0x62, 0xa6, 0x67, 0xd8, 0x97, 0x2d, 0x88, 0x4d, 0x06, 0xe8, 0x75, 0x28, 0xb5, 0x7c, + 0xe6, 0x68, 0x1a, 0x48, 0xef, 0xed, 0xc7, 0x3b, 0xda, 0x1c, 0x78, 0xd4, 0xb2, 0x80, 0xf7, 0x42, + 0x45, 0x16, 0xc5, 0x31, 0x17, 0x74, 0x15, 0x06, 0x5b, 0x01, 0xa9, 0x46, 0x2c, 0xa4, 0x4e, 0xef, + 0x0c, 0xf9, 0xac, 0xe1, 0x05, 0xb1, 0xe4, 0x60, 0xff, 0x67, 0x0b, 0x26, 0x92, 0xa4, 0xe8, 0x43, + 0xd0, 0x47, 0xee, 0x90, 0x9a, 0x68, 0x6f, 0xe6, 0x21, 0x1b, 0x2b, 0x1d, 0x78, 0x07, 0xd0, 0xff, + 0x98, 0x95, 0x42, 0x57, 0x60, 0x90, 0x9e, 0xb0, 0x97, 0x55, 0xf8, 0xb8, 0x47, 0xf3, 0x4e, 0x69, + 0x25, 0xaa, 0xf0, 0xc6, 0x09, 0x10, 0x96, 0xc5, 0x99, 0x3b, 0x56, 0xad, 0x55, 0xa5, 0x97, 0x97, + 0xa8, 0xd3, 0x1d, 0x7b, 0x7d, 0xa1, 0xc2, 0x89, 0x04, 0x37, 0xee, 0x8e, 0x25, 0x81, 0x38, 0x66, + 0x62, 0xff, 0xbc, 0x05, 0xc0, 0xbd, 0xcf, 0x1c, 0x6f, 0x8b, 0x1c, 0x83, 0x9e, 0x7c, 0x11, 0xfa, + 0xc2, 0x16, 0xa9, 0x75, 0xf2, 0x81, 0x8e, 0xdb, 0x53, 0x6d, 0x91, 0x5a, 0x3c, 0xe3, 0xe8, 0x3f, + 0xcc, 0x4a, 0xdb, 0xdf, 0x07, 0x30, 0x16, 0x93, 0xad, 0x44, 0xa4, 0x89, 0x9e, 0x35, 0x02, 0x75, + 0x9c, 0x4e, 0x04, 0xea, 0x28, 0x31, 0x6a, 0x4d, 0x25, 0xfb, 0x69, 0x28, 0x36, 0x9d, 0x3b, 0x42, + 0xe7, 0xf6, 0x74, 0xe7, 0x66, 0x50, 0xfe, 0xb3, 0xab, 0xce, 0x1d, 0x7e, 0x2d, 0x7d, 0x5a, 0xae, + 0x90, 0x55, 0xe7, 0x4e, 0x57, 0x3f, 0x5d, 0x5a, 0x09, 0xab, 0xcb, 0xf5, 0x84, 0x63, 0x55, 0x4f, + 0x75, 0xb9, 0x5e, 0xb2, 0x2e, 0xd7, 0xeb, 0xa1, 0x2e, 0xd7, 0x43, 0x77, 0x61, 0x50, 0xf8, 0x3d, + 0x8a, 0x50, 0x5e, 0x17, 0x7b, 0xa8, 0x4f, 0xb8, 0x4d, 0xf2, 0x3a, 0x2f, 0xca, 0x6b, 0xb7, 0x80, + 0x76, 0xad, 0x57, 0x56, 0x88, 0xfe, 0xaa, 0x05, 0x63, 0xe2, 0x37, 0x26, 0x6f, 0xb5, 0x49, 0x18, + 0x09, 0xb1, 0xf4, 0xfd, 0xbd, 0xb7, 0x41, 0x14, 0xe4, 0x4d, 0x79, 0xbf, 0x3c, 0x67, 0x4c, 0x64, + 0xd7, 0x16, 0x25, 0x5a, 0x81, 0xfe, 0xae, 0x05, 0x27, 0x9a, 0xce, 0x1d, 0x5e, 0x23, 0x87, 0x61, + 0x27, 0x72, 0x7d, 0xe1, 0x3f, 0xf0, 0xa1, 0xde, 0x86, 0x3f, 0x55, 0x9c, 0x37, 0x52, 0xda, 0x1f, + 0x4f, 0x64, 0x91, 0x74, 0x6d, 0x6a, 0x66, 0xbb, 0x66, 0x36, 0x61, 0x48, 0xce, 0xb7, 0x07, 0xe9, + 0x64, 0xcd, 0xea, 0x11, 0x73, 0xed, 0x81, 0xd6, 0xf3, 0x69, 0x18, 0xd1, 0xe7, 0xd8, 0x03, 0xad, + 0xeb, 0x2d, 0x98, 0xca, 0x98, 0x4b, 0x0f, 0xb4, 0xca, 0xdb, 0x70, 0x3a, 0x77, 0x7e, 0x3c, 0x50, + 0x27, 0xf9, 0xaf, 0x5a, 0xfa, 0x3e, 0x78, 0x0c, 0xc6, 0x8a, 0x05, 0xd3, 0x58, 0x71, 0xb6, 0xf3, + 0xca, 0xc9, 0xb1, 0x58, 0xbc, 0xa9, 0x37, 0x9a, 0xee, 0xea, 0xe8, 0x35, 0x18, 0x68, 0x50, 0x88, + 0xf4, 0x9e, 0xb5, 0xbb, 0xaf, 0xc8, 0x58, 0x98, 0x64, 0xf0, 0x10, 0x0b, 0x0e, 0xf6, 0x2f, 0x59, + 0xd0, 0x77, 0x0c, 0x3d, 0x81, 0xcd, 0x9e, 0x78, 0x36, 0x97, 0xb5, 0x88, 0x6a, 0x3e, 0x8b, 0x9d, + 0xdb, 0x4b, 0x77, 0x22, 0xe2, 0x85, 0xec, 0x44, 0xce, 0xec, 0x98, 0x9f, 0xb6, 0x60, 0xea, 0x9a, + 0xef, 0xd4, 0xe7, 0x9d, 0x86, 0xe3, 0xd5, 0x48, 0xb0, 0xe2, 0x6d, 0x1d, 0xca, 0xf5, 0xbb, 0xd0, + 0xd5, 0xf5, 0x7b, 0x41, 0x7a, 0x4e, 0xf5, 0xe5, 0x8f, 0x1f, 0x95, 0xa4, 0x93, 0xa1, 0x8b, 0x0c, + 0x1f, 0xdf, 0x6d, 0x40, 0x7a, 0x2b, 0xc5, 0x03, 0x28, 0x0c, 0x83, 0x2e, 0x6f, 0xaf, 0x18, 0xc4, + 0x27, 0xb3, 0x25, 0xdc, 0xd4, 0xe7, 0x69, 0x4f, 0x7b, 0x38, 0x00, 0x4b, 0x46, 0xf6, 0x4b, 0x90, + 0x19, 0x6a, 0xa2, 0xbb, 0x5e, 0xc2, 0xfe, 0x18, 0x4c, 0xb2, 0x92, 0x87, 0xd4, 0x0c, 0xd8, 0x09, + 0x6d, 0x6a, 0x46, 0xd8, 0x4c, 0xfb, 0xf3, 0x16, 0x8c, 0xaf, 0x25, 0xa2, 0x09, 0x9e, 0x67, 0xf6, + 0xd7, 0x0c, 0x25, 0x7e, 0x95, 0x41, 0xb1, 0xc0, 0x1e, 0xb9, 0x92, 0xeb, 0xcf, 0x2d, 0x88, 0xa3, + 0xbf, 0x1c, 0x83, 0xf8, 0xb6, 0x60, 0x88, 0x6f, 0x99, 0x82, 0xac, 0x6a, 0x4e, 0x9e, 0xf4, 0x86, + 0xae, 0xaa, 0xb8, 0x68, 0x1d, 0x64, 0xd8, 0x98, 0x0d, 0x9f, 0x8a, 0x63, 0x66, 0xf0, 0x34, 0x19, + 0x29, 0xcd, 0xfe, 0xdd, 0x02, 0x20, 0x45, 0xdb, 0x73, 0xdc, 0xb6, 0x74, 0x89, 0xa3, 0x89, 0xdb, + 0xb6, 0x0b, 0x88, 0x79, 0x10, 0x04, 0x8e, 0x17, 0x72, 0xb6, 0xae, 0x50, 0xeb, 0x1d, 0xce, 0x3d, + 0x61, 0x46, 0xbe, 0x0d, 0xbb, 0x96, 0xe2, 0x86, 0x33, 0x6a, 0xd0, 0x3c, 0x43, 0xfa, 0x7b, 0xf5, + 0x0c, 0x19, 0xe8, 0xf2, 0xc8, 0xf1, 0x2b, 0x16, 0x8c, 0xaa, 0x6e, 0x7a, 0x87, 0xb8, 0xc2, 0xab, + 0xf6, 0xe4, 0x6c, 0xa0, 0x15, 0xad, 0xc9, 0xec, 0x60, 0xf9, 0x2e, 0xf6, 0x58, 0xd5, 0x69, 0xb8, + 0x77, 0x89, 0x8a, 0xf3, 0x59, 0x16, 0x8f, 0x4f, 0x05, 0xf4, 0x60, 0xbf, 0x3c, 0xaa, 0xfe, 0xf1, + 0x38, 0xe6, 0x71, 0x11, 0xba, 0x25, 0x8f, 0x27, 0xa6, 0x22, 0x7a, 0x11, 0xfa, 0x5b, 0xdb, 0x4e, + 0x48, 0x12, 0x4f, 0x86, 0xfa, 0x2b, 0x14, 0x78, 0xb0, 0x5f, 0x1e, 0x53, 0x05, 0x18, 0x04, 0x73, + 0xea, 0xde, 0xa3, 0xe1, 0xa5, 0x27, 0x67, 0xd7, 0x68, 0x78, 0x7f, 0x6a, 0x41, 0xdf, 0x9a, 0x5f, + 0x3f, 0x8e, 0x2d, 0xe0, 0x55, 0x63, 0x0b, 0x78, 0x24, 0x2f, 0xc5, 0x44, 0xee, 0xea, 0x5f, 0x4e, + 0xac, 0xfe, 0xb3, 0xb9, 0x1c, 0x3a, 0x2f, 0xfc, 0x26, 0x0c, 0xb3, 0xc4, 0x15, 0xe2, 0x79, 0xd4, + 0xf3, 0xc6, 0x82, 0x2f, 0x27, 0x16, 0xfc, 0xb8, 0x46, 0xaa, 0xad, 0xf4, 0xa7, 0x60, 0x50, 0xbc, + 0xb7, 0x49, 0xbe, 0xf9, 0x15, 0xb4, 0x58, 0xe2, 0xed, 0x9f, 0x28, 0x82, 0x91, 0x28, 0x03, 0xfd, + 0x8a, 0x05, 0xb3, 0x01, 0xf7, 0xc3, 0xad, 0x2f, 0xb6, 0x03, 0xd7, 0xdb, 0xaa, 0xd6, 0xb6, 0x49, + 0xbd, 0xdd, 0x70, 0xbd, 0xad, 0x95, 0x2d, 0xcf, 0x57, 0xe0, 0xa5, 0x3b, 0xa4, 0xd6, 0x66, 0x66, + 0xb7, 0x2e, 0x59, 0x39, 0x94, 0x3f, 0xfb, 0x73, 0xf7, 0xf6, 0xcb, 0xb3, 0xf8, 0x50, 0xbc, 0xf1, + 0x21, 0xdb, 0x82, 0x7e, 0xcb, 0x82, 0x8b, 0x3c, 0x7f, 0x44, 0xef, 0xed, 0xef, 0x70, 0x5b, 0xae, + 0x48, 0x56, 0x31, 0x93, 0x75, 0x12, 0x34, 0xe7, 0x3f, 0x20, 0x3a, 0xf4, 0x62, 0xe5, 0x70, 0x75, + 0xe1, 0xc3, 0x36, 0xce, 0xfe, 0xc7, 0x45, 0x18, 0x15, 0x51, 0xd3, 0xc4, 0x19, 0xf0, 0xa2, 0x31, + 0x25, 0x1e, 0x4d, 0x4c, 0x89, 0x49, 0x83, 0xf8, 0x68, 0xb6, 0xff, 0x10, 0x26, 0xe9, 0xe6, 0x7c, + 0x85, 0x38, 0x41, 0xb4, 0x41, 0x1c, 0xee, 0xf0, 0x55, 0x3c, 0xf4, 0xee, 0xaf, 0xf4, 0x93, 0xd7, + 0x92, 0xcc, 0x70, 0x9a, 0xff, 0x77, 0xd2, 0x99, 0xe3, 0xc1, 0x44, 0x2a, 0xf0, 0xdd, 0x1b, 0x50, + 0x52, 0x8f, 0x45, 0xc4, 0xa6, 0xd3, 0x39, 0x7e, 0x64, 0x92, 0x03, 0x57, 0x7f, 0xc5, 0x0f, 0x95, + 0x62, 0x76, 0xf6, 0xdf, 0x2f, 0x18, 0x15, 0xf2, 0x41, 0x5c, 0x83, 0x21, 0x27, 0x0c, 0xdd, 0x2d, + 0x8f, 0xd4, 0x3b, 0x69, 0x28, 0x53, 0xd5, 0xb0, 0x07, 0x3b, 0x73, 0xa2, 0x24, 0x56, 0x3c, 0xd0, + 0x15, 0xee, 0x56, 0xb7, 0x4b, 0x3a, 0xa9, 0x27, 0x53, 0xdc, 0x40, 0x3a, 0xde, 0xed, 0x12, 0x2c, + 0xca, 0xa3, 0x4f, 0x70, 0xbf, 0xc7, 0xab, 0x9e, 0x7f, 0xdb, 0xbb, 0xec, 0xfb, 0x32, 0xe8, 0x46, + 0x6f, 0x0c, 0x27, 0xa5, 0xb7, 0xa3, 0x2a, 0x8e, 0x4d, 0x6e, 0xbd, 0x45, 0x92, 0xfd, 0x0c, 0xb0, + 0x78, 0xf9, 0xe6, 0xdb, 0xec, 0x10, 0x11, 0x18, 0x17, 0x21, 0xf9, 0x24, 0x4c, 0xf4, 0x5d, 0xe6, + 0x55, 0xce, 0x2c, 0x1d, 0x2b, 0xd2, 0xaf, 0x9a, 0x2c, 0x70, 0x92, 0xa7, 0xfd, 0xb3, 0x16, 0xb0, + 0x77, 0xaa, 0xc7, 0x20, 0x8f, 0x7c, 0xd8, 0x94, 0x47, 0xa6, 0xf3, 0x3a, 0x39, 0x47, 0x14, 0x79, + 0x81, 0xcf, 0xac, 0x4a, 0xe0, 0xdf, 0xd9, 0x13, 0xce, 0x2a, 0xdd, 0xef, 0x1f, 0xf6, 0xff, 0xb6, + 0xf8, 0x26, 0x16, 0xbf, 0xea, 0xff, 0x2c, 0x0c, 0xd5, 0x9c, 0x96, 0x53, 0xe3, 0x59, 0x9d, 0x72, + 0x35, 0x7a, 0x46, 0xa1, 0xd9, 0x05, 0x51, 0x82, 0x6b, 0xa8, 0x64, 0x68, 0xc7, 0x21, 0x09, 0xee, + 0xaa, 0x95, 0x52, 0x55, 0xce, 0xec, 0xc0, 0xa8, 0xc1, 0xec, 0x81, 0xaa, 0x33, 0x3e, 0xcb, 0x8f, + 0x58, 0x15, 0x8a, 0xb4, 0x09, 0x93, 0x9e, 0xf6, 0x9f, 0x1e, 0x28, 0xf2, 0x72, 0xf9, 0x78, 0xb7, + 0x43, 0x94, 0x9d, 0x3e, 0xda, 0x13, 0xd8, 0x04, 0x1b, 0x9c, 0xe6, 0x6c, 0xff, 0xa4, 0x05, 0x0f, + 0xe9, 0x84, 0xda, 0x2b, 0x9b, 0x6e, 0x46, 0x92, 0x45, 0x18, 0xf2, 0x5b, 0x24, 0x70, 0x22, 0x3f, + 0x10, 0xa7, 0xc6, 0x05, 0xd9, 0xe9, 0xd7, 0x05, 0xfc, 0x40, 0xe4, 0x28, 0x90, 0xdc, 0x25, 0x1c, + 0xab, 0x92, 0xf4, 0xf6, 0xc9, 0x3a, 0x23, 0x14, 0xef, 0xa9, 0xd8, 0x1e, 0xc0, 0x2c, 0xe9, 0x21, + 0x16, 0x18, 0xfb, 0x9b, 0x16, 0x9f, 0x58, 0x7a, 0xd3, 0xd1, 0x5b, 0x30, 0xd1, 0x74, 0xa2, 0xda, + 0xf6, 0xd2, 0x9d, 0x56, 0xc0, 0x4d, 0x4e, 0xb2, 0x9f, 0x9e, 0xee, 0xd6, 0x4f, 0xda, 0x47, 0xc6, + 0xae, 0x9c, 0xab, 0x09, 0x66, 0x38, 0xc5, 0x1e, 0x6d, 0xc0, 0x30, 0x83, 0xb1, 0xa7, 0x82, 0x61, + 0x27, 0xd1, 0x20, 0xaf, 0x36, 0xe5, 0x8c, 0xb0, 0x1a, 0xf3, 0xc1, 0x3a, 0x53, 0xfb, 0xcb, 0x45, + 0xbe, 0xda, 0x99, 0x28, 0xff, 0x14, 0x0c, 0xb6, 0xfc, 0xfa, 0xc2, 0xca, 0x22, 0x16, 0xa3, 0xa0, + 0x8e, 0x91, 0x0a, 0x07, 0x63, 0x89, 0x47, 0x17, 0x60, 0x48, 0xfc, 0x94, 0x26, 0x42, 0xb6, 0x37, + 0x0b, 0xba, 0x10, 0x2b, 0x2c, 0x7a, 0x0e, 0xa0, 0x15, 0xf8, 0xbb, 0x6e, 0x9d, 0x85, 0x0e, 0x29, + 0x9a, 0x7e, 0x44, 0x15, 0x85, 0xc1, 0x1a, 0x15, 0x7a, 0x05, 0x46, 0xdb, 0x5e, 0xc8, 0xc5, 0x11, + 0x2d, 0x9a, 0xb2, 0xf2, 0x70, 0xb9, 0xa1, 0x23, 0xb1, 0x49, 0x8b, 0xe6, 0x60, 0x20, 0x72, 0x98, + 0x5f, 0x4c, 0x7f, 0xbe, 0xbb, 0xef, 0x3a, 0xa5, 0xd0, 0x13, 0x08, 0xd1, 0x02, 0x58, 0x14, 0x44, + 0x6f, 0xc8, 0x57, 0xbb, 0x7c, 0x63, 0x17, 0x7e, 0xf6, 0xbd, 0x1d, 0x02, 0xda, 0x9b, 0x5d, 0xe1, + 0xbf, 0x6f, 0xf0, 0x42, 0x2f, 0x03, 0x90, 0x3b, 0x11, 0x09, 0x3c, 0xa7, 0xa1, 0xbc, 0xd9, 0x94, + 0x5c, 0xb0, 0xe8, 0xaf, 0xf9, 0xd1, 0x8d, 0x90, 0x2c, 0x29, 0x0a, 0xac, 0x51, 0xdb, 0xbf, 0x55, + 0x02, 0x88, 0xe5, 0x76, 0x74, 0x37, 0xb5, 0x71, 0x3d, 0xd3, 0x59, 0xd2, 0x3f, 0xba, 0x5d, 0x0b, + 0x7d, 0xbf, 0x05, 0xc3, 0x22, 0x42, 0x0a, 0x1b, 0xa1, 0x42, 0xe7, 0x8d, 0xd3, 0x0c, 0xd4, 0x42, + 0x4b, 0xf0, 0x26, 0x3c, 0x2f, 0x67, 0xa8, 0x86, 0xe9, 0xda, 0x0a, 0xbd, 0x62, 0xf4, 0x3e, 0x79, + 0x55, 0x2c, 0x1a, 0x5d, 0xa9, 0xae, 0x8a, 0x25, 0x76, 0x46, 0xe8, 0xb7, 0xc4, 0x1b, 0xc6, 0x2d, + 0xb1, 0x2f, 0xff, 0x59, 0xa2, 0x21, 0xbe, 0x76, 0xbb, 0x20, 0xa2, 0x8a, 0x1e, 0xa2, 0xa0, 0x3f, + 0xff, 0x79, 0x9e, 0x76, 0x4f, 0xea, 0x12, 0x9e, 0xe0, 0xd3, 0x30, 0x5e, 0x37, 0x85, 0x00, 0x31, + 0x13, 0x9f, 0xcc, 0xe3, 0x9b, 0x90, 0x19, 0xe2, 0x63, 0x3f, 0x81, 0xc0, 0x49, 0xc6, 0xa8, 0xc2, + 0x23, 0x56, 0xac, 0x78, 0x9b, 0xbe, 0x78, 0xeb, 0x61, 0xe7, 0x8e, 0xe5, 0x5e, 0x18, 0x91, 0x26, + 0xa5, 0x8c, 0x4f, 0xf7, 0x35, 0x51, 0x16, 0x2b, 0x2e, 0xe8, 0x35, 0x18, 0x60, 0xef, 0xb3, 0xc2, + 0xe9, 0xa1, 0x7c, 0x8d, 0xb3, 0x19, 0xba, 0x2f, 0x5e, 0x90, 0xec, 0x6f, 0x88, 0x05, 0x07, 0x74, + 0x45, 0xbe, 0x7e, 0x0c, 0x57, 0xbc, 0x1b, 0x21, 0x61, 0xaf, 0x1f, 0x4b, 0xf3, 0x8f, 0xc7, 0x0f, + 0x1b, 0x39, 0x3c, 0x33, 0xcd, 0xa0, 0x51, 0x92, 0x4a, 0x51, 0xe2, 0xbf, 0xcc, 0x5e, 0x28, 0x02, + 0x0d, 0x65, 0x36, 0xcf, 0xcc, 0x70, 0x18, 0x77, 0xe7, 0x4d, 0x93, 0x05, 0x4e, 0xf2, 0xa4, 0x12, + 0x29, 0x5f, 0xf5, 0xe2, 0xb5, 0x48, 0xb7, 0xbd, 0x83, 0x5f, 0xc4, 0xd9, 0x69, 0xc4, 0x21, 0x58, + 0x94, 0x3f, 0x56, 0xf1, 0x60, 0xc6, 0x83, 0x89, 0xe4, 0x12, 0x7d, 0xa0, 0xe2, 0xc8, 0x1f, 0xf6, + 0xc1, 0x98, 0x39, 0xa5, 0xd0, 0x45, 0x28, 0x09, 0x26, 0x2a, 0x03, 0x88, 0x5a, 0x25, 0xab, 0x12, + 0x81, 0x63, 0x1a, 0x96, 0xf8, 0x85, 0x15, 0xd7, 0xdc, 0x83, 0xe3, 0xc4, 0x2f, 0x0a, 0x83, 0x35, + 0x2a, 0x7a, 0xb1, 0xda, 0xf0, 0xfd, 0x48, 0x1d, 0x48, 0x6a, 0xde, 0xcd, 0x33, 0x28, 0x16, 0x58, + 0x7a, 0x10, 0xed, 0x90, 0xc0, 0x23, 0x0d, 0x33, 0xf2, 0xb6, 0x3a, 0x88, 0xae, 0xea, 0x48, 0x6c, + 0xd2, 0xd2, 0xe3, 0xd4, 0x0f, 0xd9, 0x44, 0x16, 0xd7, 0xb7, 0xd8, 0xdd, 0xba, 0xca, 0x5f, 0x79, + 0x4b, 0x3c, 0xfa, 0x18, 0x3c, 0xa4, 0x02, 0x67, 0x61, 0x6e, 0xcd, 0x90, 0x35, 0x0e, 0x18, 0xda, + 0x96, 0x87, 0x16, 0xb2, 0xc9, 0x70, 0x5e, 0x79, 0xf4, 0x2a, 0x8c, 0x09, 0x11, 0x5f, 0x72, 0x1c, + 0x34, 0x3d, 0x8c, 0xae, 0x1a, 0x58, 0x9c, 0xa0, 0x96, 0xb1, 0xc3, 0x99, 0x94, 0x2d, 0x39, 0x0c, + 0xa5, 0x63, 0x87, 0xeb, 0x78, 0x9c, 0x2a, 0x81, 0xe6, 0x60, 0x9c, 0xcb, 0x60, 0xae, 0xb7, 0xc5, + 0xc7, 0x44, 0x3c, 0xe6, 0x52, 0x4b, 0xea, 0xba, 0x89, 0xc6, 0x49, 0x7a, 0xf4, 0x12, 0x8c, 0x38, + 0x41, 0x6d, 0xdb, 0x8d, 0x48, 0x2d, 0x6a, 0x07, 0xfc, 0x95, 0x97, 0xe6, 0xa2, 0x35, 0xa7, 0xe1, + 0xb0, 0x41, 0x69, 0xdf, 0x85, 0xa9, 0x8c, 0xf0, 0x0f, 0x74, 0xe2, 0x38, 0x2d, 0x57, 0x7e, 0x53, + 0xc2, 0xc3, 0x79, 0xae, 0xb2, 0x22, 0xbf, 0x46, 0xa3, 0xa2, 0xb3, 0x93, 0x85, 0x89, 0xd0, 0x92, + 0x95, 0xaa, 0xd9, 0xb9, 0x2c, 0x11, 0x38, 0xa6, 0xb1, 0xff, 0x5b, 0x01, 0xc6, 0x33, 0x6c, 0x2b, + 0x2c, 0x61, 0x66, 0xe2, 0x92, 0x12, 0xe7, 0xc7, 0x34, 0x43, 0xd1, 0x17, 0x0e, 0x11, 0x8a, 0xbe, + 0xd8, 0x2d, 0x14, 0x7d, 0xdf, 0xdb, 0x09, 0x45, 0x6f, 0xf6, 0x58, 0x7f, 0x4f, 0x3d, 0x96, 0x11, + 0xbe, 0x7e, 0xe0, 0x90, 0xe1, 0xeb, 0x8d, 0x4e, 0x1f, 0xec, 0xa1, 0xd3, 0x7f, 0xb4, 0x00, 0x13, + 0x49, 0x57, 0xd2, 0x63, 0xd0, 0xdb, 0xbe, 0x66, 0xe8, 0x6d, 0x2f, 0xf4, 0xf2, 0xf8, 0x36, 0x57, + 0x87, 0x8b, 0x13, 0x3a, 0xdc, 0xf7, 0xf6, 0xc4, 0xad, 0xb3, 0x3e, 0xf7, 0xa7, 0x0a, 0x70, 0x32, + 0xf3, 0xf5, 0xef, 0x31, 0xf4, 0xcd, 0x75, 0xa3, 0x6f, 0x9e, 0xed, 0xf9, 0x61, 0x72, 0x6e, 0x07, + 0xdd, 0x4a, 0x74, 0xd0, 0xc5, 0xde, 0x59, 0x76, 0xee, 0xa5, 0xaf, 0x17, 0xe1, 0x6c, 0x66, 0xb9, + 0x58, 0xed, 0xb9, 0x6c, 0xa8, 0x3d, 0x9f, 0x4b, 0xa8, 0x3d, 0xed, 0xce, 0xa5, 0x8f, 0x46, 0x0f, + 0x2a, 0x1e, 0xe8, 0xb2, 0x30, 0x03, 0xf7, 0xa9, 0x03, 0x35, 0x1e, 0xe8, 0x2a, 0x46, 0xd8, 0xe4, + 0xfb, 0x9d, 0xa4, 0xfb, 0xfc, 0x97, 0x16, 0x9c, 0xce, 0x1c, 0x9b, 0x63, 0xd0, 0x75, 0xad, 0x99, + 0xba, 0xae, 0xa7, 0x7a, 0x9e, 0xad, 0x39, 0xca, 0xaf, 0x9f, 0xe9, 0xcf, 0xf9, 0x16, 0x76, 0x93, + 0xbf, 0x0e, 0xc3, 0x4e, 0xad, 0x46, 0xc2, 0x70, 0xd5, 0xaf, 0xab, 0x40, 0xd8, 0xcf, 0xb2, 0x7b, + 0x56, 0x0c, 0x3e, 0xd8, 0x2f, 0xcf, 0x24, 0x59, 0xc4, 0x68, 0xac, 0x73, 0x40, 0x9f, 0x80, 0xa1, + 0x50, 0x9c, 0x9b, 0x62, 0xec, 0x9f, 0xef, 0xb1, 0x73, 0x9c, 0x0d, 0xd2, 0x30, 0x23, 0x2e, 0x29, + 0x4d, 0x85, 0x62, 0x69, 0x46, 0x67, 0x29, 0x1c, 0x69, 0x74, 0x96, 0xe7, 0x00, 0x76, 0xd5, 0x65, + 0x20, 0xa9, 0x7f, 0xd0, 0xae, 0x09, 0x1a, 0x15, 0xfa, 0x08, 0x4c, 0x84, 0x3c, 0x24, 0xe1, 0x42, + 0xc3, 0x09, 0xd9, 0x3b, 0x1a, 0x31, 0x0b, 0x59, 0x54, 0xa7, 0x6a, 0x02, 0x87, 0x53, 0xd4, 0x68, + 0x59, 0xd6, 0xca, 0xe2, 0x27, 0xf2, 0x89, 0x79, 0x3e, 0xae, 0x51, 0xa4, 0xeb, 0x3e, 0x91, 0xec, + 0x7e, 0xd6, 0xf1, 0x5a, 0x49, 0xf4, 0x09, 0x00, 0x3a, 0x7d, 0x84, 0x1e, 0x62, 0x30, 0x7f, 0xf3, + 0xa4, 0xbb, 0x4a, 0x3d, 0xd3, 0xb9, 0x99, 0xbd, 0xa9, 0x5d, 0x54, 0x4c, 0xb0, 0xc6, 0x10, 0x39, + 0x30, 0x1a, 0xff, 0x8b, 0xb3, 0xd9, 0x5e, 0xc8, 0xad, 0x21, 0xc9, 0x9c, 0xa9, 0xbc, 0x17, 0x75, + 0x16, 0xd8, 0xe4, 0x68, 0xff, 0xf8, 0x20, 0x3c, 0xdc, 0x61, 0x1b, 0x46, 0x73, 0xa6, 0xa9, 0xf7, + 0xe9, 0xe4, 0xfd, 0x7d, 0x26, 0xb3, 0xb0, 0x71, 0xa1, 0x4f, 0xcc, 0xf6, 0xc2, 0xdb, 0x9e, 0xed, + 0x3f, 0x6c, 0x69, 0x9a, 0x15, 0xee, 0x54, 0xfa, 0xe1, 0x43, 0x1e, 0x2f, 0x47, 0xa8, 0x6a, 0xd9, + 0xcc, 0xd0, 0x57, 0x3c, 0xd7, 0x73, 0x73, 0x7a, 0x57, 0x60, 0x7c, 0x35, 0x3b, 0x0e, 0x2f, 0x57, + 0x65, 0x5c, 0x3e, 0xec, 0xf7, 0x1f, 0x57, 0x4c, 0xde, 0x8f, 0xc9, 0xe8, 0x4b, 0xbc, 0x5e, 0xb1, + 0xd6, 0x5e, 0x8c, 0xc3, 0x29, 0xa9, 0xb3, 0xf4, 0xd1, 0xcc, 0xe6, 0xea, 0x44, 0xd8, 0x60, 0x75, + 0xbc, 0x57, 0xef, 0x6f, 0x51, 0x10, 0xe0, 0xdf, 0xb1, 0xe0, 0x4c, 0xc7, 0x88, 0x30, 0xdf, 0x86, + 0xb2, 0xa1, 0xfd, 0x39, 0x0b, 0xb2, 0x07, 0xdb, 0xf0, 0x28, 0xbb, 0x08, 0xa5, 0x5a, 0x22, 0xef, + 0x66, 0x1c, 0x1b, 0x41, 0xe5, 0xdc, 0x8c, 0x69, 0x0c, 0xc7, 0xb1, 0x42, 0x57, 0xc7, 0xb1, 0x5f, + 0xb7, 0x20, 0xb5, 0xbf, 0x1f, 0x83, 0xa0, 0xb1, 0x62, 0x0a, 0x1a, 0x8f, 0xf7, 0xd2, 0x9b, 0x39, + 0x32, 0xc6, 0x9f, 0x8c, 0xc3, 0xa9, 0x9c, 0x17, 0x79, 0xbb, 0x30, 0xb9, 0x55, 0x23, 0xe6, 0xe3, + 0xea, 0x4e, 0x41, 0x87, 0x3a, 0xbe, 0xc4, 0xe6, 0xe9, 0x4e, 0x53, 0x24, 0x38, 0x5d, 0x05, 0xfa, + 0x9c, 0x05, 0x27, 0x9c, 0xdb, 0xe1, 0x12, 0x15, 0x18, 0xdd, 0xda, 0x7c, 0xc3, 0xaf, 0xed, 0xd0, + 0xd3, 0x58, 0x2e, 0x84, 0x17, 0x32, 0x95, 0x78, 0xb7, 0xaa, 0x29, 0x7a, 0xa3, 0x7a, 0x96, 0xdc, + 0x3a, 0x8b, 0x0a, 0x67, 0xd6, 0x85, 0xb0, 0x48, 0xed, 0x41, 0xaf, 0xa3, 0x1d, 0x9e, 0xff, 0x67, + 0x3d, 0x9d, 0xe4, 0x12, 0x90, 0xc4, 0x60, 0xc5, 0x07, 0x7d, 0x0a, 0x4a, 0x5b, 0xf2, 0xa5, 0x6f, + 0x86, 0x84, 0x15, 0x77, 0x64, 0xe7, 0xf7, 0xcf, 0xdc, 0x12, 0xaf, 0x88, 0x70, 0xcc, 0x14, 0xbd, + 0x0a, 0x45, 0x6f, 0x33, 0xec, 0x94, 0x1f, 0x3a, 0xe1, 0x72, 0xc9, 0x83, 0x6c, 0xac, 0x2d, 0x57, + 0x31, 0x2d, 0x88, 0xae, 0x40, 0x31, 0xd8, 0xa8, 0x0b, 0x0d, 0x74, 0xe6, 0x22, 0xc5, 0xf3, 0x8b, + 0x39, 0xad, 0x62, 0x9c, 0xf0, 0xfc, 0x22, 0xa6, 0x2c, 0x50, 0x05, 0xfa, 0xd9, 0x33, 0x36, 0x21, + 0xcf, 0x64, 0xde, 0xdc, 0x3a, 0x3c, 0x07, 0xe5, 0x91, 0x38, 0x18, 0x01, 0xe6, 0x8c, 0xd0, 0x3a, + 0x0c, 0xd4, 0x58, 0x2e, 0x61, 0x21, 0xc0, 0xbc, 0x2f, 0x53, 0xd7, 0xdc, 0x21, 0xc9, 0xb2, 0x50, + 0xbd, 0x32, 0x0a, 0x2c, 0x78, 0x31, 0xae, 0xa4, 0xb5, 0xbd, 0x19, 0x8a, 0x5c, 0xfb, 0xd9, 0x5c, + 0x3b, 0xe4, 0x0e, 0x17, 0x5c, 0x19, 0x05, 0x16, 0xbc, 0xd0, 0xcb, 0x50, 0xd8, 0xac, 0x89, 0x27, + 0x6a, 0x99, 0x4a, 0x67, 0x33, 0x4e, 0xca, 0xfc, 0xc0, 0xbd, 0xfd, 0x72, 0x61, 0x79, 0x01, 0x17, + 0x36, 0x6b, 0x68, 0x0d, 0x06, 0x37, 0x79, 0x64, 0x05, 0xa1, 0x57, 0x7e, 0x32, 0x3b, 0xe8, 0x43, + 0x2a, 0xf8, 0x02, 0x7f, 0xee, 0x24, 0x10, 0x58, 0x32, 0x61, 0x99, 0x26, 0x54, 0x84, 0x08, 0x11, + 0xa0, 0x6e, 0xf6, 0x70, 0x51, 0x3d, 0xb8, 0x7c, 0x19, 0xc7, 0x99, 0xc0, 0x1a, 0x47, 0x3a, 0xab, + 0x9d, 0xbb, 0xed, 0x80, 0x85, 0x1a, 0x17, 0x91, 0x8c, 0x32, 0x67, 0xf5, 0x9c, 0x24, 0xea, 0x34, + 0xab, 0x15, 0x11, 0x8e, 0x99, 0xa2, 0x1d, 0x18, 0xdd, 0x0d, 0x5b, 0xdb, 0x44, 0x2e, 0x69, 0x16, + 0xd8, 0x28, 0x47, 0x3e, 0xba, 0x29, 0x08, 0xdd, 0x20, 0x6a, 0x3b, 0x8d, 0xd4, 0x2e, 0xc4, 0x64, + 0xd9, 0x9b, 0x3a, 0x33, 0x6c, 0xf2, 0xa6, 0xdd, 0xff, 0x56, 0xdb, 0xdf, 0xd8, 0x8b, 0x88, 0x88, + 0x2b, 0x97, 0xd9, 0xfd, 0xaf, 0x73, 0x92, 0x74, 0xf7, 0x0b, 0x04, 0x96, 0x4c, 0xd0, 0x4d, 0xd1, + 0x3d, 0x6c, 0xf7, 0x9c, 0xc8, 0x8f, 0x30, 0x3b, 0x27, 0x89, 0x72, 0x3a, 0x85, 0xed, 0x96, 0x31, + 0x2b, 0xb6, 0x4b, 0xb6, 0xb6, 0xfd, 0xc8, 0xf7, 0x12, 0x3b, 0xf4, 0x64, 0xfe, 0x2e, 0x59, 0xc9, + 0xa0, 0x4f, 0xef, 0x92, 0x59, 0x54, 0x38, 0xb3, 0x2e, 0x54, 0x87, 0xb1, 0x96, 0x1f, 0x44, 0xb7, + 0xfd, 0x40, 0xce, 0x2f, 0xd4, 0x41, 0x2f, 0x66, 0x50, 0x8a, 0x1a, 0x59, 0xc8, 0x46, 0x13, 0x83, + 0x13, 0x3c, 0xd1, 0x47, 0x61, 0x30, 0xac, 0x39, 0x0d, 0xb2, 0x72, 0x7d, 0x7a, 0x2a, 0xff, 0xf8, + 0xa9, 0x72, 0x92, 0x9c, 0xd9, 0xc5, 0x03, 0x63, 0x70, 0x12, 0x2c, 0xd9, 0xa1, 0x65, 0xe8, 0x67, + 0xe9, 0x16, 0x59, 0x10, 0xc4, 0x9c, 0x40, 0xb9, 0x29, 0x07, 0x78, 0xbe, 0x37, 0x31, 0x30, 0xe6, + 0xc5, 0xe9, 0x1a, 0x10, 0xd7, 0x43, 0x3f, 0x9c, 0x3e, 0x99, 0xbf, 0x06, 0xc4, 0xad, 0xf2, 0x7a, + 0xb5, 0xd3, 0x1a, 0x50, 0x44, 0x38, 0x66, 0x4a, 0x77, 0x66, 0xba, 0x9b, 0x9e, 0xea, 0xe0, 0xb9, + 0x95, 0xbb, 0x97, 0xb2, 0x9d, 0x99, 0xee, 0xa4, 0x94, 0x85, 0xfd, 0x07, 0x83, 0x69, 0x99, 0x85, + 0x29, 0x14, 0xfe, 0x82, 0x95, 0xb2, 0x35, 0xbf, 0xbf, 0x57, 0xfd, 0xe6, 0x11, 0x5e, 0x85, 0x3e, + 0x67, 0xc1, 0xa9, 0x56, 0xe6, 0x87, 0x08, 0x01, 0xa0, 0x37, 0x35, 0x29, 0xff, 0x74, 0x15, 0x30, + 0x33, 0x1b, 0x8f, 0x73, 0x6a, 0x4a, 0x5e, 0x37, 0x8b, 0x6f, 0xfb, 0xba, 0xb9, 0x0a, 0x43, 0x35, + 0x7e, 0x15, 0xe9, 0x98, 0x5b, 0x3f, 0x79, 0xf7, 0x66, 0xa2, 0x84, 0xb8, 0xc3, 0x6c, 0x62, 0xc5, + 0x02, 0xfd, 0x88, 0x05, 0x67, 0x92, 0x4d, 0xc7, 0x84, 0xa1, 0x45, 0x94, 0x4d, 0xae, 0xcb, 0x58, + 0x16, 0xdf, 0x9f, 0x92, 0xff, 0x0d, 0xe2, 0x83, 0x6e, 0x04, 0xb8, 0x73, 0x65, 0x68, 0x31, 0x43, + 0x99, 0x32, 0x60, 0x1a, 0x90, 0x7a, 0x50, 0xa8, 0xbc, 0x00, 0x23, 0x4d, 0xbf, 0xed, 0x45, 0xc2, + 0xd1, 0x4b, 0x38, 0x9d, 0x30, 0x67, 0x8b, 0x55, 0x0d, 0x8e, 0x0d, 0xaa, 0x84, 0x1a, 0x66, 0xe8, + 0xbe, 0xd5, 0x30, 0x6f, 0xc2, 0x88, 0xa7, 0x79, 0x26, 0x0b, 0x79, 0xe0, 0x7c, 0x7e, 0x84, 0x5c, + 0xdd, 0x8f, 0x99, 0xb7, 0x52, 0x87, 0x60, 0x83, 0xdb, 0xf1, 0x7a, 0x80, 0x7d, 0xc9, 0xca, 0x10, + 0xea, 0xb9, 0x2a, 0xe6, 0x43, 0xa6, 0x2a, 0xe6, 0x7c, 0x52, 0x15, 0x93, 0x32, 0x1e, 0x18, 0x5a, + 0x98, 0xde, 0xb3, 0x3b, 0xf5, 0x1a, 0x65, 0xd3, 0x6e, 0xc0, 0xb9, 0x6e, 0xc7, 0x12, 0xf3, 0xf8, + 0xab, 0x2b, 0x53, 0x71, 0xec, 0xf1, 0x57, 0x5f, 0x59, 0xc4, 0x0c, 0xd3, 0x6b, 0xfc, 0x26, 0xfb, + 0xbf, 0x58, 0x50, 0xac, 0xf8, 0xf5, 0x63, 0xb8, 0xf0, 0x7e, 0xd8, 0xb8, 0xf0, 0x3e, 0x9c, 0x7d, + 0x20, 0xd6, 0x73, 0x4d, 0x1f, 0x4b, 0x09, 0xd3, 0xc7, 0x99, 0x3c, 0x06, 0x9d, 0x0d, 0x1d, 0x3f, + 0x5d, 0x84, 0xe1, 0x8a, 0x5f, 0x57, 0xee, 0xf6, 0xff, 0xf4, 0x7e, 0xdc, 0xed, 0x73, 0x73, 0x65, + 0x68, 0x9c, 0x99, 0xa3, 0xa0, 0x7c, 0x69, 0xfc, 0x6d, 0xe6, 0x75, 0x7f, 0x8b, 0xb8, 0x5b, 0xdb, + 0x11, 0xa9, 0x27, 0x3f, 0xe7, 0xf8, 0xbc, 0xee, 0xff, 0xa0, 0x00, 0xe3, 0x89, 0xda, 0x51, 0x03, + 0x46, 0x1b, 0xba, 0x62, 0x5d, 0xcc, 0xd3, 0xfb, 0xd2, 0xc9, 0x0b, 0xaf, 0x65, 0x0d, 0x84, 0x4d, + 0xe6, 0x68, 0x16, 0x40, 0x59, 0x9a, 0xa5, 0x7a, 0x95, 0x49, 0xfd, 0xca, 0x14, 0x1d, 0x62, 0x8d, + 0x02, 0xbd, 0x08, 0xc3, 0x91, 0xdf, 0xf2, 0x1b, 0xfe, 0xd6, 0xde, 0x55, 0x22, 0x43, 0x7b, 0x29, + 0x5f, 0xc4, 0xf5, 0x18, 0x85, 0x75, 0x3a, 0x74, 0x07, 0x26, 0x15, 0x93, 0xea, 0x11, 0x18, 0x1b, + 0x98, 0x56, 0x61, 0x2d, 0xc9, 0x11, 0xa7, 0x2b, 0xb1, 0x7f, 0xae, 0xc8, 0xbb, 0xd8, 0x8b, 0xdc, + 0x77, 0x57, 0xc3, 0x3b, 0x7b, 0x35, 0x7c, 0xdd, 0x82, 0x09, 0x5a, 0x3b, 0x73, 0xb4, 0x92, 0xc7, + 0xbc, 0x8a, 0xc9, 0x6d, 0x75, 0x88, 0xc9, 0x7d, 0x9e, 0xee, 0x9a, 0x75, 0xbf, 0x1d, 0x09, 0xdd, + 0x9d, 0xb6, 0x2d, 0x52, 0x28, 0x16, 0x58, 0x41, 0x47, 0x82, 0x40, 0x3c, 0x0e, 0xd5, 0xe9, 0x48, + 0x10, 0x60, 0x81, 0x95, 0x21, 0xbb, 0xfb, 0xb2, 0x43, 0x76, 0xf3, 0xc8, 0xab, 0xc2, 0x25, 0x47, + 0x08, 0x5c, 0x5a, 0xe4, 0x55, 0xe9, 0xab, 0x13, 0xd3, 0xd8, 0x5f, 0x2d, 0xc2, 0x48, 0xc5, 0xaf, + 0xc7, 0x56, 0xe6, 0x17, 0x0c, 0x2b, 0xf3, 0xb9, 0x84, 0x95, 0x79, 0x42, 0xa7, 0x7d, 0xd7, 0xa6, + 0xfc, 0xad, 0xb2, 0x29, 0xff, 0x9a, 0xc5, 0x46, 0x6d, 0x71, 0xad, 0xca, 0xfd, 0xf6, 0xd0, 0x25, + 0x18, 0x66, 0x1b, 0x0c, 0x7b, 0x8d, 0x2c, 0x4d, 0xaf, 0x2c, 0xdf, 0xd5, 0x5a, 0x0c, 0xc6, 0x3a, + 0x0d, 0xba, 0x00, 0x43, 0x21, 0x71, 0x82, 0xda, 0xb6, 0xda, 0x5d, 0x85, 0x9d, 0x94, 0xc3, 0xb0, + 0xc2, 0xa2, 0xd7, 0xe3, 0xa0, 0x9f, 0xc5, 0xfc, 0xd7, 0x8d, 0x7a, 0x7b, 0xf8, 0x12, 0xc9, 0x8f, + 0xf4, 0x69, 0xdf, 0x02, 0x94, 0xa6, 0xef, 0x21, 0x2c, 0x5d, 0xd9, 0x0c, 0x4b, 0x57, 0x4a, 0x85, + 0xa4, 0xfb, 0x33, 0x0b, 0xc6, 0x2a, 0x7e, 0x9d, 0x2e, 0xdd, 0xef, 0xa4, 0x75, 0xaa, 0x47, 0x3c, + 0x1e, 0xe8, 0x10, 0xf1, 0xf8, 0x31, 0xe8, 0xaf, 0xf8, 0xf5, 0x95, 0x4a, 0xa7, 0xd0, 0x02, 0xf6, + 0xdf, 0xb4, 0x60, 0xb0, 0xe2, 0xd7, 0x8f, 0xc1, 0x2c, 0xf0, 0x21, 0xd3, 0x2c, 0xf0, 0x50, 0xce, + 0xbc, 0xc9, 0xb1, 0x04, 0xfc, 0x8d, 0x3e, 0x18, 0xa5, 0xed, 0xf4, 0xb7, 0xe4, 0x50, 0x1a, 0xdd, + 0x66, 0xf5, 0xd0, 0x6d, 0x54, 0x0a, 0xf7, 0x1b, 0x0d, 0xff, 0x76, 0x72, 0x58, 0x97, 0x19, 0x14, + 0x0b, 0x2c, 0x7a, 0x06, 0x86, 0x5a, 0x01, 0xd9, 0x75, 0x7d, 0x21, 0xde, 0x6a, 0x46, 0x96, 0x8a, + 0x80, 0x63, 0x45, 0x41, 0xaf, 0x85, 0xa1, 0xeb, 0xd1, 0xa3, 0xbc, 0xe6, 0x7b, 0x75, 0xae, 0x39, + 0x2f, 0x8a, 0xb4, 0x1c, 0x1a, 0x1c, 0x1b, 0x54, 0xe8, 0x16, 0x94, 0xd8, 0x7f, 0xb6, 0xed, 0x1c, + 0x3e, 0x7b, 0xaf, 0xc8, 0x2a, 0x28, 0x18, 0xe0, 0x98, 0x17, 0x7a, 0x0e, 0x20, 0x92, 0xa1, 0xed, + 0x43, 0x11, 0x68, 0x4d, 0x5d, 0x05, 0x54, 0xd0, 0xfb, 0x10, 0x6b, 0x54, 0xe8, 0x69, 0x28, 0x45, + 0x8e, 0xdb, 0xb8, 0xe6, 0x7a, 0x24, 0x64, 0x1a, 0xf1, 0xa2, 0x4c, 0xee, 0x27, 0x80, 0x38, 0xc6, + 0x53, 0x51, 0x8c, 0x05, 0xe1, 0xe0, 0xb9, 0xcb, 0x87, 0x18, 0x35, 0x13, 0xc5, 0xae, 0x29, 0x28, + 0xd6, 0x28, 0xd0, 0x36, 0x3c, 0xe2, 0x7a, 0x2c, 0x85, 0x05, 0xa9, 0xee, 0xb8, 0xad, 0xf5, 0x6b, + 0xd5, 0x9b, 0x24, 0x70, 0x37, 0xf7, 0xe6, 0x9d, 0xda, 0x0e, 0xf1, 0x64, 0x5e, 0x56, 0x99, 0xae, + 0xfb, 0x91, 0x95, 0x0e, 0xb4, 0xb8, 0x23, 0x27, 0xfb, 0x79, 0x36, 0xdf, 0xaf, 0x57, 0xd1, 0x7b, + 0x8d, 0xad, 0xe3, 0x94, 0xbe, 0x75, 0x1c, 0xec, 0x97, 0x07, 0xae, 0x57, 0xb5, 0x18, 0x12, 0x2f, + 0xc1, 0xc9, 0x8a, 0x5f, 0xaf, 0xf8, 0x41, 0xb4, 0xec, 0x07, 0xb7, 0x9d, 0xa0, 0x2e, 0xa7, 0x57, + 0x59, 0x46, 0xd1, 0xa0, 0xfb, 0x67, 0x3f, 0xdf, 0x5d, 0x8c, 0x08, 0x19, 0xcf, 0x33, 0x89, 0xed, + 0x90, 0x6f, 0xbf, 0x6a, 0x4c, 0x76, 0x50, 0x49, 0x60, 0x2e, 0x3b, 0x11, 0x41, 0xd7, 0x59, 0xe6, + 0xf5, 0xf8, 0x18, 0x15, 0xc5, 0x9f, 0xd2, 0x32, 0xaf, 0xc7, 0xc8, 0xcc, 0x73, 0xd7, 0x2c, 0x6f, + 0x7f, 0x56, 0x54, 0xc2, 0xef, 0xe0, 0xdc, 0xbf, 0xae, 0x97, 0xd4, 0xc5, 0x32, 0x4b, 0x44, 0x21, + 0x3f, 0xbd, 0x00, 0xb7, 0x7a, 0x76, 0xcc, 0x12, 0x61, 0xbf, 0x08, 0x93, 0xf4, 0xea, 0xa7, 0xe4, + 0x28, 0xf6, 0x91, 0xdd, 0xa3, 0x79, 0xfc, 0xd7, 0x7e, 0x76, 0x0e, 0x24, 0xd2, 0x9f, 0xa0, 0x4f, + 0xc2, 0x58, 0x48, 0xae, 0xb9, 0x5e, 0xfb, 0x8e, 0x54, 0xbc, 0x74, 0x78, 0x73, 0x58, 0x5d, 0xd2, + 0x29, 0xb9, 0xfa, 0xd6, 0x84, 0xe1, 0x04, 0x37, 0xd4, 0x84, 0xb1, 0xdb, 0xae, 0x57, 0xf7, 0x6f, + 0x87, 0x92, 0xff, 0x50, 0xbe, 0x16, 0xf7, 0x16, 0xa7, 0x4c, 0xb4, 0xd1, 0xa8, 0xee, 0x96, 0xc1, + 0x0c, 0x27, 0x98, 0xd3, 0xb5, 0x16, 0xb4, 0xbd, 0xb9, 0xf0, 0x46, 0x48, 0x02, 0x91, 0xf9, 0x9f, + 0xa7, 0xe5, 0x95, 0x40, 0x1c, 0xe3, 0xe9, 0x5a, 0x63, 0x7f, 0x2e, 0x07, 0x7e, 0x9b, 0xe7, 0xda, + 0x10, 0x6b, 0x0d, 0x2b, 0x28, 0xd6, 0x28, 0xe8, 0x5e, 0xc4, 0xfe, 0xad, 0xf9, 0x1e, 0xf6, 0xfd, + 0x48, 0xee, 0x5e, 0xcc, 0x13, 0x41, 0x83, 0x63, 0x83, 0x0a, 0x2d, 0x03, 0x0a, 0xdb, 0xad, 0x56, + 0x83, 0x39, 0x33, 0x39, 0x0d, 0xc6, 0x8a, 0x7b, 0x79, 0x14, 0x79, 0xac, 0xe0, 0x6a, 0x0a, 0x8b, + 0x33, 0x4a, 0xd0, 0x63, 0x69, 0x53, 0x34, 0xb5, 0x9f, 0x35, 0x95, 0x5b, 0x7c, 0xaa, 0xbc, 0x9d, + 0x12, 0x87, 0x96, 0x60, 0x30, 0xdc, 0x0b, 0x6b, 0x91, 0x08, 0xed, 0x98, 0x93, 0x46, 0xab, 0xca, + 0x48, 0xb4, 0x2c, 0x8e, 0xbc, 0x08, 0x96, 0x65, 0x51, 0x0d, 0xa6, 0x04, 0xc7, 0x85, 0x6d, 0xc7, + 0x53, 0xf9, 0x82, 0xb8, 0x4f, 0xf7, 0xa5, 0x7b, 0xfb, 0xe5, 0x29, 0x51, 0xb3, 0x8e, 0x3e, 0xd8, + 0x2f, 0x9f, 0xaa, 0xf8, 0xf5, 0x0c, 0x0c, 0xce, 0xe2, 0xc6, 0x27, 0x5f, 0xad, 0xe6, 0x37, 0x5b, + 0x95, 0xc0, 0xdf, 0x74, 0x1b, 0xa4, 0x93, 0xd5, 0xac, 0x6a, 0x50, 0x8a, 0xc9, 0x67, 0xc0, 0x70, + 0x82, 0x9b, 0xfd, 0x59, 0x26, 0xba, 0xb1, 0x64, 0xf1, 0x51, 0x3b, 0x20, 0xa8, 0x09, 0xa3, 0x2d, + 0xb6, 0xb8, 0x45, 0x06, 0x0c, 0x31, 0xd7, 0x5f, 0xe8, 0x51, 0xfb, 0x73, 0x9b, 0xe5, 0xf5, 0x32, + 0x3c, 0xa3, 0x2a, 0x3a, 0x3b, 0x6c, 0x72, 0xb7, 0xff, 0xf5, 0x69, 0x76, 0xf8, 0x57, 0xb9, 0x4a, + 0x67, 0x50, 0x3c, 0x21, 0x11, 0xb7, 0xc8, 0x99, 0x7c, 0xdd, 0x62, 0x3c, 0x2c, 0xe2, 0x19, 0x0a, + 0x96, 0x65, 0xd1, 0x27, 0x60, 0x8c, 0x5e, 0xca, 0xd4, 0x01, 0x1c, 0x4e, 0x9f, 0xc8, 0x0f, 0xf5, + 0xa1, 0xa8, 0xf4, 0xec, 0x38, 0x7a, 0x61, 0x9c, 0x60, 0x86, 0x5e, 0x67, 0x9e, 0x48, 0x92, 0x75, + 0xa1, 0x17, 0xd6, 0xba, 0xd3, 0x91, 0x64, 0xab, 0x31, 0x41, 0x6d, 0x98, 0x4a, 0x27, 0xec, 0x0b, + 0xa7, 0xed, 0x7c, 0xe9, 0x36, 0x9d, 0x73, 0x2f, 0x4e, 0x63, 0x92, 0xc6, 0x85, 0x38, 0x8b, 0x3f, + 0xba, 0x06, 0xa3, 0x22, 0x63, 0xba, 0x98, 0xb9, 0x45, 0x43, 0xe5, 0x39, 0x8a, 0x75, 0xe4, 0x41, + 0x12, 0x80, 0xcd, 0xc2, 0x68, 0x0b, 0xce, 0x68, 0x49, 0xae, 0x2e, 0x07, 0x0e, 0xf3, 0x5b, 0x70, + 0xd9, 0x76, 0xaa, 0x89, 0x25, 0x8f, 0xde, 0xdb, 0x2f, 0x9f, 0x59, 0xef, 0x44, 0x88, 0x3b, 0xf3, + 0x41, 0xd7, 0xe1, 0x24, 0x7f, 0xa8, 0xbe, 0x48, 0x9c, 0x7a, 0xc3, 0xf5, 0x94, 0xdc, 0xc3, 0x97, + 0xfc, 0xe9, 0x7b, 0xfb, 0xe5, 0x93, 0x73, 0x59, 0x04, 0x38, 0xbb, 0x1c, 0xfa, 0x10, 0x94, 0xea, + 0x5e, 0x28, 0xfa, 0x60, 0xc0, 0xc8, 0x23, 0x56, 0x5a, 0x5c, 0xab, 0xaa, 0xef, 0x8f, 0xff, 0xe0, + 0xb8, 0x00, 0xda, 0xe2, 0x6a, 0x71, 0xa5, 0xac, 0x19, 0x4c, 0x05, 0xea, 0x4a, 0xea, 0x33, 0x8d, + 0xa7, 0xaa, 0xdc, 0x1e, 0xa4, 0x5e, 0x70, 0x18, 0xaf, 0x58, 0x0d, 0xc6, 0xe8, 0x35, 0x40, 0x22, + 0x5e, 0xfd, 0x5c, 0x8d, 0xa5, 0x57, 0x61, 0x56, 0x84, 0x21, 0xf3, 0xf1, 0x64, 0x35, 0x45, 0x81, + 0x33, 0x4a, 0xa1, 0x2b, 0x74, 0x57, 0xd1, 0xa1, 0x62, 0xd7, 0x52, 0xa9, 0x25, 0x17, 0x49, 0x2b, + 0x20, 0xcc, 0x0f, 0xcb, 0xe4, 0x88, 0x13, 0xe5, 0x50, 0x1d, 0x1e, 0x71, 0xda, 0x91, 0xcf, 0x2c, + 0x0e, 0x26, 0xe9, 0xba, 0xbf, 0x43, 0x3c, 0x66, 0xec, 0x1b, 0x9a, 0x3f, 0x47, 0x05, 0xab, 0xb9, + 0x0e, 0x74, 0xb8, 0x23, 0x17, 0x2a, 0x10, 0xab, 0x5c, 0xd2, 0x60, 0x86, 0x1f, 0xcb, 0xc8, 0x27, + 0xfd, 0x22, 0x0c, 0x6f, 0xfb, 0x61, 0xb4, 0x46, 0xa2, 0xdb, 0x7e, 0xb0, 0x23, 0xc2, 0xe8, 0xc6, + 0x41, 0xc9, 0x63, 0x14, 0xd6, 0xe9, 0xe8, 0x8d, 0x97, 0xb9, 0xa2, 0xac, 0x2c, 0x32, 0x2f, 0x80, + 0xa1, 0x78, 0x8f, 0xb9, 0xc2, 0xc1, 0x58, 0xe2, 0x25, 0xe9, 0x4a, 0x65, 0x81, 0x59, 0xf4, 0x13, + 0xa4, 0x2b, 0x95, 0x05, 0x2c, 0xf1, 0x74, 0xba, 0x86, 0xdb, 0x4e, 0x40, 0x2a, 0x81, 0x5f, 0x23, + 0xa1, 0x16, 0x0a, 0xff, 0x61, 0x1e, 0x24, 0x98, 0x4e, 0xd7, 0x6a, 0x16, 0x01, 0xce, 0x2e, 0x87, + 0x48, 0x3a, 0xc1, 0xdb, 0x58, 0xbe, 0x29, 0x26, 0x2d, 0xcf, 0xf4, 0x98, 0xe3, 0xcd, 0x83, 0x09, + 0x95, 0x5a, 0x8e, 0x87, 0x05, 0x0e, 0xa7, 0xc7, 0xd9, 0xdc, 0xee, 0x3d, 0xa6, 0xb0, 0x32, 0x6e, + 0xad, 0x24, 0x38, 0xe1, 0x14, 0x6f, 0x23, 0xc2, 0xdc, 0x44, 0xd7, 0x08, 0x73, 0x17, 0xa1, 0x14, + 0xb6, 0x37, 0xea, 0x7e, 0xd3, 0x71, 0x3d, 0x66, 0xd1, 0xd7, 0xae, 0x5e, 0x55, 0x89, 0xc0, 0x31, + 0x0d, 0x5a, 0x86, 0x21, 0x47, 0x5a, 0xae, 0x50, 0x7e, 0x4c, 0x21, 0x65, 0xaf, 0xe2, 0x61, 0x36, + 0xa4, 0xad, 0x4a, 0x95, 0x45, 0xaf, 0xc0, 0xa8, 0x78, 0x68, 0x2d, 0x52, 0xa7, 0x4e, 0x99, 0xaf, + 0xe1, 0xaa, 0x3a, 0x12, 0x9b, 0xb4, 0xe8, 0x06, 0x0c, 0x47, 0x7e, 0x83, 0x3d, 0xe9, 0xa2, 0x62, + 0xde, 0xa9, 0xfc, 0xe8, 0x78, 0xeb, 0x8a, 0x4c, 0x57, 0x1a, 0xab, 0xa2, 0x58, 0xe7, 0x83, 0xd6, + 0xf9, 0x7c, 0x67, 0x81, 0xef, 0x49, 0x28, 0x72, 0x6f, 0x9e, 0xc9, 0x73, 0xc7, 0x62, 0x64, 0xe6, + 0x72, 0x10, 0x25, 0xb1, 0xce, 0x06, 0x5d, 0x86, 0xc9, 0x56, 0xe0, 0xfa, 0x6c, 0x4e, 0x28, 0xa3, + 0xe5, 0xb4, 0x99, 0xe6, 0xaa, 0x92, 0x24, 0xc0, 0xe9, 0x32, 0xec, 0x9d, 0xbc, 0x00, 0x4e, 0x9f, + 0xe6, 0xa9, 0x3a, 0xf8, 0x4d, 0x96, 0xc3, 0xb0, 0xc2, 0xa2, 0x55, 0xb6, 0x13, 0x73, 0x25, 0xcc, + 0xf4, 0x4c, 0x7e, 0x18, 0x23, 0x5d, 0x59, 0xc3, 0x85, 0x57, 0xf5, 0x17, 0xc7, 0x1c, 0x50, 0x5d, + 0xcb, 0x90, 0x49, 0xaf, 0x00, 0xe1, 0xf4, 0x23, 0x1d, 0xfc, 0x01, 0x13, 0x97, 0xa2, 0x58, 0x20, + 0x30, 0xc0, 0x21, 0x4e, 0xf0, 0x44, 0x1f, 0x81, 0x09, 0x11, 0x7c, 0x31, 0xee, 0xa6, 0x33, 0xb1, + 0xa3, 0x3c, 0x4e, 0xe0, 0x70, 0x8a, 0x9a, 0xa7, 0xca, 0x70, 0x36, 0x1a, 0x44, 0x6c, 0x7d, 0xd7, + 0x5c, 0x6f, 0x27, 0x9c, 0x3e, 0xcb, 0xf6, 0x07, 0x91, 0x2a, 0x23, 0x89, 0xc5, 0x19, 0x25, 0xd0, + 0x3a, 0x4c, 0xb4, 0x02, 0x42, 0x9a, 0x4c, 0xd0, 0x17, 0xe7, 0x59, 0x99, 0x87, 0x89, 0xa0, 0x2d, + 0xa9, 0x24, 0x70, 0x07, 0x19, 0x30, 0x9c, 0xe2, 0x80, 0x6e, 0xc3, 0x90, 0xbf, 0x4b, 0x82, 0x6d, + 0xe2, 0xd4, 0xa7, 0xcf, 0x75, 0x78, 0xb8, 0x21, 0x0e, 0xb7, 0xeb, 0x82, 0x36, 0xe1, 0xe8, 0x20, + 0xc1, 0xdd, 0x1d, 0x1d, 0x64, 0x65, 0xe8, 0x2f, 0x5a, 0x70, 0x5a, 0xda, 0x46, 0xaa, 0x2d, 0xda, + 0xeb, 0x0b, 0xbe, 0x17, 0x46, 0x01, 0x0f, 0x6c, 0xf0, 0x68, 0xfe, 0x63, 0xff, 0xf5, 0x9c, 0x42, + 0x4a, 0x0f, 0x7c, 0x3a, 0x8f, 0x22, 0xc4, 0xf9, 0x35, 0xa2, 0x05, 0x98, 0x0c, 0x49, 0x24, 0x37, + 0xa3, 0xb9, 0x70, 0xf9, 0xf5, 0xc5, 0xb5, 0xe9, 0xc7, 0x78, 0x54, 0x06, 0xba, 0x18, 0xaa, 0x49, + 0x24, 0x4e, 0xd3, 0xa3, 0x4b, 0x50, 0xf0, 0xc3, 0xe9, 0xc7, 0x3b, 0x24, 0x55, 0xf5, 0xeb, 0xd7, + 0xab, 0xdc, 0xe1, 0xed, 0x7a, 0x15, 0x17, 0xfc, 0x50, 0xa6, 0xab, 0xa0, 0xf7, 0xb1, 0x70, 0xfa, + 0x09, 0xae, 0x35, 0x94, 0xe9, 0x2a, 0x18, 0x10, 0xc7, 0x78, 0xb4, 0x0d, 0xe3, 0xa1, 0x71, 0xef, + 0x0d, 0xa7, 0xcf, 0xb3, 0x9e, 0x7a, 0x22, 0x6f, 0xd0, 0x0c, 0x6a, 0x2d, 0xda, 0xbc, 0xc9, 0x05, + 0x27, 0xd9, 0xf2, 0xd5, 0xa5, 0x5d, 0xf0, 0xc3, 0xe9, 0x27, 0xbb, 0xac, 0x2e, 0x8d, 0x58, 0x5f, + 0x5d, 0x3a, 0x0f, 0x9c, 0xe0, 0x39, 0xf3, 0x5d, 0x30, 0x99, 0x12, 0x97, 0x0e, 0x93, 0x89, 0x69, + 0x66, 0x07, 0x46, 0x8d, 0x29, 0xf9, 0x40, 0x1d, 0x0b, 0xbe, 0x67, 0x08, 0x4a, 0xca, 0xe8, 0x8c, + 0x2e, 0x9a, 0xbe, 0x04, 0xa7, 0x93, 0xbe, 0x04, 0x43, 0x15, 0xbf, 0x6e, 0xb8, 0x0f, 0xac, 0x67, + 0xc4, 0xee, 0xcb, 0xdb, 0x00, 0x7b, 0x7f, 0xd3, 0xa0, 0x69, 0xf2, 0x8b, 0x3d, 0x3b, 0x25, 0xf4, + 0x75, 0x34, 0x0e, 0x5c, 0x86, 0x49, 0xcf, 0x67, 0x32, 0x3a, 0xa9, 0x4b, 0x01, 0x8c, 0xc9, 0x59, + 0x25, 0x3d, 0x18, 0x4e, 0x82, 0x00, 0xa7, 0xcb, 0xd0, 0x0a, 0xb9, 0xa0, 0x94, 0xb4, 0x46, 0x70, + 0x39, 0x0a, 0x0b, 0x2c, 0x7a, 0x0c, 0xfa, 0x5b, 0x7e, 0x7d, 0xa5, 0x22, 0xe4, 0x73, 0x2d, 0x62, + 0x6c, 0x7d, 0xa5, 0x82, 0x39, 0x0e, 0xcd, 0xc1, 0x00, 0xfb, 0x11, 0x4e, 0x8f, 0xe4, 0x47, 0x3d, + 0x61, 0x25, 0xb4, 0x3c, 0x57, 0xac, 0x00, 0x16, 0x05, 0x99, 0x56, 0x94, 0x5e, 0x6a, 0x98, 0x56, + 0x74, 0xf0, 0x3e, 0xb5, 0xa2, 0x92, 0x01, 0x8e, 0x79, 0xa1, 0x3b, 0x70, 0xd2, 0xb8, 0x48, 0xf2, + 0x29, 0x42, 0x42, 0x11, 0x79, 0xe1, 0xb1, 0x8e, 0x37, 0x48, 0xe1, 0xc4, 0x70, 0x46, 0x34, 0xfa, + 0xe4, 0x4a, 0x16, 0x27, 0x9c, 0x5d, 0x01, 0x6a, 0xc0, 0x64, 0x2d, 0x55, 0xeb, 0x50, 0xef, 0xb5, + 0xaa, 0x01, 0x4d, 0xd7, 0x98, 0x66, 0x8c, 0x5e, 0x81, 0xa1, 0xb7, 0xfc, 0x90, 0x9d, 0x6d, 0xe2, + 0x4e, 0x21, 0x9f, 0xed, 0x0f, 0xbd, 0x7e, 0xbd, 0xca, 0xe0, 0x07, 0xfb, 0xe5, 0xe1, 0x8a, 0x5f, + 0x97, 0x7f, 0xb1, 0x2a, 0x80, 0x7e, 0xc0, 0x82, 0x99, 0xf4, 0x4d, 0x55, 0x35, 0x7a, 0xb4, 0xf7, + 0x46, 0xdb, 0xa2, 0xd2, 0x99, 0xa5, 0x5c, 0x76, 0xb8, 0x43, 0x55, 0xe8, 0x83, 0x74, 0x21, 0x84, + 0xee, 0x5d, 0x22, 0x92, 0x84, 0x3e, 0x1a, 0x2f, 0x04, 0x0a, 0x3d, 0xd8, 0x2f, 0x8f, 0xf3, 0x2d, + 0x2d, 0x7e, 0x37, 0x23, 0x0a, 0xd8, 0xbf, 0x6c, 0x31, 0xb5, 0xac, 0x80, 0x92, 0xb0, 0xdd, 0x38, + 0x8e, 0xcc, 0xc0, 0x4b, 0x86, 0xc9, 0xf3, 0xbe, 0xfd, 0x61, 0xfe, 0x89, 0xc5, 0xfc, 0x61, 0x8e, + 0xf1, 0xe1, 0xcb, 0xeb, 0x30, 0x14, 0xc9, 0x8c, 0xcd, 0x1d, 0x92, 0x19, 0x6b, 0x8d, 0x62, 0x3e, + 0x41, 0xea, 0x72, 0xa0, 0x92, 0x33, 0x2b, 0x36, 0xf6, 0x3f, 0xe4, 0x23, 0x20, 0x31, 0xc7, 0x60, + 0x59, 0x5a, 0x34, 0x2d, 0x4b, 0xe5, 0x2e, 0x5f, 0x90, 0x63, 0x61, 0xfa, 0x07, 0x66, 0xbb, 0x99, + 0x52, 0xec, 0x9d, 0xee, 0x88, 0x65, 0x7f, 0xde, 0x02, 0x88, 0x63, 0x79, 0xf7, 0x90, 0x93, 0xef, + 0x25, 0x7a, 0x1d, 0xf0, 0x23, 0xbf, 0xe6, 0x37, 0x84, 0xdd, 0xf4, 0x91, 0xd8, 0xb8, 0xc5, 0xe1, + 0x07, 0xda, 0x6f, 0xac, 0xa8, 0x51, 0x59, 0x46, 0x0e, 0x2c, 0xc6, 0xe6, 0x56, 0x23, 0x6a, 0xe0, + 0x17, 0x2d, 0x38, 0x91, 0xe5, 0x45, 0x4d, 0x2f, 0x97, 0x5c, 0x3d, 0xa8, 0x9c, 0xe4, 0xd4, 0x68, + 0xde, 0x14, 0x70, 0xac, 0x28, 0x7a, 0x4e, 0x76, 0x78, 0xb8, 0x20, 0xda, 0xd7, 0x61, 0xb4, 0x12, + 0x10, 0xed, 0x5c, 0x7e, 0x95, 0x47, 0xa3, 0xe0, 0xed, 0x79, 0xe6, 0xd0, 0x91, 0x28, 0xec, 0x2f, + 0x17, 0xe0, 0x04, 0xf7, 0x35, 0x99, 0xdb, 0xf5, 0xdd, 0x7a, 0xc5, 0xaf, 0x8b, 0xb7, 0x72, 0x6f, + 0xc0, 0x48, 0x4b, 0xd3, 0xe9, 0x76, 0x0a, 0x08, 0xab, 0xeb, 0x7e, 0x63, 0x2d, 0x94, 0x0e, 0xc5, + 0x06, 0x2f, 0x54, 0x87, 0x11, 0xb2, 0xeb, 0xd6, 0x94, 0xc3, 0x42, 0xe1, 0xd0, 0x67, 0xa4, 0xaa, + 0x65, 0x49, 0xe3, 0x83, 0x0d, 0xae, 0x0f, 0x20, 0x05, 0xb9, 0xfd, 0x63, 0x16, 0x3c, 0x94, 0x13, + 0x3e, 0x96, 0x56, 0x77, 0x9b, 0x79, 0xf5, 0x88, 0x69, 0xab, 0xaa, 0xe3, 0xbe, 0x3e, 0x58, 0x60, + 0xd1, 0x47, 0x01, 0xb8, 0xaf, 0x0e, 0xf1, 0x6a, 0x5d, 0xe3, 0x6c, 0x1a, 0x21, 0x02, 0xb5, 0x68, + 0x6f, 0xb2, 0x3c, 0xd6, 0x78, 0xd9, 0x5f, 0xec, 0x83, 0x7e, 0xe6, 0x1b, 0x82, 0x2a, 0x30, 0xb8, + 0xcd, 0x13, 0x02, 0x75, 0x1c, 0x37, 0x4a, 0x2b, 0x73, 0x0c, 0xc5, 0xe3, 0xa6, 0x41, 0xb1, 0x64, + 0x83, 0x56, 0x61, 0x8a, 0xe7, 0x65, 0x6a, 0x2c, 0x92, 0x86, 0xb3, 0x27, 0xd5, 0xa5, 0x3c, 0x89, + 0xb0, 0x52, 0x1b, 0xaf, 0xa4, 0x49, 0x70, 0x56, 0x39, 0xf4, 0x2a, 0x8c, 0xd1, 0xeb, 0xab, 0xdf, + 0x8e, 0x24, 0x27, 0x9e, 0x91, 0x49, 0x49, 0xf4, 0xeb, 0x06, 0x16, 0x27, 0xa8, 0xd1, 0x2b, 0x30, + 0xda, 0x4a, 0x29, 0x86, 0xfb, 0x63, 0x0d, 0x8a, 0xa9, 0x0c, 0x36, 0x69, 0x99, 0x23, 0x75, 0x9b, + 0xb9, 0x8d, 0xaf, 0x6f, 0x07, 0x24, 0xdc, 0xf6, 0x1b, 0x75, 0x26, 0x39, 0xf6, 0x6b, 0x8e, 0xd4, + 0x09, 0x3c, 0x4e, 0x95, 0xa0, 0x5c, 0x36, 0x1d, 0xb7, 0xd1, 0x0e, 0x48, 0xcc, 0x65, 0xc0, 0xe4, + 0xb2, 0x9c, 0xc0, 0xe3, 0x54, 0x89, 0xee, 0x1a, 0xef, 0xc1, 0xa3, 0xd1, 0x78, 0xdb, 0x3f, 0x53, + 0x00, 0x63, 0x68, 0xbf, 0x73, 0x33, 0x45, 0xd1, 0x2f, 0xdb, 0x0a, 0x5a, 0x35, 0xe1, 0x07, 0x95, + 0xf9, 0x65, 0x71, 0x02, 0x58, 0xfe, 0x65, 0xf4, 0x3f, 0x66, 0xa5, 0xe8, 0x1a, 0x3f, 0x59, 0x09, + 0x7c, 0x7a, 0xc8, 0xc9, 0x78, 0x65, 0xea, 0xbd, 0xc2, 0xa0, 0x7c, 0xcb, 0xdd, 0x21, 0xb2, 0xa7, + 0xf0, 0xe8, 0xe6, 0x1c, 0x0c, 0x97, 0xa1, 0xaa, 0x08, 0xaa, 0x20, 0xb9, 0xa0, 0x4b, 0x30, 0x2c, + 0xd2, 0xff, 0x30, 0xb7, 0x7a, 0xbe, 0x98, 0x98, 0x8b, 0xd3, 0x62, 0x0c, 0xc6, 0x3a, 0x8d, 0xfd, + 0x83, 0x05, 0x98, 0xca, 0x78, 0x17, 0xc5, 0x8f, 0x91, 0x2d, 0x37, 0x8c, 0x54, 0x8e, 0x59, 0xed, + 0x18, 0xe1, 0x70, 0xac, 0x28, 0xe8, 0x5e, 0xc5, 0x0f, 0xaa, 0xe4, 0xe1, 0x24, 0xde, 0x1d, 0x08, + 0xec, 0x21, 0xb3, 0xb5, 0x9e, 0x83, 0xbe, 0x76, 0x48, 0x64, 0x4c, 0x5e, 0x75, 0x6c, 0x33, 0x73, + 0x30, 0xc3, 0xd0, 0x1b, 0xd8, 0x96, 0xb2, 0xac, 0x6a, 0x37, 0x30, 0x6e, 0x5b, 0xe5, 0x38, 0xda, + 0xb8, 0x88, 0x78, 0x8e, 0x17, 0x89, 0x7b, 0x5a, 0x1c, 0x5c, 0x92, 0x41, 0xb1, 0xc0, 0xda, 0x5f, + 0x28, 0xc2, 0xe9, 0xdc, 0x97, 0x92, 0xb4, 0xe9, 0x4d, 0xdf, 0x73, 0x23, 0x5f, 0xf9, 0x8e, 0xf1, + 0x80, 0x92, 0xa4, 0xb5, 0xbd, 0x2a, 0xe0, 0x58, 0x51, 0xa0, 0xf3, 0xd0, 0xcf, 0x94, 0xc9, 0xa9, + 0x6c, 0xbb, 0xf3, 0x8b, 0x3c, 0xc2, 0x18, 0x47, 0xf7, 0x9c, 0x20, 0xfd, 0x31, 0x2a, 0xc1, 0xf8, + 0x8d, 0xe4, 0x81, 0x42, 0x9b, 0xeb, 0xfb, 0x0d, 0xcc, 0x90, 0xe8, 0x09, 0xd1, 0x5f, 0x09, 0x67, + 0x29, 0xec, 0xd4, 0xfd, 0x50, 0xeb, 0xb4, 0xa7, 0x60, 0x70, 0x87, 0xec, 0x05, 0xae, 0xb7, 0x95, + 0x74, 0xa2, 0xbb, 0xca, 0xc1, 0x58, 0xe2, 0xcd, 0xf4, 0x90, 0x83, 0x47, 0x9d, 0xd9, 0x7c, 0xa8, + 0xab, 0x78, 0xf2, 0xc3, 0x45, 0x18, 0xc7, 0xf3, 0x8b, 0xef, 0x0e, 0xc4, 0x8d, 0xf4, 0x40, 0x1c, + 0x75, 0x66, 0xf3, 0xee, 0xa3, 0xf1, 0x0b, 0x16, 0x8c, 0xb3, 0x24, 0x44, 0x22, 0x1e, 0x82, 0xeb, + 0x7b, 0xc7, 0x70, 0x15, 0x78, 0x0c, 0xfa, 0x03, 0x5a, 0x69, 0x32, 0xcd, 0x2e, 0x6b, 0x09, 0xe6, + 0x38, 0xf4, 0x08, 0xf4, 0xb1, 0x26, 0xd0, 0xc1, 0x1b, 0xe1, 0x5b, 0xf0, 0xa2, 0x13, 0x39, 0x98, + 0x41, 0x59, 0x7c, 0x2d, 0x4c, 0x5a, 0x0d, 0x97, 0x37, 0x3a, 0x36, 0xf5, 0xbf, 0x33, 0x62, 0x28, + 0x64, 0x36, 0xed, 0xed, 0xc5, 0xd7, 0xca, 0x66, 0xd9, 0xf9, 0x9a, 0xfd, 0xc7, 0x05, 0x38, 0x9b, + 0x59, 0xae, 0xe7, 0xf8, 0x5a, 0x9d, 0x4b, 0x3f, 0xc8, 0x34, 0x33, 0xc5, 0x63, 0x74, 0x51, 0xee, + 0xeb, 0x55, 0xfa, 0xef, 0xef, 0x21, 0xec, 0x55, 0x66, 0x97, 0xbd, 0x43, 0xc2, 0x5e, 0x65, 0xb6, + 0x2d, 0x47, 0x4d, 0xf0, 0xe7, 0x85, 0x9c, 0x6f, 0x61, 0x0a, 0x83, 0x0b, 0x74, 0x9f, 0x61, 0xc8, + 0x50, 0x5e, 0xc2, 0xf9, 0x1e, 0xc3, 0x61, 0x58, 0x61, 0xd1, 0x1c, 0x8c, 0x37, 0x5d, 0x8f, 0x6e, + 0x3e, 0x7b, 0xa6, 0x28, 0xae, 0x6c, 0x00, 0xab, 0x26, 0x1a, 0x27, 0xe9, 0x91, 0xab, 0x85, 0xc4, + 0xe2, 0x5f, 0xf7, 0xca, 0xa1, 0x56, 0xdd, 0xac, 0xe9, 0x06, 0xa1, 0x7a, 0x31, 0x23, 0x3c, 0xd6, + 0xaa, 0xa6, 0x27, 0x2a, 0xf6, 0xae, 0x27, 0x1a, 0xc9, 0xd6, 0x11, 0xcd, 0xbc, 0x02, 0xa3, 0xf7, + 0x6d, 0x53, 0xb0, 0xbf, 0x5e, 0x84, 0x87, 0x3b, 0x2c, 0x7b, 0xbe, 0xd7, 0x1b, 0x63, 0xa0, 0xed, + 0xf5, 0xa9, 0x71, 0xa8, 0xc0, 0x89, 0xcd, 0x76, 0xa3, 0xb1, 0xc7, 0x5e, 0xee, 0x90, 0xba, 0xa4, + 0x10, 0x32, 0xa5, 0x54, 0x8e, 0x9c, 0x58, 0xce, 0xa0, 0xc1, 0x99, 0x25, 0xe9, 0x15, 0x8b, 0x9e, + 0x24, 0x7b, 0x8a, 0x55, 0xe2, 0x8a, 0x85, 0x75, 0x24, 0x36, 0x69, 0xd1, 0x65, 0x98, 0x74, 0x76, + 0x1d, 0x97, 0xc7, 0x15, 0x97, 0x0c, 0xf8, 0x1d, 0x4b, 0xa9, 0x82, 0xe7, 0x92, 0x04, 0x38, 0x5d, + 0x06, 0xbd, 0x06, 0xc8, 0xdf, 0x60, 0xfe, 0xfd, 0xf5, 0xcb, 0xc4, 0x13, 0xd6, 0x6a, 0x36, 0x76, + 0xc5, 0x78, 0x4b, 0xb8, 0x9e, 0xa2, 0xc0, 0x19, 0xa5, 0x12, 0xf1, 0x9f, 0x06, 0xf2, 0xe3, 0x3f, + 0x75, 0xde, 0x17, 0xbb, 0x66, 0x38, 0xba, 0x04, 0xa3, 0x87, 0xf4, 0x5a, 0xb5, 0xff, 0x83, 0x45, + 0x4f, 0x3c, 0x5e, 0xc6, 0x0c, 0xae, 0xfa, 0x0a, 0x73, 0xab, 0xe5, 0x9a, 0x65, 0x2d, 0xc0, 0xce, + 0x49, 0xcd, 0xad, 0x36, 0x46, 0x62, 0x93, 0x96, 0xcf, 0x21, 0xcd, 0x1d, 0xd6, 0xb8, 0x15, 0x88, + 0x08, 0x70, 0x8a, 0x02, 0x7d, 0x0c, 0x06, 0xeb, 0xee, 0xae, 0x1b, 0x0a, 0xe5, 0xd8, 0xa1, 0x8d, + 0x58, 0xf1, 0xd6, 0xb9, 0xc8, 0xd9, 0x60, 0xc9, 0xcf, 0xfe, 0xe1, 0x42, 0xdc, 0x27, 0xaf, 0xb7, + 0xfd, 0xc8, 0x39, 0x86, 0x93, 0xfc, 0xb2, 0x71, 0x92, 0x3f, 0xd1, 0x29, 0x0c, 0x1e, 0x6b, 0x52, + 0xee, 0x09, 0x7e, 0x3d, 0x71, 0x82, 0x3f, 0xd9, 0x9d, 0x55, 0xe7, 0x93, 0xfb, 0x1f, 0x59, 0x30, + 0x69, 0xd0, 0x1f, 0xc3, 0x01, 0xb2, 0x6c, 0x1e, 0x20, 0x8f, 0x76, 0xfd, 0x86, 0x9c, 0x83, 0xe3, + 0xfb, 0x8a, 0x89, 0xb6, 0xb3, 0x03, 0xe3, 0x2d, 0xe8, 0xdb, 0x76, 0x82, 0x7a, 0xa7, 0xb4, 0x1f, + 0xa9, 0x42, 0xb3, 0x57, 0x9c, 0x40, 0x58, 0xf8, 0x9f, 0x91, 0xbd, 0x4e, 0x41, 0x5d, 0xad, 0xfb, + 0xac, 0x2a, 0xf4, 0x12, 0x0c, 0x84, 0x35, 0xbf, 0xa5, 0x9e, 0xfa, 0x9c, 0x63, 0x1d, 0xcd, 0x20, + 0x07, 0xfb, 0x65, 0x64, 0x56, 0x47, 0xc1, 0x58, 0xd0, 0xa3, 0x37, 0x60, 0x94, 0xfd, 0x52, 0xee, + 0x76, 0xc5, 0x7c, 0x0d, 0x46, 0x55, 0x27, 0xe4, 0xbe, 0xa8, 0x06, 0x08, 0x9b, 0xac, 0x66, 0xb6, + 0xa0, 0xa4, 0x3e, 0xeb, 0x81, 0x5a, 0x89, 0xff, 0x6d, 0x11, 0xa6, 0x32, 0xe6, 0x1c, 0x0a, 0x8d, + 0x91, 0xb8, 0xd4, 0xe3, 0x54, 0x7d, 0x9b, 0x63, 0x11, 0xb2, 0x0b, 0x54, 0x5d, 0xcc, 0xad, 0x9e, + 0x2b, 0xbd, 0x11, 0x92, 0x64, 0xa5, 0x14, 0xd4, 0xbd, 0x52, 0x5a, 0xd9, 0xb1, 0x75, 0x35, 0xad, + 0x48, 0xb5, 0xf4, 0x81, 0x8e, 0xe9, 0xaf, 0xf5, 0xc1, 0x89, 0xac, 0xc8, 0x9c, 0xe8, 0x33, 0x89, + 0xa4, 0xb3, 0x2f, 0xf4, 0x1a, 0xd3, 0x93, 0x67, 0xa2, 0x15, 0x11, 0x03, 0x67, 0xcd, 0x34, 0xb4, + 0x5d, 0xbb, 0x59, 0xd4, 0xc9, 0x62, 0x96, 0x04, 0x3c, 0x59, 0xb0, 0xdc, 0x3e, 0xde, 0xdf, 0x73, + 0x03, 0x44, 0x96, 0xe1, 0x30, 0xe1, 0xca, 0x23, 0xc1, 0xdd, 0x5d, 0x79, 0x64, 0xcd, 0x68, 0x05, + 0x06, 0x6a, 0xdc, 0x47, 0xa4, 0xd8, 0x7d, 0x0b, 0xe3, 0x0e, 0x22, 0x6a, 0x03, 0x16, 0x8e, 0x21, + 0x82, 0xc1, 0x8c, 0x0b, 0xc3, 0x5a, 0xc7, 0x3c, 0xd0, 0xc9, 0xb3, 0x43, 0x0f, 0x3e, 0xad, 0x0b, + 0x1e, 0xe8, 0x04, 0xfa, 0x31, 0x0b, 0x12, 0x0f, 0x45, 0x94, 0x52, 0xce, 0xca, 0x55, 0xca, 0x9d, + 0x83, 0xbe, 0xc0, 0x6f, 0x90, 0x64, 0xa2, 0x57, 0xec, 0x37, 0x08, 0x66, 0x18, 0x4a, 0x11, 0xc5, + 0xaa, 0x96, 0x11, 0xfd, 0x1a, 0x29, 0x2e, 0x88, 0x8f, 0x41, 0x7f, 0x83, 0xec, 0x92, 0x46, 0x32, + 0x1f, 0xd7, 0x35, 0x0a, 0xc4, 0x1c, 0x67, 0xff, 0x42, 0x1f, 0x9c, 0xe9, 0x18, 0x40, 0x88, 0x5e, + 0xc6, 0xb6, 0x9c, 0x88, 0xdc, 0x76, 0xf6, 0x92, 0x89, 0x73, 0x2e, 0x73, 0x30, 0x96, 0x78, 0xf6, + 0x6a, 0x91, 0xc7, 0xbf, 0x4f, 0xa8, 0x30, 0x45, 0xd8, 0x7b, 0x81, 0x35, 0x55, 0x62, 0xc5, 0xa3, + 0x50, 0x89, 0x3d, 0x07, 0x10, 0x86, 0x0d, 0xee, 0x4e, 0x57, 0x17, 0xcf, 0x21, 0xe3, 0x3c, 0x09, + 0xd5, 0x6b, 0x02, 0x83, 0x35, 0x2a, 0xb4, 0x08, 0x13, 0xad, 0xc0, 0x8f, 0xb8, 0x46, 0x78, 0x91, + 0x7b, 0x9c, 0xf6, 0x9b, 0xb1, 0x5b, 0x2a, 0x09, 0x3c, 0x4e, 0x95, 0x40, 0x2f, 0xc2, 0xb0, 0x88, + 0xe7, 0x52, 0xf1, 0xfd, 0x86, 0x50, 0x42, 0x29, 0x27, 0xcc, 0x6a, 0x8c, 0xc2, 0x3a, 0x9d, 0x56, + 0x8c, 0xa9, 0x99, 0x07, 0x33, 0x8b, 0x71, 0x55, 0xb3, 0x46, 0x97, 0x08, 0xf8, 0x3b, 0xd4, 0x53, + 0xc0, 0xdf, 0x58, 0x2d, 0x57, 0xea, 0xd9, 0xea, 0x09, 0x5d, 0x15, 0x59, 0x5f, 0xe9, 0x83, 0x29, + 0x31, 0x71, 0x1e, 0xf4, 0x74, 0xb9, 0x91, 0x9e, 0x2e, 0x47, 0xa1, 0xb8, 0x7b, 0x77, 0xce, 0x1c, + 0xf7, 0x9c, 0xf9, 0x11, 0x0b, 0x4c, 0x49, 0x0d, 0xfd, 0x7f, 0xb9, 0x99, 0xc7, 0x5e, 0xcc, 0x95, + 0xfc, 0x94, 0xc3, 0xe1, 0xdb, 0xcc, 0x41, 0x66, 0xff, 0x3b, 0x0b, 0x1e, 0xed, 0xca, 0x11, 0x2d, + 0x41, 0x89, 0x89, 0x93, 0xda, 0x45, 0xef, 0x49, 0xe5, 0x91, 0x2e, 0x11, 0x39, 0xd2, 0x6d, 0x5c, + 0x12, 0x2d, 0xa5, 0x52, 0xbc, 0x3d, 0x95, 0x91, 0xe2, 0xed, 0xa4, 0xd1, 0x3d, 0xf7, 0x99, 0xe3, + 0xed, 0x87, 0xe8, 0x89, 0x63, 0xbc, 0x06, 0x43, 0xef, 0x37, 0x94, 0x8e, 0x76, 0x42, 0xe9, 0x88, + 0x4c, 0x6a, 0xed, 0x0c, 0xf9, 0x08, 0x4c, 0xb0, 0x40, 0x6f, 0xec, 0x7d, 0x84, 0x78, 0xa7, 0x56, + 0x88, 0x7d, 0xa0, 0xaf, 0x25, 0x70, 0x38, 0x45, 0x6d, 0xff, 0x51, 0x11, 0x06, 0xf8, 0xf2, 0x3b, + 0x86, 0xeb, 0xe5, 0xd3, 0x50, 0x72, 0x9b, 0xcd, 0x36, 0xcf, 0xda, 0xd5, 0x1f, 0x7b, 0xd4, 0xae, + 0x48, 0x20, 0x8e, 0xf1, 0x68, 0x59, 0xe8, 0xbb, 0x3b, 0xc4, 0x92, 0xe5, 0x0d, 0x9f, 0x5d, 0x74, + 0x22, 0x87, 0xcb, 0x4a, 0xea, 0x9c, 0x8d, 0x35, 0xe3, 0xe8, 0x93, 0x00, 0x61, 0x14, 0xb8, 0xde, + 0x16, 0x85, 0x89, 0x10, 0xd6, 0xef, 0xed, 0xc0, 0xad, 0xaa, 0x88, 0x39, 0xcf, 0x78, 0xcf, 0x51, + 0x08, 0xac, 0x71, 0x44, 0xb3, 0xc6, 0x49, 0x3f, 0x93, 0x18, 0x3b, 0xe0, 0x5c, 0xe3, 0x31, 0x9b, + 0xf9, 0x00, 0x94, 0x14, 0xf3, 0x6e, 0xda, 0xaf, 0x11, 0x5d, 0x2c, 0xfa, 0x30, 0x8c, 0x27, 0xda, + 0x76, 0x28, 0xe5, 0xd9, 0x2f, 0x5a, 0x30, 0xce, 0x1b, 0xb3, 0xe4, 0xed, 0x8a, 0xd3, 0xe0, 0x2e, + 0x9c, 0x68, 0x64, 0xec, 0xca, 0x62, 0xf8, 0x7b, 0xdf, 0xc5, 0x95, 0xb2, 0x2c, 0x0b, 0x8b, 0x33, + 0xeb, 0x40, 0x17, 0xe8, 0x8a, 0xa3, 0xbb, 0xae, 0xd3, 0x10, 0xcf, 0xf2, 0x47, 0xf8, 0x6a, 0xe3, + 0x30, 0xac, 0xb0, 0xf6, 0xef, 0x59, 0x30, 0xc9, 0x5b, 0x7e, 0x95, 0xec, 0xa9, 0xbd, 0xe9, 0x5b, + 0xd9, 0x76, 0x91, 0x2f, 0xb2, 0x90, 0x93, 0x2f, 0x52, 0xff, 0xb4, 0x62, 0xc7, 0x4f, 0xfb, 0xb2, + 0x05, 0x62, 0x86, 0x1c, 0x83, 0x3e, 0xe3, 0xbb, 0x4c, 0x7d, 0xc6, 0x4c, 0xfe, 0x22, 0xc8, 0x51, + 0x64, 0xfc, 0x99, 0x05, 0x13, 0x9c, 0x20, 0xb6, 0xd5, 0x7f, 0x4b, 0xc7, 0xa1, 0x97, 0xac, 0xf2, + 0x57, 0xc9, 0xde, 0xba, 0x5f, 0x71, 0xa2, 0xed, 0xec, 0x8f, 0x32, 0x06, 0xab, 0xaf, 0xe3, 0x60, + 0xd5, 0xe5, 0x02, 0x32, 0xd2, 0x29, 0x75, 0x79, 0x5c, 0x7f, 0xd8, 0x74, 0x4a, 0xf6, 0x37, 0x2d, + 0x40, 0xbc, 0x1a, 0x43, 0x70, 0xa3, 0xe2, 0x10, 0x83, 0x6a, 0x07, 0x5d, 0xbc, 0x35, 0x29, 0x0c, + 0xd6, 0xa8, 0x8e, 0xa4, 0x7b, 0x12, 0x0e, 0x17, 0xc5, 0xee, 0x0e, 0x17, 0x87, 0xe8, 0xd1, 0x7f, + 0x31, 0x00, 0xc9, 0x17, 0x71, 0xe8, 0x26, 0x8c, 0xd4, 0x9c, 0x96, 0xb3, 0xe1, 0x36, 0xdc, 0xc8, + 0x25, 0x61, 0x27, 0x6f, 0xac, 0x05, 0x8d, 0x4e, 0x98, 0xc8, 0x35, 0x08, 0x36, 0xf8, 0xa0, 0x59, + 0x80, 0x56, 0xe0, 0xee, 0xba, 0x0d, 0xb2, 0xc5, 0xd4, 0x2e, 0x2c, 0x10, 0x08, 0x77, 0x0d, 0x93, + 0x50, 0xac, 0x51, 0x64, 0x84, 0x1f, 0x28, 0x3e, 0xe0, 0xf0, 0x03, 0x70, 0x6c, 0xe1, 0x07, 0xfa, + 0x0e, 0x15, 0x7e, 0x60, 0xe8, 0xd0, 0xe1, 0x07, 0xfa, 0x7b, 0x0a, 0x3f, 0x80, 0xe1, 0x94, 0x94, + 0x3d, 0xe9, 0xff, 0x65, 0xb7, 0x41, 0xc4, 0x85, 0x83, 0x47, 0x2f, 0x99, 0xb9, 0xb7, 0x5f, 0x3e, + 0x85, 0x33, 0x29, 0x70, 0x4e, 0x49, 0xf4, 0x51, 0x98, 0x76, 0x1a, 0x0d, 0xff, 0xb6, 0x1a, 0xd4, + 0xa5, 0xb0, 0xe6, 0x34, 0xb8, 0x09, 0x64, 0x90, 0x71, 0x7d, 0xe4, 0xde, 0x7e, 0x79, 0x7a, 0x2e, + 0x87, 0x06, 0xe7, 0x96, 0x46, 0x1f, 0x82, 0x52, 0x2b, 0xf0, 0x6b, 0xab, 0xda, 0xb3, 0xdd, 0xb3, + 0xb4, 0x03, 0x2b, 0x12, 0x78, 0xb0, 0x5f, 0x1e, 0x55, 0x7f, 0xd8, 0x81, 0x1f, 0x17, 0xc8, 0x88, + 0x27, 0x30, 0x7c, 0xa4, 0xf1, 0x04, 0x76, 0x60, 0xaa, 0x4a, 0x02, 0xd7, 0x69, 0xb8, 0x77, 0xa9, + 0xbc, 0x2c, 0xf7, 0xa7, 0x75, 0x28, 0x05, 0x89, 0x1d, 0xb9, 0xa7, 0xf8, 0xae, 0x5a, 0x5e, 0x1b, + 0xb9, 0x03, 0xc7, 0x8c, 0xec, 0xff, 0x65, 0xc1, 0xa0, 0x78, 0x01, 0x77, 0x0c, 0x52, 0xe3, 0x9c, + 0x61, 0x94, 0x28, 0x67, 0x77, 0x18, 0x6b, 0x4c, 0xae, 0x39, 0x62, 0x25, 0x61, 0x8e, 0x78, 0xb4, + 0x13, 0x93, 0xce, 0x86, 0x88, 0xbf, 0x5e, 0xa4, 0xd2, 0xbb, 0xf1, 0x16, 0xfb, 0xc1, 0x77, 0xc1, + 0x1a, 0x0c, 0x86, 0xe2, 0x2d, 0x70, 0x21, 0xff, 0x31, 0x46, 0x72, 0x10, 0x63, 0x2f, 0x3a, 0xf1, + 0xfa, 0x57, 0x32, 0xc9, 0x7c, 0x64, 0x5c, 0x7c, 0x80, 0x8f, 0x8c, 0xbb, 0xbd, 0x56, 0xef, 0x3b, + 0x8a, 0xd7, 0xea, 0xf6, 0xd7, 0xd8, 0xc9, 0xa9, 0xc3, 0x8f, 0x41, 0xa8, 0xba, 0x6c, 0x9e, 0xb1, + 0x76, 0x87, 0x99, 0x25, 0x1a, 0x95, 0x23, 0x5c, 0xfd, 0xbc, 0x05, 0x67, 0x32, 0xbe, 0x4a, 0x93, + 0xb4, 0x9e, 0x81, 0x21, 0xa7, 0x5d, 0x77, 0xd5, 0x5a, 0xd6, 0x4c, 0x93, 0x73, 0x02, 0x8e, 0x15, + 0x05, 0x5a, 0x80, 0x49, 0x72, 0xa7, 0xe5, 0x72, 0x43, 0xae, 0xee, 0x7c, 0x5c, 0xe4, 0xcf, 0x26, + 0x97, 0x92, 0x48, 0x9c, 0xa6, 0x57, 0x71, 0x8d, 0x8a, 0xb9, 0x71, 0x8d, 0xfe, 0x8e, 0x05, 0xc3, + 0xea, 0x35, 0xec, 0x03, 0xef, 0xed, 0x8f, 0x98, 0xbd, 0xfd, 0x70, 0x87, 0xde, 0xce, 0xe9, 0xe6, + 0xdf, 0x29, 0xa8, 0xf6, 0x56, 0xfc, 0x20, 0xea, 0x41, 0x82, 0xbb, 0xff, 0x87, 0x13, 0x97, 0x60, + 0xd8, 0x69, 0xb5, 0x24, 0x42, 0x7a, 0xc0, 0xb1, 0x68, 0xdd, 0x31, 0x18, 0xeb, 0x34, 0xea, 0x1d, + 0x47, 0x31, 0xf7, 0x1d, 0x47, 0x1d, 0x20, 0x72, 0x82, 0x2d, 0x12, 0x51, 0x98, 0x70, 0xd8, 0xcd, + 0xdf, 0x6f, 0xda, 0x91, 0xdb, 0x98, 0x75, 0xbd, 0x28, 0x8c, 0x82, 0xd9, 0x15, 0x2f, 0xba, 0x1e, + 0xf0, 0x2b, 0xa4, 0x16, 0x19, 0x4c, 0xf1, 0xc2, 0x1a, 0x5f, 0x19, 0xf9, 0x81, 0xd5, 0xd1, 0x6f, + 0xba, 0x52, 0xac, 0x09, 0x38, 0x56, 0x14, 0xf6, 0x07, 0xd8, 0xe9, 0xc3, 0xfa, 0xf4, 0x70, 0x51, + 0xb1, 0x7e, 0x6a, 0x44, 0x8d, 0x06, 0x33, 0x8a, 0x2e, 0xea, 0xb1, 0xb7, 0x3a, 0x6f, 0xf6, 0xb4, + 0x62, 0xfd, 0x41, 0x62, 0x1c, 0xa0, 0x0b, 0x7d, 0x3c, 0xe5, 0x1e, 0xf3, 0x6c, 0x97, 0x53, 0xe3, + 0x10, 0x0e, 0x31, 0x2c, 0x75, 0x0f, 0x4b, 0x6c, 0xb2, 0x52, 0x11, 0xeb, 0x42, 0x4b, 0xdd, 0x23, + 0x10, 0x38, 0xa6, 0xa1, 0xc2, 0x94, 0xfa, 0x13, 0x4e, 0xa3, 0x38, 0x84, 0xad, 0xa2, 0x0e, 0xb1, + 0x46, 0x81, 0x2e, 0x0a, 0x85, 0x02, 0xb7, 0x0b, 0x3c, 0x9c, 0x50, 0x28, 0xc8, 0xee, 0xd2, 0xb4, + 0x40, 0x97, 0x60, 0x58, 0x25, 0x6a, 0xaf, 0xf0, 0xa4, 0x59, 0x62, 0x9a, 0x2d, 0xc5, 0x60, 0xac, + 0xd3, 0xa0, 0x75, 0x18, 0x0f, 0xb9, 0x9e, 0x4d, 0xc5, 0x15, 0xe7, 0xfa, 0xca, 0xf7, 0xaa, 0x77, + 0xc8, 0x26, 0xfa, 0x80, 0x81, 0xf8, 0xee, 0x24, 0xa3, 0x33, 0x24, 0x59, 0xa0, 0x57, 0x61, 0xac, + 0xe1, 0x3b, 0xf5, 0x79, 0xa7, 0xe1, 0x78, 0x35, 0xd6, 0x3f, 0x43, 0x66, 0xbe, 0xdf, 0x6b, 0x06, + 0x16, 0x27, 0xa8, 0xa9, 0xf0, 0xa6, 0x43, 0x44, 0x74, 0x31, 0xc7, 0xdb, 0x22, 0xa1, 0x48, 0xbb, + 0xcd, 0x84, 0xb7, 0x6b, 0x39, 0x34, 0x38, 0xb7, 0x34, 0x7a, 0x09, 0x46, 0xe4, 0xe7, 0x6b, 0xc1, + 0x4c, 0xe2, 0x27, 0x31, 0x1a, 0x0e, 0x1b, 0x94, 0x28, 0x84, 0x93, 0xf2, 0xff, 0x7a, 0xe0, 0x6c, + 0x6e, 0xba, 0x35, 0xf1, 0xc2, 0x9f, 0x3f, 0xbb, 0xfd, 0xb0, 0x7c, 0x1b, 0xba, 0x94, 0x45, 0x74, + 0xb0, 0x5f, 0x7e, 0x44, 0xf4, 0x5a, 0x26, 0x1e, 0x67, 0xf3, 0x46, 0xab, 0x30, 0xb5, 0x4d, 0x9c, + 0x46, 0xb4, 0xbd, 0xb0, 0x4d, 0x6a, 0x3b, 0x72, 0xc1, 0xb1, 0xf0, 0x28, 0xda, 0xd3, 0x91, 0x2b, + 0x69, 0x12, 0x9c, 0x55, 0x0e, 0xbd, 0x09, 0xd3, 0xad, 0xf6, 0x46, 0xc3, 0x0d, 0xb7, 0xd7, 0xfc, + 0x88, 0x39, 0x21, 0xa9, 0x9c, 0xef, 0x22, 0x8e, 0x8a, 0x0a, 0x40, 0x53, 0xc9, 0xa1, 0xc3, 0xb9, + 0x1c, 0xd0, 0x5d, 0x38, 0x99, 0x98, 0x08, 0x22, 0x92, 0xc4, 0x58, 0x7e, 0x56, 0x91, 0x6a, 0x56, + 0x01, 0x11, 0x94, 0x25, 0x0b, 0x85, 0xb3, 0xab, 0x40, 0x2f, 0x03, 0xb8, 0xad, 0x65, 0xa7, 0xe9, + 0x36, 0xe8, 0x55, 0x71, 0x8a, 0xcd, 0x11, 0x7a, 0x6d, 0x80, 0x95, 0x8a, 0x84, 0xd2, 0xbd, 0x59, + 0xfc, 0xdb, 0xc3, 0x1a, 0x35, 0xba, 0x06, 0x63, 0xe2, 0xdf, 0x9e, 0x18, 0x52, 0x1e, 0xd0, 0xe4, + 0x71, 0x16, 0x8d, 0xaa, 0xa2, 0x63, 0x0e, 0x52, 0x10, 0x9c, 0x28, 0x8b, 0xb6, 0xe0, 0x8c, 0xcc, + 0x10, 0xa7, 0xcf, 0x4f, 0x39, 0x06, 0x21, 0x4b, 0xe5, 0x31, 0xc4, 0x5f, 0xa5, 0xcc, 0x75, 0x22, + 0xc4, 0x9d, 0xf9, 0xd0, 0x73, 0x5d, 0x9f, 0xe6, 0xfc, 0xc9, 0xef, 0x49, 0xee, 0xe1, 0x44, 0xcf, + 0xf5, 0x6b, 0x49, 0x24, 0x4e, 0xd3, 0x23, 0x1f, 0x4e, 0xba, 0x5e, 0xd6, 0xac, 0x3e, 0xc5, 0x18, + 0x7d, 0x90, 0xbf, 0x76, 0xee, 0x3c, 0xa3, 0x33, 0xf1, 0x38, 0x9b, 0xef, 0xdb, 0xf3, 0xfb, 0xfb, + 0x5d, 0x8b, 0x96, 0xd6, 0xa4, 0x73, 0xf4, 0x29, 0x18, 0xd1, 0x3f, 0x4a, 0x48, 0x1a, 0xe7, 0xb3, + 0x85, 0x57, 0x6d, 0x4f, 0xe0, 0xb2, 0xbd, 0x5a, 0xf7, 0x3a, 0x0e, 0x1b, 0x1c, 0x51, 0x2d, 0x23, + 0x26, 0xc0, 0xc5, 0xde, 0x24, 0x99, 0xde, 0xdd, 0xde, 0x08, 0x64, 0x4f, 0x77, 0x74, 0x0d, 0x86, + 0x6a, 0x0d, 0x97, 0x78, 0xd1, 0x4a, 0xa5, 0x53, 0xd4, 0xc3, 0x05, 0x41, 0x23, 0xd6, 0x8f, 0xc8, + 0xca, 0xc1, 0x61, 0x58, 0x71, 0xb0, 0x7f, 0xa3, 0x00, 0xe5, 0x2e, 0x29, 0x5e, 0x12, 0x66, 0x28, + 0xab, 0x27, 0x33, 0xd4, 0x1c, 0x8c, 0xc7, 0xff, 0x74, 0x0d, 0x97, 0xf2, 0x64, 0xbd, 0x69, 0xa2, + 0x71, 0x92, 0xbe, 0xe7, 0x47, 0x09, 0xba, 0x25, 0xab, 0xaf, 0xeb, 0xb3, 0x1a, 0xc3, 0x82, 0xdd, + 0xdf, 0xfb, 0xb5, 0x37, 0xd7, 0x1a, 0x69, 0x7f, 0xad, 0x00, 0x27, 0x55, 0x17, 0x7e, 0xe7, 0x76, + 0xdc, 0x8d, 0x74, 0xc7, 0x1d, 0x81, 0x2d, 0xd7, 0xbe, 0x0e, 0x03, 0x3c, 0x8c, 0x63, 0x0f, 0xe2, + 0xf6, 0x63, 0x66, 0x70, 0x67, 0x25, 0xe1, 0x19, 0x01, 0x9e, 0x7f, 0xc0, 0x82, 0xf1, 0xc4, 0xeb, + 0x36, 0x84, 0xb5, 0x27, 0xd0, 0xf7, 0x23, 0x12, 0x67, 0x09, 0xdb, 0xe7, 0xa0, 0x6f, 0xdb, 0x0f, + 0xa3, 0xa4, 0xa3, 0xc7, 0x15, 0x3f, 0x8c, 0x30, 0xc3, 0xd8, 0xbf, 0x6f, 0x41, 0xff, 0xba, 0xe3, + 0x7a, 0x91, 0x34, 0x0a, 0x58, 0x39, 0x46, 0x81, 0x5e, 0xbe, 0x0b, 0xbd, 0x08, 0x03, 0x64, 0x73, + 0x93, 0xd4, 0x22, 0x31, 0xaa, 0x32, 0xf4, 0xc4, 0xc0, 0x12, 0x83, 0x52, 0xf9, 0x8f, 0x55, 0xc6, + 0xff, 0x62, 0x41, 0x8c, 0x6e, 0x41, 0x29, 0x72, 0x9b, 0x64, 0xae, 0x5e, 0x17, 0xa6, 0xf2, 0xfb, + 0x08, 0x9f, 0xb1, 0x2e, 0x19, 0xe0, 0x98, 0x97, 0xfd, 0x85, 0x02, 0x40, 0x1c, 0xff, 0xaa, 0xdb, + 0x27, 0xce, 0xa7, 0x8c, 0xa8, 0xe7, 0x33, 0x8c, 0xa8, 0x28, 0x66, 0x98, 0x61, 0x41, 0x55, 0xdd, + 0x54, 0xec, 0xa9, 0x9b, 0xfa, 0x0e, 0xd3, 0x4d, 0x0b, 0x30, 0x19, 0xc7, 0xef, 0x32, 0xc3, 0x17, + 0xb2, 0xa3, 0x73, 0x3d, 0x89, 0xc4, 0x69, 0x7a, 0x9b, 0xc0, 0x39, 0x15, 0xc6, 0x48, 0x9c, 0x68, + 0xcc, 0x0f, 0x5c, 0x37, 0x4a, 0x77, 0xe9, 0xa7, 0xd8, 0x4a, 0x5c, 0xc8, 0xb5, 0x12, 0xff, 0xa4, + 0x05, 0x27, 0x92, 0xf5, 0xb0, 0x47, 0xd3, 0x9f, 0xb7, 0xe0, 0x24, 0xb3, 0x95, 0xb3, 0x5a, 0xd3, + 0x96, 0xf9, 0x17, 0x3a, 0x86, 0x66, 0xca, 0x69, 0x71, 0x1c, 0xe3, 0x64, 0x35, 0x8b, 0x35, 0xce, + 0xae, 0xd1, 0xfe, 0x9f, 0x7d, 0x30, 0x9d, 0x17, 0xd3, 0x89, 0x3d, 0x13, 0x71, 0xee, 0x54, 0x77, + 0xc8, 0x6d, 0xe1, 0x8c, 0x1f, 0x3f, 0x13, 0xe1, 0x60, 0x2c, 0xf1, 0xc9, 0xac, 0x1d, 0x85, 0x1e, + 0xb3, 0x76, 0x6c, 0xc3, 0xe4, 0xed, 0x6d, 0xe2, 0xdd, 0xf0, 0x42, 0x27, 0x72, 0xc3, 0x4d, 0x97, + 0xd9, 0x95, 0xf9, 0xbc, 0x91, 0xa9, 0x7e, 0x27, 0x6f, 0x25, 0x09, 0x0e, 0xf6, 0xcb, 0x67, 0x0c, + 0x40, 0xdc, 0x64, 0xbe, 0x91, 0xe0, 0x34, 0xd3, 0x74, 0xd2, 0x93, 0xbe, 0x07, 0x9c, 0xf4, 0xa4, + 0xe9, 0x0a, 0x6f, 0x14, 0xf9, 0x06, 0x80, 0xdd, 0x18, 0x57, 0x15, 0x14, 0x6b, 0x14, 0xe8, 0x13, + 0x80, 0xf4, 0xa4, 0x4e, 0x46, 0x48, 0xcd, 0x67, 0xef, 0xed, 0x97, 0xd1, 0x5a, 0x0a, 0x7b, 0xb0, + 0x5f, 0x9e, 0xa2, 0xd0, 0x15, 0x8f, 0xde, 0x3c, 0xe3, 0x38, 0x64, 0x19, 0x8c, 0xd0, 0x2d, 0x98, + 0xa0, 0x50, 0xb6, 0xa2, 0x64, 0xbc, 0x4e, 0x7e, 0x5b, 0x7c, 0xfa, 0xde, 0x7e, 0x79, 0x62, 0x2d, + 0x81, 0xcb, 0x63, 0x9d, 0x62, 0x82, 0x5e, 0x86, 0xb1, 0x78, 0x5e, 0x5d, 0x25, 0x7b, 0x3c, 0x3e, + 0x4e, 0x89, 0x2b, 0xbc, 0x57, 0x0d, 0x0c, 0x4e, 0x50, 0xda, 0x9f, 0xb7, 0xe0, 0x74, 0x6e, 0xe2, + 0x71, 0x74, 0x01, 0x86, 0x9c, 0x96, 0xcb, 0xcd, 0x17, 0xe2, 0xa8, 0x61, 0x6a, 0xb2, 0xca, 0x0a, + 0x37, 0x5e, 0x28, 0x2c, 0xdd, 0xe1, 0x77, 0x5c, 0xaf, 0x9e, 0xdc, 0xe1, 0xaf, 0xba, 0x5e, 0x1d, + 0x33, 0x8c, 0x3a, 0xb2, 0x8a, 0xb9, 0x4f, 0x11, 0xbe, 0x42, 0xd7, 0x6a, 0x46, 0x8a, 0xf2, 0xe3, + 0x6d, 0x06, 0x7a, 0x5a, 0x37, 0x35, 0x0a, 0xaf, 0xc2, 0x5c, 0x33, 0xe3, 0xf7, 0x5b, 0x20, 0x9e, + 0x2e, 0xf7, 0x70, 0x26, 0xbf, 0x01, 0x23, 0xbb, 0xe9, 0x84, 0x77, 0xe7, 0xf2, 0xdf, 0x72, 0x8b, + 0x40, 0xe1, 0x4a, 0xd0, 0x36, 0x92, 0xdb, 0x19, 0xbc, 0xec, 0x3a, 0x08, 0xec, 0x22, 0x61, 0x06, + 0x85, 0xee, 0xad, 0x79, 0x0e, 0xa0, 0xce, 0x68, 0x59, 0x16, 0xdc, 0x82, 0x29, 0x71, 0x2d, 0x2a, + 0x0c, 0xd6, 0xa8, 0xec, 0x7f, 0x55, 0x80, 0x61, 0x99, 0x60, 0xad, 0xed, 0xf5, 0xa2, 0xf6, 0x3b, + 0x54, 0xc6, 0x65, 0x74, 0x11, 0x4a, 0x4c, 0x2f, 0x5d, 0x89, 0xb5, 0xa5, 0x4a, 0x2b, 0xb4, 0x2a, + 0x11, 0x38, 0xa6, 0xa1, 0xbb, 0x63, 0xd8, 0xde, 0x60, 0xe4, 0x89, 0x87, 0xb6, 0x55, 0x0e, 0xc6, + 0x12, 0x8f, 0x3e, 0x0a, 0x13, 0xbc, 0x5c, 0xe0, 0xb7, 0x9c, 0x2d, 0x6e, 0xcb, 0xea, 0x57, 0xd1, + 0x4b, 0x26, 0x56, 0x13, 0xb8, 0x83, 0xfd, 0xf2, 0x89, 0x24, 0x8c, 0x19, 0x69, 0x53, 0x5c, 0x98, + 0xcb, 0x1a, 0xaf, 0x84, 0xee, 0xea, 0x29, 0x4f, 0xb7, 0x18, 0x85, 0x75, 0x3a, 0xfb, 0x53, 0x80, + 0xd2, 0xa9, 0xe6, 0xd0, 0x6b, 0xdc, 0xe5, 0xd9, 0x0d, 0x48, 0xbd, 0x93, 0xd1, 0x56, 0x8f, 0xd1, + 0x21, 0xdf, 0xc8, 0xf1, 0x52, 0x58, 0x95, 0xb7, 0xff, 0x52, 0x11, 0x26, 0x92, 0x51, 0x01, 0xd0, + 0x15, 0x18, 0xe0, 0x22, 0xa5, 0x60, 0xdf, 0xc1, 0x27, 0x48, 0x8b, 0x25, 0xc0, 0x0e, 0x57, 0x21, + 0x95, 0x8a, 0xf2, 0xe8, 0x4d, 0x18, 0xae, 0xfb, 0xb7, 0xbd, 0xdb, 0x4e, 0x50, 0x9f, 0xab, 0xac, + 0x88, 0xe9, 0x9c, 0xa9, 0xa8, 0x58, 0x8c, 0xc9, 0xf4, 0xf8, 0x04, 0xcc, 0xfe, 0x1d, 0xa3, 0xb0, + 0xce, 0x0e, 0xad, 0xb3, 0xfc, 0x14, 0x9b, 0xee, 0xd6, 0xaa, 0xd3, 0xea, 0xf4, 0xfe, 0x65, 0x41, + 0x12, 0x69, 0x9c, 0x47, 0x45, 0x12, 0x0b, 0x8e, 0xc0, 0x31, 0x23, 0xf4, 0x19, 0x98, 0x0a, 0x73, + 0x4c, 0x27, 0x79, 0x99, 0x47, 0x3b, 0x59, 0x13, 0xe6, 0x1f, 0xba, 0xb7, 0x5f, 0x9e, 0xca, 0x32, + 0xb2, 0x64, 0x55, 0x63, 0x7f, 0xf1, 0x04, 0x18, 0x8b, 0xd8, 0x48, 0x44, 0x6d, 0x1d, 0x51, 0x22, + 0x6a, 0x0c, 0x43, 0xa4, 0xd9, 0x8a, 0xf6, 0x16, 0xdd, 0x40, 0x8c, 0x49, 0x26, 0xcf, 0x25, 0x41, + 0x93, 0xe6, 0x29, 0x31, 0x58, 0xf1, 0xc9, 0xce, 0x16, 0x5e, 0xfc, 0x16, 0x66, 0x0b, 0xef, 0x3b, + 0xc6, 0x6c, 0xe1, 0x6b, 0x30, 0xb8, 0xe5, 0x46, 0x98, 0xb4, 0x7c, 0x71, 0x99, 0xcb, 0x9c, 0x87, + 0x97, 0x39, 0x49, 0x3a, 0x2f, 0xad, 0x40, 0x60, 0xc9, 0x04, 0xbd, 0xa6, 0x56, 0xe0, 0x40, 0xbe, + 0xc2, 0x25, 0xed, 0xbc, 0x92, 0xb9, 0x06, 0x45, 0x4e, 0xf0, 0xc1, 0xfb, 0xcd, 0x09, 0xbe, 0x2c, + 0x33, 0x79, 0x0f, 0xe5, 0x3f, 0x56, 0x63, 0x89, 0xba, 0xbb, 0xe4, 0xef, 0xbe, 0xa9, 0x67, 0x3f, + 0x2f, 0xe5, 0xef, 0x04, 0x2a, 0xb1, 0x79, 0x8f, 0x39, 0xcf, 0xbf, 0xdf, 0x82, 0x93, 0xc9, 0xec, + 0xa4, 0xec, 0x4d, 0x85, 0xf0, 0xf3, 0x78, 0xb1, 0x97, 0x74, 0xb1, 0xac, 0x80, 0x51, 0x21, 0xd3, + 0x91, 0x66, 0x92, 0xe1, 0xec, 0xea, 0x68, 0x47, 0x07, 0x1b, 0x75, 0xe1, 0x6f, 0xf0, 0x58, 0x4e, + 0xf2, 0xf4, 0x0e, 0x29, 0xd3, 0xd7, 0x33, 0x12, 0x75, 0x3f, 0x9e, 0x97, 0xa8, 0xbb, 0xe7, 0xf4, + 0xdc, 0xaf, 0xa9, 0xb4, 0xe9, 0xa3, 0xf9, 0x53, 0x89, 0x27, 0x45, 0xef, 0x9a, 0x2c, 0xfd, 0x35, + 0x95, 0x2c, 0xbd, 0x43, 0x44, 0x6e, 0x9e, 0x0a, 0xbd, 0x6b, 0x8a, 0x74, 0x2d, 0xcd, 0xf9, 0xf8, + 0xd1, 0xa4, 0x39, 0x37, 0x8e, 0x1a, 0x9e, 0x69, 0xfb, 0xe9, 0x2e, 0x47, 0x8d, 0xc1, 0xb7, 0xf3, + 0x61, 0xc3, 0x53, 0xba, 0x4f, 0xde, 0x57, 0x4a, 0xf7, 0x9b, 0x7a, 0x8a, 0x74, 0xd4, 0x25, 0x07, + 0x38, 0x25, 0xea, 0x31, 0x31, 0xfa, 0x4d, 0xfd, 0x00, 0x9c, 0xca, 0xe7, 0xab, 0xce, 0xb9, 0x34, + 0xdf, 0xcc, 0x23, 0x30, 0x95, 0x70, 0xfd, 0xc4, 0xf1, 0x24, 0x5c, 0x3f, 0x79, 0xe4, 0x09, 0xd7, + 0x4f, 0x1d, 0x43, 0xc2, 0xf5, 0x87, 0x8e, 0x31, 0xe1, 0xfa, 0x4d, 0xe6, 0x1c, 0xc5, 0x03, 0x40, + 0x89, 0x08, 0xe2, 0x4f, 0xe5, 0xc4, 0x4f, 0x4b, 0x47, 0x89, 0xe2, 0x1f, 0xa7, 0x50, 0x38, 0x66, + 0x95, 0x91, 0xc8, 0x7d, 0xfa, 0x01, 0x24, 0x72, 0x5f, 0x8b, 0x13, 0xb9, 0x9f, 0xce, 0x1f, 0xea, + 0x8c, 0xe7, 0x34, 0x39, 0xe9, 0xdb, 0x6f, 0xea, 0x69, 0xd7, 0x1f, 0xee, 0x60, 0x05, 0xcb, 0x52, + 0x28, 0x77, 0x48, 0xb6, 0xfe, 0x2a, 0x4f, 0xb6, 0xfe, 0x48, 0xfe, 0x4e, 0x9e, 0x3c, 0xee, 0x8c, + 0x14, 0xeb, 0xb4, 0x5d, 0x2a, 0xf6, 0x2a, 0x8b, 0x95, 0x9e, 0xd3, 0x2e, 0x15, 0xbc, 0x35, 0xdd, + 0x2e, 0x85, 0xc2, 0x31, 0x2b, 0xfb, 0x07, 0x0b, 0x70, 0xb6, 0xf3, 0x7a, 0x8b, 0xb5, 0xe4, 0x95, + 0xd8, 0x21, 0x20, 0xa1, 0x25, 0xe7, 0x77, 0xb6, 0x98, 0xaa, 0xe7, 0x78, 0x90, 0x97, 0x61, 0x52, + 0xbd, 0xc3, 0x69, 0xb8, 0xb5, 0xbd, 0xb5, 0xf8, 0x9a, 0xac, 0x22, 0x27, 0x54, 0x93, 0x04, 0x38, + 0x5d, 0x06, 0xcd, 0xc1, 0xb8, 0x01, 0x5c, 0x59, 0x14, 0x77, 0xb3, 0x38, 0x3a, 0xb7, 0x89, 0xc6, + 0x49, 0x7a, 0xfb, 0x4b, 0x16, 0x3c, 0x94, 0x93, 0xa9, 0xb4, 0xe7, 0x70, 0x87, 0x9b, 0x30, 0xde, + 0x32, 0x8b, 0x76, 0x89, 0xd0, 0x6a, 0xe4, 0x43, 0x55, 0x6d, 0x4d, 0x20, 0x70, 0x92, 0xa9, 0xfd, + 0xb3, 0x05, 0x38, 0xd3, 0xd1, 0xb1, 0x14, 0x61, 0x38, 0xb5, 0xd5, 0x0c, 0x9d, 0x85, 0x80, 0xd4, + 0x89, 0x17, 0xb9, 0x4e, 0xa3, 0xda, 0x22, 0x35, 0xcd, 0xce, 0xc1, 0x3c, 0x34, 0x2f, 0xaf, 0x56, + 0xe7, 0xd2, 0x14, 0x38, 0xa7, 0x24, 0x5a, 0x06, 0x94, 0xc6, 0x88, 0x11, 0x66, 0x51, 0xf7, 0xd3, + 0xfc, 0x70, 0x46, 0x09, 0xf4, 0x01, 0x18, 0x55, 0x0e, 0xab, 0xda, 0x88, 0xb3, 0x8d, 0x1d, 0xeb, + 0x08, 0x6c, 0xd2, 0xa1, 0x4b, 0x3c, 0x6d, 0x83, 0x48, 0xf0, 0x21, 0x8c, 0x22, 0xe3, 0x32, 0x27, + 0x83, 0x00, 0x63, 0x9d, 0x66, 0xfe, 0xa5, 0xdf, 0xfc, 0xc6, 0xd9, 0xf7, 0xfc, 0xf6, 0x37, 0xce, + 0xbe, 0xe7, 0xf7, 0xbe, 0x71, 0xf6, 0x3d, 0xdf, 0x7d, 0xef, 0xac, 0xf5, 0x9b, 0xf7, 0xce, 0x5a, + 0xbf, 0x7d, 0xef, 0xac, 0xf5, 0x7b, 0xf7, 0xce, 0x5a, 0x7f, 0x70, 0xef, 0xac, 0xf5, 0x85, 0x3f, + 0x3c, 0xfb, 0x9e, 0x37, 0x50, 0x1c, 0x40, 0xf4, 0x22, 0x1d, 0x9d, 0x8b, 0xbb, 0x97, 0xfe, 0x5f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xb0, 0x6c, 0x51, 0x7f, 0x2c, 0x10, 0x01, 0x00, } func (m *AWSElasticBlockStoreVolumeSource) Marshal() (dAtA []byte, err error) { @@ -8714,6 +8752,22 @@ func (m *Container) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ResizePolicy) > 0 { + for iNdEx := len(m.ResizePolicy) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResizePolicy[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba + } + } if m.StartupProbe != nil { { size, err := m.StartupProbe.MarshalToSizedBuffer(dAtA[:i]) @@ -9022,6 +9076,39 @@ func (m *ContainerPort) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ContainerResizePolicy) 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 *ContainerResizePolicy) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContainerResizePolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.RestartPolicy) + copy(dAtA[i:], m.RestartPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.RestartPolicy))) + i-- + dAtA[i] = 0x12 + i -= len(m.ResourceName) + copy(dAtA[i:], m.ResourceName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ContainerState) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -9231,6 +9318,47 @@ func (m *ContainerStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Resources != nil { + { + size, err := m.Resources.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } + if len(m.AllocatedResources) > 0 { + keysForAllocatedResources := make([]string, 0, len(m.AllocatedResources)) + for k := range m.AllocatedResources { + keysForAllocatedResources = append(keysForAllocatedResources, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAllocatedResources) + for iNdEx := len(keysForAllocatedResources) - 1; iNdEx >= 0; iNdEx-- { + v := m.AllocatedResources[ResourceName(keysForAllocatedResources[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(keysForAllocatedResources[iNdEx]) + copy(dAtA[i:], keysForAllocatedResources[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForAllocatedResources[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x52 + } + } if m.Started != nil { i-- if *m.Started { @@ -9977,6 +10105,22 @@ func (m *EphemeralContainerCommon) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if len(m.ResizePolicy) > 0 { + for iNdEx := len(m.ResizePolicy) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResizePolicy[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xba + } + } if m.StartupProbe != nil { { size, err := m.StartupProbe.MarshalToSizedBuffer(dAtA[:i]) @@ -15792,6 +15936,11 @@ func (m *PodStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.Resize) + copy(dAtA[i:], m.Resize) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resize))) + i-- + dAtA[i] = 0x72 if len(m.EphemeralContainerStatuses) > 0 { for iNdEx := len(m.EphemeralContainerStatuses) - 1; iNdEx >= 0; iNdEx-- { { @@ -20815,6 +20964,12 @@ func (m *Container) Size() (n int) { l = m.StartupProbe.Size() n += 2 + l + sovGenerated(uint64(l)) } + if len(m.ResizePolicy) > 0 { + for _, e := range m.ResizePolicy { + l = e.Size() + n += 2 + l + sovGenerated(uint64(l)) + } + } return n } @@ -20851,6 +21006,19 @@ func (m *ContainerPort) Size() (n int) { return n } +func (m *ContainerResizePolicy) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ResourceName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.RestartPolicy) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ContainerState) Size() (n int) { if m == nil { return 0 @@ -20940,6 +21108,19 @@ func (m *ContainerStatus) Size() (n int) { if m.Started != nil { n += 2 } + if len(m.AllocatedResources) > 0 { + for k, v := range m.AllocatedResources { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } + } + if m.Resources != nil { + l = m.Resources.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -21282,6 +21463,12 @@ func (m *EphemeralContainerCommon) Size() (n int) { l = m.StartupProbe.Size() n += 2 + l + sovGenerated(uint64(l)) } + if len(m.ResizePolicy) > 0 { + for _, e := range m.ResizePolicy { + l = e.Size() + n += 2 + l + sovGenerated(uint64(l)) + } + } return n } @@ -23363,6 +23550,8 @@ func (m *PodStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + l = len(m.Resize) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -25367,6 +25556,11 @@ func (this *Container) String() string { repeatedStringForVolumeDevices += strings.Replace(strings.Replace(f.String(), "VolumeDevice", "VolumeDevice", 1), `&`, ``, 1) + "," } repeatedStringForVolumeDevices += "}" + repeatedStringForResizePolicy := "[]ContainerResizePolicy{" + for _, f := range this.ResizePolicy { + repeatedStringForResizePolicy += strings.Replace(strings.Replace(f.String(), "ContainerResizePolicy", "ContainerResizePolicy", 1), `&`, ``, 1) + "," + } + repeatedStringForResizePolicy += "}" s := strings.Join([]string{`&Container{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Image:` + fmt.Sprintf("%v", this.Image) + `,`, @@ -25390,6 +25584,7 @@ func (this *Container) String() string { `TerminationMessagePolicy:` + fmt.Sprintf("%v", this.TerminationMessagePolicy) + `,`, `VolumeDevices:` + repeatedStringForVolumeDevices + `,`, `StartupProbe:` + strings.Replace(this.StartupProbe.String(), "Probe", "Probe", 1) + `,`, + `ResizePolicy:` + repeatedStringForResizePolicy + `,`, `}`, }, "") return s @@ -25419,6 +25614,17 @@ func (this *ContainerPort) String() string { }, "") return s } +func (this *ContainerResizePolicy) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ContainerResizePolicy{`, + `ResourceName:` + fmt.Sprintf("%v", this.ResourceName) + `,`, + `RestartPolicy:` + fmt.Sprintf("%v", this.RestartPolicy) + `,`, + `}`, + }, "") + return s +} func (this *ContainerState) String() string { if this == nil { return "nil" @@ -25472,6 +25678,16 @@ func (this *ContainerStatus) String() string { if this == nil { return "nil" } + keysForAllocatedResources := make([]string, 0, len(this.AllocatedResources)) + for k := range this.AllocatedResources { + keysForAllocatedResources = append(keysForAllocatedResources, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForAllocatedResources) + mapStringForAllocatedResources := "ResourceList{" + for _, k := range keysForAllocatedResources { + mapStringForAllocatedResources += fmt.Sprintf("%v: %v,", k, this.AllocatedResources[ResourceName(k)]) + } + mapStringForAllocatedResources += "}" s := strings.Join([]string{`&ContainerStatus{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `State:` + strings.Replace(strings.Replace(this.State.String(), "ContainerState", "ContainerState", 1), `&`, ``, 1) + `,`, @@ -25482,6 +25698,8 @@ func (this *ContainerStatus) String() string { `ImageID:` + fmt.Sprintf("%v", this.ImageID) + `,`, `ContainerID:` + fmt.Sprintf("%v", this.ContainerID) + `,`, `Started:` + valueToStringGenerated(this.Started) + `,`, + `AllocatedResources:` + mapStringForAllocatedResources + `,`, + `Resources:` + strings.Replace(this.Resources.String(), "ResourceRequirements", "ResourceRequirements", 1) + `,`, `}`, }, "") return s @@ -25713,6 +25931,11 @@ func (this *EphemeralContainerCommon) String() string { repeatedStringForVolumeDevices += strings.Replace(strings.Replace(f.String(), "VolumeDevice", "VolumeDevice", 1), `&`, ``, 1) + "," } repeatedStringForVolumeDevices += "}" + repeatedStringForResizePolicy := "[]ContainerResizePolicy{" + for _, f := range this.ResizePolicy { + repeatedStringForResizePolicy += strings.Replace(strings.Replace(f.String(), "ContainerResizePolicy", "ContainerResizePolicy", 1), `&`, ``, 1) + "," + } + repeatedStringForResizePolicy += "}" s := strings.Join([]string{`&EphemeralContainerCommon{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Image:` + fmt.Sprintf("%v", this.Image) + `,`, @@ -25736,6 +25959,7 @@ func (this *EphemeralContainerCommon) String() string { `TerminationMessagePolicy:` + fmt.Sprintf("%v", this.TerminationMessagePolicy) + `,`, `VolumeDevices:` + repeatedStringForVolumeDevices + `,`, `StartupProbe:` + strings.Replace(this.StartupProbe.String(), "Probe", "Probe", 1) + `,`, + `ResizePolicy:` + repeatedStringForResizePolicy + `,`, `}`, }, "") return s @@ -27323,6 +27547,7 @@ func (this *PodStatus) String() string { `NominatedNodeName:` + fmt.Sprintf("%v", this.NominatedNodeName) + `,`, `PodIPs:` + repeatedStringForPodIPs + `,`, `EphemeralContainerStatuses:` + repeatedStringForEphemeralContainerStatuses + `,`, + `Resize:` + fmt.Sprintf("%v", this.Resize) + `,`, `}`, }, "") return s @@ -33866,6 +34091,40 @@ func (m *Container) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 23: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResizePolicy", 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.ResizePolicy = append(m.ResizePolicy, ContainerResizePolicy{}) + if err := m.ResizePolicy[len(m.ResizePolicy)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -34172,6 +34431,120 @@ func (m *ContainerPort) Unmarshal(dAtA []byte) error { } return nil } +func (m *ContainerResizePolicy) 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: ContainerResizePolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContainerResizePolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResourceName", 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.ResourceName = ResourceName(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RestartPolicy", 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.RestartPolicy = ResourceResizeRestartPolicy(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 *ContainerState) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -35060,6 +35433,171 @@ func (m *ContainerStatus) Unmarshal(dAtA []byte) error { } b := bool(v != 0) m.Started = &b + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocatedResources", 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.AllocatedResources == nil { + m.AllocatedResources = make(ResourceList) + } + var mapkey ResourceName + 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 = ResourceName(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.AllocatedResources[ResourceName(mapkey)] = *mapvalue + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", 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.Resources == nil { + m.Resources = &ResourceRequirements{} + } + if err := m.Resources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -37706,6 +38244,40 @@ func (m *EphemeralContainerCommon) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 23: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResizePolicy", 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.ResizePolicy = append(m.ResizePolicy, ContainerResizePolicy{}) + if err := m.ResizePolicy[len(m.ResizePolicy)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -55879,6 +56451,38 @@ func (m *PodStatus) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resize", 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.Resize = PodResizeStatus(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -65016,7 +65620,7 @@ func (m *ServiceSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ExternalTrafficPolicy = ServiceExternalTrafficPolicyType(dAtA[iNdEx:postIndex]) + m.ExternalTrafficPolicy = ServiceExternalTrafficPolicy(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 12: if wireType != 0 { @@ -65274,7 +65878,7 @@ func (m *ServiceSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - s := ServiceInternalTrafficPolicyType(dAtA[iNdEx:postIndex]) + s := ServiceInternalTrafficPolicy(dAtA[iNdEx:postIndex]) m.InternalTrafficPolicy = &s iNdEx = postIndex default: diff --git a/vendor/k8s.io/api/core/v1/generated.proto b/vendor/k8s.io/api/core/v1/generated.proto index 416811e29..8ef67ca40 100644 --- a/vendor/k8s.io/api/core/v1/generated.proto +++ b/vendor/k8s.io/api/core/v1/generated.proto @@ -220,7 +220,6 @@ message CSIPersistentVolumeSource { // controllerExpandSecretRef is a reference to the secret object containing // sensitive information to pass to the CSI driver to complete the CSI // ControllerExpandVolume call. - // This is an beta field and requires enabling ExpandCSIVolumes feature gate. // This field is optional, and may be empty if no secret is required. If the // secret object contains more than one secret, all secrets are passed. // +optional @@ -229,9 +228,10 @@ message CSIPersistentVolumeSource { // nodeExpandSecretRef is a reference to the secret object containing // sensitive information to pass to the CSI driver to complete the CSI // NodeExpandVolume call. - // This is an alpha field and requires enabling CSINodeExpandSecret feature gate. + // This is a beta field which is enabled default by CSINodeExpandSecret feature gate. // This field is optional, may be omitted if no secret is required. If the // secret object contains more than one secret, all secrets are passed. + // +featureGate=CSINodeExpandSecret // +optional optional SecretReference nodeExpandSecretRef = 10; } @@ -723,6 +723,12 @@ message Container { // +optional optional ResourceRequirements resources = 8; + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + // +listType=atomic + repeated ContainerResizePolicy resizePolicy = 23; + // Pod volumes to mount into the container's filesystem. // Cannot be updated. // +optional @@ -863,6 +869,17 @@ message ContainerPort { optional string hostIP = 5; } +// ContainerResizePolicy represents resource resize policy for the container. +message ContainerResizePolicy { + // Name of the resource to which this resource resize policy applies. + // Supported values: cpu, memory. + optional string resourceName = 1; + + // Restart policy to apply when specified resource is resized. + // If not specified, it defaults to NotRequired. + optional string restartPolicy = 2; +} + // ContainerState holds a possible state of container. // Only one of its members may be specified. // If none of them is specified, the default one is ContainerStateWaiting. @@ -930,41 +947,76 @@ message ContainerStateWaiting { // ContainerStatus contains details for the current status of this container. message ContainerStatus { - // This must be a DNS_LABEL. Each container in a pod must have a unique name. + // Name is a DNS_LABEL representing the unique name of the container. + // Each container in a pod must have a unique name across all container types. // Cannot be updated. optional string name = 1; - // Details about the container's current condition. + // State holds details about the container's current condition. // +optional optional ContainerState state = 2; - // Details about the container's last termination condition. + // LastTerminationState holds the last termination state of the container to + // help debug container crashes and restarts. This field is not + // populated if the container is still running and RestartCount is 0. // +optional optional ContainerState lastState = 3; - // Specifies whether the container has passed its readiness probe. + // Ready specifies whether the container is currently passing its readiness check. + // The value will change as readiness probes keep executing. If no readiness + // probes are specified, this field defaults to true once the container is + // fully started (see Started field). + // + // The value is typically used to determine whether a container is ready to + // accept traffic. optional bool ready = 4; - // The number of times the container has been restarted. + // RestartCount holds the number of times the container has been restarted. + // Kubelet makes an effort to always increment the value, but there + // are cases when the state may be lost due to node restarts and then the value + // may be reset to 0. The value is never negative. optional int32 restartCount = 5; - // The image the container is running. + // Image is the name of container image that the container is running. + // The container image may not match the image used in the PodSpec, + // as it may have been resolved by the runtime. // More info: https://kubernetes.io/docs/concepts/containers/images. optional string image = 6; - // ImageID of the container's image. + // ImageID is the image ID of the container's image. The image ID may not + // match the image ID of the image used in the PodSpec, as it may have been + // resolved by the runtime. optional string imageID = 7; - // Container's ID in the format '://'. + // ContainerID is the ID of the container in the format '://'. + // Where type is a container runtime identifier, returned from Version call of CRI API + // (for example "containerd"). // +optional optional string containerID = 8; - // Specifies whether the container has passed its startup probe. - // Initialized as false, becomes true after startupProbe is considered successful. - // Resets to false when the container is restarted, or if kubelet loses state temporarily. - // Is always true when no startupProbe is defined. + // Started indicates whether the container has finished its postStart lifecycle hook + // and passed its startup probe. + // Initialized as false, becomes true after startupProbe is considered + // successful. Resets to false when the container is restarted, or if kubelet + // loses state temporarily. In both cases, startup probes will run again. + // Is always true when no startupProbe is defined and container is running and + // has passed the postStart lifecycle hook. The null value must be treated the + // same as false. // +optional optional bool started = 9; + + // AllocatedResources represents the compute resources allocated for this container by the + // node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission + // and after successfully admitting desired pod resize. + // +featureGate=InPlacePodVerticalScaling + // +optional + map allocatedResources = 10; + + // Resources represents the compute resource requests and limits that have been successfully + // enacted on the running container after it has been started or has been successfully resized. + // +featureGate=InPlacePodVerticalScaling + // +optional + optional ResourceRequirements resources = 11; } // DaemonEndpoint contains information about a single Daemon endpoint. @@ -1040,7 +1092,7 @@ message EmptyDirVolumeSource { // The maximum usage on memory medium EmptyDir would be the minimum value between // the SizeLimit specified here and the sum of memory limits of all containers in a pod. // The default is nil which means that the limit is undefined. - // More info: http://kubernetes.io/docs/user-guide/volumes#emptydir + // More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity sizeLimit = 2; } @@ -1049,11 +1101,8 @@ message EmptyDirVolumeSource { // +structType=atomic message EndpointAddress { // The IP of this endpoint. - // May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), - // or link-local multicast ((224.0.0.0/24). - // IPv6 is also accepted but not fully supported on all platforms. Also, certain - // kubernetes components, like kube-proxy, are not IPv6 ready. - // TODO: This should allow hostname or IP, See #4447. + // 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). optional string ip = 1; // The Hostname of this endpoint @@ -1089,10 +1138,17 @@ message EndpointPort { optional string protocol = 3; // 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. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional optional string appProtocol = 4; @@ -1324,6 +1380,12 @@ message EphemeralContainerCommon { // +optional optional ResourceRequirements resources = 8; + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + // +listType=atomic + repeated ContainerResizePolicy resizePolicy = 23; + // Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. // Cannot be updated. // +optional @@ -1791,7 +1853,8 @@ message HTTPGetAction { // HTTPHeader describes a custom header to be used in HTTP probes message HTTPHeader { - // The header field name + // The header field name. + // This will be canonicalized upon output, so case-variant names will be understood as the same header. optional string name = 1; // The header field value @@ -2484,6 +2547,10 @@ message NodeStatus { // Note: This field is declared as mergeable, but the merge key is not sufficiently // unique, which can cause data corruption when it is merged. Callers should instead // use a full-replacement patch. See https://pr.k8s.io/79391 for an example. + // Consumers should assume that addresses can change during the + // lifetime of a Node. However, there are some exceptions where this may not + // be possible, such as Pods that inherit a Node's address in its own status or + // consumers of the downward API (status.hostIP). // +optional // +patchMergeKey=type // +patchStrategy=merge @@ -2665,7 +2732,7 @@ message PersistentVolumeClaim { optional PersistentVolumeClaimStatus status = 3; } -// PersistentVolumeClaimCondition contails details about state of pvc +// PersistentVolumeClaimCondition contains details about state of pvc message PersistentVolumeClaimCondition { optional string type = 1; @@ -3553,7 +3620,7 @@ message PodSpec { repeated EphemeralContainer ephemeralContainers = 34; // Restart policy for all containers within the pod. - // One of Always, OnFailure, Never. + // 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 // +optional @@ -3808,14 +3875,19 @@ message PodSpec { optional bool hostUsers = 37; // SchedulingGates is an opaque list of values that if specified will block scheduling the pod. - // More info: https://git.k8s.io/enhancements/keps/sig-scheduling/3521-pod-scheduling-readiness. + // If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + // scheduler will not attempt to schedule the pod. + // + // SchedulingGates can only be set at pod creation time, and be removed only afterwards. + // + // This is a beta feature enabled by the PodSchedulingReadiness feature gate. // - // This is an alpha-level feature enabled by PodSchedulingReadiness feature gate. - // +optional // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name + // +featureGate=PodSchedulingReadiness + // +optional repeated PodSchedulingGate schedulingGates = 38; // ResourceClaims defines which ResourceClaims must be allocated @@ -3923,13 +3995,20 @@ message PodStatus { // The Quality of Service (QOS) classification assigned to the pod based on resource requirements // See PodQOSClass type for available QOS classes - // More info: https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#quality-of-service-classes // +optional optional string qosClass = 9; // Status for any ephemeral containers that have run in this pod. // +optional repeated ContainerStatus ephemeralContainerStatuses = 13; + + // 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" + // +featureGate=InPlacePodVerticalScaling + // +optional + optional string resize = 14; } // PodStatusResult is a wrapper for PodStatus returned by kubelet that can be encode/decoded @@ -4122,8 +4201,6 @@ message ProbeHandler { optional TCPSocketAction tcpSocket = 3; // GRPC specifies an action involving a GRPC port. - // This is a beta field and requires enabling GRPCContainerProbe feature gate. - // +featureGate=GRPCContainerProbe // +optional optional GRPCAction grpc = 4; } @@ -4373,6 +4450,7 @@ message ReplicationControllerSpec { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. This takes precedence over a TemplateRef. + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template // +optional optional PodTemplateSpec template = 3; @@ -4501,7 +4579,7 @@ message ResourceRequirements { // Requests describes the minimum amount of compute resources required. // If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - // otherwise to an implementation-defined value. + // otherwise to an implementation-defined value. Requests cannot exceed Limits. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ // +optional map requests = 2; @@ -5628,8 +5706,12 @@ message TopologySpreadConstraint { // 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. Keys that don't exist in the incoming pod labels will + // 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. + // + // This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). // +listType=atomic // +optional repeated string matchLabelKeys = 8; diff --git a/vendor/k8s.io/api/core/v1/toleration.go b/vendor/k8s.io/api/core/v1/toleration.go index 9341abf89..e803d518b 100644 --- a/vendor/k8s.io/api/core/v1/toleration.go +++ b/vendor/k8s.io/api/core/v1/toleration.go @@ -28,15 +28,13 @@ func (t *Toleration) MatchToleration(tolerationToMatch *Toleration) bool { // ToleratesTaint checks if the toleration tolerates the taint. // The matching follows the rules below: -// (1) Empty toleration.effect means to match all taint effects, // -// otherwise taint effect must equal to toleration.effect. -// -// (2) If toleration.operator is 'Exists', it means to match all taint values. -// (3) Empty toleration.key means to match all taint keys. -// -// If toleration.key is empty, toleration.operator must be 'Exists'; -// this combination means to match all taint values and all taint keys. +// 1. Empty toleration.effect means to match all taint effects, +// otherwise taint effect must equal to toleration.effect. +// 2. If toleration.operator is 'Exists', it means to match all taint values. +// 3. Empty toleration.key means to match all taint keys. +// If toleration.key is empty, toleration.operator must be 'Exists'; +// this combination means to match all taint values and all taint keys. func (t *Toleration) ToleratesTaint(taint *Taint) bool { if len(t.Effect) > 0 && t.Effect != taint.Effect { return false diff --git a/vendor/k8s.io/api/core/v1/types.go b/vendor/k8s.io/api/core/v1/types.go index 0101e95d9..c831d5961 100644 --- a/vendor/k8s.io/api/core/v1/types.go +++ b/vendor/k8s.io/api/core/v1/types.go @@ -577,7 +577,7 @@ const ( PersistentVolumeClaimNodeExpansionFailed PersistentVolumeClaimResizeStatus = "NodeExpansionFailed" ) -// PersistentVolumeClaimCondition contails details about state of pvc +// PersistentVolumeClaimCondition contains details about state of pvc type PersistentVolumeClaimCondition struct { Type PersistentVolumeClaimConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=PersistentVolumeClaimConditionType"` Status ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=ConditionStatus"` @@ -735,7 +735,7 @@ type EmptyDirVolumeSource struct { // The maximum usage on memory medium EmptyDir would be the minimum value between // the SizeLimit specified here and the sum of memory limits of all containers in a pod. // The default is nil which means that the limit is undefined. - // More info: http://kubernetes.io/docs/user-guide/volumes#emptydir + // More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir // +optional SizeLimit *resource.Quantity `json:"sizeLimit,omitempty" protobuf:"bytes,2,opt,name=sizeLimit"` } @@ -1826,7 +1826,6 @@ type CSIPersistentVolumeSource struct { // controllerExpandSecretRef is a reference to the secret object containing // sensitive information to pass to the CSI driver to complete the CSI // ControllerExpandVolume call. - // This is an beta field and requires enabling ExpandCSIVolumes feature gate. // This field is optional, and may be empty if no secret is required. If the // secret object contains more than one secret, all secrets are passed. // +optional @@ -1835,9 +1834,10 @@ type CSIPersistentVolumeSource struct { // nodeExpandSecretRef is a reference to the secret object containing // sensitive information to pass to the CSI driver to complete the CSI // NodeExpandVolume call. - // This is an alpha field and requires enabling CSINodeExpandSecret feature gate. + // This is a beta field which is enabled default by CSINodeExpandSecret feature gate. // This field is optional, may be omitted if no secret is required. If the // secret object contains more than one secret, all secrets are passed. + // +featureGate=CSINodeExpandSecret // +optional NodeExpandSecretRef *SecretReference `json:"nodeExpandSecretRef,omitempty" protobuf:"bytes,10,opt,name=nodeExpandSecretRef"` } @@ -2137,7 +2137,8 @@ type SecretEnvSource struct { // HTTPHeader describes a custom header to be used in HTTP probes type HTTPHeader struct { - // The header field name + // The header field name. + // This will be canonicalized upon output, so case-variant names will be understood as the same header. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` // The header field value Value string `json:"value" protobuf:"bytes,2,opt,name=value"` @@ -2264,6 +2265,33 @@ const ( PullIfNotPresent PullPolicy = "IfNotPresent" ) +// ResourceResizeRestartPolicy specifies how to handle container resource resize. +type ResourceResizeRestartPolicy string + +// These are the valid resource resize restart policy values: +const ( + // 'NotRequired' means Kubernetes will try to resize the container + // without restarting it, if possible. Kubernetes may however choose to + // restart the container if it is unable to actuate resize without a + // restart. For e.g. the runtime doesn't support restart-free resizing. + NotRequired ResourceResizeRestartPolicy = "NotRequired" + // 'RestartContainer' means Kubernetes will resize the container in-place + // by stopping and starting the container when new resources are applied. + // This is needed for legacy applications. For e.g. java apps using the + // -xmxN flag which are unable to use resized memory without restarting. + RestartContainer ResourceResizeRestartPolicy = "RestartContainer" +) + +// ContainerResizePolicy represents resource resize policy for the container. +type ContainerResizePolicy struct { + // Name of the resource to which this resource resize policy applies. + // Supported values: cpu, memory. + ResourceName ResourceName `json:"resourceName" protobuf:"bytes,1,opt,name=resourceName,casttype=ResourceName"` + // Restart policy to apply when specified resource is resized. + // If not specified, it defaults to NotRequired. + RestartPolicy ResourceResizeRestartPolicy `json:"restartPolicy" protobuf:"bytes,2,opt,name=restartPolicy,casttype=ResourceResizeRestartPolicy"` +} + // PreemptionPolicy describes a policy for if/when to preempt a pod. // +enum type PreemptionPolicy string @@ -2310,7 +2338,7 @@ type ResourceRequirements struct { Limits ResourceList `json:"limits,omitempty" protobuf:"bytes,1,rep,name=limits,casttype=ResourceList,castkey=ResourceName"` // Requests describes the minimum amount of compute resources required. // If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, - // otherwise to an implementation-defined value. + // otherwise to an implementation-defined value. Requests cannot exceed Limits. // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ // +optional Requests ResourceList `json:"requests,omitempty" protobuf:"bytes,2,rep,name=requests,casttype=ResourceList,castkey=ResourceName"` @@ -2413,6 +2441,11 @@ type Container struct { // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ // +optional Resources ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + // +listType=atomic + ResizePolicy []ContainerResizePolicy `json:"resizePolicy,omitempty" protobuf:"bytes,23,rep,name=resizePolicy"` // Pod volumes to mount into the container's filesystem. // Cannot be updated. // +optional @@ -2517,8 +2550,6 @@ type ProbeHandler struct { TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" protobuf:"bytes,3,opt,name=tcpSocket"` // GRPC specifies an action involving a GRPC port. - // This is a beta field and requires enabling GRPCContainerProbe feature gate. - // +featureGate=GRPCContainerProbe // +optional GRPC *GRPCAction `json:"grpc,omitempty" protobuf:"bytes,4,opt,name=grpc"` } @@ -2632,33 +2663,66 @@ type ContainerState struct { // ContainerStatus contains details for the current status of this container. type ContainerStatus struct { - // This must be a DNS_LABEL. Each container in a pod must have a unique name. + // Name is a DNS_LABEL representing the unique name of the container. + // Each container in a pod must have a unique name across all container types. // Cannot be updated. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Details about the container's current condition. + // State holds details about the container's current condition. // +optional State ContainerState `json:"state,omitempty" protobuf:"bytes,2,opt,name=state"` - // Details about the container's last termination condition. + // LastTerminationState holds the last termination state of the container to + // help debug container crashes and restarts. This field is not + // populated if the container is still running and RestartCount is 0. // +optional LastTerminationState ContainerState `json:"lastState,omitempty" protobuf:"bytes,3,opt,name=lastState"` - // Specifies whether the container has passed its readiness probe. + // Ready specifies whether the container is currently passing its readiness check. + // The value will change as readiness probes keep executing. If no readiness + // probes are specified, this field defaults to true once the container is + // fully started (see Started field). + // + // The value is typically used to determine whether a container is ready to + // accept traffic. Ready bool `json:"ready" protobuf:"varint,4,opt,name=ready"` - // The number of times the container has been restarted. + // RestartCount holds the number of times the container has been restarted. + // Kubelet makes an effort to always increment the value, but there + // are cases when the state may be lost due to node restarts and then the value + // may be reset to 0. The value is never negative. RestartCount int32 `json:"restartCount" protobuf:"varint,5,opt,name=restartCount"` - // The image the container is running. + // Image is the name of container image that the container is running. + // The container image may not match the image used in the PodSpec, + // as it may have been resolved by the runtime. // More info: https://kubernetes.io/docs/concepts/containers/images. Image string `json:"image" protobuf:"bytes,6,opt,name=image"` - // ImageID of the container's image. + // ImageID is the image ID of the container's image. The image ID may not + // match the image ID of the image used in the PodSpec, as it may have been + // resolved by the runtime. ImageID string `json:"imageID" protobuf:"bytes,7,opt,name=imageID"` - // Container's ID in the format '://'. + // ContainerID is the ID of the container in the format '://'. + // Where type is a container runtime identifier, returned from Version call of CRI API + // (for example "containerd"). // +optional ContainerID string `json:"containerID,omitempty" protobuf:"bytes,8,opt,name=containerID"` - // Specifies whether the container has passed its startup probe. - // Initialized as false, becomes true after startupProbe is considered successful. - // Resets to false when the container is restarted, or if kubelet loses state temporarily. - // Is always true when no startupProbe is defined. + // Started indicates whether the container has finished its postStart lifecycle hook + // and passed its startup probe. + // Initialized as false, becomes true after startupProbe is considered + // successful. Resets to false when the container is restarted, or if kubelet + // loses state temporarily. In both cases, startup probes will run again. + // Is always true when no startupProbe is defined and container is running and + // has passed the postStart lifecycle hook. The null value must be treated the + // same as false. // +optional Started *bool `json:"started,omitempty" protobuf:"varint,9,opt,name=started"` + // AllocatedResources represents the compute resources allocated for this container by the + // node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission + // and after successfully admitting desired pod resize. + // +featureGate=InPlacePodVerticalScaling + // +optional + AllocatedResources ResourceList `json:"allocatedResources,omitempty" protobuf:"bytes,10,rep,name=allocatedResources,casttype=ResourceList,castkey=ResourceName"` + // Resources represents the compute resource requests and limits that have been successfully + // enacted on the running container after it has been started or has been successfully resized. + // +featureGate=InPlacePodVerticalScaling + // +optional + Resources *ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,11,opt,name=resources"` } // PodPhase is a label for the condition of a pod at the current time. @@ -2722,6 +2786,10 @@ const ( // TerminationByKubelet reason in DisruptionTarget pod condition indicates that the termination // is initiated by kubelet PodReasonTerminationByKubelet = "TerminationByKubelet" + + // PodReasonPreemptionByScheduler reason in DisruptionTarget pod condition indicates that the + // disruption was initiated by scheduler's preemption. + PodReasonPreemptionByScheduler = "PreemptionByScheduler" ) // PodCondition contains details for the current condition of this pod. @@ -2747,6 +2815,20 @@ 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. +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. + PodResizeStatusDeferred PodResizeStatus = "Deferred" + // Requested pod resize is not feasible and will not be re-evaluated. + PodResizeStatusInfeasible PodResizeStatus = "Infeasible" +) + // RestartPolicy describes how the container should be restarted. // Only one of the following restart policies may be specified. // If none of the following policies is specified, the default one @@ -3157,7 +3239,7 @@ type PodSpec struct { // +patchStrategy=merge EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,34,rep,name=ephemeralContainers"` // Restart policy for all containers within the pod. - // One of Always, OnFailure, Never. + // 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 // +optional @@ -3383,14 +3465,19 @@ type PodSpec struct { HostUsers *bool `json:"hostUsers,omitempty" protobuf:"bytes,37,opt,name=hostUsers"` // SchedulingGates is an opaque list of values that if specified will block scheduling the pod. - // More info: https://git.k8s.io/enhancements/keps/sig-scheduling/3521-pod-scheduling-readiness. + // If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the + // scheduler will not attempt to schedule the pod. + // + // SchedulingGates can only be set at pod creation time, and be removed only afterwards. + // + // This is a beta feature enabled by the PodSchedulingReadiness feature gate. // - // This is an alpha-level feature enabled by PodSchedulingReadiness feature gate. - // +optional // +patchMergeKey=name // +patchStrategy=merge // +listType=map // +listMapKey=name + // +featureGate=PodSchedulingReadiness + // +optional SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,38,opt,name=schedulingGates"` // ResourceClaims defines which ResourceClaims must be allocated // and reserved before the Pod is allowed to start. The resources @@ -3611,8 +3698,12 @@ type TopologySpreadConstraint struct { // 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. Keys that don't exist in the incoming pod labels will + // 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. + // + // This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). // +listType=atomic // +optional MatchLabelKeys []string `json:"matchLabelKeys,omitempty" protobuf:"bytes,8,opt,name=matchLabelKeys"` @@ -3880,6 +3971,11 @@ type EphemeralContainerCommon struct { // already allocated to the pod. // +optional Resources ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` + // Resources resize policy for the container. + // +featureGate=InPlacePodVerticalScaling + // +optional + // +listType=atomic + ResizePolicy []ContainerResizePolicy `json:"resizePolicy,omitempty" protobuf:"bytes,23,rep,name=resizePolicy"` // Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. // Cannot be updated. // +optional @@ -4065,12 +4161,19 @@ type PodStatus struct { ContainerStatuses []ContainerStatus `json:"containerStatuses,omitempty" protobuf:"bytes,8,rep,name=containerStatuses"` // The Quality of Service (QOS) classification assigned to the pod based on resource requirements // See PodQOSClass type for available QOS classes - // More info: https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#quality-of-service-classes // +optional QOSClass PodQOSClass `json:"qosClass,omitempty" protobuf:"bytes,9,rep,name=qosClass"` // Status for any ephemeral containers that have run in this pod. // +optional EphemeralContainerStatuses []ContainerStatus `json:"ephemeralContainerStatuses,omitempty" protobuf:"bytes,13,rep,name=ephemeralContainerStatuses"` + + // 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" + // +featureGate=InPlacePodVerticalScaling + // +optional + Resize PodResizeStatus `json:"resize,omitempty" protobuf:"bytes,14,opt,name=resize,casttype=PodResizeStatus"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -4209,6 +4312,7 @@ type ReplicationControllerSpec struct { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. This takes precedence over a TemplateRef. + // The only allowed template.spec.restartPolicy value is "Always". // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template // +optional Template *PodTemplateSpec `json:"template,omitempty" protobuf:"bytes,3,opt,name=template"` @@ -4369,34 +4473,47 @@ const ( ServiceTypeExternalName ServiceType = "ExternalName" ) -// ServiceInternalTrafficPolicyType describes how nodes distribute service traffic they +// ServiceInternalTrafficPolicy describes how nodes distribute service traffic they // receive on the ClusterIP. // +enum -type ServiceInternalTrafficPolicyType string +type ServiceInternalTrafficPolicy string const ( // ServiceInternalTrafficPolicyCluster routes traffic to all endpoints. - ServiceInternalTrafficPolicyCluster ServiceInternalTrafficPolicyType = "Cluster" + ServiceInternalTrafficPolicyCluster ServiceInternalTrafficPolicy = "Cluster" // ServiceInternalTrafficPolicyLocal routes traffic only to endpoints on the same // node as the client pod (dropping the traffic if there are no local endpoints). - ServiceInternalTrafficPolicyLocal ServiceInternalTrafficPolicyType = "Local" + ServiceInternalTrafficPolicyLocal ServiceInternalTrafficPolicy = "Local" ) -// ServiceExternalTrafficPolicyType describes how nodes distribute service traffic they -// receive on one of the Service's "externally-facing" addresses (NodePorts, ExternalIPs, -// and LoadBalancer IPs). +// for backwards compat // +enum -type ServiceExternalTrafficPolicyType string +type ServiceInternalTrafficPolicyType = ServiceInternalTrafficPolicy + +// ServiceExternalTrafficPolicy describes how nodes distribute service traffic they +// receive on one of the Service's "externally-facing" addresses (NodePorts, ExternalIPs, +// and LoadBalancer IPs. +// +enum +type ServiceExternalTrafficPolicy string const ( - // ServiceExternalTrafficPolicyTypeCluster routes traffic to all endpoints. - ServiceExternalTrafficPolicyTypeCluster ServiceExternalTrafficPolicyType = "Cluster" + // ServiceExternalTrafficPolicyCluster routes traffic to all endpoints. + ServiceExternalTrafficPolicyCluster ServiceExternalTrafficPolicy = "Cluster" - // ServiceExternalTrafficPolicyTypeLocal preserves the source IP of the traffic by + // ServiceExternalTrafficPolicyLocal preserves the source IP of the traffic by // routing only to endpoints on the same node as the traffic was received on // (dropping the traffic if there are no local endpoints). - ServiceExternalTrafficPolicyTypeLocal ServiceExternalTrafficPolicyType = "Local" + ServiceExternalTrafficPolicyLocal ServiceExternalTrafficPolicy = "Local" +) + +// for backwards compat +// +enum +type ServiceExternalTrafficPolicyType = ServiceExternalTrafficPolicy + +const ( + ServiceExternalTrafficPolicyTypeLocal = ServiceExternalTrafficPolicyLocal + ServiceExternalTrafficPolicyTypeCluster = ServiceExternalTrafficPolicyCluster ) // These are the valid conditions of a service. @@ -4404,6 +4521,9 @@ const ( // LoadBalancerPortsError represents the condition of the requested ports // on the cloud load balancer instance. LoadBalancerPortsError = "LoadBalancerPortsError" + // LoadBalancerPortsErrorReason reason in ServiceStatus condition LoadBalancerPortsError + // means the LoadBalancer was not able to be configured correctly. + LoadBalancerPortsErrorReason = "LoadBalancerMixedProtocolNotSupported" ) // ServiceStatus represents the current status of a service. @@ -4629,7 +4749,7 @@ type ServiceSpec struct { // a NodePort from within the cluster may need to take traffic policy into account // when picking a node. // +optional - ExternalTrafficPolicy ServiceExternalTrafficPolicyType `json:"externalTrafficPolicy,omitempty" protobuf:"bytes,11,opt,name=externalTrafficPolicy"` + ExternalTrafficPolicy ServiceExternalTrafficPolicy `json:"externalTrafficPolicy,omitempty" protobuf:"bytes,11,opt,name=externalTrafficPolicy"` // healthCheckNodePort specifies the healthcheck nodePort for the service. // This only applies when type is set to LoadBalancer and @@ -4726,7 +4846,7 @@ type ServiceSpec struct { // "Cluster", uses the standard behavior of routing to all endpoints evenly // (possibly modified by topology and other features). // +optional - InternalTrafficPolicy *ServiceInternalTrafficPolicyType `json:"internalTrafficPolicy,omitempty" protobuf:"bytes,22,opt,name=internalTrafficPolicy"` + InternalTrafficPolicy *ServiceInternalTrafficPolicy `json:"internalTrafficPolicy,omitempty" protobuf:"bytes,22,opt,name=internalTrafficPolicy"` } // ServicePort contains information on service's port. @@ -4947,11 +5067,8 @@ type EndpointSubset struct { // +structType=atomic type EndpointAddress struct { // The IP of this endpoint. - // May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), - // or link-local multicast ((224.0.0.0/24). - // IPv6 is also accepted but not fully supported on all platforms. Also, certain - // kubernetes components, like kube-proxy, are not IPv6 ready. - // TODO: This should allow hostname or IP, See #4447. + // 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). IP string `json:"ip" protobuf:"bytes,1,opt,name=ip"` // The Hostname of this endpoint // +optional @@ -4984,10 +5101,17 @@ type EndpointPort struct { Protocol Protocol `json:"protocol,omitempty" protobuf:"bytes,3,opt,name=protocol,casttype=Protocol"` // 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. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional AppProtocol *string `json:"appProtocol,omitempty" protobuf:"bytes,4,opt,name=appProtocol"` @@ -5206,6 +5330,10 @@ type NodeStatus struct { // Note: This field is declared as mergeable, but the merge key is not sufficiently // unique, which can cause data corruption when it is merged. Callers should instead // use a full-replacement patch. See https://pr.k8s.io/79391 for an example. + // Consumers should assume that addresses can change during the + // lifetime of a Node. However, there are some exceptions where this may not + // be possible, such as Pods that inherit a Node's address in its own status or + // consumers of the downward API (status.hostIP). // +optional // +patchMergeKey=type // +patchStrategy=merge @@ -6760,6 +6888,13 @@ const ( PortForwardRequestIDHeader = "requestID" ) +const ( + // MixedProtocolNotSupported error in PortStatus means that the cloud provider + // can't publish the port on the load balancer because mixed values of protocols + // on the same LoadBalancer type of Service are not supported by the cloud provider. + MixedProtocolNotSupported = "MixedProtocolNotSupported" +) + // PortStatus represents the error condition of a service port type PortStatus struct { diff --git a/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go index 99391a423..a01ae3717 100644 --- a/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AWSElasticBlockStoreVolumeSource = map[string]string{ @@ -126,8 +126,8 @@ var map_CSIPersistentVolumeSource = map[string]string{ "controllerPublishSecretRef": "controllerPublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerPublishVolume and ControllerUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", "nodeStageSecretRef": "nodeStageSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeStageVolume and NodeStageVolume and NodeUnstageVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", "nodePublishSecretRef": "nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", - "controllerExpandSecretRef": "controllerExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerExpandVolume call. This is an beta field and requires enabling ExpandCSIVolumes feature gate. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", - "nodeExpandSecretRef": "nodeExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeExpandVolume call. This is an alpha field and requires enabling CSINodeExpandSecret feature gate. This field is optional, may be omitted if no secret is required. If the secret object contains more than one secret, all secrets are passed.", + "controllerExpandSecretRef": "controllerExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI ControllerExpandVolume call. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secrets are passed.", + "nodeExpandSecretRef": "nodeExpandSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodeExpandVolume call. This is a beta field which is enabled default by CSINodeExpandSecret feature gate. This field is optional, may be omitted if no secret is required. If the secret object contains more than one secret, all secrets are passed.", } func (CSIPersistentVolumeSource) SwaggerDoc() map[string]string { @@ -346,6 +346,7 @@ var map_Container = map[string]string{ "envFrom": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "env": "List of environment variables to set in the container. Cannot be updated.", "resources": "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "resizePolicy": "Resources resize policy for the container.", "volumeMounts": "Pod volumes to mount into the container's filesystem. Cannot be updated.", "volumeDevices": "volumeDevices is the list of block devices to be used by the container.", "livenessProbe": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", @@ -388,6 +389,16 @@ func (ContainerPort) SwaggerDoc() map[string]string { return map_ContainerPort } +var map_ContainerResizePolicy = map[string]string{ + "": "ContainerResizePolicy represents resource resize policy for the container.", + "resourceName": "Name of the resource to which this resource resize policy applies. Supported values: cpu, memory.", + "restartPolicy": "Restart policy to apply when specified resource is resized. If not specified, it defaults to NotRequired.", +} + +func (ContainerResizePolicy) SwaggerDoc() map[string]string { + return map_ContainerResizePolicy +} + var map_ContainerState = map[string]string{ "": "ContainerState holds a possible state of container. Only one of its members may be specified. If none of them is specified, the default one is ContainerStateWaiting.", "waiting": "Details about a waiting container", @@ -434,16 +445,18 @@ func (ContainerStateWaiting) SwaggerDoc() map[string]string { } var map_ContainerStatus = map[string]string{ - "": "ContainerStatus contains details for the current status of this container.", - "name": "This must be a DNS_LABEL. Each container in a pod must have a unique name. Cannot be updated.", - "state": "Details about the container's current condition.", - "lastState": "Details about the container's last termination condition.", - "ready": "Specifies whether the container has passed its readiness probe.", - "restartCount": "The number of times the container has been restarted.", - "image": "The image the container is running. More info: https://kubernetes.io/docs/concepts/containers/images.", - "imageID": "ImageID of the container's image.", - "containerID": "Container's ID in the format '://'.", - "started": "Specifies whether the container has passed its startup probe. Initialized as false, becomes true after startupProbe is considered successful. Resets to false when the container is restarted, or if kubelet loses state temporarily. Is always true when no startupProbe is defined.", + "": "ContainerStatus contains details for the current status of this container.", + "name": "Name is a DNS_LABEL representing the unique name of the container. Each container in a pod must have a unique name across all container types. Cannot be updated.", + "state": "State holds details about the container's current condition.", + "lastState": "LastTerminationState holds the last termination state of the container to help debug container crashes and restarts. This field is not populated if the container is still running and RestartCount is 0.", + "ready": "Ready specifies whether the container is currently passing its readiness check. The value will change as readiness probes keep executing. If no readiness probes are specified, this field defaults to true once the container is fully started (see Started field).\n\nThe value is typically used to determine whether a container is ready to accept traffic.", + "restartCount": "RestartCount holds the number of times the container has been restarted. Kubelet makes an effort to always increment the value, but there are cases when the state may be lost due to node restarts and then the value may be reset to 0. The value is never negative.", + "image": "Image is the name of container image that the container is running. The container image may not match the image used in the PodSpec, as it may have been resolved by the runtime. More info: https://kubernetes.io/docs/concepts/containers/images.", + "imageID": "ImageID is the image ID of the container's image. The image ID may not match the image ID of the image used in the PodSpec, as it may have been resolved by the runtime.", + "containerID": "ContainerID is the ID of the container in the format '://'. Where type is a container runtime identifier, returned from Version call of CRI API (for example \"containerd\").", + "started": "Started indicates whether the container has finished its postStart lifecycle hook and passed its startup probe. Initialized as false, becomes true after startupProbe is considered successful. Resets to false when the container is restarted, or if kubelet loses state temporarily. In both cases, startup probes will run again. Is always true when no startupProbe is defined and container is running and has passed the postStart lifecycle hook. The null value must be treated the same as false.", + "allocatedResources": "AllocatedResources represents the compute resources allocated for this container by the node. Kubelet sets this value to Container.Resources.Requests upon successful pod admission and after successfully admitting desired pod resize.", + "resources": "Resources represents the compute resource requests and limits that have been successfully enacted on the running container after it has been started or has been successfully resized.", } func (ContainerStatus) SwaggerDoc() map[string]string { @@ -493,7 +506,7 @@ func (DownwardAPIVolumeSource) SwaggerDoc() map[string]string { var map_EmptyDirVolumeSource = map[string]string{ "": "Represents an empty directory for a pod. Empty directory volumes support ownership management and SELinux relabeling.", "medium": "medium represents what type of storage medium should back this directory. The default is \"\" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir", - "sizeLimit": "sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir", + "sizeLimit": "sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir", } func (EmptyDirVolumeSource) SwaggerDoc() map[string]string { @@ -502,7 +515,7 @@ func (EmptyDirVolumeSource) SwaggerDoc() map[string]string { var map_EndpointAddress = map[string]string{ "": "EndpointAddress is a tuple that describes single IP address.", - "ip": "The IP of this endpoint. May not be loopback (127.0.0.0/8), link-local (169.254.0.0/16), or link-local multicast ((224.0.0.0/24). IPv6 is also accepted but not fully supported on all platforms. Also, certain kubernetes components, like kube-proxy, are not IPv6 ready.", + "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.", "targetRef": "Reference to object providing the endpoint.", @@ -517,7 +530,7 @@ var map_EndpointPort = map[string]string{ "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.", - "appProtocol": "The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", + "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 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", } func (EndpointPort) SwaggerDoc() map[string]string { @@ -609,6 +622,7 @@ var map_EphemeralContainerCommon = map[string]string{ "envFrom": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", "env": "List of environment variables to set in the container. Cannot be updated.", "resources": "Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod.", + "resizePolicy": "Resources resize policy for the container.", "volumeMounts": "Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. Cannot be updated.", "volumeDevices": "volumeDevices is the list of block devices to be used by the container.", "livenessProbe": "Probes are not allowed for ephemeral containers.", @@ -818,7 +832,7 @@ func (HTTPGetAction) SwaggerDoc() map[string]string { var map_HTTPHeader = map[string]string{ "": "HTTPHeader describes a custom header to be used in HTTP probes", - "name": "The header field name", + "name": "The header field name. This will be canonicalized upon output, so case-variant names will be understood as the same header.", "value": "The header field value", } @@ -1213,7 +1227,7 @@ var map_NodeStatus = map[string]string{ "allocatable": "Allocatable represents the resources of a node that are available for scheduling. Defaults to Capacity.", "phase": "NodePhase is the recently observed lifecycle phase of the node. More info: https://kubernetes.io/docs/concepts/nodes/node/#phase The field is never populated, and now is deprecated.", "conditions": "Conditions is an array of current observed node conditions. More info: https://kubernetes.io/docs/concepts/nodes/node/#condition", - "addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: https://kubernetes.io/docs/concepts/nodes/node/#addresses Note: This field is declared as mergeable, but the merge key is not sufficiently unique, which can cause data corruption when it is merged. Callers should instead use a full-replacement patch. See https://pr.k8s.io/79391 for an example.", + "addresses": "List of addresses reachable to the node. Queried from cloud provider, if available. More info: https://kubernetes.io/docs/concepts/nodes/node/#addresses Note: This field is declared as mergeable, but the merge key is not sufficiently unique, which can cause data corruption when it is merged. Callers should instead use a full-replacement patch. See https://pr.k8s.io/79391 for an example. Consumers should assume that addresses can change during the lifetime of a Node. However, there are some exceptions where this may not be possible, such as Pods that inherit a Node's address in its own status or consumers of the downward API (status.hostIP).", "daemonEndpoints": "Endpoints of daemons running on the Node.", "nodeInfo": "Set of ids/uuids to uniquely identify the node. More info: https://kubernetes.io/docs/concepts/nodes/node/#info", "images": "List of container images on this node", @@ -1292,7 +1306,7 @@ func (PersistentVolumeClaim) SwaggerDoc() map[string]string { } var map_PersistentVolumeClaimCondition = map[string]string{ - "": "PersistentVolumeClaimCondition contails details about state of pvc", + "": "PersistentVolumeClaimCondition contains details about state of pvc", "lastProbeTime": "lastProbeTime is the time we probed the condition.", "lastTransitionTime": "lastTransitionTime is the time the condition transitioned from one status to another.", "reason": "reason is a unique, this should be a short, machine understandable string that gives the reason for condition's last transition. If it reports \"ResizeStarted\" that means the underlying persistent volume is being resized.", @@ -1668,7 +1682,7 @@ var map_PodSpec = map[string]string{ "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/", "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. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy", + "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", "terminationGracePeriodSeconds": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.", "activeDeadlineSeconds": "Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer.", "dnsPolicy": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.", @@ -1701,7 +1715,7 @@ var map_PodSpec = map[string]string{ "setHostnameAsFQDN": "If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. If a pod does not have FQDN, this has no effect. Default to false.", "os": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.hostUsers - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup", "hostUsers": "Use the host's user namespace. Optional: Default to true. If set to true or not present, the pod will be run in the host user namespace, useful for when the pod needs a feature only available to the host user namespace, such as loading a kernel module with CAP_SYS_MODULE. When set to false, a new userns is created for the pod. Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root without actually having root privileges on the host. This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.", - "schedulingGates": "SchedulingGates is an opaque list of values that if specified will block scheduling the pod. More info: https://git.k8s.io/enhancements/keps/sig-scheduling/3521-pod-scheduling-readiness.\n\nThis is an alpha-level feature enabled by PodSchedulingReadiness feature gate.", + "schedulingGates": "SchedulingGates is an opaque list of values that if specified will block scheduling the pod. If schedulingGates is not empty, the pod will stay in the SchedulingGated state and the scheduler will not attempt to schedule the pod.\n\nSchedulingGates can only be set at pod creation time, and be removed only afterwards.\n\nThis is a beta feature enabled by the PodSchedulingReadiness feature gate.", "resourceClaims": "ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name.\n\nThis is an alpha field and requires enabling the DynamicResourceAllocation feature gate.\n\nThis field is immutable.", } @@ -1722,8 +1736,9 @@ var map_PodStatus = map[string]string{ "startTime": "RFC 3339 date and time at which the object was acknowledged by the Kubelet. This is before the Kubelet pulled the container image(s) for the pod.", "initContainerStatuses": "The list has one entry per init container in the manifest. The most recent successful init container will have ready = true, the most recently started container will have startTime set. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", "containerStatuses": "The list has one entry per container in the manifest. 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://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md", + "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": "Status for any ephemeral containers that have run in this pod.", + "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\"", } func (PodStatus) SwaggerDoc() map[string]string { @@ -1841,7 +1856,7 @@ var map_ProbeHandler = map[string]string{ "exec": "Exec specifies the action to take.", "httpGet": "HTTPGet specifies the http request to perform.", "tcpSocket": "TCPSocket specifies an action involving a TCP port.", - "grpc": "GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate.", + "grpc": "GRPC specifies an action involving a GRPC port.", } func (ProbeHandler) SwaggerDoc() map[string]string { @@ -1954,7 +1969,7 @@ var map_ReplicationControllerSpec = map[string]string{ "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", "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 Replicas count. If 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 replication controller, if empty defaulted to labels on Pod template. 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. This takes precedence over a TemplateRef. 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. This takes precedence over a TemplateRef. The only allowed template.spec.restartPolicy value is \"Always\". More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", } func (ReplicationControllerSpec) SwaggerDoc() map[string]string { @@ -2040,7 +2055,7 @@ func (ResourceQuotaStatus) SwaggerDoc() map[string]string { var map_ResourceRequirements = map[string]string{ "": "ResourceRequirements describes the compute resource requirements.", "limits": "Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", - "requests": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "requests": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", "claims": "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.\n\nThis is an alpha field and requires enabling the DynamicResourceAllocation feature gate.\n\nThis field is immutable. It can only be set for containers.", } @@ -2450,7 +2465,7 @@ var map_TopologySpreadConstraint = map[string]string{ "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.", - "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. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector.", + "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).", } func (TopologySpreadConstraint) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go b/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go index 2bf1c8ad6..bfb7e0bff 100644 --- a/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go @@ -788,6 +788,11 @@ func (in *Container) DeepCopyInto(out *Container) { } } in.Resources.DeepCopyInto(&out.Resources) + if in.ResizePolicy != nil { + in, out := &in.ResizePolicy, &out.ResizePolicy + *out = make([]ContainerResizePolicy, len(*in)) + copy(*out, *in) + } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts *out = make([]VolumeMount, len(*in)) @@ -875,6 +880,22 @@ func (in *ContainerPort) DeepCopy() *ContainerPort { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerResizePolicy) DeepCopyInto(out *ContainerResizePolicy) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResizePolicy. +func (in *ContainerResizePolicy) DeepCopy() *ContainerResizePolicy { + if in == nil { + return nil + } + out := new(ContainerResizePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ContainerState) DeepCopyInto(out *ContainerState) { *out = *in @@ -967,6 +988,18 @@ func (in *ContainerStatus) DeepCopyInto(out *ContainerStatus) { *out = new(bool) **out = **in } + if in.AllocatedResources != nil { + in, out := &in.AllocatedResources, &out.AllocatedResources + *out = make(ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(ResourceRequirements) + (*in).DeepCopyInto(*out) + } return } @@ -1382,6 +1415,11 @@ func (in *EphemeralContainerCommon) DeepCopyInto(out *EphemeralContainerCommon) } } in.Resources.DeepCopyInto(&out.Resources) + if in.ResizePolicy != nil { + in, out := &in.ResizePolicy, &out.ResizePolicy + *out = make([]ContainerResizePolicy, len(*in)) + copy(*out, *in) + } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts *out = make([]VolumeMount, len(*in)) @@ -5517,7 +5555,7 @@ func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { } if in.InternalTrafficPolicy != nil { in, out := &in.InternalTrafficPolicy, &out.InternalTrafficPolicy - *out = new(ServiceInternalTrafficPolicyType) + *out = new(ServiceInternalTrafficPolicy) **out = **in } return diff --git a/vendor/k8s.io/api/discovery/v1/generated.proto b/vendor/k8s.io/api/discovery/v1/generated.proto index 9cbe46394..b7150ef2c 100644 --- a/vendor/k8s.io/api/discovery/v1/generated.proto +++ b/vendor/k8s.io/api/discovery/v1/generated.proto @@ -86,7 +86,9 @@ message EndpointConditions { // 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. + // "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. // +optional optional bool ready = 1; @@ -115,9 +117,8 @@ message EndpointHints { // EndpointPort represents a Port used by an EndpointSlice // +structType=atomic message EndpointPort { - // The name of this port. All ports in an EndpointSlice must have a unique - // name. If the EndpointSlice is dervied from a Kubernetes service, this - // corresponds to the Service.ports[].name. + // name represents the name of this port. All ports in an EndpointSlice must have a unique name. + // If the EndpointSlice is dervied 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 '-'. @@ -125,21 +126,28 @@ message EndpointPort { // Default is empty string. optional string name = 1; - // The IP protocol for this port. + // protocol represents the IP protocol for this port. // Must be UDP, TCP, or SCTP. // Default is TCP. optional string protocol = 2; - // The port number of the endpoint. + // 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. optional int32 port = 3; // 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. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional optional string appProtocol = 4; @@ -183,7 +191,7 @@ message EndpointSliceList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // List of endpoint slices + // items is the list of endpoint slices repeated EndpointSlice items = 2; } diff --git a/vendor/k8s.io/api/discovery/v1/types.go b/vendor/k8s.io/api/discovery/v1/types.go index 2df80c3d5..9b4daafca 100644 --- a/vendor/k8s.io/api/discovery/v1/types.go +++ b/vendor/k8s.io/api/discovery/v1/types.go @@ -29,9 +29,11 @@ import ( // labels, which must be joined to produce the full set of endpoints. type EndpointSlice struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // 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 @@ -40,10 +42,12 @@ type EndpointSlice struct { // * IPv6: Represents an IPv6 Address. // * FQDN: Represents a Fully Qualified Domain Name. AddressType AddressType `json:"addressType" protobuf:"bytes,4,rep,name=addressType"` + // endpoints is a list of unique endpoints in this slice. Each slice may // include a maximum of 1000 endpoints. // +listType=atomic 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 @@ -61,8 +65,10 @@ type AddressType string const ( // AddressTypeIPv4 represents an IPv4 Address. AddressTypeIPv4 = AddressType(v1.IPv4Protocol) + // AddressTypeIPv6 represents an IPv6 Address. AddressTypeIPv6 = AddressType(v1.IPv6Protocol) + // AddressTypeFQDN represents a FQDN. AddressTypeFQDN = AddressType("FQDN") ) @@ -77,8 +83,10 @@ type Endpoint struct { // use the first element. Refer to: https://issue.k8s.io/106267 // +listType=set Addresses []string `json:"addresses" protobuf:"bytes,1,rep,name=addresses"` + // conditions contains information about the current status of the endpoint. Conditions EndpointConditions `json:"conditions,omitempty" protobuf:"bytes,2,opt,name=conditions"` + // 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 @@ -86,6 +94,7 @@ type Endpoint struct { // Label (RFC 1123) validation. // +optional Hostname *string `json:"hostname,omitempty" protobuf:"bytes,3,opt,name=hostname"` + // targetRef is a reference to a Kubernetes object that represents this // endpoint. // +optional @@ -104,9 +113,11 @@ type Endpoint struct { // be used to determine endpoints local to a Node. // +optional NodeName *string `json:"nodeName,omitempty" protobuf:"bytes,6,opt,name=nodeName"` + // zone is the name of the Zone this endpoint exists in. // +optional Zone *string `json:"zone,omitempty" protobuf:"bytes,7,opt,name=zone"` + // hints contains information associated with how an endpoint should be // consumed. // +optional @@ -119,7 +130,9 @@ type EndpointConditions struct { // 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. + // "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. // +optional Ready *bool `json:"ready,omitempty" protobuf:"bytes,1,name=ready"` @@ -154,28 +167,37 @@ type ForZone struct { // EndpointPort represents a Port used by an EndpointSlice // +structType=atomic type EndpointPort struct { - // The name of this port. All ports in an EndpointSlice must have a unique - // name. If the EndpointSlice is dervied from a Kubernetes service, this - // corresponds to the Service.ports[].name. + // name represents the name of this port. All ports in an EndpointSlice must have a unique name. + // If the EndpointSlice is dervied 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. Name *string `json:"name,omitempty" protobuf:"bytes,1,name=name"` - // The IP protocol for this port. + + // protocol represents the IP protocol for this port. // Must be UDP, TCP, or SCTP. // Default is TCP. Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,2,name=protocol"` - // The port number of the endpoint. + + // 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 *int32 `json:"port,omitempty" protobuf:"bytes,3,opt,name=port"` + // 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. - // Un-prefixed names are reserved for IANA standard service names (as per + // Valid values are either: + // + // * Un-prefixed protocol names - reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). - // Non-standard protocols should use prefixed names such as + // + // * Kubernetes-defined prefixed names: + // * 'kubernetes.io/h2c' - HTTP/2 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540 + // + // * Other protocols should use implementation-defined prefixed names such as // mycompany.com/my-custom-protocol. // +optional AppProtocol *string `json:"appProtocol,omitempty" protobuf:"bytes,4,name=appProtocol"` @@ -186,9 +208,11 @@ type EndpointPort struct { // EndpointSliceList represents a list of endpoint slices type EndpointSliceList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // List of endpoint slices + + // items is the list of endpoint slices Items []EndpointSlice `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go index 746408b66..c780c9573 100644 --- a/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Endpoint = map[string]string{ @@ -45,7 +45,7 @@ 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.", + "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.", } @@ -65,10 +65,10 @@ func (EndpointHints) SwaggerDoc() map[string]string { var map_EndpointPort = map[string]string{ "": "EndpointPort represents a Port used by an EndpointSlice", - "name": "The name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied 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": "The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", - "port": "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.", - "appProtocol": "The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", + "name": "name represents the name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied 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.", + "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 over cleartext as described in https://www.rfc-editor.org/rfc/rfc7540\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", } func (EndpointPort) SwaggerDoc() map[string]string { @@ -90,7 +90,7 @@ func (EndpointSlice) SwaggerDoc() map[string]string { var map_EndpointSliceList = map[string]string{ "": "EndpointSliceList represents a list of endpoint slices", "metadata": "Standard list metadata.", - "items": "List of endpoint slices", + "items": "items is the list of endpoint slices", } func (EndpointSliceList) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/discovery/v1beta1/generated.proto b/vendor/k8s.io/api/discovery/v1beta1/generated.proto index 2979e64a7..8b6c360b0 100644 --- a/vendor/k8s.io/api/discovery/v1beta1/generated.proto +++ b/vendor/k8s.io/api/discovery/v1beta1/generated.proto @@ -118,9 +118,8 @@ message EndpointHints { // EndpointPort represents a Port used by an EndpointSlice message EndpointPort { - // The name of this port. All ports in an EndpointSlice must have a unique - // name. If the EndpointSlice is dervied from a Kubernetes service, this - // corresponds to the Service.ports[].name. + // name represents the name of this port. All ports in an EndpointSlice must have a unique name. + // If the EndpointSlice is dervied 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 '-'. @@ -128,17 +127,17 @@ message EndpointPort { // Default is empty string. optional string name = 1; - // The IP protocol for this port. + // protocol represents the IP protocol for this port. // Must be UDP, TCP, or SCTP. // Default is TCP. optional string protocol = 2; - // The port number of the endpoint. + // 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. optional int32 port = 3; - // The application protocol for this port. + // appProtocol represents the application protocol for this port. // This field follows standard Kubernetes label syntax. // Un-prefixed names are reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). @@ -186,7 +185,7 @@ message EndpointSliceList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // List of endpoint slices + // items is the list of endpoint slices repeated EndpointSlice items = 2; } diff --git a/vendor/k8s.io/api/discovery/v1beta1/types.go b/vendor/k8s.io/api/discovery/v1beta1/types.go index 7a02bead5..f09f7f320 100644 --- a/vendor/k8s.io/api/discovery/v1beta1/types.go +++ b/vendor/k8s.io/api/discovery/v1beta1/types.go @@ -33,9 +33,11 @@ import ( // labels, which must be joined to produce the full set of endpoints. type EndpointSlice struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // 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 @@ -44,10 +46,12 @@ type EndpointSlice struct { // * IPv6: Represents an IPv6 Address. // * FQDN: Represents a Fully Qualified Domain Name. AddressType AddressType `json:"addressType" protobuf:"bytes,4,rep,name=addressType"` + // endpoints is a list of unique endpoints in this slice. Each slice may // include a maximum of 1000 endpoints. // +listType=atomic 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 @@ -64,8 +68,10 @@ type AddressType string const ( // AddressTypeIPv4 represents an IPv4 Address. AddressTypeIPv4 = AddressType(v1.IPv4Protocol) + // AddressTypeIPv6 represents an IPv6 Address. AddressTypeIPv6 = AddressType(v1.IPv6Protocol) + // AddressTypeFQDN represents a FQDN. AddressTypeFQDN = AddressType("FQDN") ) @@ -80,8 +86,10 @@ type Endpoint struct { // use the first element. Refer to: https://issue.k8s.io/106267 // +listType=set Addresses []string `json:"addresses" protobuf:"bytes,1,rep,name=addresses"` + // conditions contains information about the current status of the endpoint. Conditions EndpointConditions `json:"conditions,omitempty" protobuf:"bytes,2,opt,name=conditions"` + // 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 @@ -89,10 +97,12 @@ type Endpoint struct { // Label (RFC 1123) validation. // +optional Hostname *string `json:"hostname,omitempty" protobuf:"bytes,3,opt,name=hostname"` + // targetRef is a reference to a Kubernetes object that represents this // endpoint. // +optional TargetRef *v1.ObjectReference `json:"targetRef,omitempty" protobuf:"bytes,4,opt,name=targetRef"` + // topology contains arbitrary topology information associated with the // endpoint. These key/value pairs must conform with the label format. // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels @@ -108,10 +118,12 @@ type Endpoint struct { // This field is deprecated and will be removed in future api versions. // +optional Topology map[string]string `json:"topology,omitempty" protobuf:"bytes,5,opt,name=topology"` + // nodeName represents the name of the Node hosting this endpoint. This can // be used to determine endpoints local to a Node. // +optional NodeName *string `json:"nodeName,omitempty" protobuf:"bytes,6,opt,name=nodeName"` + // hints contains information associated with how an endpoint should be // consumed. // +featureGate=TopologyAwareHints @@ -159,24 +171,26 @@ type ForZone struct { // EndpointPort represents a Port used by an EndpointSlice type EndpointPort struct { - // The name of this port. All ports in an EndpointSlice must have a unique - // name. If the EndpointSlice is dervied from a Kubernetes service, this - // corresponds to the Service.ports[].name. + // name represents the name of this port. All ports in an EndpointSlice must have a unique name. + // If the EndpointSlice is dervied 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. Name *string `json:"name,omitempty" protobuf:"bytes,1,name=name"` - // The IP protocol for this port. + + // protocol represents the IP protocol for this port. // Must be UDP, TCP, or SCTP. // Default is TCP. Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,2,name=protocol"` - // The port number of the endpoint. + + // 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 *int32 `json:"port,omitempty" protobuf:"bytes,3,opt,name=port"` - // The application protocol for this port. + + // appProtocol represents the application protocol for this port. // This field follows standard Kubernetes label syntax. // Un-prefixed names are reserved for IANA standard service names (as per // RFC-6335 and https://www.iana.org/assignments/service-names). @@ -195,9 +209,11 @@ type EndpointPort struct { // EndpointSliceList represents a list of endpoint slices type EndpointSliceList struct { metav1.TypeMeta `json:",inline"` + // Standard list metadata. // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // List of endpoint slices + + // items is the list of endpoint slices Items []EndpointSlice `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go index e1c974b39..b1d4c306c 100644 --- a/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Endpoint = map[string]string{ @@ -64,10 +64,10 @@ func (EndpointHints) SwaggerDoc() map[string]string { var map_EndpointPort = map[string]string{ "": "EndpointPort represents a Port used by an EndpointSlice", - "name": "The name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied 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": "The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", - "port": "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.", - "appProtocol": "The application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", + "name": "name represents the name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is dervied 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.", + "appProtocol": "appProtocol represents the application protocol for this port. This field follows standard Kubernetes label syntax. Un-prefixed names are reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names). Non-standard protocols should use prefixed names such as mycompany.com/my-custom-protocol.", } func (EndpointPort) SwaggerDoc() map[string]string { @@ -89,7 +89,7 @@ func (EndpointSlice) SwaggerDoc() map[string]string { var map_EndpointSliceList = map[string]string{ "": "EndpointSliceList represents a list of endpoint slices", "metadata": "Standard list metadata.", - "items": "List of endpoint slices", + "items": "items is the list of endpoint slices", } func (EndpointSliceList) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/events/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/events/v1/types_swagger_doc_generated.go index 797da63bb..44ac0c3bb 100644 --- a/vendor/k8s.io/api/events/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/events/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Event = map[string]string{ diff --git a/vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go index 0e6bd5a83..e6c28a4f8 100644 --- a/vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/events/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Event = map[string]string{ diff --git a/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go b/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go index 333142b3e..863ebbc4a 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go +++ b/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go @@ -49,94 +49,10 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -func (m *AllowedCSIDriver) Reset() { *m = AllowedCSIDriver{} } -func (*AllowedCSIDriver) ProtoMessage() {} -func (*AllowedCSIDriver) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{0} -} -func (m *AllowedCSIDriver) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AllowedCSIDriver) 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 *AllowedCSIDriver) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllowedCSIDriver.Merge(m, src) -} -func (m *AllowedCSIDriver) XXX_Size() int { - return m.Size() -} -func (m *AllowedCSIDriver) XXX_DiscardUnknown() { - xxx_messageInfo_AllowedCSIDriver.DiscardUnknown(m) -} - -var xxx_messageInfo_AllowedCSIDriver proto.InternalMessageInfo - -func (m *AllowedFlexVolume) Reset() { *m = AllowedFlexVolume{} } -func (*AllowedFlexVolume) ProtoMessage() {} -func (*AllowedFlexVolume) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{1} -} -func (m *AllowedFlexVolume) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AllowedFlexVolume) 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 *AllowedFlexVolume) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllowedFlexVolume.Merge(m, src) -} -func (m *AllowedFlexVolume) XXX_Size() int { - return m.Size() -} -func (m *AllowedFlexVolume) XXX_DiscardUnknown() { - xxx_messageInfo_AllowedFlexVolume.DiscardUnknown(m) -} - -var xxx_messageInfo_AllowedFlexVolume proto.InternalMessageInfo - -func (m *AllowedHostPath) Reset() { *m = AllowedHostPath{} } -func (*AllowedHostPath) ProtoMessage() {} -func (*AllowedHostPath) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{2} -} -func (m *AllowedHostPath) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AllowedHostPath) 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 *AllowedHostPath) XXX_Merge(src proto.Message) { - xxx_messageInfo_AllowedHostPath.Merge(m, src) -} -func (m *AllowedHostPath) XXX_Size() int { - return m.Size() -} -func (m *AllowedHostPath) XXX_DiscardUnknown() { - xxx_messageInfo_AllowedHostPath.DiscardUnknown(m) -} - -var xxx_messageInfo_AllowedHostPath proto.InternalMessageInfo - func (m *DaemonSet) Reset() { *m = DaemonSet{} } func (*DaemonSet) ProtoMessage() {} func (*DaemonSet) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{3} + return fileDescriptor_cdc93917efc28165, []int{0} } func (m *DaemonSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -164,7 +80,7 @@ var xxx_messageInfo_DaemonSet proto.InternalMessageInfo func (m *DaemonSetCondition) Reset() { *m = DaemonSetCondition{} } func (*DaemonSetCondition) ProtoMessage() {} func (*DaemonSetCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{4} + return fileDescriptor_cdc93917efc28165, []int{1} } func (m *DaemonSetCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -192,7 +108,7 @@ var xxx_messageInfo_DaemonSetCondition proto.InternalMessageInfo func (m *DaemonSetList) Reset() { *m = DaemonSetList{} } func (*DaemonSetList) ProtoMessage() {} func (*DaemonSetList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{5} + return fileDescriptor_cdc93917efc28165, []int{2} } func (m *DaemonSetList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -220,7 +136,7 @@ var xxx_messageInfo_DaemonSetList proto.InternalMessageInfo func (m *DaemonSetSpec) Reset() { *m = DaemonSetSpec{} } func (*DaemonSetSpec) ProtoMessage() {} func (*DaemonSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{6} + return fileDescriptor_cdc93917efc28165, []int{3} } func (m *DaemonSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -248,7 +164,7 @@ var xxx_messageInfo_DaemonSetSpec proto.InternalMessageInfo func (m *DaemonSetStatus) Reset() { *m = DaemonSetStatus{} } func (*DaemonSetStatus) ProtoMessage() {} func (*DaemonSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{7} + return fileDescriptor_cdc93917efc28165, []int{4} } func (m *DaemonSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -276,7 +192,7 @@ var xxx_messageInfo_DaemonSetStatus proto.InternalMessageInfo func (m *DaemonSetUpdateStrategy) Reset() { *m = DaemonSetUpdateStrategy{} } func (*DaemonSetUpdateStrategy) ProtoMessage() {} func (*DaemonSetUpdateStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{8} + return fileDescriptor_cdc93917efc28165, []int{5} } func (m *DaemonSetUpdateStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -304,7 +220,7 @@ var xxx_messageInfo_DaemonSetUpdateStrategy proto.InternalMessageInfo func (m *Deployment) Reset() { *m = Deployment{} } func (*Deployment) ProtoMessage() {} func (*Deployment) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{9} + return fileDescriptor_cdc93917efc28165, []int{6} } func (m *Deployment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -332,7 +248,7 @@ var xxx_messageInfo_Deployment proto.InternalMessageInfo func (m *DeploymentCondition) Reset() { *m = DeploymentCondition{} } func (*DeploymentCondition) ProtoMessage() {} func (*DeploymentCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{10} + return fileDescriptor_cdc93917efc28165, []int{7} } func (m *DeploymentCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -360,7 +276,7 @@ var xxx_messageInfo_DeploymentCondition proto.InternalMessageInfo func (m *DeploymentList) Reset() { *m = DeploymentList{} } func (*DeploymentList) ProtoMessage() {} func (*DeploymentList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{11} + return fileDescriptor_cdc93917efc28165, []int{8} } func (m *DeploymentList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -388,7 +304,7 @@ var xxx_messageInfo_DeploymentList proto.InternalMessageInfo func (m *DeploymentRollback) Reset() { *m = DeploymentRollback{} } func (*DeploymentRollback) ProtoMessage() {} func (*DeploymentRollback) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{12} + return fileDescriptor_cdc93917efc28165, []int{9} } func (m *DeploymentRollback) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -416,7 +332,7 @@ var xxx_messageInfo_DeploymentRollback proto.InternalMessageInfo func (m *DeploymentSpec) Reset() { *m = DeploymentSpec{} } func (*DeploymentSpec) ProtoMessage() {} func (*DeploymentSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{13} + return fileDescriptor_cdc93917efc28165, []int{10} } func (m *DeploymentSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -444,7 +360,7 @@ var xxx_messageInfo_DeploymentSpec proto.InternalMessageInfo func (m *DeploymentStatus) Reset() { *m = DeploymentStatus{} } func (*DeploymentStatus) ProtoMessage() {} func (*DeploymentStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{14} + return fileDescriptor_cdc93917efc28165, []int{11} } func (m *DeploymentStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -472,7 +388,7 @@ var xxx_messageInfo_DeploymentStatus proto.InternalMessageInfo func (m *DeploymentStrategy) Reset() { *m = DeploymentStrategy{} } func (*DeploymentStrategy) ProtoMessage() {} func (*DeploymentStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{15} + return fileDescriptor_cdc93917efc28165, []int{12} } func (m *DeploymentStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -497,38 +413,10 @@ func (m *DeploymentStrategy) XXX_DiscardUnknown() { var xxx_messageInfo_DeploymentStrategy proto.InternalMessageInfo -func (m *FSGroupStrategyOptions) Reset() { *m = FSGroupStrategyOptions{} } -func (*FSGroupStrategyOptions) ProtoMessage() {} -func (*FSGroupStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{16} -} -func (m *FSGroupStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *FSGroupStrategyOptions) 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 *FSGroupStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_FSGroupStrategyOptions.Merge(m, src) -} -func (m *FSGroupStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *FSGroupStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_FSGroupStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_FSGroupStrategyOptions proto.InternalMessageInfo - func (m *HTTPIngressPath) Reset() { *m = HTTPIngressPath{} } func (*HTTPIngressPath) ProtoMessage() {} func (*HTTPIngressPath) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{17} + return fileDescriptor_cdc93917efc28165, []int{13} } func (m *HTTPIngressPath) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -556,7 +444,7 @@ var xxx_messageInfo_HTTPIngressPath proto.InternalMessageInfo func (m *HTTPIngressRuleValue) Reset() { *m = HTTPIngressRuleValue{} } func (*HTTPIngressRuleValue) ProtoMessage() {} func (*HTTPIngressRuleValue) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{18} + return fileDescriptor_cdc93917efc28165, []int{14} } func (m *HTTPIngressRuleValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -581,66 +469,10 @@ func (m *HTTPIngressRuleValue) XXX_DiscardUnknown() { var xxx_messageInfo_HTTPIngressRuleValue proto.InternalMessageInfo -func (m *HostPortRange) Reset() { *m = HostPortRange{} } -func (*HostPortRange) ProtoMessage() {} -func (*HostPortRange) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{19} -} -func (m *HostPortRange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *HostPortRange) 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 *HostPortRange) XXX_Merge(src proto.Message) { - xxx_messageInfo_HostPortRange.Merge(m, src) -} -func (m *HostPortRange) XXX_Size() int { - return m.Size() -} -func (m *HostPortRange) XXX_DiscardUnknown() { - xxx_messageInfo_HostPortRange.DiscardUnknown(m) -} - -var xxx_messageInfo_HostPortRange proto.InternalMessageInfo - -func (m *IDRange) Reset() { *m = IDRange{} } -func (*IDRange) ProtoMessage() {} -func (*IDRange) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{20} -} -func (m *IDRange) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *IDRange) 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 *IDRange) XXX_Merge(src proto.Message) { - xxx_messageInfo_IDRange.Merge(m, src) -} -func (m *IDRange) XXX_Size() int { - return m.Size() -} -func (m *IDRange) XXX_DiscardUnknown() { - xxx_messageInfo_IDRange.DiscardUnknown(m) -} - -var xxx_messageInfo_IDRange proto.InternalMessageInfo - func (m *IPBlock) Reset() { *m = IPBlock{} } func (*IPBlock) ProtoMessage() {} func (*IPBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{21} + return fileDescriptor_cdc93917efc28165, []int{15} } func (m *IPBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -668,7 +500,7 @@ var xxx_messageInfo_IPBlock proto.InternalMessageInfo func (m *Ingress) Reset() { *m = Ingress{} } func (*Ingress) ProtoMessage() {} func (*Ingress) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{22} + return fileDescriptor_cdc93917efc28165, []int{16} } func (m *Ingress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -696,7 +528,7 @@ var xxx_messageInfo_Ingress proto.InternalMessageInfo func (m *IngressBackend) Reset() { *m = IngressBackend{} } func (*IngressBackend) ProtoMessage() {} func (*IngressBackend) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{23} + return fileDescriptor_cdc93917efc28165, []int{17} } func (m *IngressBackend) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -724,7 +556,7 @@ var xxx_messageInfo_IngressBackend proto.InternalMessageInfo func (m *IngressList) Reset() { *m = IngressList{} } func (*IngressList) ProtoMessage() {} func (*IngressList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{24} + return fileDescriptor_cdc93917efc28165, []int{18} } func (m *IngressList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -752,7 +584,7 @@ var xxx_messageInfo_IngressList proto.InternalMessageInfo func (m *IngressLoadBalancerIngress) Reset() { *m = IngressLoadBalancerIngress{} } func (*IngressLoadBalancerIngress) ProtoMessage() {} func (*IngressLoadBalancerIngress) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{25} + return fileDescriptor_cdc93917efc28165, []int{19} } func (m *IngressLoadBalancerIngress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -780,7 +612,7 @@ var xxx_messageInfo_IngressLoadBalancerIngress proto.InternalMessageInfo func (m *IngressLoadBalancerStatus) Reset() { *m = IngressLoadBalancerStatus{} } func (*IngressLoadBalancerStatus) ProtoMessage() {} func (*IngressLoadBalancerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{26} + return fileDescriptor_cdc93917efc28165, []int{20} } func (m *IngressLoadBalancerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -808,7 +640,7 @@ var xxx_messageInfo_IngressLoadBalancerStatus proto.InternalMessageInfo func (m *IngressPortStatus) Reset() { *m = IngressPortStatus{} } func (*IngressPortStatus) ProtoMessage() {} func (*IngressPortStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{27} + return fileDescriptor_cdc93917efc28165, []int{21} } func (m *IngressPortStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -836,7 +668,7 @@ var xxx_messageInfo_IngressPortStatus proto.InternalMessageInfo func (m *IngressRule) Reset() { *m = IngressRule{} } func (*IngressRule) ProtoMessage() {} func (*IngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{28} + return fileDescriptor_cdc93917efc28165, []int{22} } func (m *IngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -864,7 +696,7 @@ var xxx_messageInfo_IngressRule proto.InternalMessageInfo func (m *IngressRuleValue) Reset() { *m = IngressRuleValue{} } func (*IngressRuleValue) ProtoMessage() {} func (*IngressRuleValue) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{29} + return fileDescriptor_cdc93917efc28165, []int{23} } func (m *IngressRuleValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -892,7 +724,7 @@ var xxx_messageInfo_IngressRuleValue proto.InternalMessageInfo func (m *IngressSpec) Reset() { *m = IngressSpec{} } func (*IngressSpec) ProtoMessage() {} func (*IngressSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{30} + return fileDescriptor_cdc93917efc28165, []int{24} } func (m *IngressSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -920,7 +752,7 @@ var xxx_messageInfo_IngressSpec proto.InternalMessageInfo func (m *IngressStatus) Reset() { *m = IngressStatus{} } func (*IngressStatus) ProtoMessage() {} func (*IngressStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{31} + return fileDescriptor_cdc93917efc28165, []int{25} } func (m *IngressStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -948,7 +780,7 @@ var xxx_messageInfo_IngressStatus proto.InternalMessageInfo func (m *IngressTLS) Reset() { *m = IngressTLS{} } func (*IngressTLS) ProtoMessage() {} func (*IngressTLS) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{32} + return fileDescriptor_cdc93917efc28165, []int{26} } func (m *IngressTLS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -976,7 +808,7 @@ var xxx_messageInfo_IngressTLS proto.InternalMessageInfo func (m *NetworkPolicy) Reset() { *m = NetworkPolicy{} } func (*NetworkPolicy) ProtoMessage() {} func (*NetworkPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{33} + return fileDescriptor_cdc93917efc28165, []int{27} } func (m *NetworkPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1004,7 +836,7 @@ var xxx_messageInfo_NetworkPolicy proto.InternalMessageInfo func (m *NetworkPolicyEgressRule) Reset() { *m = NetworkPolicyEgressRule{} } func (*NetworkPolicyEgressRule) ProtoMessage() {} func (*NetworkPolicyEgressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{34} + return fileDescriptor_cdc93917efc28165, []int{28} } func (m *NetworkPolicyEgressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1032,7 +864,7 @@ var xxx_messageInfo_NetworkPolicyEgressRule proto.InternalMessageInfo func (m *NetworkPolicyIngressRule) Reset() { *m = NetworkPolicyIngressRule{} } func (*NetworkPolicyIngressRule) ProtoMessage() {} func (*NetworkPolicyIngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{35} + return fileDescriptor_cdc93917efc28165, []int{29} } func (m *NetworkPolicyIngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1060,7 +892,7 @@ var xxx_messageInfo_NetworkPolicyIngressRule proto.InternalMessageInfo func (m *NetworkPolicyList) Reset() { *m = NetworkPolicyList{} } func (*NetworkPolicyList) ProtoMessage() {} func (*NetworkPolicyList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{36} + return fileDescriptor_cdc93917efc28165, []int{30} } func (m *NetworkPolicyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1088,7 +920,7 @@ var xxx_messageInfo_NetworkPolicyList proto.InternalMessageInfo func (m *NetworkPolicyPeer) Reset() { *m = NetworkPolicyPeer{} } func (*NetworkPolicyPeer) ProtoMessage() {} func (*NetworkPolicyPeer) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{37} + return fileDescriptor_cdc93917efc28165, []int{31} } func (m *NetworkPolicyPeer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1116,7 +948,7 @@ var xxx_messageInfo_NetworkPolicyPeer proto.InternalMessageInfo func (m *NetworkPolicyPort) Reset() { *m = NetworkPolicyPort{} } func (*NetworkPolicyPort) ProtoMessage() {} func (*NetworkPolicyPort) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{38} + return fileDescriptor_cdc93917efc28165, []int{32} } func (m *NetworkPolicyPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1144,7 +976,7 @@ var xxx_messageInfo_NetworkPolicyPort proto.InternalMessageInfo func (m *NetworkPolicySpec) Reset() { *m = NetworkPolicySpec{} } func (*NetworkPolicySpec) ProtoMessage() {} func (*NetworkPolicySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{39} + return fileDescriptor_cdc93917efc28165, []int{33} } func (m *NetworkPolicySpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1172,7 +1004,7 @@ var xxx_messageInfo_NetworkPolicySpec proto.InternalMessageInfo func (m *NetworkPolicyStatus) Reset() { *m = NetworkPolicyStatus{} } func (*NetworkPolicyStatus) ProtoMessage() {} func (*NetworkPolicyStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{40} + return fileDescriptor_cdc93917efc28165, []int{34} } func (m *NetworkPolicyStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1197,94 +1029,10 @@ func (m *NetworkPolicyStatus) XXX_DiscardUnknown() { var xxx_messageInfo_NetworkPolicyStatus proto.InternalMessageInfo -func (m *PodSecurityPolicy) Reset() { *m = PodSecurityPolicy{} } -func (*PodSecurityPolicy) ProtoMessage() {} -func (*PodSecurityPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{41} -} -func (m *PodSecurityPolicy) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PodSecurityPolicy) 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 *PodSecurityPolicy) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSecurityPolicy.Merge(m, src) -} -func (m *PodSecurityPolicy) XXX_Size() int { - return m.Size() -} -func (m *PodSecurityPolicy) XXX_DiscardUnknown() { - xxx_messageInfo_PodSecurityPolicy.DiscardUnknown(m) -} - -var xxx_messageInfo_PodSecurityPolicy proto.InternalMessageInfo - -func (m *PodSecurityPolicyList) Reset() { *m = PodSecurityPolicyList{} } -func (*PodSecurityPolicyList) ProtoMessage() {} -func (*PodSecurityPolicyList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{42} -} -func (m *PodSecurityPolicyList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PodSecurityPolicyList) 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 *PodSecurityPolicyList) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSecurityPolicyList.Merge(m, src) -} -func (m *PodSecurityPolicyList) XXX_Size() int { - return m.Size() -} -func (m *PodSecurityPolicyList) XXX_DiscardUnknown() { - xxx_messageInfo_PodSecurityPolicyList.DiscardUnknown(m) -} - -var xxx_messageInfo_PodSecurityPolicyList proto.InternalMessageInfo - -func (m *PodSecurityPolicySpec) Reset() { *m = PodSecurityPolicySpec{} } -func (*PodSecurityPolicySpec) ProtoMessage() {} -func (*PodSecurityPolicySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{43} -} -func (m *PodSecurityPolicySpec) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PodSecurityPolicySpec) 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 *PodSecurityPolicySpec) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSecurityPolicySpec.Merge(m, src) -} -func (m *PodSecurityPolicySpec) XXX_Size() int { - return m.Size() -} -func (m *PodSecurityPolicySpec) XXX_DiscardUnknown() { - xxx_messageInfo_PodSecurityPolicySpec.DiscardUnknown(m) -} - -var xxx_messageInfo_PodSecurityPolicySpec proto.InternalMessageInfo - func (m *ReplicaSet) Reset() { *m = ReplicaSet{} } func (*ReplicaSet) ProtoMessage() {} func (*ReplicaSet) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{44} + return fileDescriptor_cdc93917efc28165, []int{35} } func (m *ReplicaSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1312,7 +1060,7 @@ var xxx_messageInfo_ReplicaSet proto.InternalMessageInfo func (m *ReplicaSetCondition) Reset() { *m = ReplicaSetCondition{} } func (*ReplicaSetCondition) ProtoMessage() {} func (*ReplicaSetCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{45} + return fileDescriptor_cdc93917efc28165, []int{36} } func (m *ReplicaSetCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1340,7 +1088,7 @@ var xxx_messageInfo_ReplicaSetCondition proto.InternalMessageInfo func (m *ReplicaSetList) Reset() { *m = ReplicaSetList{} } func (*ReplicaSetList) ProtoMessage() {} func (*ReplicaSetList) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{46} + return fileDescriptor_cdc93917efc28165, []int{37} } func (m *ReplicaSetList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1368,7 +1116,7 @@ var xxx_messageInfo_ReplicaSetList proto.InternalMessageInfo func (m *ReplicaSetSpec) Reset() { *m = ReplicaSetSpec{} } func (*ReplicaSetSpec) ProtoMessage() {} func (*ReplicaSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{47} + return fileDescriptor_cdc93917efc28165, []int{38} } func (m *ReplicaSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1396,7 +1144,7 @@ var xxx_messageInfo_ReplicaSetSpec proto.InternalMessageInfo func (m *ReplicaSetStatus) Reset() { *m = ReplicaSetStatus{} } func (*ReplicaSetStatus) ProtoMessage() {} func (*ReplicaSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{48} + return fileDescriptor_cdc93917efc28165, []int{39} } func (m *ReplicaSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1424,7 +1172,7 @@ var xxx_messageInfo_ReplicaSetStatus proto.InternalMessageInfo func (m *RollbackConfig) Reset() { *m = RollbackConfig{} } func (*RollbackConfig) ProtoMessage() {} func (*RollbackConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{49} + return fileDescriptor_cdc93917efc28165, []int{40} } func (m *RollbackConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1452,7 +1200,7 @@ var xxx_messageInfo_RollbackConfig proto.InternalMessageInfo func (m *RollingUpdateDaemonSet) Reset() { *m = RollingUpdateDaemonSet{} } func (*RollingUpdateDaemonSet) ProtoMessage() {} func (*RollingUpdateDaemonSet) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{50} + return fileDescriptor_cdc93917efc28165, []int{41} } func (m *RollingUpdateDaemonSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1480,7 +1228,7 @@ var xxx_messageInfo_RollingUpdateDaemonSet proto.InternalMessageInfo func (m *RollingUpdateDeployment) Reset() { *m = RollingUpdateDeployment{} } func (*RollingUpdateDeployment) ProtoMessage() {} func (*RollingUpdateDeployment) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{51} + return fileDescriptor_cdc93917efc28165, []int{42} } func (m *RollingUpdateDeployment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1505,122 +1253,10 @@ func (m *RollingUpdateDeployment) XXX_DiscardUnknown() { var xxx_messageInfo_RollingUpdateDeployment proto.InternalMessageInfo -func (m *RunAsGroupStrategyOptions) Reset() { *m = RunAsGroupStrategyOptions{} } -func (*RunAsGroupStrategyOptions) ProtoMessage() {} -func (*RunAsGroupStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{52} -} -func (m *RunAsGroupStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RunAsGroupStrategyOptions) 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 *RunAsGroupStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_RunAsGroupStrategyOptions.Merge(m, src) -} -func (m *RunAsGroupStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *RunAsGroupStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_RunAsGroupStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_RunAsGroupStrategyOptions proto.InternalMessageInfo - -func (m *RunAsUserStrategyOptions) Reset() { *m = RunAsUserStrategyOptions{} } -func (*RunAsUserStrategyOptions) ProtoMessage() {} -func (*RunAsUserStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{53} -} -func (m *RunAsUserStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RunAsUserStrategyOptions) 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 *RunAsUserStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_RunAsUserStrategyOptions.Merge(m, src) -} -func (m *RunAsUserStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *RunAsUserStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_RunAsUserStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_RunAsUserStrategyOptions proto.InternalMessageInfo - -func (m *RuntimeClassStrategyOptions) Reset() { *m = RuntimeClassStrategyOptions{} } -func (*RuntimeClassStrategyOptions) ProtoMessage() {} -func (*RuntimeClassStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{54} -} -func (m *RuntimeClassStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RuntimeClassStrategyOptions) 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 *RuntimeClassStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_RuntimeClassStrategyOptions.Merge(m, src) -} -func (m *RuntimeClassStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *RuntimeClassStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_RuntimeClassStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_RuntimeClassStrategyOptions proto.InternalMessageInfo - -func (m *SELinuxStrategyOptions) Reset() { *m = SELinuxStrategyOptions{} } -func (*SELinuxStrategyOptions) ProtoMessage() {} -func (*SELinuxStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{55} -} -func (m *SELinuxStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SELinuxStrategyOptions) 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 *SELinuxStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_SELinuxStrategyOptions.Merge(m, src) -} -func (m *SELinuxStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *SELinuxStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_SELinuxStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_SELinuxStrategyOptions proto.InternalMessageInfo - func (m *Scale) Reset() { *m = Scale{} } func (*Scale) ProtoMessage() {} func (*Scale) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{56} + return fileDescriptor_cdc93917efc28165, []int{43} } func (m *Scale) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1648,7 +1284,7 @@ var xxx_messageInfo_Scale proto.InternalMessageInfo func (m *ScaleSpec) Reset() { *m = ScaleSpec{} } func (*ScaleSpec) ProtoMessage() {} func (*ScaleSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{57} + return fileDescriptor_cdc93917efc28165, []int{44} } func (m *ScaleSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1676,7 +1312,7 @@ var xxx_messageInfo_ScaleSpec proto.InternalMessageInfo func (m *ScaleStatus) Reset() { *m = ScaleStatus{} } func (*ScaleStatus) ProtoMessage() {} func (*ScaleStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{58} + return fileDescriptor_cdc93917efc28165, []int{45} } func (m *ScaleStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1701,38 +1337,7 @@ func (m *ScaleStatus) XXX_DiscardUnknown() { var xxx_messageInfo_ScaleStatus proto.InternalMessageInfo -func (m *SupplementalGroupsStrategyOptions) Reset() { *m = SupplementalGroupsStrategyOptions{} } -func (*SupplementalGroupsStrategyOptions) ProtoMessage() {} -func (*SupplementalGroupsStrategyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_cdc93917efc28165, []int{59} -} -func (m *SupplementalGroupsStrategyOptions) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *SupplementalGroupsStrategyOptions) 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 *SupplementalGroupsStrategyOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_SupplementalGroupsStrategyOptions.Merge(m, src) -} -func (m *SupplementalGroupsStrategyOptions) XXX_Size() int { - return m.Size() -} -func (m *SupplementalGroupsStrategyOptions) XXX_DiscardUnknown() { - xxx_messageInfo_SupplementalGroupsStrategyOptions.DiscardUnknown(m) -} - -var xxx_messageInfo_SupplementalGroupsStrategyOptions proto.InternalMessageInfo - func init() { - proto.RegisterType((*AllowedCSIDriver)(nil), "k8s.io.api.extensions.v1beta1.AllowedCSIDriver") - proto.RegisterType((*AllowedFlexVolume)(nil), "k8s.io.api.extensions.v1beta1.AllowedFlexVolume") - proto.RegisterType((*AllowedHostPath)(nil), "k8s.io.api.extensions.v1beta1.AllowedHostPath") proto.RegisterType((*DaemonSet)(nil), "k8s.io.api.extensions.v1beta1.DaemonSet") proto.RegisterType((*DaemonSetCondition)(nil), "k8s.io.api.extensions.v1beta1.DaemonSetCondition") proto.RegisterType((*DaemonSetList)(nil), "k8s.io.api.extensions.v1beta1.DaemonSetList") @@ -1747,11 +1352,8 @@ func init() { proto.RegisterType((*DeploymentSpec)(nil), "k8s.io.api.extensions.v1beta1.DeploymentSpec") proto.RegisterType((*DeploymentStatus)(nil), "k8s.io.api.extensions.v1beta1.DeploymentStatus") proto.RegisterType((*DeploymentStrategy)(nil), "k8s.io.api.extensions.v1beta1.DeploymentStrategy") - proto.RegisterType((*FSGroupStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.FSGroupStrategyOptions") proto.RegisterType((*HTTPIngressPath)(nil), "k8s.io.api.extensions.v1beta1.HTTPIngressPath") proto.RegisterType((*HTTPIngressRuleValue)(nil), "k8s.io.api.extensions.v1beta1.HTTPIngressRuleValue") - proto.RegisterType((*HostPortRange)(nil), "k8s.io.api.extensions.v1beta1.HostPortRange") - proto.RegisterType((*IDRange)(nil), "k8s.io.api.extensions.v1beta1.IDRange") proto.RegisterType((*IPBlock)(nil), "k8s.io.api.extensions.v1beta1.IPBlock") proto.RegisterType((*Ingress)(nil), "k8s.io.api.extensions.v1beta1.Ingress") proto.RegisterType((*IngressBackend)(nil), "k8s.io.api.extensions.v1beta1.IngressBackend") @@ -1772,9 +1374,6 @@ func init() { proto.RegisterType((*NetworkPolicyPort)(nil), "k8s.io.api.extensions.v1beta1.NetworkPolicyPort") proto.RegisterType((*NetworkPolicySpec)(nil), "k8s.io.api.extensions.v1beta1.NetworkPolicySpec") proto.RegisterType((*NetworkPolicyStatus)(nil), "k8s.io.api.extensions.v1beta1.NetworkPolicyStatus") - proto.RegisterType((*PodSecurityPolicy)(nil), "k8s.io.api.extensions.v1beta1.PodSecurityPolicy") - proto.RegisterType((*PodSecurityPolicyList)(nil), "k8s.io.api.extensions.v1beta1.PodSecurityPolicyList") - proto.RegisterType((*PodSecurityPolicySpec)(nil), "k8s.io.api.extensions.v1beta1.PodSecurityPolicySpec") proto.RegisterType((*ReplicaSet)(nil), "k8s.io.api.extensions.v1beta1.ReplicaSet") proto.RegisterType((*ReplicaSetCondition)(nil), "k8s.io.api.extensions.v1beta1.ReplicaSetCondition") proto.RegisterType((*ReplicaSetList)(nil), "k8s.io.api.extensions.v1beta1.ReplicaSetList") @@ -1783,15 +1382,10 @@ func init() { proto.RegisterType((*RollbackConfig)(nil), "k8s.io.api.extensions.v1beta1.RollbackConfig") proto.RegisterType((*RollingUpdateDaemonSet)(nil), "k8s.io.api.extensions.v1beta1.RollingUpdateDaemonSet") proto.RegisterType((*RollingUpdateDeployment)(nil), "k8s.io.api.extensions.v1beta1.RollingUpdateDeployment") - proto.RegisterType((*RunAsGroupStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.RunAsGroupStrategyOptions") - proto.RegisterType((*RunAsUserStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.RunAsUserStrategyOptions") - proto.RegisterType((*RuntimeClassStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.RuntimeClassStrategyOptions") - proto.RegisterType((*SELinuxStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.SELinuxStrategyOptions") proto.RegisterType((*Scale)(nil), "k8s.io.api.extensions.v1beta1.Scale") proto.RegisterType((*ScaleSpec)(nil), "k8s.io.api.extensions.v1beta1.ScaleSpec") proto.RegisterType((*ScaleStatus)(nil), "k8s.io.api.extensions.v1beta1.ScaleStatus") proto.RegisterMapType((map[string]string)(nil), "k8s.io.api.extensions.v1beta1.ScaleStatus.SelectorEntry") - proto.RegisterType((*SupplementalGroupsStrategyOptions)(nil), "k8s.io.api.extensions.v1beta1.SupplementalGroupsStrategyOptions") } func init() { @@ -1799,344 +1393,188 @@ func init() { } var fileDescriptor_cdc93917efc28165 = []byte{ - // 3920 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5c, 0x4b, 0x6c, 0x1c, 0xd9, - 0x75, 0x55, 0x75, 0x93, 0xec, 0xe6, 0xa5, 0xf8, 0x7b, 0xa4, 0xc8, 0x1e, 0xca, 0x62, 0xcb, 0x35, - 0xc8, 0x44, 0x33, 0xd1, 0x74, 0x5b, 0x1c, 0x49, 0x1e, 0x8f, 0x10, 0x7b, 0xd8, 0xfc, 0x48, 0xb4, - 0xf9, 0xe9, 0x79, 0x4d, 0xca, 0xc6, 0x20, 0xe3, 0xb8, 0x58, 0xfd, 0xd8, 0xac, 0x61, 0x75, 0x55, - 0xa5, 0xaa, 0x9a, 0x66, 0x07, 0x59, 0x24, 0x48, 0x36, 0x06, 0x02, 0x24, 0x1b, 0x27, 0x59, 0x66, - 0x60, 0x20, 0xbb, 0x20, 0xcb, 0x64, 0xe1, 0x18, 0x09, 0xe2, 0x00, 0x42, 0xe0, 0x04, 0x06, 0xb2, - 0x88, 0x57, 0x44, 0x86, 0x5e, 0x05, 0x59, 0x65, 0x17, 0x68, 0x15, 0xbc, 0x4f, 0xfd, 0xab, 0xd8, - 0xd5, 0x8c, 0x44, 0xc4, 0x81, 0x57, 0x62, 0xbd, 0x7b, 0xef, 0x79, 0xbf, 0xfb, 0xee, 0x3d, 0xef, - 0xd3, 0x82, 0xcd, 0x93, 0xf7, 0x9d, 0x9a, 0x66, 0xd6, 0x4f, 0x7a, 0x87, 0xc4, 0x36, 0x88, 0x4b, - 0x9c, 0xfa, 0x29, 0x31, 0xda, 0xa6, 0x5d, 0x17, 0x02, 0xc5, 0xd2, 0xea, 0xe4, 0xcc, 0x25, 0x86, - 0xa3, 0x99, 0x86, 0x53, 0x3f, 0x7d, 0x70, 0x48, 0x5c, 0xe5, 0x41, 0xbd, 0x43, 0x0c, 0x62, 0x2b, - 0x2e, 0x69, 0xd7, 0x2c, 0xdb, 0x74, 0x4d, 0x74, 0x87, 0xab, 0xd7, 0x14, 0x4b, 0xab, 0x05, 0xea, - 0x35, 0xa1, 0xbe, 0xf4, 0x6e, 0x47, 0x73, 0x8f, 0x7b, 0x87, 0x35, 0xd5, 0xec, 0xd6, 0x3b, 0x66, - 0xc7, 0xac, 0x33, 0xab, 0xc3, 0xde, 0x11, 0xfb, 0x62, 0x1f, 0xec, 0x2f, 0x8e, 0xb6, 0x24, 0x87, - 0x2a, 0x57, 0x4d, 0x9b, 0xd4, 0x4f, 0x13, 0x35, 0x2e, 0x3d, 0x0c, 0x74, 0xba, 0x8a, 0x7a, 0xac, - 0x19, 0xc4, 0xee, 0xd7, 0xad, 0x93, 0x0e, 0x2d, 0x70, 0xea, 0x5d, 0xe2, 0x2a, 0x69, 0x56, 0xf5, - 0x2c, 0x2b, 0xbb, 0x67, 0xb8, 0x5a, 0x97, 0x24, 0x0c, 0x1e, 0x0f, 0x32, 0x70, 0xd4, 0x63, 0xd2, - 0x55, 0x12, 0x76, 0xef, 0x65, 0xd9, 0xf5, 0x5c, 0x4d, 0xaf, 0x6b, 0x86, 0xeb, 0xb8, 0x76, 0xdc, - 0x48, 0x7e, 0x08, 0x33, 0xab, 0xba, 0x6e, 0x7e, 0x97, 0xb4, 0xd7, 0x5a, 0x5b, 0xeb, 0xb6, 0x76, - 0x4a, 0x6c, 0x74, 0x17, 0x46, 0x0c, 0xa5, 0x4b, 0x2a, 0xd2, 0x5d, 0xe9, 0xde, 0x78, 0xe3, 0xe6, - 0x8b, 0xf3, 0xea, 0x8d, 0x8b, 0xf3, 0xea, 0xc8, 0xae, 0xd2, 0x25, 0x98, 0x49, 0xe4, 0x27, 0x30, - 0x2b, 0xac, 0x36, 0x75, 0x72, 0xf6, 0xdc, 0xd4, 0x7b, 0x5d, 0x82, 0xde, 0x82, 0xb1, 0x36, 0x03, - 0x10, 0x86, 0x53, 0xc2, 0x70, 0x8c, 0xc3, 0x62, 0x21, 0x95, 0x1d, 0x98, 0x16, 0xc6, 0xcf, 0x4c, - 0xc7, 0x6d, 0x2a, 0xee, 0x31, 0x5a, 0x01, 0xb0, 0x14, 0xf7, 0xb8, 0x69, 0x93, 0x23, 0xed, 0x4c, - 0x98, 0x23, 0x61, 0x0e, 0x4d, 0x5f, 0x82, 0x43, 0x5a, 0xe8, 0x3e, 0x94, 0x6d, 0xa2, 0xb4, 0xf7, - 0x0c, 0xbd, 0x5f, 0x29, 0xdc, 0x95, 0xee, 0x95, 0x1b, 0x33, 0xc2, 0xa2, 0x8c, 0x45, 0x39, 0xf6, - 0x35, 0xe4, 0xef, 0x17, 0x60, 0x7c, 0x5d, 0x21, 0x5d, 0xd3, 0x68, 0x11, 0x17, 0x7d, 0x07, 0xca, - 0x74, 0xba, 0xda, 0x8a, 0xab, 0xb0, 0xda, 0x26, 0x56, 0xbe, 0x54, 0x0b, 0xdc, 0xc9, 0x1f, 0xbd, - 0x9a, 0x75, 0xd2, 0xa1, 0x05, 0x4e, 0x8d, 0x6a, 0xd7, 0x4e, 0x1f, 0xd4, 0xf6, 0x0e, 0x3f, 0x25, - 0xaa, 0xbb, 0x43, 0x5c, 0x25, 0x68, 0x5f, 0x50, 0x86, 0x7d, 0x54, 0xb4, 0x0b, 0x23, 0x8e, 0x45, - 0x54, 0xd6, 0xb2, 0x89, 0x95, 0xfb, 0xb5, 0x4b, 0x9d, 0xb5, 0xe6, 0xb7, 0xac, 0x65, 0x11, 0x35, - 0x18, 0x71, 0xfa, 0x85, 0x19, 0x0e, 0x7a, 0x0e, 0x63, 0x8e, 0xab, 0xb8, 0x3d, 0xa7, 0x52, 0x64, - 0x88, 0xb5, 0xdc, 0x88, 0xcc, 0x2a, 0x98, 0x0c, 0xfe, 0x8d, 0x05, 0x9a, 0xfc, 0x1f, 0x05, 0x40, - 0xbe, 0xee, 0x9a, 0x69, 0xb4, 0x35, 0x57, 0x33, 0x0d, 0xf4, 0x01, 0x8c, 0xb8, 0x7d, 0xcb, 0x73, - 0x81, 0xb7, 0xbc, 0x06, 0xed, 0xf7, 0x2d, 0xf2, 0xf2, 0xbc, 0xba, 0x90, 0xb4, 0xa0, 0x12, 0xcc, - 0x6c, 0xd0, 0xb6, 0xdf, 0xd4, 0x02, 0xb3, 0x7e, 0x18, 0xad, 0xfa, 0xe5, 0x79, 0x35, 0x65, 0xb1, - 0xd5, 0x7c, 0xa4, 0x68, 0x03, 0xd1, 0x29, 0x20, 0x5d, 0x71, 0xdc, 0x7d, 0x5b, 0x31, 0x1c, 0x5e, - 0x93, 0xd6, 0x25, 0x62, 0x10, 0xde, 0xc9, 0x37, 0x69, 0xd4, 0xa2, 0xb1, 0x24, 0x5a, 0x81, 0xb6, - 0x13, 0x68, 0x38, 0xa5, 0x06, 0xea, 0xcd, 0x36, 0x51, 0x1c, 0xd3, 0xa8, 0x8c, 0x44, 0xbd, 0x19, - 0xb3, 0x52, 0x2c, 0xa4, 0xe8, 0x6d, 0x28, 0x75, 0x89, 0xe3, 0x28, 0x1d, 0x52, 0x19, 0x65, 0x8a, - 0xd3, 0x42, 0xb1, 0xb4, 0xc3, 0x8b, 0xb1, 0x27, 0x97, 0x7f, 0x28, 0xc1, 0xa4, 0x3f, 0x72, 0xdb, - 0x9a, 0xe3, 0xa2, 0xdf, 0x48, 0xf8, 0x61, 0x2d, 0x5f, 0x97, 0xa8, 0x35, 0xf3, 0x42, 0xdf, 0xe7, - 0xbd, 0x92, 0x90, 0x0f, 0xee, 0xc0, 0xa8, 0xe6, 0x92, 0x2e, 0x9d, 0x87, 0xe2, 0xbd, 0x89, 0x95, - 0x7b, 0x79, 0x5d, 0xa6, 0x31, 0x29, 0x40, 0x47, 0xb7, 0xa8, 0x39, 0xe6, 0x28, 0xf2, 0x9f, 0x8c, - 0x84, 0x9a, 0x4f, 0x5d, 0x13, 0x7d, 0x02, 0x65, 0x87, 0xe8, 0x44, 0x75, 0x4d, 0x5b, 0x34, 0xff, - 0xbd, 0x9c, 0xcd, 0x57, 0x0e, 0x89, 0xde, 0x12, 0xa6, 0x8d, 0x9b, 0xb4, 0xfd, 0xde, 0x17, 0xf6, - 0x21, 0xd1, 0x47, 0x50, 0x76, 0x49, 0xd7, 0xd2, 0x15, 0x97, 0x88, 0x75, 0xf4, 0x66, 0xb8, 0x0b, - 0xd4, 0x73, 0x28, 0x58, 0xd3, 0x6c, 0xef, 0x0b, 0x35, 0xb6, 0x7c, 0xfc, 0x21, 0xf1, 0x4a, 0xb1, - 0x0f, 0x83, 0x4e, 0x61, 0xaa, 0x67, 0xb5, 0xa9, 0xa6, 0x4b, 0xa3, 0x60, 0xa7, 0x2f, 0x3c, 0xe9, - 0x71, 0xde, 0xb1, 0x39, 0x88, 0x58, 0x37, 0x16, 0x44, 0x5d, 0x53, 0xd1, 0x72, 0x1c, 0xab, 0x05, - 0xad, 0xc2, 0x74, 0x57, 0x33, 0x68, 0x5c, 0xea, 0xb7, 0x88, 0x6a, 0x1a, 0x6d, 0x87, 0xb9, 0xd5, - 0x68, 0x63, 0x51, 0x00, 0x4c, 0xef, 0x44, 0xc5, 0x38, 0xae, 0x8f, 0xbe, 0x0e, 0xc8, 0xeb, 0xc6, - 0x53, 0x1e, 0xc4, 0x35, 0xd3, 0x60, 0x3e, 0x57, 0x0c, 0x9c, 0x7b, 0x3f, 0xa1, 0x81, 0x53, 0xac, - 0xd0, 0x36, 0xcc, 0xdb, 0xe4, 0x54, 0xa3, 0x7d, 0x7c, 0xa6, 0x39, 0xae, 0x69, 0xf7, 0xb7, 0xb5, - 0xae, 0xe6, 0x56, 0xc6, 0x58, 0x9b, 0x2a, 0x17, 0xe7, 0xd5, 0x79, 0x9c, 0x22, 0xc7, 0xa9, 0x56, - 0xf2, 0x9f, 0x8e, 0xc1, 0x74, 0x2c, 0xde, 0xa0, 0xe7, 0xb0, 0xa0, 0xf6, 0x6c, 0x9b, 0x18, 0xee, - 0x6e, 0xaf, 0x7b, 0x48, 0xec, 0x96, 0x7a, 0x4c, 0xda, 0x3d, 0x9d, 0xb4, 0x99, 0xa3, 0x8c, 0x36, - 0x96, 0x45, 0x8b, 0x17, 0xd6, 0x52, 0xb5, 0x70, 0x86, 0x35, 0x1d, 0x05, 0x83, 0x15, 0xed, 0x68, - 0x8e, 0xe3, 0x63, 0x16, 0x18, 0xa6, 0x3f, 0x0a, 0xbb, 0x09, 0x0d, 0x9c, 0x62, 0x45, 0xdb, 0xd8, - 0x26, 0x8e, 0x66, 0x93, 0x76, 0xbc, 0x8d, 0xc5, 0x68, 0x1b, 0xd7, 0x53, 0xb5, 0x70, 0x86, 0x35, - 0x7a, 0x04, 0x13, 0xbc, 0x36, 0x36, 0x7f, 0x62, 0xa2, 0xe7, 0x04, 0xd8, 0xc4, 0x6e, 0x20, 0xc2, - 0x61, 0x3d, 0xda, 0x35, 0xf3, 0xd0, 0x21, 0xf6, 0x29, 0x69, 0x67, 0x4f, 0xf0, 0x5e, 0x42, 0x03, - 0xa7, 0x58, 0xd1, 0xae, 0x71, 0x0f, 0x4c, 0x74, 0x6d, 0x2c, 0xda, 0xb5, 0x83, 0x54, 0x2d, 0x9c, - 0x61, 0x4d, 0xfd, 0x98, 0x37, 0x79, 0xf5, 0x54, 0xd1, 0x74, 0xe5, 0x50, 0x27, 0x95, 0x52, 0xd4, - 0x8f, 0x77, 0xa3, 0x62, 0x1c, 0xd7, 0x47, 0x4f, 0x61, 0x96, 0x17, 0x1d, 0x18, 0x8a, 0x0f, 0x52, - 0x66, 0x20, 0x6f, 0x08, 0x90, 0xd9, 0xdd, 0xb8, 0x02, 0x4e, 0xda, 0xa0, 0x0f, 0x60, 0x4a, 0x35, - 0x75, 0x9d, 0xf9, 0xe3, 0x9a, 0xd9, 0x33, 0xdc, 0xca, 0x38, 0x43, 0x41, 0x74, 0x3d, 0xae, 0x45, - 0x24, 0x38, 0xa6, 0x89, 0x08, 0x80, 0xea, 0x25, 0x1c, 0xa7, 0x02, 0x2c, 0x3e, 0x3e, 0xc8, 0x1b, - 0x03, 0xfc, 0x54, 0x15, 0x70, 0x00, 0xbf, 0xc8, 0xc1, 0x21, 0x60, 0xf9, 0x9f, 0x24, 0x58, 0xcc, - 0x08, 0x1d, 0xe8, 0x6b, 0x91, 0x14, 0xfb, 0x6b, 0xb1, 0x14, 0x7b, 0x3b, 0xc3, 0x2c, 0x94, 0x67, - 0x0d, 0x98, 0xb4, 0x69, 0xaf, 0x8c, 0x0e, 0x57, 0x11, 0x31, 0xf2, 0xd1, 0x80, 0x6e, 0xe0, 0xb0, - 0x4d, 0x10, 0xf3, 0x67, 0x2f, 0xce, 0xab, 0x93, 0x11, 0x19, 0x8e, 0xc2, 0xcb, 0x7f, 0x56, 0x00, - 0x58, 0x27, 0x96, 0x6e, 0xf6, 0xbb, 0xc4, 0xb8, 0x0e, 0x0e, 0xb5, 0x17, 0xe1, 0x50, 0xef, 0x0e, - 0x9a, 0x1e, 0xbf, 0x69, 0x99, 0x24, 0xea, 0x9b, 0x31, 0x12, 0x55, 0xcf, 0x0f, 0x79, 0x39, 0x8b, - 0xfa, 0xb7, 0x22, 0xcc, 0x05, 0xca, 0x01, 0x8d, 0x7a, 0x12, 0x99, 0xe3, 0x5f, 0x8d, 0xcd, 0xf1, - 0x62, 0x8a, 0xc9, 0x6b, 0xe3, 0x51, 0x9f, 0xc2, 0x14, 0x65, 0x39, 0x7c, 0x2e, 0x19, 0x87, 0x1a, - 0x1b, 0x9a, 0x43, 0xf9, 0xd9, 0x6e, 0x3b, 0x82, 0x84, 0x63, 0xc8, 0x19, 0x9c, 0xad, 0xf4, 0x8b, - 0xc8, 0xd9, 0x7e, 0x24, 0xc1, 0x54, 0x30, 0x4d, 0xd7, 0x40, 0xda, 0x76, 0xa3, 0xa4, 0xed, 0xed, - 0xdc, 0x2e, 0x9a, 0xc1, 0xda, 0xfe, 0x9b, 0x12, 0x7c, 0x5f, 0x89, 0x2e, 0xf0, 0x43, 0x45, 0x3d, - 0x19, 0xbc, 0xc7, 0x43, 0xdf, 0x97, 0x00, 0x89, 0x2c, 0xb0, 0x6a, 0x18, 0xa6, 0xab, 0xf0, 0x58, - 0xc9, 0x9b, 0xb5, 0x95, 0xbb, 0x59, 0x5e, 0x8d, 0xb5, 0x83, 0x04, 0xd6, 0x86, 0xe1, 0xda, 0xfd, - 0x60, 0x92, 0x93, 0x0a, 0x38, 0xa5, 0x01, 0x48, 0x01, 0xb0, 0x05, 0xe6, 0xbe, 0x29, 0x16, 0xf2, - 0xbb, 0x39, 0x62, 0x1e, 0x35, 0x58, 0x33, 0x8d, 0x23, 0xad, 0x13, 0x84, 0x1d, 0xec, 0x03, 0xe1, - 0x10, 0xe8, 0xd2, 0x06, 0x2c, 0x66, 0xb4, 0x16, 0xcd, 0x40, 0xf1, 0x84, 0xf4, 0xf9, 0xb0, 0x61, - 0xfa, 0x27, 0x9a, 0x87, 0xd1, 0x53, 0x45, 0xef, 0xf1, 0xf0, 0x3b, 0x8e, 0xf9, 0xc7, 0x07, 0x85, - 0xf7, 0x25, 0xf9, 0x87, 0xa3, 0x61, 0xdf, 0x61, 0x8c, 0xf9, 0x1e, 0xdd, 0xb4, 0x5a, 0xba, 0xa6, - 0x2a, 0x8e, 0x20, 0x42, 0x37, 0xf9, 0x86, 0x95, 0x97, 0x61, 0x5f, 0x1a, 0xe1, 0xd6, 0x85, 0xd7, - 0xcb, 0xad, 0x8b, 0xaf, 0x86, 0x5b, 0xff, 0x26, 0x94, 0x1d, 0x8f, 0x55, 0x8f, 0x30, 0xc8, 0x07, - 0x43, 0xc4, 0x57, 0x41, 0xa8, 0xfd, 0x0a, 0x7c, 0x2a, 0xed, 0x83, 0xa6, 0x91, 0xe8, 0xd1, 0x21, - 0x49, 0xf4, 0x2b, 0x25, 0xbe, 0x34, 0xde, 0x58, 0x4a, 0xcf, 0x21, 0x6d, 0x16, 0xdb, 0xca, 0x41, - 0xbc, 0x69, 0xb2, 0x52, 0x2c, 0xa4, 0xe8, 0x93, 0x88, 0xcb, 0x96, 0xaf, 0xe2, 0xb2, 0x53, 0xd9, - 0xee, 0x8a, 0x0e, 0x60, 0xd1, 0xb2, 0xcd, 0x8e, 0x4d, 0x1c, 0x67, 0x9d, 0x28, 0x6d, 0x5d, 0x33, - 0x88, 0x37, 0x3e, 0x9c, 0x11, 0xdd, 0xbe, 0x38, 0xaf, 0x2e, 0x36, 0xd3, 0x55, 0x70, 0x96, 0xad, - 0xfc, 0x62, 0x04, 0x66, 0xe2, 0x19, 0x30, 0x83, 0xa4, 0x4a, 0x57, 0x22, 0xa9, 0xf7, 0x43, 0x8b, - 0x81, 0x33, 0xf8, 0xd0, 0x09, 0x4e, 0x62, 0x41, 0xac, 0xc2, 0xb4, 0x88, 0x06, 0x9e, 0x50, 0xd0, - 0x74, 0x7f, 0xf6, 0x0f, 0xa2, 0x62, 0x1c, 0xd7, 0x47, 0x4f, 0x60, 0xd2, 0x66, 0xbc, 0xdb, 0x03, - 0xe0, 0xdc, 0xf5, 0x96, 0x00, 0x98, 0xc4, 0x61, 0x21, 0x8e, 0xea, 0x52, 0xde, 0x1a, 0xd0, 0x51, - 0x0f, 0x60, 0x24, 0xca, 0x5b, 0x57, 0xe3, 0x0a, 0x38, 0x69, 0x83, 0x76, 0x60, 0xae, 0x67, 0x24, - 0xa1, 0xb8, 0x2b, 0xdf, 0x16, 0x50, 0x73, 0x07, 0x49, 0x15, 0x9c, 0x66, 0x87, 0x8e, 0x22, 0x54, - 0x76, 0x8c, 0x85, 0xe7, 0x95, 0xdc, 0x0b, 0x2f, 0x37, 0x97, 0x4d, 0xa1, 0xdb, 0xe5, 0xbc, 0x74, - 0x5b, 0xfe, 0x7b, 0x29, 0x9c, 0x84, 0x7c, 0x0a, 0x3c, 0xe8, 0x94, 0x29, 0x61, 0x11, 0x62, 0x47, - 0x66, 0x3a, 0xfb, 0x7d, 0x3c, 0x14, 0xfb, 0x0d, 0x92, 0xe7, 0x60, 0xfa, 0xfb, 0x99, 0x04, 0x0b, - 0x9b, 0xad, 0xa7, 0xb6, 0xd9, 0xb3, 0xbc, 0xe6, 0xec, 0x59, 0x7c, 0x68, 0xbe, 0x0c, 0x23, 0x76, - 0x4f, 0xf7, 0xfa, 0xf1, 0xa6, 0xd7, 0x0f, 0xdc, 0xd3, 0x69, 0x3f, 0xe6, 0x62, 0x56, 0xbc, 0x13, - 0xd4, 0x00, 0xed, 0xc2, 0x98, 0xad, 0x18, 0x1d, 0xe2, 0xa5, 0xd5, 0xb7, 0x06, 0xb4, 0x7e, 0x6b, - 0x1d, 0x53, 0xf5, 0x10, 0xb1, 0x61, 0xd6, 0x58, 0xa0, 0xc8, 0xff, 0x20, 0xc1, 0xf4, 0xb3, 0xfd, - 0xfd, 0xe6, 0x96, 0xc1, 0x56, 0x34, 0x3b, 0x5b, 0xbd, 0x0b, 0x23, 0x96, 0xe2, 0x1e, 0xc7, 0x33, - 0x3d, 0x95, 0x61, 0x26, 0x41, 0x0f, 0xa1, 0x4c, 0xff, 0xa5, 0xed, 0x62, 0x4b, 0x6a, 0x9c, 0x05, - 0xc2, 0x72, 0x53, 0x94, 0xbd, 0x0c, 0xfd, 0x8d, 0x7d, 0x4d, 0xf4, 0x2d, 0x28, 0xd1, 0xf8, 0x43, - 0x8c, 0x76, 0x4e, 0x82, 0x2e, 0x1a, 0xd5, 0xe0, 0x46, 0x01, 0xe7, 0x12, 0x05, 0xd8, 0x83, 0x93, - 0x4f, 0x60, 0x3e, 0xd4, 0x09, 0x3a, 0x8a, 0xcf, 0x69, 0x4e, 0x45, 0x2d, 0x18, 0xa5, 0xb5, 0xd3, - 0xcc, 0x59, 0xcc, 0x71, 0x04, 0x1a, 0x1b, 0x88, 0x80, 0x1f, 0xd1, 0x2f, 0x07, 0x73, 0x2c, 0x79, - 0x07, 0x26, 0xd9, 0x31, 0xb4, 0x69, 0xbb, 0x6c, 0x30, 0xd1, 0x1d, 0x28, 0x76, 0x35, 0x43, 0x64, - 0xe7, 0x09, 0x61, 0x53, 0xa4, 0x99, 0x85, 0x96, 0x33, 0xb1, 0x72, 0x26, 0xe2, 0x55, 0x20, 0x56, - 0xce, 0x30, 0x2d, 0x97, 0x9f, 0x42, 0x49, 0x4c, 0x52, 0x18, 0xa8, 0x78, 0x39, 0x50, 0x31, 0x05, - 0x68, 0x0f, 0x4a, 0x5b, 0xcd, 0x86, 0x6e, 0x72, 0xae, 0xa6, 0x6a, 0x6d, 0x3b, 0x3e, 0x83, 0x6b, - 0x5b, 0xeb, 0x18, 0x33, 0x09, 0x92, 0x61, 0x8c, 0x9c, 0xa9, 0xc4, 0x72, 0x99, 0x1f, 0x8d, 0x37, - 0x80, 0xfa, 0xc6, 0x06, 0x2b, 0xc1, 0x42, 0x22, 0xff, 0x51, 0x01, 0x4a, 0x62, 0x38, 0xae, 0x61, - 0xef, 0xb6, 0x1d, 0xd9, 0xbb, 0xbd, 0x93, 0xcf, 0x35, 0x32, 0x37, 0x6e, 0xfb, 0xb1, 0x8d, 0xdb, - 0xfd, 0x9c, 0x78, 0x97, 0xef, 0xda, 0xbe, 0x57, 0x80, 0xa9, 0xa8, 0x53, 0xa2, 0x47, 0x30, 0x41, - 0xd3, 0x94, 0xa6, 0x92, 0xdd, 0x80, 0x1d, 0xfb, 0x47, 0x37, 0xad, 0x40, 0x84, 0xc3, 0x7a, 0xa8, - 0xe3, 0x9b, 0x51, 0x3f, 0x12, 0x9d, 0xce, 0x1e, 0xd2, 0x9e, 0xab, 0xe9, 0x35, 0x7e, 0x21, 0x53, - 0xdb, 0x32, 0xdc, 0x3d, 0xbb, 0xe5, 0xda, 0x9a, 0xd1, 0x49, 0x54, 0xc4, 0x9c, 0x32, 0x8c, 0x8c, - 0xbe, 0x49, 0x53, 0xa6, 0x63, 0xf6, 0x6c, 0x95, 0xa4, 0x51, 0x5f, 0x8f, 0xb6, 0xd1, 0x05, 0xda, - 0xde, 0x36, 0x55, 0x45, 0xe7, 0x93, 0x83, 0xc9, 0x11, 0xb1, 0x89, 0xa1, 0x12, 0x8f, 0x6e, 0x72, - 0x08, 0xec, 0x83, 0xc9, 0x7f, 0x23, 0xc1, 0x84, 0x18, 0x8b, 0x6b, 0xd8, 0xe4, 0x7c, 0x23, 0xba, - 0xc9, 0x79, 0x2b, 0x67, 0xe4, 0x48, 0xdf, 0xe1, 0xfc, 0xad, 0x04, 0x4b, 0x5e, 0xd3, 0x4d, 0xa5, - 0xdd, 0x50, 0x74, 0xc5, 0x50, 0x89, 0xed, 0xf9, 0xfa, 0x12, 0x14, 0x34, 0x4b, 0xcc, 0x24, 0x08, - 0x80, 0xc2, 0x56, 0x13, 0x17, 0x34, 0x8b, 0x32, 0x90, 0x63, 0xd3, 0x71, 0xd9, 0x4e, 0x88, 0x6f, - 0xb2, 0xfd, 0x56, 0x3f, 0x13, 0xe5, 0xd8, 0xd7, 0x40, 0x07, 0x30, 0x6a, 0x99, 0xb6, 0x4b, 0xb3, - 0x7e, 0x31, 0x36, 0xbf, 0x97, 0xb4, 0x9a, 0xce, 0x9b, 0x70, 0xc4, 0x20, 0x02, 0x51, 0x18, 0xcc, - 0xd1, 0xe4, 0xdf, 0x93, 0xe0, 0x8d, 0x94, 0xf6, 0x0b, 0xc2, 0xd5, 0x86, 0x92, 0xc6, 0x85, 0x22, - 0xec, 0x7d, 0x25, 0x5f, 0xb5, 0x29, 0x43, 0x11, 0x84, 0x5c, 0x2f, 0xb4, 0x7a, 0xd0, 0xf2, 0x0f, - 0x24, 0x98, 0x4d, 0xb4, 0x97, 0xa5, 0x0e, 0xea, 0xcf, 0x62, 0xa7, 0xe2, 0xa7, 0x0e, 0xea, 0x96, - 0x4c, 0x82, 0xbe, 0x01, 0x65, 0x76, 0x8f, 0xa8, 0x9a, 0xba, 0x18, 0xc0, 0xba, 0x37, 0x80, 0x4d, - 0x51, 0xfe, 0xf2, 0xbc, 0x7a, 0x3b, 0xe5, 0x9c, 0xc2, 0x13, 0x63, 0x1f, 0x00, 0x55, 0x61, 0x94, - 0xd8, 0xb6, 0x69, 0x8b, 0x24, 0x34, 0x4e, 0x47, 0x6a, 0x83, 0x16, 0x60, 0x5e, 0x2e, 0xff, 0x45, - 0xe0, 0xa4, 0x34, 0x2b, 0xd0, 0xf6, 0xd1, 0xc9, 0x89, 0x07, 0x46, 0x3a, 0x75, 0x98, 0x49, 0x50, - 0x0f, 0x66, 0xb4, 0x58, 0x1a, 0x11, 0xab, 0xb3, 0x9e, 0x6f, 0x18, 0x7d, 0xb3, 0x46, 0x45, 0xc0, - 0xcf, 0xc4, 0x25, 0x38, 0x51, 0x85, 0x4c, 0x20, 0xa1, 0x85, 0x3e, 0x82, 0x91, 0x63, 0xd7, 0xb5, - 0x52, 0x2e, 0x4a, 0x06, 0x24, 0xaf, 0xa0, 0x09, 0x65, 0xd6, 0xbb, 0xfd, 0xfd, 0x26, 0x66, 0x50, - 0xf2, 0xdf, 0x15, 0xfc, 0xf1, 0x60, 0xbb, 0xcb, 0x0f, 0xfd, 0xde, 0xae, 0xe9, 0x8a, 0xe3, 0xb0, - 0x10, 0xc6, 0x4f, 0x42, 0xe6, 0x43, 0x0d, 0xf7, 0x65, 0x38, 0xa1, 0x8d, 0xf6, 0x83, 0xa4, 0x2e, - 0x5d, 0x25, 0xa9, 0x4f, 0xa4, 0x25, 0x74, 0xf4, 0x0c, 0x8a, 0xae, 0x9e, 0xf7, 0x44, 0x43, 0x20, - 0xee, 0x6f, 0xb7, 0x82, 0xac, 0xb8, 0xbf, 0xdd, 0xc2, 0x14, 0x02, 0xed, 0xc1, 0x28, 0x25, 0x4e, - 0x34, 0x0f, 0x14, 0xf3, 0xe7, 0x15, 0x3a, 0x82, 0xc1, 0xe2, 0xa3, 0x5f, 0x0e, 0xe6, 0x38, 0xf2, - 0xef, 0x4b, 0x30, 0x19, 0xc9, 0x16, 0xc8, 0x86, 0x9b, 0x7a, 0x68, 0xed, 0x88, 0x71, 0x78, 0x7f, - 0xf8, 0x55, 0x27, 0x16, 0xfd, 0xbc, 0xa8, 0xf7, 0x66, 0x58, 0x86, 0x23, 0x75, 0xc8, 0x0a, 0x40, - 0xd0, 0x6d, 0xba, 0x0e, 0xa8, 0xf3, 0xf2, 0x05, 0x2f, 0xd6, 0x01, 0xf5, 0x69, 0x07, 0xf3, 0x72, - 0xb4, 0x02, 0xe0, 0x10, 0xd5, 0x26, 0xee, 0x6e, 0x10, 0xb8, 0xfc, 0x74, 0xdc, 0xf2, 0x25, 0x38, - 0xa4, 0x25, 0x7f, 0x56, 0x80, 0xc9, 0x5d, 0xe2, 0x7e, 0xd7, 0xb4, 0x4f, 0x9a, 0xa6, 0xae, 0xa9, - 0xfd, 0x6b, 0x20, 0x01, 0x38, 0x42, 0x02, 0x06, 0xc5, 0xcb, 0x48, 0xeb, 0x32, 0xa9, 0xc0, 0xc7, - 0x31, 0x2a, 0xb0, 0x32, 0x14, 0xea, 0xe5, 0x84, 0xe0, 0x47, 0x12, 0x2c, 0x46, 0xf4, 0x37, 0x82, - 0x58, 0xe3, 0x07, 0x7f, 0x29, 0x57, 0xf0, 0x8f, 0xc0, 0xd0, 0x80, 0x99, 0x1e, 0xfc, 0xd1, 0x36, - 0x14, 0x5c, 0x53, 0xac, 0x8c, 0xe1, 0x30, 0x09, 0xb1, 0x83, 0x7c, 0xb6, 0x6f, 0xe2, 0x82, 0x6b, - 0xca, 0xff, 0x28, 0x41, 0x25, 0xa2, 0x15, 0x8e, 0x96, 0xaf, 0xa9, 0x07, 0x18, 0x46, 0x8e, 0x6c, - 0xb3, 0x7b, 0xe5, 0x3e, 0xf8, 0x93, 0xbc, 0x69, 0x9b, 0x5d, 0xcc, 0xb0, 0xe4, 0x1f, 0x4b, 0x30, - 0x1b, 0xd1, 0xbc, 0x06, 0x4e, 0xf2, 0x51, 0x94, 0x93, 0xdc, 0x1f, 0xa6, 0x23, 0x19, 0xcc, 0xe4, - 0xc7, 0x85, 0x58, 0x37, 0x68, 0x87, 0xd1, 0x11, 0x4c, 0x58, 0x66, 0xbb, 0xf5, 0x0a, 0x2e, 0xce, - 0xa7, 0x29, 0x57, 0x6c, 0x06, 0x58, 0x38, 0x0c, 0x8c, 0xce, 0x60, 0x96, 0xd2, 0x16, 0xc7, 0x52, - 0x54, 0xd2, 0x7a, 0x05, 0x47, 0x89, 0xb7, 0xd8, 0xcd, 0x5c, 0x1c, 0x11, 0x27, 0x2b, 0x41, 0x3b, - 0x50, 0xd2, 0x2c, 0xb6, 0x77, 0x11, 0x8b, 0x74, 0x20, 0xc1, 0xe3, 0x3b, 0x1d, 0x9e, 0x3e, 0xc4, - 0x07, 0xf6, 0x30, 0xe4, 0x7f, 0x8d, 0x7b, 0x03, 0xa3, 0xc2, 0x4f, 0x43, 0xd4, 0x43, 0xdc, 0xa1, - 0x5d, 0x8d, 0x76, 0xec, 0x0a, 0x96, 0x73, 0x55, 0xd6, 0x5e, 0x8e, 0x71, 0xa2, 0x5f, 0x81, 0x12, - 0x31, 0xda, 0x6c, 0x23, 0xc0, 0x0f, 0xa8, 0x58, 0xaf, 0x36, 0x78, 0x11, 0xf6, 0x64, 0xf2, 0x1f, - 0x14, 0x63, 0xbd, 0x62, 0x29, 0xfc, 0xd3, 0x57, 0xe6, 0x1c, 0xfe, 0x66, 0x22, 0xd3, 0x41, 0x0e, - 0x03, 0x6a, 0xc9, 0x7d, 0xfe, 0xcb, 0xc3, 0xf8, 0x7c, 0x38, 0xb7, 0x66, 0x12, 0x4b, 0xf4, 0x6d, - 0x18, 0x23, 0xbc, 0x0a, 0x9e, 0xb1, 0x1f, 0x0f, 0x53, 0x45, 0x10, 0x7e, 0x83, 0x90, 0x2d, 0xca, - 0x04, 0x2a, 0xfa, 0x1a, 0x1d, 0x2f, 0xaa, 0x4b, 0xb7, 0x3c, 0x9c, 0x99, 0x8f, 0x37, 0xee, 0xf0, - 0x6e, 0xfb, 0xc5, 0x2f, 0xcf, 0xab, 0x10, 0x7c, 0xe2, 0xb0, 0x85, 0xfc, 0xdb, 0x30, 0x97, 0x92, - 0x22, 0x90, 0x1a, 0x39, 0x55, 0xe3, 0x11, 0xb3, 0x9e, 0x6f, 0x1a, 0xf2, 0x5f, 0x0f, 0xff, 0xb3, - 0x04, 0xb3, 0x6c, 0x76, 0xd4, 0x9e, 0xad, 0xb9, 0xfd, 0x6b, 0xcb, 0xcb, 0xcf, 0x23, 0x79, 0xf9, - 0xe1, 0x80, 0x29, 0x49, 0xb4, 0x30, 0x2b, 0x37, 0xcb, 0x3f, 0x91, 0xe0, 0x56, 0x42, 0xfb, 0x1a, - 0x42, 0xf7, 0x41, 0x34, 0x74, 0x7f, 0x69, 0xd8, 0x0e, 0x65, 0x84, 0xef, 0xff, 0x9a, 0x4d, 0xe9, - 0x0e, 0x5b, 0xa5, 0x2b, 0x00, 0x96, 0xad, 0x9d, 0x6a, 0x3a, 0xe9, 0x88, 0x17, 0x2d, 0xe5, 0xd0, - 0x7b, 0x45, 0x5f, 0x82, 0x43, 0x5a, 0xc8, 0x81, 0x85, 0x36, 0x39, 0x52, 0x7a, 0xba, 0xbb, 0xda, - 0x6e, 0xaf, 0x29, 0x96, 0x72, 0xa8, 0xe9, 0x9a, 0xab, 0x89, 0xb3, 0xbf, 0xf1, 0xc6, 0x13, 0xfe, - 0xd2, 0x24, 0x4d, 0xe3, 0xe5, 0x79, 0xf5, 0x4e, 0xda, 0x55, 0xaf, 0xa7, 0xd2, 0xc7, 0x19, 0xd0, - 0xa8, 0x0f, 0x15, 0x9b, 0xfc, 0x56, 0x4f, 0xb3, 0x49, 0x7b, 0xdd, 0x36, 0xad, 0x48, 0xb5, 0x45, - 0x56, 0xed, 0xaf, 0x5f, 0x9c, 0x57, 0x2b, 0x38, 0x43, 0x67, 0x70, 0xc5, 0x99, 0xf0, 0xe8, 0x53, - 0x98, 0x53, 0xc4, 0xcb, 0xd2, 0x70, 0xad, 0x7c, 0x85, 0xbe, 0x7f, 0x71, 0x5e, 0x9d, 0x5b, 0x4d, - 0x8a, 0x07, 0x57, 0x98, 0x06, 0x8a, 0xea, 0x50, 0x3a, 0x65, 0x8f, 0x50, 0x9d, 0xca, 0x28, 0xc3, - 0xa7, 0xb9, 0xaa, 0xc4, 0xdf, 0xa5, 0x52, 0xcc, 0xb1, 0xcd, 0x16, 0x5b, 0xf9, 0x9e, 0x16, 0x7a, - 0x04, 0x13, 0x94, 0x4a, 0x8b, 0x95, 0xcf, 0xae, 0x7f, 0xca, 0x41, 0xc4, 0x7c, 0x16, 0x88, 0x70, - 0x58, 0x0f, 0x7d, 0x02, 0xe3, 0xc7, 0xe2, 0xb0, 0xd0, 0xa9, 0x94, 0x72, 0xf1, 0x84, 0xc8, 0xe1, - 0x62, 0x63, 0x56, 0x54, 0x31, 0xee, 0x15, 0x3b, 0x38, 0x40, 0x44, 0x6f, 0x43, 0x89, 0x7d, 0x6c, - 0xad, 0xb3, 0xb3, 0xf5, 0x72, 0x10, 0x57, 0x9f, 0xf1, 0x62, 0xec, 0xc9, 0x3d, 0xd5, 0xad, 0xe6, - 0x1a, 0xbb, 0xe3, 0x89, 0xa9, 0x6e, 0x35, 0xd7, 0xb0, 0x27, 0x47, 0xdf, 0x81, 0x92, 0x43, 0xb6, - 0x35, 0xa3, 0x77, 0x56, 0x81, 0x5c, 0x2f, 0x44, 0x5a, 0x1b, 0x4c, 0x3b, 0x76, 0xca, 0x1d, 0xd4, - 0x20, 0xe4, 0xd8, 0x83, 0x45, 0xc7, 0x30, 0x6e, 0xf7, 0x8c, 0x55, 0xe7, 0xc0, 0x21, 0x76, 0x65, - 0x82, 0xd5, 0x31, 0x28, 0x95, 0x60, 0x4f, 0x3f, 0x5e, 0x8b, 0x3f, 0x42, 0xbe, 0x06, 0x0e, 0xc0, - 0xd1, 0x31, 0x00, 0xfb, 0x60, 0x07, 0xea, 0x95, 0x85, 0x5c, 0x5b, 0x33, 0xec, 0x1b, 0xc4, 0xeb, - 0xe2, 0x97, 0x6a, 0xbe, 0x18, 0x87, 0xb0, 0xd1, 0x1f, 0x4a, 0x80, 0x9c, 0x9e, 0x65, 0xe9, 0xa4, - 0x4b, 0x0c, 0x57, 0xd1, 0x59, 0xa9, 0x53, 0xb9, 0xc9, 0xaa, 0xfc, 0x70, 0xd0, 0x08, 0x26, 0x0c, - 0xe3, 0x55, 0xfb, 0x77, 0x65, 0x49, 0x55, 0x9c, 0x52, 0x2f, 0x9d, 0xc4, 0x23, 0xd1, 0xeb, 0xc9, - 0x5c, 0x93, 0x98, 0x7e, 0x55, 0x11, 0x4c, 0xa2, 0x90, 0x63, 0x0f, 0x16, 0x3d, 0x87, 0x05, 0xef, - 0xb5, 0x34, 0x36, 0x4d, 0x77, 0x53, 0xd3, 0x89, 0xd3, 0x77, 0x5c, 0xd2, 0xad, 0x4c, 0x31, 0x07, - 0xf3, 0x9f, 0x8c, 0xe1, 0x54, 0x2d, 0x9c, 0x61, 0x8d, 0xba, 0x50, 0xf5, 0x82, 0x13, 0x5d, 0xb9, - 0x7e, 0x74, 0xdc, 0x70, 0x54, 0x45, 0xe7, 0xd7, 0x87, 0xd3, 0xac, 0x82, 0x37, 0x2f, 0xce, 0xab, - 0xd5, 0xf5, 0xcb, 0x55, 0xf1, 0x20, 0x2c, 0xf4, 0x2d, 0xa8, 0x28, 0x59, 0xf5, 0xcc, 0xb0, 0x7a, - 0xbe, 0x40, 0x23, 0x5e, 0x66, 0x05, 0x99, 0xd6, 0xc8, 0x85, 0x19, 0x25, 0xfa, 0x6e, 0xdd, 0xa9, - 0xcc, 0xe6, 0xba, 0x89, 0x88, 0x3d, 0x77, 0x0f, 0x8e, 0x92, 0x62, 0x02, 0x07, 0x27, 0x6a, 0x40, - 0xbf, 0x03, 0x48, 0x89, 0x3f, 0xb5, 0x77, 0x2a, 0x28, 0x57, 0xa2, 0x4b, 0xbc, 0xd1, 0x0f, 0xdc, - 0x2e, 0x21, 0x72, 0x70, 0x4a, 0x3d, 0x74, 0x0f, 0xa1, 0xc4, 0x7e, 0x1e, 0xe0, 0x54, 0x16, 0x13, - 0x6c, 0xe8, 0x92, 0xca, 0x7d, 0xbb, 0xd0, 0x2d, 0x69, 0x1c, 0x11, 0x27, 0x2b, 0x41, 0xdb, 0x30, - 0x2f, 0x0a, 0x0f, 0x0c, 0x47, 0x39, 0x22, 0xad, 0xbe, 0xa3, 0xba, 0xba, 0x53, 0x99, 0x63, 0xf1, - 0x9d, 0xdd, 0xd4, 0xaf, 0xa6, 0xc8, 0x71, 0xaa, 0x15, 0xfa, 0x10, 0x66, 0x8e, 0x4c, 0xfb, 0x50, - 0x6b, 0xb7, 0x89, 0xe1, 0x21, 0xcd, 0x33, 0x24, 0x76, 0x32, 0xb6, 0x19, 0x93, 0xe1, 0x84, 0x36, - 0x72, 0xe0, 0x96, 0x40, 0x6e, 0xda, 0xa6, 0xba, 0x63, 0xf6, 0x0c, 0x97, 0x53, 0xce, 0x5b, 0x7e, - 0x1a, 0xbd, 0xb5, 0x9a, 0xa6, 0xf0, 0xf2, 0xbc, 0x7a, 0x37, 0x7d, 0x23, 0x12, 0x28, 0xe1, 0x74, - 0x6c, 0x64, 0xc1, 0x4d, 0xf1, 0xa3, 0x0f, 0x76, 0x44, 0x57, 0xa9, 0xb0, 0xa5, 0xff, 0xc1, 0xe0, - 0x80, 0xe7, 0x9b, 0xc4, 0xd7, 0xff, 0xcc, 0xc5, 0x79, 0xf5, 0x66, 0x58, 0x01, 0x47, 0x6a, 0x60, - 0x8f, 0xfc, 0xc4, 0xd5, 0xf2, 0xf5, 0xfc, 0x50, 0x62, 0xb8, 0x47, 0x7e, 0x41, 0xd3, 0x5e, 0xd9, - 0x23, 0xbf, 0x10, 0xe4, 0xe5, 0xa7, 0x43, 0xff, 0x59, 0x80, 0xb9, 0x40, 0x39, 0xf7, 0x23, 0xbf, - 0x14, 0x93, 0x5f, 0xfe, 0x58, 0x22, 0xdf, 0xc3, 0xbb, 0x60, 0xe8, 0xfe, 0xef, 0x3d, 0xbc, 0x0b, - 0xda, 0x96, 0xb1, 0x7b, 0xf8, 0xab, 0x42, 0xb8, 0x03, 0x43, 0xbe, 0xfe, 0x7a, 0x05, 0xbf, 0x17, - 0xf8, 0x85, 0x7b, 0x40, 0x26, 0xff, 0xa4, 0x08, 0x33, 0xf1, 0xd5, 0x18, 0x79, 0x24, 0x24, 0x0d, - 0x7c, 0x24, 0xd4, 0x84, 0xf9, 0xa3, 0x9e, 0xae, 0xf7, 0x59, 0x1f, 0x42, 0x2f, 0x85, 0xf8, 0x75, - 0xfd, 0x17, 0x84, 0xe5, 0xfc, 0x66, 0x8a, 0x0e, 0x4e, 0xb5, 0x4c, 0xbe, 0x19, 0x1a, 0xf9, 0xdf, - 0xbe, 0x19, 0x1a, 0xbd, 0xc2, 0x9b, 0xa1, 0xf4, 0x67, 0x57, 0xc5, 0x2b, 0x3d, 0xbb, 0xba, 0xca, - 0x83, 0xa1, 0x94, 0x20, 0x36, 0xf0, 0x74, 0xe3, 0xab, 0x30, 0x15, 0x7d, 0xc4, 0xc6, 0xe7, 0x92, - 0xbf, 0xa3, 0x13, 0xcf, 0x22, 0x42, 0x73, 0xc9, 0xcb, 0xb1, 0xaf, 0x21, 0x5f, 0x48, 0xb0, 0x90, - 0xfe, 0x58, 0x1d, 0xe9, 0x30, 0xd5, 0x55, 0xce, 0xc2, 0x3f, 0x20, 0x90, 0xae, 0x78, 0x78, 0xc7, - 0x5e, 0x2f, 0xed, 0x44, 0xb0, 0x70, 0x0c, 0x1b, 0x7d, 0x0c, 0xe5, 0xae, 0x72, 0xd6, 0xea, 0xd9, - 0x1d, 0x72, 0xe5, 0x43, 0x42, 0xb6, 0x8c, 0x76, 0x04, 0x0a, 0xf6, 0xf1, 0xe4, 0x9f, 0x4b, 0xb0, - 0x98, 0xf1, 0x26, 0xe9, 0xff, 0x51, 0x2f, 0x7f, 0x20, 0xc1, 0x1b, 0x99, 0xdb, 0x30, 0xf4, 0x38, - 0xf2, 0x7c, 0x4a, 0x8e, 0x3d, 0x9f, 0x42, 0x49, 0xc3, 0xd7, 0xf4, 0x7a, 0xea, 0x33, 0x09, 0x2a, - 0x59, 0xfb, 0x52, 0xf4, 0x28, 0xd2, 0xc8, 0x2f, 0xc6, 0x1a, 0x39, 0x9b, 0xb0, 0x7b, 0x4d, 0x6d, - 0xfc, 0x17, 0x09, 0x6e, 0x5f, 0xc2, 0xef, 0xfc, 0xed, 0x0f, 0x69, 0x87, 0xb5, 0xd8, 0xa9, 0xbd, - 0xb8, 0x4e, 0x0c, 0xb6, 0x3f, 0x29, 0x3a, 0x38, 0xd3, 0x1a, 0x1d, 0xc0, 0xa2, 0xd8, 0x7b, 0xc5, - 0x65, 0x82, 0xba, 0xb0, 0x57, 0xa6, 0xeb, 0xe9, 0x2a, 0x38, 0xcb, 0x56, 0xfe, 0x4b, 0x09, 0x16, - 0xd2, 0x0f, 0x1c, 0xd0, 0x7b, 0x91, 0x21, 0xaf, 0xc6, 0x86, 0x7c, 0x3a, 0x66, 0x25, 0x06, 0xfc, - 0xdb, 0x30, 0x25, 0x8e, 0x25, 0x04, 0x8c, 0x70, 0x66, 0x39, 0x2d, 0x3b, 0x09, 0x08, 0x8f, 0x1c, - 0xb3, 0x65, 0x12, 0x2d, 0xc3, 0x31, 0x34, 0xf9, 0x7b, 0x05, 0x18, 0x6d, 0xa9, 0x8a, 0x4e, 0xae, - 0x81, 0x1b, 0x7f, 0x3d, 0xc2, 0x8d, 0x07, 0xfd, 0x7e, 0x93, 0xb5, 0x2a, 0x93, 0x16, 0xe3, 0x18, - 0x2d, 0x7e, 0x27, 0x17, 0xda, 0xe5, 0x8c, 0xf8, 0x2b, 0x30, 0xee, 0x57, 0x3a, 0x5c, 0xa2, 0x96, - 0xff, 0xbc, 0x00, 0x13, 0xa1, 0x2a, 0x86, 0x4c, 0xf3, 0x47, 0x11, 0x6e, 0x53, 0xcc, 0x71, 0x08, - 0x14, 0xaa, 0xab, 0xe6, 0xb1, 0x19, 0xfe, 0xfb, 0x83, 0xe0, 0xc5, 0x79, 0x92, 0xe4, 0x7c, 0x15, - 0xa6, 0x5c, 0xc5, 0xee, 0x10, 0xd7, 0xbf, 0x90, 0xe1, 0x4f, 0x53, 0xfc, 0x1f, 0xc2, 0xec, 0x47, - 0xa4, 0x38, 0xa6, 0xbd, 0xf4, 0x04, 0x26, 0x23, 0x95, 0x0d, 0xf5, 0xf3, 0x81, 0xbf, 0x96, 0xe0, - 0x8b, 0x03, 0x0f, 0x92, 0x50, 0x23, 0xb2, 0x48, 0x6a, 0xb1, 0x45, 0xb2, 0x9c, 0x0d, 0xf0, 0xfa, - 0x9e, 0xa1, 0x36, 0xd6, 0x5e, 0x7c, 0xbe, 0x7c, 0xe3, 0xa7, 0x9f, 0x2f, 0xdf, 0xf8, 0xd9, 0xe7, - 0xcb, 0x37, 0x7e, 0xf7, 0x62, 0x59, 0x7a, 0x71, 0xb1, 0x2c, 0xfd, 0xf4, 0x62, 0x59, 0xfa, 0xd9, - 0xc5, 0xb2, 0xf4, 0xef, 0x17, 0xcb, 0xd2, 0x1f, 0xff, 0x7c, 0xf9, 0xc6, 0xc7, 0x77, 0x2e, 0xfd, - 0xff, 0x1e, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0x08, 0x20, 0x7f, 0x0a, 0x28, 0x42, 0x00, 0x00, -} - -func (m *AllowedCSIDriver) 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 *AllowedCSIDriver) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AllowedCSIDriver) 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 *AllowedFlexVolume) 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 *AllowedFlexVolume) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AllowedFlexVolume) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - 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 *AllowedHostPath) 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 *AllowedHostPath) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AllowedHostPath) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i-- - if m.ReadOnly { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 - i -= len(m.PathPrefix) - copy(dAtA[i:], m.PathPrefix) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.PathPrefix))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil + // 2890 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, 0x33, 0xc3, 0x6e, 0x92, 0x25, 0x3f, 0xa4, 0x84, 0x1d, 0xef, 0x26, + 0xeb, 0xc4, 0x1e, 0x4f, 0x6a, 0xc6, 0x09, 0x8a, 0x08, 0xd0, 0xee, 0x29, 0x8f, 0x3b, 0xee, 0xe9, + 0x1e, 0x75, 0xd7, 0x98, 0x35, 0x27, 0x10, 0x5c, 0x72, 0x82, 0x4b, 0x20, 0x47, 0x10, 0x12, 0x57, + 0xae, 0x1c, 0x42, 0x04, 0x22, 0x48, 0x2b, 0xc4, 0x21, 0x12, 0x07, 0x72, 0xb2, 0x88, 0x73, 0x42, + 0xfc, 0x03, 0x68, 0x4f, 0xa8, 0x7e, 0x74, 0xf5, 0x6f, 0xbb, 0xc7, 0x38, 0x16, 0x41, 0x9c, 0x3c, + 0x5d, 0xef, 0xbd, 0x4f, 0xbd, 0xaa, 0x7a, 0xf5, 0xde, 0xa7, 0xba, 0xda, 0xf0, 0xf2, 0xee, 0xb3, + 0x7e, 0xcd, 0x72, 0xeb, 0xbb, 0xc3, 0x2d, 0xe2, 0x39, 0x84, 0x12, 0xbf, 0xbe, 0x47, 0x9c, 0xae, + 0xeb, 0xd5, 0xa5, 0xc0, 0x18, 0x58, 0x75, 0x72, 0x8f, 0x12, 0xc7, 0xb7, 0x5c, 0xc7, 0xaf, 0xef, + 0x5d, 0xdf, 0x22, 0xd4, 0xb8, 0x5e, 0xef, 0x11, 0x87, 0x78, 0x06, 0x25, 0xdd, 0xda, 0xc0, 0x73, + 0xa9, 0x8b, 0x1e, 0x11, 0xea, 0x35, 0x63, 0x60, 0xd5, 0x42, 0xf5, 0x9a, 0x54, 0x5f, 0x7c, 0xb2, + 0x67, 0xd1, 0x9d, 0xe1, 0x56, 0xcd, 0x74, 0xfb, 0xf5, 0x9e, 0xdb, 0x73, 0xeb, 0xdc, 0x6a, 0x6b, + 0xb8, 0xcd, 0x9f, 0xf8, 0x03, 0xff, 0x25, 0xd0, 0x16, 0xf5, 0x48, 0xe7, 0xa6, 0xeb, 0x91, 0xfa, + 0x5e, 0xaa, 0xc7, 0xc5, 0xa7, 0x43, 0x9d, 0xbe, 0x61, 0xee, 0x58, 0x0e, 0xf1, 0xf6, 0xeb, 0x83, + 0xdd, 0x1e, 0x6b, 0xf0, 0xeb, 0x7d, 0x42, 0x8d, 0x2c, 0xab, 0x7a, 0x9e, 0x95, 0x37, 0x74, 0xa8, + 0xd5, 0x27, 0x29, 0x83, 0x9b, 0xc7, 0x19, 0xf8, 0xe6, 0x0e, 0xe9, 0x1b, 0x29, 0xbb, 0xa7, 0xf2, + 0xec, 0x86, 0xd4, 0xb2, 0xeb, 0x96, 0x43, 0x7d, 0xea, 0x25, 0x8d, 0xf4, 0xf7, 0x4a, 0x30, 0x79, + 0xdb, 0x20, 0x7d, 0xd7, 0x69, 0x13, 0x8a, 0xbe, 0x03, 0x55, 0x36, 0x8c, 0xae, 0x41, 0x8d, 0x05, + 0xed, 0x51, 0xed, 0xea, 0xd4, 0x8d, 0xaf, 0xd6, 0xc2, 0x69, 0x56, 0xa8, 0xb5, 0xc1, 0x6e, 0x8f, + 0x35, 0xf8, 0x35, 0xa6, 0x5d, 0xdb, 0xbb, 0x5e, 0xdb, 0xd8, 0x7a, 0x87, 0x98, 0x74, 0x9d, 0x50, + 0xa3, 0x81, 0xee, 0x1f, 0x2c, 0x9f, 0x3b, 0x3c, 0x58, 0x86, 0xb0, 0x0d, 0x2b, 0x54, 0xd4, 0x84, + 0x31, 0x7f, 0x40, 0xcc, 0x85, 0x12, 0x47, 0xbf, 0x56, 0x3b, 0x72, 0x11, 0x6b, 0xca, 0xb3, 0xf6, + 0x80, 0x98, 0x8d, 0xf3, 0x12, 0x79, 0x8c, 0x3d, 0x61, 0x8e, 0x83, 0xde, 0x80, 0x71, 0x9f, 0x1a, + 0x74, 0xe8, 0x2f, 0x94, 0x39, 0x62, 0xad, 0x30, 0x22, 0xb7, 0x6a, 0xcc, 0x48, 0xcc, 0x71, 0xf1, + 0x8c, 0x25, 0x9a, 0xfe, 0xf7, 0x12, 0x20, 0xa5, 0xbb, 0xe2, 0x3a, 0x5d, 0x8b, 0x5a, 0xae, 0x83, + 0x9e, 0x87, 0x31, 0xba, 0x3f, 0x20, 0x7c, 0x72, 0x26, 0x1b, 0x8f, 0x05, 0x0e, 0x75, 0xf6, 0x07, + 0xe4, 0xc1, 0xc1, 0xf2, 0xe5, 0xb4, 0x05, 0x93, 0x60, 0x6e, 0x83, 0xd6, 0x94, 0xab, 0x25, 0x6e, + 0xfd, 0x74, 0xbc, 0xeb, 0x07, 0x07, 0xcb, 0x19, 0x41, 0x58, 0x53, 0x48, 0x71, 0x07, 0xd1, 0x1e, + 0x20, 0xdb, 0xf0, 0x69, 0xc7, 0x33, 0x1c, 0x5f, 0xf4, 0x64, 0xf5, 0x89, 0x9c, 0x84, 0x27, 0x8a, + 0x2d, 0x1a, 0xb3, 0x68, 0x2c, 0x4a, 0x2f, 0xd0, 0x5a, 0x0a, 0x0d, 0x67, 0xf4, 0x80, 0x1e, 0x83, + 0x71, 0x8f, 0x18, 0xbe, 0xeb, 0x2c, 0x8c, 0xf1, 0x51, 0xa8, 0x09, 0xc4, 0xbc, 0x15, 0x4b, 0x29, + 0x7a, 0x1c, 0x26, 0xfa, 0xc4, 0xf7, 0x8d, 0x1e, 0x59, 0xa8, 0x70, 0xc5, 0x59, 0xa9, 0x38, 0xb1, + 0x2e, 0x9a, 0x71, 0x20, 0xd7, 0x3f, 0xd0, 0x60, 0x5a, 0xcd, 0xdc, 0x9a, 0xe5, 0x53, 0xf4, 0xcd, + 0x54, 0x1c, 0xd6, 0x8a, 0x0d, 0x89, 0x59, 0xf3, 0x28, 0xbc, 0x20, 0x7b, 0xab, 0x06, 0x2d, 0x91, + 0x18, 0x5c, 0x87, 0x8a, 0x45, 0x49, 0x9f, 0xad, 0x43, 0xf9, 0xea, 0xd4, 0x8d, 0xab, 0x45, 0x43, + 0xa6, 0x31, 0x2d, 0x41, 0x2b, 0xab, 0xcc, 0x1c, 0x0b, 0x14, 0xfd, 0xa7, 0x63, 0x11, 0xf7, 0x59, + 0x68, 0xa2, 0xb7, 0xa1, 0xea, 0x13, 0x9b, 0x98, 0xd4, 0xf5, 0xa4, 0xfb, 0x4f, 0x15, 0x74, 0xdf, + 0xd8, 0x22, 0x76, 0x5b, 0x9a, 0x36, 0xce, 0x33, 0xff, 0x83, 0x27, 0xac, 0x20, 0xd1, 0xeb, 0x50, + 0xa5, 0xa4, 0x3f, 0xb0, 0x0d, 0x4a, 0xe4, 0x3e, 0xfa, 0xff, 0xe8, 0x10, 0x58, 0xe4, 0x30, 0xb0, + 0x96, 0xdb, 0xed, 0x48, 0x35, 0xbe, 0x7d, 0xd4, 0x94, 0x04, 0xad, 0x58, 0xc1, 0xa0, 0x3d, 0x98, + 0x19, 0x0e, 0xba, 0x4c, 0x93, 0xb2, 0xec, 0xd0, 0xdb, 0x97, 0x91, 0x74, 0xb3, 0xe8, 0xdc, 0x6c, + 0xc6, 0xac, 0x1b, 0x97, 0x65, 0x5f, 0x33, 0xf1, 0x76, 0x9c, 0xe8, 0x05, 0xdd, 0x82, 0xd9, 0xbe, + 0xe5, 0x60, 0x62, 0x74, 0xf7, 0xdb, 0xc4, 0x74, 0x9d, 0xae, 0xcf, 0xc3, 0xaa, 0xd2, 0x98, 0x97, + 0x00, 0xb3, 0xeb, 0x71, 0x31, 0x4e, 0xea, 0xa3, 0x57, 0x01, 0x05, 0xc3, 0x78, 0x45, 0x24, 0x37, + 0xcb, 0x75, 0x78, 0xcc, 0x95, 0xc3, 0xe0, 0xee, 0xa4, 0x34, 0x70, 0x86, 0x15, 0x5a, 0x83, 0x39, + 0x8f, 0xec, 0x59, 0x6c, 0x8c, 0x77, 0x2d, 0x9f, 0xba, 0xde, 0xfe, 0x9a, 0xd5, 0xb7, 0xe8, 0xc2, + 0x38, 0xf7, 0x69, 0xe1, 0xf0, 0x60, 0x79, 0x0e, 0x67, 0xc8, 0x71, 0xa6, 0x95, 0xfe, 0xb3, 0x71, + 0x98, 0x4d, 0xe4, 0x1b, 0xf4, 0x06, 0x5c, 0x36, 0x87, 0x9e, 0x47, 0x1c, 0xda, 0x1c, 0xf6, 0xb7, + 0x88, 0xd7, 0x36, 0x77, 0x48, 0x77, 0x68, 0x93, 0x2e, 0x0f, 0x94, 0x4a, 0x63, 0x49, 0x7a, 0x7c, + 0x79, 0x25, 0x53, 0x0b, 0xe7, 0x58, 0xb3, 0x59, 0x70, 0x78, 0xd3, 0xba, 0xe5, 0xfb, 0x0a, 0xb3, + 0xc4, 0x31, 0xd5, 0x2c, 0x34, 0x53, 0x1a, 0x38, 0xc3, 0x8a, 0xf9, 0xd8, 0x25, 0xbe, 0xe5, 0x91, + 0x6e, 0xd2, 0xc7, 0x72, 0xdc, 0xc7, 0xdb, 0x99, 0x5a, 0x38, 0xc7, 0x1a, 0x3d, 0x03, 0x53, 0xa2, + 0x37, 0xbe, 0x7e, 0x72, 0xa1, 0x2f, 0x49, 0xb0, 0xa9, 0x66, 0x28, 0xc2, 0x51, 0x3d, 0x36, 0x34, + 0x77, 0xcb, 0x27, 0xde, 0x1e, 0xe9, 0xe6, 0x2f, 0xf0, 0x46, 0x4a, 0x03, 0x67, 0x58, 0xb1, 0xa1, + 0x89, 0x08, 0x4c, 0x0d, 0x6d, 0x3c, 0x3e, 0xb4, 0xcd, 0x4c, 0x2d, 0x9c, 0x63, 0xcd, 0xe2, 0x58, + 0xb8, 0x7c, 0x6b, 0xcf, 0xb0, 0x6c, 0x63, 0xcb, 0x26, 0x0b, 0x13, 0xf1, 0x38, 0x6e, 0xc6, 0xc5, + 0x38, 0xa9, 0x8f, 0x5e, 0x81, 0x8b, 0xa2, 0x69, 0xd3, 0x31, 0x14, 0x48, 0x95, 0x83, 0x3c, 0x2c, + 0x41, 0x2e, 0x36, 0x93, 0x0a, 0x38, 0x6d, 0x83, 0x9e, 0x87, 0x19, 0xd3, 0xb5, 0x6d, 0x1e, 0x8f, + 0x2b, 0xee, 0xd0, 0xa1, 0x0b, 0x93, 0x1c, 0x05, 0xb1, 0xfd, 0xb8, 0x12, 0x93, 0xe0, 0x84, 0x26, + 0x22, 0x00, 0x66, 0x50, 0x70, 0xfc, 0x05, 0xe0, 0xf9, 0xf1, 0x7a, 0xd1, 0x1c, 0xa0, 0x4a, 0x55, + 0xc8, 0x01, 0x54, 0x93, 0x8f, 0x23, 0xc0, 0xfa, 0x9f, 0x34, 0x98, 0xcf, 0x49, 0x1d, 0xe8, 0xa5, + 0x58, 0x89, 0xfd, 0x4a, 0xa2, 0xc4, 0x5e, 0xc9, 0x31, 0x8b, 0xd4, 0x59, 0x07, 0xa6, 0x3d, 0x36, + 0x2a, 0xa7, 0x27, 0x54, 0x64, 0x8e, 0x7c, 0xe6, 0x98, 0x61, 0xe0, 0xa8, 0x4d, 0x98, 0xf3, 0x2f, + 0x1e, 0x1e, 0x2c, 0x4f, 0xc7, 0x64, 0x38, 0x0e, 0xaf, 0xbf, 0x5f, 0x02, 0xb8, 0x4d, 0x06, 0xb6, + 0xbb, 0xdf, 0x27, 0xce, 0x59, 0x70, 0xa8, 0x8d, 0x18, 0x87, 0x7a, 0xf2, 0xb8, 0xe5, 0x51, 0xae, + 0xe5, 0x92, 0xa8, 0x37, 0x13, 0x24, 0xaa, 0x5e, 0x1c, 0xf2, 0x68, 0x16, 0xf5, 0xd7, 0x32, 0x5c, + 0x0a, 0x95, 0x43, 0x1a, 0xf5, 0x42, 0x6c, 0x8d, 0xbf, 0x9c, 0x58, 0xe3, 0xf9, 0x0c, 0x93, 0xcf, + 0x8d, 0x47, 0xbd, 0x03, 0x33, 0x8c, 0xe5, 0x88, 0xb5, 0xe4, 0x1c, 0x6a, 0x7c, 0x64, 0x0e, 0xa5, + 0xaa, 0xdd, 0x5a, 0x0c, 0x09, 0x27, 0x90, 0x73, 0x38, 0xdb, 0xc4, 0x17, 0x91, 0xb3, 0x7d, 0xa8, + 0xc1, 0x4c, 0xb8, 0x4c, 0x67, 0x40, 0xda, 0x9a, 0x71, 0xd2, 0xf6, 0x78, 0xe1, 0x10, 0xcd, 0x61, + 0x6d, 0xff, 0x64, 0x04, 0x5f, 0x29, 0xb1, 0x0d, 0xbe, 0x65, 0x98, 0xbb, 0xe8, 0x51, 0x18, 0x73, + 0x8c, 0x7e, 0x10, 0x99, 0x6a, 0xb3, 0x34, 0x8d, 0x3e, 0xc1, 0x5c, 0x82, 0xde, 0xd3, 0x00, 0xc9, + 0x2a, 0x70, 0xcb, 0x71, 0x5c, 0x6a, 0x88, 0x5c, 0x29, 0xdc, 0x5a, 0x2d, 0xec, 0x56, 0xd0, 0x63, + 0x6d, 0x33, 0x85, 0x75, 0xc7, 0xa1, 0xde, 0x7e, 0xb8, 0xc8, 0x69, 0x05, 0x9c, 0xe1, 0x00, 0x32, + 0x00, 0x3c, 0x89, 0xd9, 0x71, 0xe5, 0x46, 0x7e, 0xb2, 0x40, 0xce, 0x63, 0x06, 0x2b, 0xae, 0xb3, + 0x6d, 0xf5, 0xc2, 0xb4, 0x83, 0x15, 0x10, 0x8e, 0x80, 0x2e, 0xde, 0x81, 0xf9, 0x1c, 0x6f, 0xd1, + 0x05, 0x28, 0xef, 0x92, 0x7d, 0x31, 0x6d, 0x98, 0xfd, 0x44, 0x73, 0x50, 0xd9, 0x33, 0xec, 0xa1, + 0x48, 0xbf, 0x93, 0x58, 0x3c, 0x3c, 0x5f, 0x7a, 0x56, 0xd3, 0x3f, 0xa8, 0x44, 0x63, 0x87, 0x33, + 0xe6, 0xab, 0x50, 0xf5, 0xc8, 0xc0, 0xb6, 0x4c, 0xc3, 0x97, 0x44, 0x88, 0x93, 0x5f, 0x2c, 0xdb, + 0xb0, 0x92, 0xc6, 0xb8, 0x75, 0xe9, 0xf3, 0xe5, 0xd6, 0xe5, 0xd3, 0xe1, 0xd6, 0xdf, 0x86, 0xaa, + 0x1f, 0xb0, 0xea, 0x31, 0x0e, 0x79, 0x7d, 0x84, 0xfc, 0x2a, 0x09, 0xb5, 0xea, 0x40, 0x51, 0x69, + 0x05, 0x9a, 0x45, 0xa2, 0x2b, 0x23, 0x92, 0xe8, 0x53, 0x25, 0xbe, 0x2c, 0xdf, 0x0c, 0x8c, 0xa1, + 0x4f, 0xba, 0x3c, 0xb7, 0x55, 0xc3, 0x7c, 0xd3, 0xe2, 0xad, 0x58, 0x4a, 0xd1, 0xdb, 0xb1, 0x90, + 0xad, 0x9e, 0x24, 0x64, 0x67, 0xf2, 0xc3, 0x15, 0x6d, 0xc2, 0xfc, 0xc0, 0x73, 0x7b, 0x1e, 0xf1, + 0xfd, 0xdb, 0xc4, 0xe8, 0xda, 0x96, 0x43, 0x82, 0xf9, 0x11, 0x8c, 0xe8, 0xca, 0xe1, 0xc1, 0xf2, + 0x7c, 0x2b, 0x5b, 0x05, 0xe7, 0xd9, 0xea, 0xf7, 0xc7, 0xe0, 0x42, 0xb2, 0x02, 0xe6, 0x90, 0x54, + 0xed, 0x44, 0x24, 0xf5, 0x5a, 0x64, 0x33, 0x08, 0x06, 0xaf, 0x56, 0x3f, 0x63, 0x43, 0xdc, 0x82, + 0x59, 0x99, 0x0d, 0x02, 0xa1, 0xa4, 0xe9, 0x6a, 0xf5, 0x37, 0xe3, 0x62, 0x9c, 0xd4, 0x47, 0x2f, + 0xc0, 0xb4, 0xc7, 0x79, 0x77, 0x00, 0x20, 0xb8, 0xeb, 0x43, 0x12, 0x60, 0x1a, 0x47, 0x85, 0x38, + 0xae, 0xcb, 0x78, 0x6b, 0x48, 0x47, 0x03, 0x80, 0xb1, 0x38, 0x6f, 0xbd, 0x95, 0x54, 0xc0, 0x69, + 0x1b, 0xb4, 0x0e, 0x97, 0x86, 0x4e, 0x1a, 0x4a, 0x84, 0xf2, 0x15, 0x09, 0x75, 0x69, 0x33, 0xad, + 0x82, 0xb3, 0xec, 0xd0, 0x76, 0x8c, 0xca, 0x8e, 0xf3, 0xf4, 0x7c, 0xa3, 0xf0, 0xc6, 0x2b, 0xcc, + 0x65, 0x33, 0xe8, 0x76, 0xb5, 0x28, 0xdd, 0xd6, 0x7f, 0xaf, 0x45, 0x8b, 0x90, 0xa2, 0xc0, 0xc7, + 0xbd, 0x65, 0x4a, 0x59, 0x44, 0xd8, 0x91, 0x9b, 0xcd, 0x7e, 0x6f, 0x8e, 0xc4, 0x7e, 0xc3, 0xe2, + 0x79, 0x3c, 0xfd, 0xfd, 0x83, 0x06, 0xb3, 0x77, 0x3b, 0x9d, 0xd6, 0xaa, 0xc3, 0x77, 0x4b, 0xcb, + 0xa0, 0x3b, 0xac, 0x8a, 0x0e, 0x0c, 0xba, 0x93, 0xac, 0xa2, 0x4c, 0x86, 0xb9, 0x04, 0x3d, 0x0d, + 0x55, 0xf6, 0x97, 0x39, 0xce, 0xc3, 0x75, 0x92, 0x27, 0x99, 0x6a, 0x4b, 0xb6, 0x3d, 0x88, 0xfc, + 0xc6, 0x4a, 0x13, 0x7d, 0x03, 0x26, 0xd8, 0xde, 0x26, 0x4e, 0xb7, 0x20, 0xf9, 0x95, 0x4e, 0x35, + 0x84, 0x51, 0xc8, 0x67, 0x64, 0x03, 0x0e, 0xe0, 0xf4, 0x5d, 0x98, 0x8b, 0x0c, 0x02, 0x0f, 0x6d, + 0xf2, 0x06, 0xab, 0x57, 0xa8, 0x0d, 0x15, 0xd6, 0x3b, 0xab, 0x4a, 0xe5, 0x02, 0xaf, 0x17, 0x13, + 0x13, 0x11, 0x72, 0x0f, 0xf6, 0xe4, 0x63, 0x81, 0xa5, 0x6f, 0xc0, 0xc4, 0x6a, 0xab, 0x61, 0xbb, + 0x82, 0x6f, 0x98, 0x56, 0xd7, 0x4b, 0xce, 0xd4, 0xca, 0xea, 0x6d, 0x8c, 0xb9, 0x04, 0xe9, 0x30, + 0x4e, 0xee, 0x99, 0x64, 0x40, 0x39, 0xc5, 0x98, 0x6c, 0x00, 0x4b, 0xa4, 0x77, 0x78, 0x0b, 0x96, + 0x12, 0xfd, 0xc7, 0x25, 0x98, 0x90, 0xdd, 0x9e, 0xc1, 0xf9, 0x63, 0x2d, 0x76, 0xfe, 0x78, 0xa2, + 0xd8, 0x12, 0xe4, 0x1e, 0x3e, 0x3a, 0x89, 0xc3, 0xc7, 0xb5, 0x82, 0x78, 0x47, 0x9f, 0x3c, 0xde, + 0x2d, 0xc1, 0x4c, 0x7c, 0xf1, 0xd1, 0x33, 0x30, 0xc5, 0x52, 0xad, 0x65, 0x92, 0x66, 0xc8, 0xf0, + 0xd4, 0xeb, 0x87, 0x76, 0x28, 0xc2, 0x51, 0x3d, 0xd4, 0x53, 0x66, 0x2d, 0xd7, 0xa3, 0x72, 0xd0, + 0xf9, 0x53, 0x3a, 0xa4, 0x96, 0x5d, 0x13, 0x2f, 0xdb, 0x6b, 0xab, 0x0e, 0xdd, 0xf0, 0xda, 0xd4, + 0xb3, 0x9c, 0x5e, 0xaa, 0x23, 0x06, 0x86, 0xa3, 0xc8, 0xe8, 0x4d, 0x96, 0xf6, 0x7d, 0x77, 0xe8, + 0x99, 0x24, 0x8b, 0xbe, 0x05, 0xd4, 0x83, 0x6d, 0x84, 0xee, 0x9a, 0x6b, 0x1a, 0xb6, 0x58, 0x1c, + 0x4c, 0xb6, 0x89, 0x47, 0x1c, 0x93, 0x04, 0x94, 0x49, 0x40, 0x60, 0x05, 0xa6, 0xff, 0x46, 0x83, + 0x29, 0x39, 0x17, 0x67, 0x40, 0xd4, 0x5f, 0x8b, 0x13, 0xf5, 0xc7, 0x0a, 0xee, 0xd0, 0x6c, 0x96, + 0xfe, 0x5b, 0x0d, 0x16, 0x03, 0xd7, 0x5d, 0xa3, 0xdb, 0x30, 0x6c, 0xc3, 0x31, 0x89, 0x17, 0xc4, + 0xfa, 0x22, 0x94, 0xac, 0x81, 0x5c, 0x49, 0x90, 0x00, 0xa5, 0xd5, 0x16, 0x2e, 0x59, 0x03, 0x56, + 0x45, 0x77, 0x5c, 0x9f, 0x72, 0x36, 0x2f, 0x0e, 0x8a, 0xca, 0xeb, 0xbb, 0xb2, 0x1d, 0x2b, 0x0d, + 0xb4, 0x09, 0x95, 0x81, 0xeb, 0x51, 0x56, 0xb9, 0xca, 0x89, 0xf5, 0x3d, 0xc2, 0x6b, 0xb6, 0x6e, + 0x32, 0x10, 0xc3, 0x9d, 0xce, 0x60, 0xb0, 0x40, 0xd3, 0x7f, 0xa0, 0xc1, 0xc3, 0x19, 0xfe, 0x4b, + 0xd2, 0xd0, 0x85, 0x09, 0x4b, 0x08, 0x65, 0x7a, 0x79, 0xae, 0x58, 0xb7, 0x19, 0x53, 0x11, 0xa6, + 0xb6, 0x20, 0x85, 0x05, 0xd0, 0xfa, 0x2f, 0x35, 0xb8, 0x98, 0xf2, 0x97, 0xa7, 0x68, 0x16, 0xcf, + 0x92, 0x6d, 0xab, 0x14, 0xcd, 0xc2, 0x92, 0x4b, 0xd0, 0x6b, 0x50, 0xe5, 0x77, 0x44, 0xa6, 0x6b, + 0xcb, 0x09, 0xac, 0x07, 0x13, 0xd8, 0x92, 0xed, 0x0f, 0x0e, 0x96, 0xaf, 0x64, 0x9c, 0xb5, 0x03, + 0x31, 0x56, 0x00, 0x68, 0x19, 0x2a, 0xc4, 0xf3, 0x5c, 0x4f, 0x26, 0xfb, 0x49, 0x36, 0x53, 0x77, + 0x58, 0x03, 0x16, 0xed, 0xfa, 0xaf, 0xc2, 0x20, 0x65, 0xd9, 0x97, 0xf9, 0xc7, 0x16, 0x27, 0x99, + 0x18, 0xd9, 0xd2, 0x61, 0x2e, 0x41, 0x43, 0xb8, 0x60, 0x25, 0xd2, 0xb5, 0xdc, 0x9d, 0xf5, 0x62, + 0xd3, 0xa8, 0xcc, 0x1a, 0x0b, 0x12, 0xfe, 0x42, 0x52, 0x82, 0x53, 0x5d, 0xe8, 0x04, 0x52, 0x5a, + 0xe8, 0x75, 0x18, 0xdb, 0xa1, 0x74, 0x90, 0xf1, 0xb2, 0xff, 0x98, 0x22, 0x11, 0xba, 0x50, 0xe5, + 0xa3, 0xeb, 0x74, 0x5a, 0x98, 0x43, 0xe9, 0xbf, 0x2b, 0xa9, 0xf9, 0xe0, 0x27, 0xa4, 0xaf, 0xab, + 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, 0x77, 0xa1, 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, 0x9e, 0x7c, 0x2c, 0x70, 0xf4, 0x1f, 0x6a, 0x30, 0x1d, 0xab, 0x16, 0xc8, 0x83, + 0xf3, 0x76, 0x64, 0xef, 0xc8, 0x79, 0x78, 0x76, 0xf4, 0x5d, 0x27, 0x37, 0xfd, 0x9c, 0xec, 0xf7, + 0x7c, 0x54, 0x86, 0x63, 0x7d, 0xe8, 0x06, 0x40, 0x38, 0x6c, 0xb6, 0x0f, 0x58, 0xf0, 0x8a, 0x0d, + 0x2f, 0xf7, 0x01, 0x8b, 0x69, 0x1f, 0x8b, 0x76, 0x74, 0x03, 0xc0, 0x27, 0xa6, 0x47, 0x68, 0x33, + 0x4c, 0x5c, 0xaa, 0x1c, 0xb7, 0x95, 0x04, 0x47, 0xb4, 0xf4, 0x5f, 0x94, 0x60, 0xba, 0x49, 0xe8, + 0x77, 0x5d, 0x6f, 0xb7, 0xe5, 0xda, 0x96, 0xb9, 0x7f, 0x06, 0x24, 0x00, 0xc7, 0x48, 0xc0, 0x71, + 0xf9, 0x32, 0xe6, 0x5d, 0x2e, 0x15, 0x78, 0x2b, 0x41, 0x05, 0x6e, 0x8c, 0x84, 0x7a, 0x34, 0x21, + 0xf8, 0x50, 0x83, 0xf9, 0x98, 0xfe, 0x9d, 0x30, 0xd7, 0xa8, 0xe4, 0xaf, 0x15, 0x4a, 0xfe, 0x31, + 0x18, 0x96, 0x30, 0xb3, 0x93, 0x3f, 0x5a, 0x83, 0x12, 0x75, 0xe5, 0xce, 0x18, 0x0d, 0x93, 0x10, + 0x2f, 0xac, 0x67, 0x1d, 0x17, 0x97, 0xa8, 0xab, 0xff, 0x51, 0x83, 0x85, 0x98, 0x56, 0x34, 0x5b, + 0x7e, 0x4e, 0x23, 0xc0, 0x30, 0xb6, 0xed, 0xb9, 0xfd, 0x13, 0x8f, 0x41, 0x2d, 0xf2, 0xcb, 0x9e, + 0xdb, 0xc7, 0x1c, 0x4b, 0xff, 0x48, 0x83, 0x8b, 0x31, 0xcd, 0x33, 0xe0, 0x24, 0xaf, 0xc7, 0x39, + 0xc9, 0xb5, 0x51, 0x06, 0x92, 0xc3, 0x4c, 0x3e, 0x2a, 0x25, 0x86, 0xc1, 0x06, 0x8c, 0xb6, 0x61, + 0x6a, 0xe0, 0x76, 0xdb, 0xa7, 0x70, 0xf9, 0x3b, 0xcb, 0xb8, 0x62, 0x2b, 0xc4, 0xc2, 0x51, 0x60, + 0x74, 0x0f, 0x2e, 0x32, 0xda, 0xe2, 0x0f, 0x0c, 0x93, 0xb4, 0x4f, 0xe1, 0x75, 0xd8, 0x43, 0xfc, + 0x76, 0x29, 0x89, 0x88, 0xd3, 0x9d, 0xa0, 0x75, 0x98, 0xb0, 0x06, 0xfc, 0xec, 0x22, 0x37, 0xe9, + 0xb1, 0x04, 0x4f, 0x9c, 0x74, 0x44, 0xf9, 0x90, 0x0f, 0x38, 0xc0, 0xd0, 0xff, 0x92, 0x8c, 0x06, + 0x4e, 0x85, 0x5f, 0x89, 0x50, 0x0f, 0x79, 0x0f, 0x74, 0x32, 0xda, 0xd1, 0x94, 0x2c, 0xe7, 0xa4, + 0xac, 0xbd, 0x9a, 0xe0, 0x44, 0x5f, 0x82, 0x09, 0xe2, 0x74, 0xf9, 0x41, 0x40, 0xbc, 0x64, 0xe1, + 0xa3, 0xba, 0x23, 0x9a, 0x70, 0x20, 0xd3, 0x7f, 0x54, 0x4e, 0x8c, 0x8a, 0x97, 0xf0, 0x77, 0x4e, + 0x2d, 0x38, 0xd4, 0x61, 0x22, 0x37, 0x40, 0xb6, 0x42, 0x6a, 0x29, 0x62, 0xfe, 0x6b, 0xa3, 0xc4, + 0x7c, 0xb4, 0xb6, 0xe6, 0x12, 0x4b, 0xf4, 0x2d, 0x18, 0x27, 0xa2, 0x0b, 0x51, 0xb1, 0x6f, 0x8e, + 0xd2, 0x45, 0x98, 0x7e, 0xc3, 0x94, 0x2d, 0xdb, 0x24, 0x2a, 0x7a, 0x89, 0xcd, 0x17, 0xd3, 0x65, + 0x47, 0x1e, 0xc1, 0xcc, 0x27, 0x1b, 0x8f, 0x88, 0x61, 0xab, 0xe6, 0x07, 0x07, 0xcb, 0x10, 0x3e, + 0xe2, 0xa8, 0x85, 0xfe, 0x3d, 0xb8, 0x94, 0x51, 0x22, 0x90, 0x19, 0x7b, 0x33, 0x24, 0x32, 0x66, + 0xbd, 0xd8, 0x32, 0x14, 0xbf, 0xe2, 0x7c, 0xbf, 0x04, 0x20, 0xdf, 0x45, 0x9d, 0xcd, 0x97, 0x55, + 0xa3, 0xdd, 0x0a, 0x86, 0xae, 0x9d, 0xda, 0xad, 0x60, 0x04, 0xf2, 0xe8, 0x52, 0xfc, 0x8f, 0x12, + 0x5c, 0x0a, 0x95, 0x0b, 0xdf, 0x0a, 0x66, 0x98, 0xfc, 0xef, 0xeb, 0xaa, 0x62, 0x37, 0x75, 0xe1, + 0xd4, 0xfd, 0xe7, 0xdd, 0xd4, 0x85, 0xbe, 0xe5, 0x54, 0xda, 0x5f, 0x97, 0xa2, 0x03, 0x18, 0xf1, + 0xba, 0xe8, 0x14, 0x3e, 0x30, 0xfa, 0xc2, 0xdd, 0x38, 0xe9, 0x7f, 0x2e, 0xc3, 0x85, 0xe4, 0x6e, + 0x8c, 0xdd, 0x2a, 0x68, 0xc7, 0xde, 0x2a, 0xb4, 0x60, 0x6e, 0x7b, 0x68, 0xdb, 0xfb, 0x7c, 0x0c, + 0x91, 0xab, 0x05, 0x71, 0x1f, 0xf1, 0x7f, 0xd2, 0x72, 0xee, 0xe5, 0x0c, 0x1d, 0x9c, 0x69, 0x99, + 0xbe, 0x64, 0x18, 0xfb, 0x77, 0x2f, 0x19, 0x2a, 0x27, 0xb8, 0x64, 0xc8, 0xbe, 0xa7, 0x29, 0x9f, + 0xe8, 0x9e, 0xe6, 0x24, 0x37, 0x0c, 0x19, 0x49, 0xec, 0xd8, 0x52, 0xf2, 0x22, 0xcc, 0xc4, 0x6f, + 0xbd, 0xc4, 0x5a, 0x8a, 0x8b, 0x37, 0x79, 0xc7, 0x14, 0x59, 0x4b, 0xd1, 0x8e, 0x95, 0x86, 0x7e, + 0xa8, 0xc1, 0xe5, 0xec, 0xaf, 0x5b, 0x90, 0x0d, 0x33, 0x7d, 0xe3, 0x5e, 0xf4, 0x8b, 0x23, 0xed, + 0x84, 0x4c, 0x89, 0x5f, 0x77, 0xac, 0xc7, 0xb0, 0x70, 0x02, 0x1b, 0xbd, 0x05, 0xd5, 0xbe, 0x71, + 0xaf, 0x3d, 0xf4, 0x7a, 0xe4, 0xc4, 0x8c, 0x8c, 0x6f, 0xa3, 0x75, 0x89, 0x82, 0x15, 0x9e, 0xfe, + 0x99, 0x06, 0xf3, 0x39, 0x97, 0x18, 0xff, 0x45, 0xa3, 0x7c, 0xb7, 0x04, 0x95, 0xb6, 0x69, 0xd8, + 0xe4, 0x0c, 0x08, 0xc5, 0xab, 0x31, 0x42, 0x71, 0xdc, 0x57, 0xb2, 0xdc, 0xab, 0x5c, 0x2e, 0x81, + 0x13, 0x5c, 0xe2, 0x89, 0x42, 0x68, 0x47, 0xd3, 0x88, 0xe7, 0x60, 0x52, 0x75, 0x3a, 0x5a, 0x76, + 0xd3, 0x7f, 0x5e, 0x82, 0xa9, 0x48, 0x17, 0x23, 0xe6, 0xc6, 0xed, 0x58, 0x41, 0x28, 0x17, 0x78, + 0x83, 0x14, 0xe9, 0xab, 0x16, 0x94, 0x00, 0xf1, 0x95, 0x47, 0x78, 0xaf, 0x9f, 0xae, 0x0c, 0x2f, + 0xc2, 0x0c, 0x35, 0xbc, 0x1e, 0xa1, 0xea, 0xc8, 0x20, 0x5e, 0x9e, 0xaa, 0xcf, 0x8d, 0x3a, 0x31, + 0x29, 0x4e, 0x68, 0x2f, 0xbe, 0x00, 0xd3, 0xb1, 0xce, 0x46, 0xf9, 0x48, 0xa3, 0xb1, 0x72, 0xff, + 0xd3, 0xa5, 0x73, 0x1f, 0x7f, 0xba, 0x74, 0xee, 0x93, 0x4f, 0x97, 0xce, 0x7d, 0xff, 0x70, 0x49, + 0xbb, 0x7f, 0xb8, 0xa4, 0x7d, 0x7c, 0xb8, 0xa4, 0x7d, 0x72, 0xb8, 0xa4, 0xfd, 0xed, 0x70, 0x49, + 0xfb, 0xc9, 0x67, 0x4b, 0xe7, 0xde, 0x7a, 0xe4, 0xc8, 0xff, 0xd9, 0xf8, 0x57, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x39, 0x36, 0x95, 0x55, 0xec, 0x31, 0x00, 0x00, } func (m *DaemonSet) Marshal() (dAtA []byte, err error) { @@ -2882,48 +2320,6 @@ func (m *DeploymentStrategy) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *FSGroupStrategyOptions) 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 *FSGroupStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *FSGroupStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func (m *HTTPIngressPath) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3006,64 +2402,6 @@ func (m *HTTPIngressRuleValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *HostPortRange) 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 *HostPortRange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HostPortRange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.Max)) - i-- - dAtA[i] = 0x10 - i = encodeVarintGenerated(dAtA, i, uint64(m.Min)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} - -func (m *IDRange) 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 *IDRange) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *IDRange) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.Max)) - i-- - dAtA[i] = 0x10 - i = encodeVarintGenerated(dAtA, i, uint64(m.Min)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} - func (m *IPBlock) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4001,380 +3339,6 @@ func (m *NetworkPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *PodSecurityPolicy) 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 *PodSecurityPolicy) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodSecurityPolicy) 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 *PodSecurityPolicyList) 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 *PodSecurityPolicyList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodSecurityPolicyList) 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 *PodSecurityPolicySpec) 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 *PodSecurityPolicySpec) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PodSecurityPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.RuntimeClass != nil { - { - size, err := m.RuntimeClass.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xc2 - } - if len(m.AllowedCSIDrivers) > 0 { - for iNdEx := len(m.AllowedCSIDrivers) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AllowedCSIDrivers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xba - } - } - if m.RunAsGroup != nil { - { - size, err := m.RunAsGroup.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xb2 - } - if len(m.AllowedProcMountTypes) > 0 { - for iNdEx := len(m.AllowedProcMountTypes) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AllowedProcMountTypes[iNdEx]) - copy(dAtA[i:], m.AllowedProcMountTypes[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllowedProcMountTypes[iNdEx]))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xaa - } - } - if len(m.ForbiddenSysctls) > 0 { - for iNdEx := len(m.ForbiddenSysctls) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ForbiddenSysctls[iNdEx]) - copy(dAtA[i:], m.ForbiddenSysctls[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ForbiddenSysctls[iNdEx]))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0xa2 - } - } - if len(m.AllowedUnsafeSysctls) > 0 { - for iNdEx := len(m.AllowedUnsafeSysctls) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AllowedUnsafeSysctls[iNdEx]) - copy(dAtA[i:], m.AllowedUnsafeSysctls[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllowedUnsafeSysctls[iNdEx]))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x9a - } - } - if len(m.AllowedFlexVolumes) > 0 { - for iNdEx := len(m.AllowedFlexVolumes) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AllowedFlexVolumes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x92 - } - } - if len(m.AllowedHostPaths) > 0 { - for iNdEx := len(m.AllowedHostPaths) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.AllowedHostPaths[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x8a - } - } - if m.AllowPrivilegeEscalation != nil { - i-- - if *m.AllowPrivilegeEscalation { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x80 - } - if m.DefaultAllowPrivilegeEscalation != nil { - i-- - if *m.DefaultAllowPrivilegeEscalation { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x78 - } - i-- - if m.ReadOnlyRootFilesystem { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x70 - { - size, err := m.FSGroup.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x6a - { - size, err := m.SupplementalGroups.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x62 - { - size, err := m.RunAsUser.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x5a - { - size, err := m.SELinux.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x52 - i-- - if m.HostIPC { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x48 - i-- - if m.HostPID { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x40 - if len(m.HostPorts) > 0 { - for iNdEx := len(m.HostPorts) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.HostPorts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a - } - } - i-- - if m.HostNetwork { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x30 - if len(m.Volumes) > 0 { - for iNdEx := len(m.Volumes) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Volumes[iNdEx]) - copy(dAtA[i:], m.Volumes[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Volumes[iNdEx]))) - i-- - dAtA[i] = 0x2a - } - } - if len(m.AllowedCapabilities) > 0 { - for iNdEx := len(m.AllowedCapabilities) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AllowedCapabilities[iNdEx]) - copy(dAtA[i:], m.AllowedCapabilities[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllowedCapabilities[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } - if len(m.RequiredDropCapabilities) > 0 { - for iNdEx := len(m.RequiredDropCapabilities) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.RequiredDropCapabilities[iNdEx]) - copy(dAtA[i:], m.RequiredDropCapabilities[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.RequiredDropCapabilities[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.DefaultAddCapabilities) > 0 { - for iNdEx := len(m.DefaultAddCapabilities) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.DefaultAddCapabilities[iNdEx]) - copy(dAtA[i:], m.DefaultAddCapabilities[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.DefaultAddCapabilities[iNdEx]))) - i-- - dAtA[i] = 0x12 - } - } - i-- - if m.Privileged { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} - func (m *ReplicaSet) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4753,169 +3717,6 @@ func (m *RollingUpdateDeployment) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *RunAsGroupStrategyOptions) 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 *RunAsGroupStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RunAsGroupStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *RunAsUserStrategyOptions) 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 *RunAsUserStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RunAsUserStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *RuntimeClassStrategyOptions) 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 *RuntimeClassStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RuntimeClassStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.DefaultRuntimeClassName != nil { - i -= len(*m.DefaultRuntimeClassName) - copy(dAtA[i:], *m.DefaultRuntimeClassName) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.DefaultRuntimeClassName))) - i-- - dAtA[i] = 0x12 - } - if len(m.AllowedRuntimeClassNames) > 0 { - for iNdEx := len(m.AllowedRuntimeClassNames) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.AllowedRuntimeClassNames[iNdEx]) - copy(dAtA[i:], m.AllowedRuntimeClassNames[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllowedRuntimeClassNames[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *SELinuxStrategyOptions) 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 *SELinuxStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SELinuxStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.SELinuxOptions != nil { - { - size, err := m.SELinuxOptions.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func (m *Scale) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5050,48 +3851,6 @@ func (m *ScaleStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *SupplementalGroupsStrategyOptions) 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 *SupplementalGroupsStrategyOptions) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SupplementalGroupsStrategyOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Ranges) > 0 { - for iNdEx := len(m.Ranges) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Ranges[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - i -= len(m.Rule) - copy(dAtA[i:], m.Rule) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Rule))) - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { offset -= sovGenerated(v) base := offset @@ -5103,40 +3862,6 @@ func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *AllowedCSIDriver) 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 *AllowedFlexVolume) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Driver) - n += 1 + l + sovGenerated(uint64(l)) - return n -} - -func (m *AllowedHostPath) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.PathPrefix) - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - return n -} - func (m *DaemonSet) Size() (n int) { if m == nil { return 0 @@ -5396,23 +4121,6 @@ func (m *DeploymentStrategy) Size() (n int) { return n } -func (m *FSGroupStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - func (m *HTTPIngressPath) Size() (n int) { if m == nil { return 0 @@ -5445,28 +4153,6 @@ func (m *HTTPIngressRuleValue) Size() (n int) { return n } -func (m *HostPortRange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovGenerated(uint64(m.Min)) - n += 1 + sovGenerated(uint64(m.Max)) - return n -} - -func (m *IDRange) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovGenerated(uint64(m.Min)) - n += 1 + sovGenerated(uint64(m.Max)) - return n -} - func (m *IPBlock) Size() (n int) { if m == nil { return 0 @@ -5825,138 +4511,6 @@ func (m *NetworkPolicyStatus) Size() (n int) { return n } -func (m *PodSecurityPolicy) 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 *PodSecurityPolicyList) 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 *PodSecurityPolicySpec) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 2 - if len(m.DefaultAddCapabilities) > 0 { - for _, s := range m.DefaultAddCapabilities { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.RequiredDropCapabilities) > 0 { - for _, s := range m.RequiredDropCapabilities { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.AllowedCapabilities) > 0 { - for _, s := range m.AllowedCapabilities { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Volumes) > 0 { - for _, s := range m.Volumes { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - n += 2 - if len(m.HostPorts) > 0 { - for _, e := range m.HostPorts { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - n += 2 - n += 2 - l = m.SELinux.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.RunAsUser.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.SupplementalGroups.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = m.FSGroup.Size() - n += 1 + l + sovGenerated(uint64(l)) - n += 2 - if m.DefaultAllowPrivilegeEscalation != nil { - n += 2 - } - if m.AllowPrivilegeEscalation != nil { - n += 3 - } - if len(m.AllowedHostPaths) > 0 { - for _, e := range m.AllowedHostPaths { - l = e.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - } - if len(m.AllowedFlexVolumes) > 0 { - for _, e := range m.AllowedFlexVolumes { - l = e.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - } - if len(m.AllowedUnsafeSysctls) > 0 { - for _, s := range m.AllowedUnsafeSysctls { - l = len(s) - n += 2 + l + sovGenerated(uint64(l)) - } - } - if len(m.ForbiddenSysctls) > 0 { - for _, s := range m.ForbiddenSysctls { - l = len(s) - n += 2 + l + sovGenerated(uint64(l)) - } - } - if len(m.AllowedProcMountTypes) > 0 { - for _, s := range m.AllowedProcMountTypes { - l = len(s) - n += 2 + l + sovGenerated(uint64(l)) - } - } - if m.RunAsGroup != nil { - l = m.RunAsGroup.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - if len(m.AllowedCSIDrivers) > 0 { - for _, e := range m.AllowedCSIDrivers { - l = e.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - } - if m.RuntimeClass != nil { - l = m.RuntimeClass.Size() - n += 2 + l + sovGenerated(uint64(l)) - } - return n -} - func (m *ReplicaSet) Size() (n int) { if m == nil { return 0 @@ -6091,74 +4645,6 @@ func (m *RollingUpdateDeployment) Size() (n int) { return n } -func (m *RunAsGroupStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *RunAsUserStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - return n -} - -func (m *RuntimeClassStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.AllowedRuntimeClassNames) > 0 { - for _, s := range m.AllowedRuntimeClassNames { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.DefaultRuntimeClassName != nil { - l = len(*m.DefaultRuntimeClassName) - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *SELinuxStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if m.SELinuxOptions != nil { - l = m.SELinuxOptions.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - func (m *Scale) Size() (n int) { if m == nil { return 0 @@ -6204,60 +4690,12 @@ func (m *ScaleStatus) Size() (n int) { return n } -func (m *SupplementalGroupsStrategyOptions) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Rule) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Ranges) > 0 { - for _, e := range m.Ranges { - 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 *AllowedCSIDriver) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AllowedCSIDriver{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `}`, - }, "") - return s -} -func (this *AllowedFlexVolume) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AllowedFlexVolume{`, - `Driver:` + fmt.Sprintf("%v", this.Driver) + `,`, - `}`, - }, "") - return s -} -func (this *AllowedHostPath) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&AllowedHostPath{`, - `PathPrefix:` + fmt.Sprintf("%v", this.PathPrefix) + `,`, - `ReadOnly:` + fmt.Sprintf("%v", this.ReadOnly) + `,`, - `}`, - }, "") - return s -} func (this *DaemonSet) String() string { if this == nil { return "nil" @@ -6466,22 +4904,6 @@ func (this *DeploymentStrategy) String() string { }, "") return s } -func (this *FSGroupStrategyOptions) String() string { - if this == nil { - return "nil" - } - repeatedStringForRanges := "[]IDRange{" - for _, f := range this.Ranges { - repeatedStringForRanges += strings.Replace(strings.Replace(f.String(), "IDRange", "IDRange", 1), `&`, ``, 1) + "," - } - repeatedStringForRanges += "}" - s := strings.Join([]string{`&FSGroupStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `Ranges:` + repeatedStringForRanges + `,`, - `}`, - }, "") - return s -} func (this *HTTPIngressPath) String() string { if this == nil { return "nil" @@ -6509,28 +4931,6 @@ func (this *HTTPIngressRuleValue) String() string { }, "") return s } -func (this *HostPortRange) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&HostPortRange{`, - `Min:` + fmt.Sprintf("%v", this.Min) + `,`, - `Max:` + fmt.Sprintf("%v", this.Max) + `,`, - `}`, - }, "") - return s -} -func (this *IDRange) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&IDRange{`, - `Min:` + fmt.Sprintf("%v", this.Min) + `,`, - `Max:` + fmt.Sprintf("%v", this.Max) + `,`, - `}`, - }, "") - return s -} func (this *IPBlock) String() string { if this == nil { return "nil" @@ -6823,86 +5223,6 @@ func (this *NetworkPolicyStatus) String() string { }, "") return s } -func (this *PodSecurityPolicy) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&PodSecurityPolicy{`, - `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "PodSecurityPolicySpec", "PodSecurityPolicySpec", 1), `&`, ``, 1) + `,`, - `}`, - }, "") - return s -} -func (this *PodSecurityPolicyList) String() string { - if this == nil { - return "nil" - } - repeatedStringForItems := "[]PodSecurityPolicy{" - for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "PodSecurityPolicy", "PodSecurityPolicy", 1), `&`, ``, 1) + "," - } - repeatedStringForItems += "}" - s := strings.Join([]string{`&PodSecurityPolicyList{`, - `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, - `Items:` + repeatedStringForItems + `,`, - `}`, - }, "") - return s -} -func (this *PodSecurityPolicySpec) String() string { - if this == nil { - return "nil" - } - repeatedStringForHostPorts := "[]HostPortRange{" - for _, f := range this.HostPorts { - repeatedStringForHostPorts += strings.Replace(strings.Replace(f.String(), "HostPortRange", "HostPortRange", 1), `&`, ``, 1) + "," - } - repeatedStringForHostPorts += "}" - repeatedStringForAllowedHostPaths := "[]AllowedHostPath{" - for _, f := range this.AllowedHostPaths { - repeatedStringForAllowedHostPaths += strings.Replace(strings.Replace(f.String(), "AllowedHostPath", "AllowedHostPath", 1), `&`, ``, 1) + "," - } - repeatedStringForAllowedHostPaths += "}" - repeatedStringForAllowedFlexVolumes := "[]AllowedFlexVolume{" - for _, f := range this.AllowedFlexVolumes { - repeatedStringForAllowedFlexVolumes += strings.Replace(strings.Replace(f.String(), "AllowedFlexVolume", "AllowedFlexVolume", 1), `&`, ``, 1) + "," - } - repeatedStringForAllowedFlexVolumes += "}" - repeatedStringForAllowedCSIDrivers := "[]AllowedCSIDriver{" - for _, f := range this.AllowedCSIDrivers { - repeatedStringForAllowedCSIDrivers += strings.Replace(strings.Replace(f.String(), "AllowedCSIDriver", "AllowedCSIDriver", 1), `&`, ``, 1) + "," - } - repeatedStringForAllowedCSIDrivers += "}" - s := strings.Join([]string{`&PodSecurityPolicySpec{`, - `Privileged:` + fmt.Sprintf("%v", this.Privileged) + `,`, - `DefaultAddCapabilities:` + fmt.Sprintf("%v", this.DefaultAddCapabilities) + `,`, - `RequiredDropCapabilities:` + fmt.Sprintf("%v", this.RequiredDropCapabilities) + `,`, - `AllowedCapabilities:` + fmt.Sprintf("%v", this.AllowedCapabilities) + `,`, - `Volumes:` + fmt.Sprintf("%v", this.Volumes) + `,`, - `HostNetwork:` + fmt.Sprintf("%v", this.HostNetwork) + `,`, - `HostPorts:` + repeatedStringForHostPorts + `,`, - `HostPID:` + fmt.Sprintf("%v", this.HostPID) + `,`, - `HostIPC:` + fmt.Sprintf("%v", this.HostIPC) + `,`, - `SELinux:` + strings.Replace(strings.Replace(this.SELinux.String(), "SELinuxStrategyOptions", "SELinuxStrategyOptions", 1), `&`, ``, 1) + `,`, - `RunAsUser:` + strings.Replace(strings.Replace(this.RunAsUser.String(), "RunAsUserStrategyOptions", "RunAsUserStrategyOptions", 1), `&`, ``, 1) + `,`, - `SupplementalGroups:` + strings.Replace(strings.Replace(this.SupplementalGroups.String(), "SupplementalGroupsStrategyOptions", "SupplementalGroupsStrategyOptions", 1), `&`, ``, 1) + `,`, - `FSGroup:` + strings.Replace(strings.Replace(this.FSGroup.String(), "FSGroupStrategyOptions", "FSGroupStrategyOptions", 1), `&`, ``, 1) + `,`, - `ReadOnlyRootFilesystem:` + fmt.Sprintf("%v", this.ReadOnlyRootFilesystem) + `,`, - `DefaultAllowPrivilegeEscalation:` + valueToStringGenerated(this.DefaultAllowPrivilegeEscalation) + `,`, - `AllowPrivilegeEscalation:` + valueToStringGenerated(this.AllowPrivilegeEscalation) + `,`, - `AllowedHostPaths:` + repeatedStringForAllowedHostPaths + `,`, - `AllowedFlexVolumes:` + repeatedStringForAllowedFlexVolumes + `,`, - `AllowedUnsafeSysctls:` + fmt.Sprintf("%v", this.AllowedUnsafeSysctls) + `,`, - `ForbiddenSysctls:` + fmt.Sprintf("%v", this.ForbiddenSysctls) + `,`, - `AllowedProcMountTypes:` + fmt.Sprintf("%v", this.AllowedProcMountTypes) + `,`, - `RunAsGroup:` + strings.Replace(this.RunAsGroup.String(), "RunAsGroupStrategyOptions", "RunAsGroupStrategyOptions", 1) + `,`, - `AllowedCSIDrivers:` + repeatedStringForAllowedCSIDrivers + `,`, - `RuntimeClass:` + strings.Replace(this.RuntimeClass.String(), "RuntimeClassStrategyOptions", "RuntimeClassStrategyOptions", 1) + `,`, - `}`, - }, "") - return s -} func (this *ReplicaSet) String() string { if this == nil { return "nil" @@ -7010,60 +5330,6 @@ func (this *RollingUpdateDeployment) String() string { }, "") return s } -func (this *RunAsGroupStrategyOptions) String() string { - if this == nil { - return "nil" - } - repeatedStringForRanges := "[]IDRange{" - for _, f := range this.Ranges { - repeatedStringForRanges += strings.Replace(strings.Replace(f.String(), "IDRange", "IDRange", 1), `&`, ``, 1) + "," - } - repeatedStringForRanges += "}" - s := strings.Join([]string{`&RunAsGroupStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `Ranges:` + repeatedStringForRanges + `,`, - `}`, - }, "") - return s -} -func (this *RunAsUserStrategyOptions) String() string { - if this == nil { - return "nil" - } - repeatedStringForRanges := "[]IDRange{" - for _, f := range this.Ranges { - repeatedStringForRanges += strings.Replace(strings.Replace(f.String(), "IDRange", "IDRange", 1), `&`, ``, 1) + "," - } - repeatedStringForRanges += "}" - s := strings.Join([]string{`&RunAsUserStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `Ranges:` + repeatedStringForRanges + `,`, - `}`, - }, "") - return s -} -func (this *RuntimeClassStrategyOptions) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&RuntimeClassStrategyOptions{`, - `AllowedRuntimeClassNames:` + fmt.Sprintf("%v", this.AllowedRuntimeClassNames) + `,`, - `DefaultRuntimeClassName:` + valueToStringGenerated(this.DefaultRuntimeClassName) + `,`, - `}`, - }, "") - return s -} -func (this *SELinuxStrategyOptions) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&SELinuxStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `SELinuxOptions:` + strings.Replace(fmt.Sprintf("%v", this.SELinuxOptions), "SELinuxOptions", "v11.SELinuxOptions", 1) + `,`, - `}`, - }, "") - return s -} func (this *Scale) String() string { if this == nil { return "nil" @@ -7108,22 +5374,6 @@ func (this *ScaleStatus) String() string { }, "") return s } -func (this *SupplementalGroupsStrategyOptions) String() string { - if this == nil { - return "nil" - } - repeatedStringForRanges := "[]IDRange{" - for _, f := range this.Ranges { - repeatedStringForRanges += strings.Replace(strings.Replace(f.String(), "IDRange", "IDRange", 1), `&`, ``, 1) + "," - } - repeatedStringForRanges += "}" - s := strings.Join([]string{`&SupplementalGroupsStrategyOptions{`, - `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, - `Ranges:` + repeatedStringForRanges + `,`, - `}`, - }, "") - return s -} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -7132,272 +5382,6 @@ func valueToStringGenerated(v interface{}) string { pv := reflect.Indirect(rv).Interface() return fmt.Sprintf("*%v", pv) } -func (m *AllowedCSIDriver) 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: AllowedCSIDriver: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AllowedCSIDriver: 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 *AllowedFlexVolume) 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: AllowedFlexVolume: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AllowedFlexVolume: 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 - 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 *AllowedHostPath) 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: AllowedHostPath: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AllowedHostPath: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PathPrefix", 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.PathPrefix = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadOnly", 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 - } - } - m.ReadOnly = bool(v != 0) - 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 *DaemonSet) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -9834,122 +7818,6 @@ func (m *DeploymentStrategy) Unmarshal(dAtA []byte) error { } return nil } -func (m *FSGroupStrategyOptions) 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: FSGroupStrategyOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: FSGroupStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", 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.Rule = FSGroupStrategyType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", 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.Ranges = append(m.Ranges, IDRange{}) - if err := m.Ranges[len(m.Ranges)-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 *HTTPIngressPath) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -10182,182 +8050,6 @@ func (m *HTTPIngressRuleValue) Unmarshal(dAtA []byte) error { } return nil } -func (m *HostPortRange) 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: HostPortRange: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: HostPortRange: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Min", wireType) - } - m.Min = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Min |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) - } - m.Max = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Max |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - 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 *IDRange) 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: IDRange: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: IDRange: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Min", wireType) - } - m.Min = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Min |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) - } - m.Max = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Max |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - 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 *IPBlock) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -12906,995 +10598,6 @@ func (m *NetworkPolicyStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodSecurityPolicy) 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: PodSecurityPolicy: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodSecurityPolicy: 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 *PodSecurityPolicyList) 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: PodSecurityPolicyList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodSecurityPolicyList: 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, PodSecurityPolicy{}) - 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 *PodSecurityPolicySpec) 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: PodSecurityPolicySpec: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PodSecurityPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Privileged", 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 - } - } - m.Privileged = bool(v != 0) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultAddCapabilities", 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.DefaultAddCapabilities = append(m.DefaultAddCapabilities, k8s_io_api_core_v1.Capability(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RequiredDropCapabilities", 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.RequiredDropCapabilities = append(m.RequiredDropCapabilities, k8s_io_api_core_v1.Capability(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedCapabilities", 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.AllowedCapabilities = append(m.AllowedCapabilities, k8s_io_api_core_v1.Capability(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Volumes", 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.Volumes = append(m.Volumes, FSType(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HostNetwork", 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 - } - } - m.HostNetwork = bool(v != 0) - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HostPorts", 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.HostPorts = append(m.HostPorts, HostPortRange{}) - if err := m.HostPorts[len(m.HostPorts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HostPID", 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 - } - } - m.HostPID = bool(v != 0) - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HostIPC", 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 - } - } - m.HostIPC = bool(v != 0) - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SELinux", 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.SELinux.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RunAsUser", 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.RunAsUser.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SupplementalGroups", 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.SupplementalGroups.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 13: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FSGroup", 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.FSGroup.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 14: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReadOnlyRootFilesystem", 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 - } - } - m.ReadOnlyRootFilesystem = bool(v != 0) - case 15: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultAllowPrivilegeEscalation", 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.DefaultAllowPrivilegeEscalation = &b - case 16: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowPrivilegeEscalation", 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.AllowPrivilegeEscalation = &b - case 17: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedHostPaths", 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.AllowedHostPaths = append(m.AllowedHostPaths, AllowedHostPath{}) - if err := m.AllowedHostPaths[len(m.AllowedHostPaths)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 18: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedFlexVolumes", 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.AllowedFlexVolumes = append(m.AllowedFlexVolumes, AllowedFlexVolume{}) - if err := m.AllowedFlexVolumes[len(m.AllowedFlexVolumes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 19: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedUnsafeSysctls", 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.AllowedUnsafeSysctls = append(m.AllowedUnsafeSysctls, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 20: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ForbiddenSysctls", 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.ForbiddenSysctls = append(m.ForbiddenSysctls, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 21: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedProcMountTypes", 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.AllowedProcMountTypes = append(m.AllowedProcMountTypes, k8s_io_api_core_v1.ProcMountType(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 22: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RunAsGroup", 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.RunAsGroup == nil { - m.RunAsGroup = &RunAsGroupStrategyOptions{} - } - if err := m.RunAsGroup.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 23: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedCSIDrivers", 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.AllowedCSIDrivers = append(m.AllowedCSIDrivers, AllowedCSIDriver{}) - if err := m.AllowedCSIDrivers[len(m.AllowedCSIDrivers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 24: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RuntimeClass", 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.RuntimeClass == nil { - m.RuntimeClass = &RuntimeClassStrategyOptions{} - } - if err := m.RuntimeClass.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 *ReplicaSet) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -15022,471 +11725,6 @@ func (m *RollingUpdateDeployment) Unmarshal(dAtA []byte) error { } return nil } -func (m *RunAsGroupStrategyOptions) 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: RunAsGroupStrategyOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RunAsGroupStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", 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.Rule = RunAsGroupStrategy(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", 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.Ranges = append(m.Ranges, IDRange{}) - if err := m.Ranges[len(m.Ranges)-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 *RunAsUserStrategyOptions) 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: RunAsUserStrategyOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RunAsUserStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", 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.Rule = RunAsUserStrategy(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", 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.Ranges = append(m.Ranges, IDRange{}) - if err := m.Ranges[len(m.Ranges)-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 *RuntimeClassStrategyOptions) 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: RuntimeClassStrategyOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RuntimeClassStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedRuntimeClassNames", 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.AllowedRuntimeClassNames = append(m.AllowedRuntimeClassNames, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultRuntimeClassName", 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.DefaultRuntimeClassName = &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 *SELinuxStrategyOptions) 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: SELinuxStrategyOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SELinuxStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", 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.Rule = SELinuxStrategy(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SELinuxOptions", 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.SELinuxOptions == nil { - m.SELinuxOptions = &v11.SELinuxOptions{} - } - if err := m.SELinuxOptions.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 *Scale) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -15933,122 +12171,6 @@ func (m *ScaleStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *SupplementalGroupsStrategyOptions) 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: SupplementalGroupsStrategyOptions: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SupplementalGroupsStrategyOptions: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rule", 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.Rule = SupplementalGroupsStrategyType(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ranges", 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.Ranges = append(m.Ranges, IDRange{}) - if err := m.Ranges[len(m.Ranges)-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 skipGenerated(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/extensions/v1beta1/generated.proto b/vendor/k8s.io/api/extensions/v1beta1/generated.proto index 0509bc3d6..3ab6a093b 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/generated.proto +++ b/vendor/k8s.io/api/extensions/v1beta1/generated.proto @@ -30,37 +30,6 @@ import "k8s.io/apimachinery/pkg/util/intstr/generated.proto"; // Package-wide variables from generator "generated". option go_package = "k8s.io/api/extensions/v1beta1"; -// AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used. -message AllowedCSIDriver { - // Name is the registered name of the CSI driver - optional string name = 1; -} - -// AllowedFlexVolume represents a single Flexvolume that is allowed to be used. -// Deprecated: use AllowedFlexVolume from policy API Group instead. -message AllowedFlexVolume { - // driver is the name of the Flexvolume driver. - optional string driver = 1; -} - -// AllowedHostPath defines the host volume conditions that will be enabled by a policy -// for pods to use. It requires the path prefix to be defined. -// Deprecated: use AllowedHostPath from policy API Group instead. -message AllowedHostPath { - // pathPrefix is the path prefix that the host volume must match. - // It does not support `*`. - // Trailing slashes are trimmed when validating the path prefix with a host path. - // - // Examples: - // `/foo` would allow `/foo`, `/foo/` and `/foo/bar` - // `/foo` would not allow `/food` or `/etc/foo` - optional string pathPrefix = 1; - - // when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly. - // +optional - optional bool readOnly = 2; -} - // DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for // more information. // DaemonSet represents the configuration of a daemon set. @@ -398,19 +367,6 @@ message DeploymentStrategy { optional RollingUpdateDeployment rollingUpdate = 2; } -// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. -// Deprecated: use FSGroupStrategyOptions from policy API Group instead. -message FSGroupStrategyOptions { - // rule is the strategy that will dictate what FSGroup is used in the SecurityContext. - // +optional - optional string rule = 1; - - // ranges are the allowed ranges of fs groups. If you would like to force a single - // fs group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - repeated IDRange ranges = 2; -} - // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. message HTTPIngressPath { @@ -453,27 +409,6 @@ message HTTPIngressRuleValue { repeated HTTPIngressPath paths = 1; } -// HostPortRange defines a range of host ports that will be enabled by a policy -// for pods to use. It requires both the start and end to be defined. -// Deprecated: use HostPortRange from policy API Group instead. -message HostPortRange { - // min is the start of the range, inclusive. - optional int32 min = 1; - - // max is the end of the range, inclusive. - optional int32 max = 2; -} - -// IDRange provides a min/max of an allowed range of IDs. -// Deprecated: use IDRange from policy API Group instead. -message IDRange { - // min is the start of the range, inclusive. - optional int64 min = 1; - - // max is the end of the range, inclusive. - optional int64 max = 2; -} - // DEPRECATED 1.9 - This group version of IPBlock is deprecated by networking/v1/IPBlock. // 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 @@ -875,164 +810,6 @@ message NetworkPolicyStatus { repeated k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 1; } -// PodSecurityPolicy governs the ability to make requests that affect the Security Context -// that will be applied to a pod and container. -// Deprecated: use PodSecurityPolicy from policy API Group instead. -message PodSecurityPolicy { - // 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 defines the policy enforced. - // +optional - optional PodSecurityPolicySpec spec = 2; -} - -// PodSecurityPolicyList is a list of PodSecurityPolicy objects. -// Deprecated: use PodSecurityPolicyList from policy API Group instead. -message PodSecurityPolicyList { - // 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 PodSecurityPolicy items = 2; -} - -// PodSecurityPolicySpec defines the policy enforced. -// Deprecated: use PodSecurityPolicySpec from policy API Group instead. -message PodSecurityPolicySpec { - // privileged determines if a pod can request to be run as privileged. - // +optional - optional bool privileged = 1; - - // defaultAddCapabilities is the default set of capabilities that will be added to the container - // unless the pod spec specifically drops the capability. You may not list a capability in both - // defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly - // allowed, and need not be included in the allowedCapabilities list. - // +optional - repeated string defaultAddCapabilities = 2; - - // requiredDropCapabilities are the capabilities that will be dropped from the container. These - // are required to be dropped and cannot be added. - // +optional - repeated string requiredDropCapabilities = 3; - - // allowedCapabilities is a list of capabilities that can be requested to add to the container. - // Capabilities in this field may be added at the pod author's discretion. - // You must not list a capability in both allowedCapabilities and requiredDropCapabilities. - // +optional - repeated string allowedCapabilities = 4; - - // volumes is an allowlist of volume plugins. Empty indicates that - // no volumes may be used. To allow all volumes you may use '*'. - // +optional - repeated string volumes = 5; - - // hostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - // +optional - optional bool hostNetwork = 6; - - // hostPorts determines which host port ranges are allowed to be exposed. - // +optional - repeated HostPortRange hostPorts = 7; - - // hostPID determines if the policy allows the use of HostPID in the pod spec. - // +optional - optional bool hostPID = 8; - - // hostIPC determines if the policy allows the use of HostIPC in the pod spec. - // +optional - optional bool hostIPC = 9; - - // seLinux is the strategy that will dictate the allowable labels that may be set. - optional SELinuxStrategyOptions seLinux = 10; - - // runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set. - optional RunAsUserStrategyOptions runAsUser = 11; - - // RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. - // If this field is omitted, the pod's RunAsGroup can take any value. This field requires the - // RunAsGroup feature gate to be enabled. - // +optional - optional RunAsGroupStrategyOptions runAsGroup = 22; - - // supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - optional SupplementalGroupsStrategyOptions supplementalGroups = 12; - - // fsGroup is the strategy that will dictate what fs group is used by the SecurityContext. - optional FSGroupStrategyOptions fsGroup = 13; - - // readOnlyRootFilesystem when set to true will force containers to run with a read only root file - // system. If the container specifically requests to run with a non-read only root file system - // the PSP should deny the pod. - // If set to false the container may run with a read only root file system if it wishes but it - // will not be forced to. - // +optional - optional bool readOnlyRootFilesystem = 14; - - // defaultAllowPrivilegeEscalation controls the default setting for whether a - // process can gain more privileges than its parent process. - // +optional - optional bool defaultAllowPrivilegeEscalation = 15; - - // allowPrivilegeEscalation determines if a pod can request to allow - // privilege escalation. If unspecified, defaults to true. - // +optional - optional bool allowPrivilegeEscalation = 16; - - // allowedHostPaths is an allowlist of host paths. Empty indicates - // that all host paths may be used. - // +optional - repeated AllowedHostPath allowedHostPaths = 17; - - // allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all - // Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes - // is allowed in the "volumes" field. - // +optional - repeated AllowedFlexVolume allowedFlexVolumes = 18; - - // AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. - // An empty value indicates that any CSI driver can be used for inline ephemeral volumes. - // +optional - repeated AllowedCSIDriver allowedCSIDrivers = 23; - - // allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. - // Kubelet has to allowlist all unsafe sysctls explicitly to avoid rejection. - // - // Examples: - // e.g. "foo/*" allows "foo/bar", "foo/baz", etc. - // e.g. "foo.*" allows "foo.bar", "foo.baz", etc. - // +optional - repeated string allowedUnsafeSysctls = 19; - - // forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. - // - // Examples: - // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. - // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. - // +optional - repeated string forbiddenSysctls = 20; - - // AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. - // Empty or nil indicates that only the DefaultProcMountType may be used. - // This requires the ProcMountType feature flag to be enabled. - // +optional - repeated string allowedProcMountTypes = 21; - - // runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. - // If this field is omitted, the pod's runtimeClassName field is unrestricted. - // Enforcement of this field depends on the RuntimeClass feature gate being enabled. - // +optional - optional RuntimeClassStrategyOptions runtimeClass = 24; -} - // DEPRECATED - This group version of ReplicaSet is deprecated by apps/v1beta2/ReplicaSet. See the release notes for // more information. // ReplicaSet ensures that a specified number of pod replicas are running at any given time. @@ -1227,57 +1004,6 @@ message RollingUpdateDeployment { optional k8s.io.apimachinery.pkg.util.intstr.IntOrString maxSurge = 2; } -// RunAsGroupStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use RunAsGroupStrategyOptions from policy API Group instead. -message RunAsGroupStrategyOptions { - // rule is the strategy that will dictate the allowable RunAsGroup values that may be set. - optional string rule = 1; - - // ranges are the allowed ranges of gids that may be used. If you would like to force a single gid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - repeated IDRange ranges = 2; -} - -// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use RunAsUserStrategyOptions from policy API Group instead. -message RunAsUserStrategyOptions { - // rule is the strategy that will dictate the allowable RunAsUser values that may be set. - optional string rule = 1; - - // ranges are the allowed ranges of uids that may be used. If you would like to force a single uid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - repeated IDRange ranges = 2; -} - -// RuntimeClassStrategyOptions define the strategy that will dictate the allowable RuntimeClasses -// for a pod. -message RuntimeClassStrategyOptions { - // allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod. - // A value of "*" means that any RuntimeClass name is allowed, and must be the only item in the - // list. An empty list requires the RuntimeClassName field to be unset. - repeated string allowedRuntimeClassNames = 1; - - // defaultRuntimeClassName is the default RuntimeClassName to set on the pod. - // The default MUST be allowed by the allowedRuntimeClassNames list. - // A value of nil does not mutate the Pod. - // +optional - optional string defaultRuntimeClassName = 2; -} - -// SELinuxStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use SELinuxStrategyOptions from policy API Group instead. -message SELinuxStrategyOptions { - // rule is the strategy that will dictate the allowable labels that may be set. - optional string rule = 1; - - // seLinuxOptions required to run as; required for MustRunAs - // More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - // +optional - optional k8s.io.api.core.v1.SELinuxOptions seLinuxOptions = 2; -} - // represents a scaling request for a resource. message Scale { // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. @@ -1305,7 +1031,7 @@ message ScaleStatus { // actual number of observed instances of the scaled object. optional int32 replicas = 1; - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional // +mapType=atomic map selector = 2; @@ -1320,16 +1046,3 @@ message ScaleStatus { optional string targetSelector = 3; } -// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. -// Deprecated: use SupplementalGroupsStrategyOptions from policy API Group instead. -message SupplementalGroupsStrategyOptions { - // rule is the strategy that will dictate what supplemental groups is used in the SecurityContext. - // +optional - optional string rule = 1; - - // ranges are the allowed ranges of supplemental groups. If you would like to force a single - // supplemental group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - repeated IDRange ranges = 2; -} - diff --git a/vendor/k8s.io/api/extensions/v1beta1/register.go b/vendor/k8s.io/api/extensions/v1beta1/register.go index c69eff0bc..d58908edc 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/register.go +++ b/vendor/k8s.io/api/extensions/v1beta1/register.go @@ -54,8 +54,6 @@ func addKnownTypes(scheme *runtime.Scheme) error { &IngressList{}, &ReplicaSet{}, &ReplicaSetList{}, - &PodSecurityPolicy{}, - &PodSecurityPolicyList{}, &NetworkPolicy{}, &NetworkPolicyList{}, ) diff --git a/vendor/k8s.io/api/extensions/v1beta1/types.go b/vendor/k8s.io/api/extensions/v1beta1/types.go index be1b95e62..c0ac6fa25 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/types.go +++ b/vendor/k8s.io/api/extensions/v1beta1/types.go @@ -35,7 +35,7 @@ type ScaleStatus struct { // actual number of observed instances of the scaled object. Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors + // selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ // +optional // +mapType=atomic Selector map[string]string `json:"selector,omitempty" protobuf:"bytes,2,rep,name=selector"` @@ -1021,389 +1021,6 @@ type ReplicaSetCondition struct { Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` } -// +genclient -// +genclient:nonNamespaced -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.2 -// +k8s:prerelease-lifecycle-gen:deprecated=1.11 -// +k8s:prerelease-lifecycle-gen:removed=1.16 -// +k8s:prerelease-lifecycle-gen:replacement=policy,v1beta1,PodSecurityPolicy - -// PodSecurityPolicy governs the ability to make requests that affect the Security Context -// that will be applied to a pod and container. -// Deprecated: use PodSecurityPolicy from policy API Group instead. -type PodSecurityPolicy 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 defines the policy enforced. - // +optional - Spec PodSecurityPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` -} - -// PodSecurityPolicySpec defines the policy enforced. -// Deprecated: use PodSecurityPolicySpec from policy API Group instead. -type PodSecurityPolicySpec struct { - // privileged determines if a pod can request to be run as privileged. - // +optional - Privileged bool `json:"privileged,omitempty" protobuf:"varint,1,opt,name=privileged"` - // defaultAddCapabilities is the default set of capabilities that will be added to the container - // unless the pod spec specifically drops the capability. You may not list a capability in both - // defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly - // allowed, and need not be included in the allowedCapabilities list. - // +optional - DefaultAddCapabilities []v1.Capability `json:"defaultAddCapabilities,omitempty" protobuf:"bytes,2,rep,name=defaultAddCapabilities,casttype=k8s.io/api/core/v1.Capability"` - // requiredDropCapabilities are the capabilities that will be dropped from the container. These - // are required to be dropped and cannot be added. - // +optional - RequiredDropCapabilities []v1.Capability `json:"requiredDropCapabilities,omitempty" protobuf:"bytes,3,rep,name=requiredDropCapabilities,casttype=k8s.io/api/core/v1.Capability"` - // allowedCapabilities is a list of capabilities that can be requested to add to the container. - // Capabilities in this field may be added at the pod author's discretion. - // You must not list a capability in both allowedCapabilities and requiredDropCapabilities. - // +optional - AllowedCapabilities []v1.Capability `json:"allowedCapabilities,omitempty" protobuf:"bytes,4,rep,name=allowedCapabilities,casttype=k8s.io/api/core/v1.Capability"` - // volumes is an allowlist of volume plugins. Empty indicates that - // no volumes may be used. To allow all volumes you may use '*'. - // +optional - Volumes []FSType `json:"volumes,omitempty" protobuf:"bytes,5,rep,name=volumes,casttype=FSType"` - // hostNetwork determines if the policy allows the use of HostNetwork in the pod spec. - // +optional - HostNetwork bool `json:"hostNetwork,omitempty" protobuf:"varint,6,opt,name=hostNetwork"` - // hostPorts determines which host port ranges are allowed to be exposed. - // +optional - HostPorts []HostPortRange `json:"hostPorts,omitempty" protobuf:"bytes,7,rep,name=hostPorts"` - // hostPID determines if the policy allows the use of HostPID in the pod spec. - // +optional - HostPID bool `json:"hostPID,omitempty" protobuf:"varint,8,opt,name=hostPID"` - // hostIPC determines if the policy allows the use of HostIPC in the pod spec. - // +optional - HostIPC bool `json:"hostIPC,omitempty" protobuf:"varint,9,opt,name=hostIPC"` - // seLinux is the strategy that will dictate the allowable labels that may be set. - SELinux SELinuxStrategyOptions `json:"seLinux" protobuf:"bytes,10,opt,name=seLinux"` - // runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set. - RunAsUser RunAsUserStrategyOptions `json:"runAsUser" protobuf:"bytes,11,opt,name=runAsUser"` - // RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. - // If this field is omitted, the pod's RunAsGroup can take any value. This field requires the - // RunAsGroup feature gate to be enabled. - // +optional - RunAsGroup *RunAsGroupStrategyOptions `json:"runAsGroup,omitempty" protobuf:"bytes,22,opt,name=runAsGroup"` - // supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext. - SupplementalGroups SupplementalGroupsStrategyOptions `json:"supplementalGroups" protobuf:"bytes,12,opt,name=supplementalGroups"` - // fsGroup is the strategy that will dictate what fs group is used by the SecurityContext. - FSGroup FSGroupStrategyOptions `json:"fsGroup" protobuf:"bytes,13,opt,name=fsGroup"` - // readOnlyRootFilesystem when set to true will force containers to run with a read only root file - // system. If the container specifically requests to run with a non-read only root file system - // the PSP should deny the pod. - // If set to false the container may run with a read only root file system if it wishes but it - // will not be forced to. - // +optional - ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty" protobuf:"varint,14,opt,name=readOnlyRootFilesystem"` - // defaultAllowPrivilegeEscalation controls the default setting for whether a - // process can gain more privileges than its parent process. - // +optional - DefaultAllowPrivilegeEscalation *bool `json:"defaultAllowPrivilegeEscalation,omitempty" protobuf:"varint,15,opt,name=defaultAllowPrivilegeEscalation"` - // allowPrivilegeEscalation determines if a pod can request to allow - // privilege escalation. If unspecified, defaults to true. - // +optional - AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty" protobuf:"varint,16,opt,name=allowPrivilegeEscalation"` - // allowedHostPaths is an allowlist of host paths. Empty indicates - // that all host paths may be used. - // +optional - AllowedHostPaths []AllowedHostPath `json:"allowedHostPaths,omitempty" protobuf:"bytes,17,rep,name=allowedHostPaths"` - // allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all - // Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes - // is allowed in the "volumes" field. - // +optional - AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"` - // AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. - // An empty value indicates that any CSI driver can be used for inline ephemeral volumes. - // +optional - AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"` - // allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. - // Kubelet has to allowlist all unsafe sysctls explicitly to avoid rejection. - // - // Examples: - // e.g. "foo/*" allows "foo/bar", "foo/baz", etc. - // e.g. "foo.*" allows "foo.bar", "foo.baz", etc. - // +optional - AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty" protobuf:"bytes,19,rep,name=allowedUnsafeSysctls"` - // forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. - // Each entry is either a plain sysctl name or ends in "*" in which case it is considered - // as a prefix of forbidden sysctls. Single * means all sysctls are forbidden. - // - // Examples: - // e.g. "foo/*" forbids "foo/bar", "foo/baz", etc. - // e.g. "foo.*" forbids "foo.bar", "foo.baz", etc. - // +optional - ForbiddenSysctls []string `json:"forbiddenSysctls,omitempty" protobuf:"bytes,20,rep,name=forbiddenSysctls"` - // AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. - // Empty or nil indicates that only the DefaultProcMountType may be used. - // This requires the ProcMountType feature flag to be enabled. - // +optional - AllowedProcMountTypes []v1.ProcMountType `json:"allowedProcMountTypes,omitempty" protobuf:"bytes,21,opt,name=allowedProcMountTypes"` - // runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. - // If this field is omitted, the pod's runtimeClassName field is unrestricted. - // Enforcement of this field depends on the RuntimeClass feature gate being enabled. - // +optional - RuntimeClass *RuntimeClassStrategyOptions `json:"runtimeClass,omitempty" protobuf:"bytes,24,opt,name=runtimeClass"` -} - -// AllowedHostPath defines the host volume conditions that will be enabled by a policy -// for pods to use. It requires the path prefix to be defined. -// Deprecated: use AllowedHostPath from policy API Group instead. -type AllowedHostPath struct { - // pathPrefix is the path prefix that the host volume must match. - // It does not support `*`. - // Trailing slashes are trimmed when validating the path prefix with a host path. - // - // Examples: - // `/foo` would allow `/foo`, `/foo/` and `/foo/bar` - // `/foo` would not allow `/food` or `/etc/foo` - PathPrefix string `json:"pathPrefix,omitempty" protobuf:"bytes,1,rep,name=pathPrefix"` - - // when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly. - // +optional - ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,2,opt,name=readOnly"` -} - -// FSType gives strong typing to different file systems that are used by volumes. -// Deprecated: use FSType from policy API Group instead. -type FSType string - -const ( - AzureFile FSType = "azureFile" - Flocker FSType = "flocker" - FlexVolume FSType = "flexVolume" - HostPath FSType = "hostPath" - EmptyDir FSType = "emptyDir" - GCEPersistentDisk FSType = "gcePersistentDisk" - AWSElasticBlockStore FSType = "awsElasticBlockStore" - GitRepo FSType = "gitRepo" - Secret FSType = "secret" - NFS FSType = "nfs" - ISCSI FSType = "iscsi" - Glusterfs FSType = "glusterfs" - PersistentVolumeClaim FSType = "persistentVolumeClaim" - RBD FSType = "rbd" - Cinder FSType = "cinder" - CephFS FSType = "cephFS" - DownwardAPI FSType = "downwardAPI" - FC FSType = "fc" - ConfigMap FSType = "configMap" - Quobyte FSType = "quobyte" - AzureDisk FSType = "azureDisk" - CSI FSType = "csi" - All FSType = "*" -) - -// AllowedFlexVolume represents a single Flexvolume that is allowed to be used. -// Deprecated: use AllowedFlexVolume from policy API Group instead. -type AllowedFlexVolume struct { - // driver is the name of the Flexvolume driver. - Driver string `json:"driver" protobuf:"bytes,1,opt,name=driver"` -} - -// AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used. -type AllowedCSIDriver struct { - // Name is the registered name of the CSI driver - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` -} - -// HostPortRange defines a range of host ports that will be enabled by a policy -// for pods to use. It requires both the start and end to be defined. -// Deprecated: use HostPortRange from policy API Group instead. -type HostPortRange struct { - // min is the start of the range, inclusive. - Min int32 `json:"min" protobuf:"varint,1,opt,name=min"` - // max is the end of the range, inclusive. - Max int32 `json:"max" protobuf:"varint,2,opt,name=max"` -} - -// SELinuxStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use SELinuxStrategyOptions from policy API Group instead. -type SELinuxStrategyOptions struct { - // rule is the strategy that will dictate the allowable labels that may be set. - Rule SELinuxStrategy `json:"rule" protobuf:"bytes,1,opt,name=rule,casttype=SELinuxStrategy"` - // seLinuxOptions required to run as; required for MustRunAs - // More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - // +optional - SELinuxOptions *v1.SELinuxOptions `json:"seLinuxOptions,omitempty" protobuf:"bytes,2,opt,name=seLinuxOptions"` -} - -// SELinuxStrategy denotes strategy types for generating SELinux options for a -// Security Context. -// Deprecated: use SELinuxStrategy from policy API Group instead. -type SELinuxStrategy string - -const ( - // SELinuxStrategyMustRunAs means that container must have SELinux labels of X applied. - // Deprecated: use SELinuxStrategyMustRunAs from policy API Group instead. - SELinuxStrategyMustRunAs SELinuxStrategy = "MustRunAs" - // SELinuxStrategyRunAsAny means that container may make requests for any SELinux context labels. - // Deprecated: use SELinuxStrategyRunAsAny from policy API Group instead. - SELinuxStrategyRunAsAny SELinuxStrategy = "RunAsAny" -) - -// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use RunAsUserStrategyOptions from policy API Group instead. -type RunAsUserStrategyOptions struct { - // rule is the strategy that will dictate the allowable RunAsUser values that may be set. - Rule RunAsUserStrategy `json:"rule" protobuf:"bytes,1,opt,name=rule,casttype=RunAsUserStrategy"` - // ranges are the allowed ranges of uids that may be used. If you would like to force a single uid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange `json:"ranges,omitempty" protobuf:"bytes,2,rep,name=ranges"` -} - -// RunAsGroupStrategyOptions defines the strategy type and any options used to create the strategy. -// Deprecated: use RunAsGroupStrategyOptions from policy API Group instead. -type RunAsGroupStrategyOptions struct { - // rule is the strategy that will dictate the allowable RunAsGroup values that may be set. - Rule RunAsGroupStrategy `json:"rule" protobuf:"bytes,1,opt,name=rule,casttype=RunAsGroupStrategy"` - // ranges are the allowed ranges of gids that may be used. If you would like to force a single gid - // then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange `json:"ranges,omitempty" protobuf:"bytes,2,rep,name=ranges"` -} - -// IDRange provides a min/max of an allowed range of IDs. -// Deprecated: use IDRange from policy API Group instead. -type IDRange struct { - // min is the start of the range, inclusive. - Min int64 `json:"min" protobuf:"varint,1,opt,name=min"` - // max is the end of the range, inclusive. - Max int64 `json:"max" protobuf:"varint,2,opt,name=max"` -} - -// RunAsUserStrategy denotes strategy types for generating RunAsUser values for a -// Security Context. -// Deprecated: use RunAsUserStrategy from policy API Group instead. -type RunAsUserStrategy string - -const ( - // RunAsUserStrategyMustRunAs means that container must run as a particular uid. - // Deprecated: use RunAsUserStrategyMustRunAs from policy API Group instead. - RunAsUserStrategyMustRunAs RunAsUserStrategy = "MustRunAs" - // RunAsUserStrategyMustRunAsNonRoot means that container must run as a non-root uid. - // Deprecated: use RunAsUserStrategyMustRunAsNonRoot from policy API Group instead. - RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategy = "MustRunAsNonRoot" - // RunAsUserStrategyRunAsAny means that container may make requests for any uid. - // Deprecated: use RunAsUserStrategyRunAsAny from policy API Group instead. - RunAsUserStrategyRunAsAny RunAsUserStrategy = "RunAsAny" -) - -// RunAsGroupStrategy denotes strategy types for generating RunAsGroup values for a -// Security Context. -// Deprecated: use RunAsGroupStrategy from policy API Group instead. -type RunAsGroupStrategy string - -const ( - // RunAsGroupStrategyMayRunAs means that container does not need to run with a particular gid. - // However, when RunAsGroup are specified, they have to fall in the defined range. - RunAsGroupStrategyMayRunAs RunAsGroupStrategy = "MayRunAs" - // RunAsGroupStrategyMustRunAs means that container must run as a particular gid. - // Deprecated: use RunAsGroupStrategyMustRunAs from policy API Group instead. - RunAsGroupStrategyMustRunAs RunAsGroupStrategy = "MustRunAs" - // RunAsGroupStrategyRunAsAny means that container may make requests for any gid. - // Deprecated: use RunAsGroupStrategyRunAsAny from policy API Group instead. - RunAsGroupStrategyRunAsAny RunAsGroupStrategy = "RunAsAny" -) - -// FSGroupStrategyOptions defines the strategy type and options used to create the strategy. -// Deprecated: use FSGroupStrategyOptions from policy API Group instead. -type FSGroupStrategyOptions struct { - // rule is the strategy that will dictate what FSGroup is used in the SecurityContext. - // +optional - Rule FSGroupStrategyType `json:"rule,omitempty" protobuf:"bytes,1,opt,name=rule,casttype=FSGroupStrategyType"` - // ranges are the allowed ranges of fs groups. If you would like to force a single - // fs group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange `json:"ranges,omitempty" protobuf:"bytes,2,rep,name=ranges"` -} - -// FSGroupStrategyType denotes strategy types for generating FSGroup values for a -// SecurityContext -// Deprecated: use FSGroupStrategyType from policy API Group instead. -type FSGroupStrategyType string - -const ( - // FSGroupStrategyMustRunAs meant that container must have FSGroup of X applied. - // Deprecated: use FSGroupStrategyMustRunAs from policy API Group instead. - FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs" - // FSGroupStrategyRunAsAny means that container may make requests for any FSGroup labels. - // Deprecated: use FSGroupStrategyRunAsAny from policy API Group instead. - FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny" -) - -// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. -// Deprecated: use SupplementalGroupsStrategyOptions from policy API Group instead. -type SupplementalGroupsStrategyOptions struct { - // rule is the strategy that will dictate what supplemental groups is used in the SecurityContext. - // +optional - Rule SupplementalGroupsStrategyType `json:"rule,omitempty" protobuf:"bytes,1,opt,name=rule,casttype=SupplementalGroupsStrategyType"` - // ranges are the allowed ranges of supplemental groups. If you would like to force a single - // supplemental group then supply a single range with the same start and end. Required for MustRunAs. - // +optional - Ranges []IDRange `json:"ranges,omitempty" protobuf:"bytes,2,rep,name=ranges"` -} - -// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental -// groups for a SecurityContext. -// Deprecated: use SupplementalGroupsStrategyType from policy API Group instead. -type SupplementalGroupsStrategyType string - -const ( - // SupplementalGroupsStrategyMustRunAs means that container must run as a particular gid. - // Deprecated: use SupplementalGroupsStrategyMustRunAs from policy API Group instead. - SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs" - // SupplementalGroupsStrategyRunAsAny means that container may make requests for any gid. - // Deprecated: use SupplementalGroupsStrategyRunAsAny from policy API Group instead. - SupplementalGroupsStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny" -) - -// RuntimeClassStrategyOptions define the strategy that will dictate the allowable RuntimeClasses -// for a pod. -type RuntimeClassStrategyOptions struct { - // allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod. - // A value of "*" means that any RuntimeClass name is allowed, and must be the only item in the - // list. An empty list requires the RuntimeClassName field to be unset. - AllowedRuntimeClassNames []string `json:"allowedRuntimeClassNames" protobuf:"bytes,1,rep,name=allowedRuntimeClassNames"` - // defaultRuntimeClassName is the default RuntimeClassName to set on the pod. - // The default MUST be allowed by the allowedRuntimeClassNames list. - // A value of nil does not mutate the Pod. - // +optional - DefaultRuntimeClassName *string `json:"defaultRuntimeClassName,omitempty" protobuf:"bytes,2,opt,name=defaultRuntimeClassName"` -} - -// AllowAllRuntimeClassNames can be used as a value for the -// RuntimeClassStrategyOptions.AllowedRuntimeClassNames field and means that any RuntimeClassName is -// allowed. -const AllowAllRuntimeClassNames = "*" - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +k8s:prerelease-lifecycle-gen:introduced=1.2 -// +k8s:prerelease-lifecycle-gen:deprecated=1.11 -// +k8s:prerelease-lifecycle-gen:removed=1.16 -// +k8s:prerelease-lifecycle-gen:replacement=policy,v1beta1,PodSecurityPolicyList - -// PodSecurityPolicyList is a list of PodSecurityPolicy objects. -// Deprecated: use PodSecurityPolicyList from policy API Group instead. -type PodSecurityPolicyList 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 []PodSecurityPolicy `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.3 diff --git a/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go index 302eb9538..39aaf4853 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go @@ -24,37 +24,9 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. -var map_AllowedCSIDriver = map[string]string{ - "": "AllowedCSIDriver represents a single inline CSI Driver that is allowed to be used.", - "name": "Name is the registered name of the CSI driver", -} - -func (AllowedCSIDriver) SwaggerDoc() map[string]string { - return map_AllowedCSIDriver -} - -var map_AllowedFlexVolume = map[string]string{ - "": "AllowedFlexVolume represents a single Flexvolume that is allowed to be used. Deprecated: use AllowedFlexVolume from policy API Group instead.", - "driver": "driver is the name of the Flexvolume driver.", -} - -func (AllowedFlexVolume) SwaggerDoc() map[string]string { - return map_AllowedFlexVolume -} - -var map_AllowedHostPath = map[string]string{ - "": "AllowedHostPath defines the host volume conditions that will be enabled by a policy for pods to use. It requires the path prefix to be defined. Deprecated: use AllowedHostPath from policy API Group instead.", - "pathPrefix": "pathPrefix is the path prefix that the host volume must match. It does not support `*`. Trailing slashes are trimmed when validating the path prefix with a host path.\n\nExamples: `/foo` would allow `/foo`, `/foo/` and `/foo/bar` `/foo` would not allow `/food` or `/etc/foo`", - "readOnly": "when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly.", -} - -func (AllowedHostPath) SwaggerDoc() map[string]string { - return map_AllowedHostPath -} - var map_DaemonSet = map[string]string{ "": "DEPRECATED - This group version of DaemonSet is deprecated by apps/v1beta2/DaemonSet. See the release notes for more information. DaemonSet represents the configuration of a daemon set.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", @@ -220,16 +192,6 @@ func (DeploymentStrategy) SwaggerDoc() map[string]string { return map_DeploymentStrategy } -var map_FSGroupStrategyOptions = map[string]string{ - "": "FSGroupStrategyOptions defines the strategy type and options used to create the strategy. Deprecated: use FSGroupStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate what FSGroup is used in the SecurityContext.", - "ranges": "ranges are the allowed ranges of fs groups. If you would like to force a single fs group then supply a single range with the same start and end. Required for MustRunAs.", -} - -func (FSGroupStrategyOptions) SwaggerDoc() map[string]string { - return map_FSGroupStrategyOptions -} - var map_HTTPIngressPath = map[string]string{ "": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", "path": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/'. When unspecified, all paths from incoming requests are matched.", @@ -250,26 +212,6 @@ func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { return map_HTTPIngressRuleValue } -var map_HostPortRange = map[string]string{ - "": "HostPortRange defines a range of host ports that will be enabled by a policy for pods to use. It requires both the start and end to be defined. Deprecated: use HostPortRange from policy API Group instead.", - "min": "min is the start of the range, inclusive.", - "max": "max is the end of the range, inclusive.", -} - -func (HostPortRange) SwaggerDoc() map[string]string { - return map_HostPortRange -} - -var map_IDRange = map[string]string{ - "": "IDRange provides a min/max of an allowed range of IDs. Deprecated: use IDRange from policy API Group instead.", - "min": "min is the start of the range, inclusive.", - "max": "max is the end of the range, inclusive.", -} - -func (IDRange) SwaggerDoc() map[string]string { - return map_IDRange -} - var map_IPBlock = map[string]string{ "": "DEPRECATED 1.9 - This group version of IPBlock is deprecated by networking/v1/IPBlock. 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 IP Block Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"", @@ -476,58 +418,6 @@ func (NetworkPolicyStatus) SwaggerDoc() map[string]string { return map_NetworkPolicyStatus } -var map_PodSecurityPolicy = map[string]string{ - "": "PodSecurityPolicy governs the ability to make requests that affect the Security Context that will be applied to a pod and container. Deprecated: use PodSecurityPolicy from policy API Group instead.", - "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "spec defines the policy enforced.", -} - -func (PodSecurityPolicy) SwaggerDoc() map[string]string { - return map_PodSecurityPolicy -} - -var map_PodSecurityPolicyList = map[string]string{ - "": "PodSecurityPolicyList is a list of PodSecurityPolicy objects. Deprecated: use PodSecurityPolicyList from policy API Group instead.", - "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 (PodSecurityPolicyList) SwaggerDoc() map[string]string { - return map_PodSecurityPolicyList -} - -var map_PodSecurityPolicySpec = map[string]string{ - "": "PodSecurityPolicySpec defines the policy enforced. Deprecated: use PodSecurityPolicySpec from policy API Group instead.", - "privileged": "privileged determines if a pod can request to be run as privileged.", - "defaultAddCapabilities": "defaultAddCapabilities is the default set of capabilities that will be added to the container unless the pod spec specifically drops the capability. You may not list a capability in both defaultAddCapabilities and requiredDropCapabilities. Capabilities added here are implicitly allowed, and need not be included in the allowedCapabilities list.", - "requiredDropCapabilities": "requiredDropCapabilities are the capabilities that will be dropped from the container. These are required to be dropped and cannot be added.", - "allowedCapabilities": "allowedCapabilities is a list of capabilities that can be requested to add to the container. Capabilities in this field may be added at the pod author's discretion. You must not list a capability in both allowedCapabilities and requiredDropCapabilities.", - "volumes": "volumes is an allowlist of volume plugins. Empty indicates that no volumes may be used. To allow all volumes you may use '*'.", - "hostNetwork": "hostNetwork determines if the policy allows the use of HostNetwork in the pod spec.", - "hostPorts": "hostPorts determines which host port ranges are allowed to be exposed.", - "hostPID": "hostPID determines if the policy allows the use of HostPID in the pod spec.", - "hostIPC": "hostIPC determines if the policy allows the use of HostIPC in the pod spec.", - "seLinux": "seLinux is the strategy that will dictate the allowable labels that may be set.", - "runAsUser": "runAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.", - "runAsGroup": "RunAsGroup is the strategy that will dictate the allowable RunAsGroup values that may be set. If this field is omitted, the pod's RunAsGroup can take any value. This field requires the RunAsGroup feature gate to be enabled.", - "supplementalGroups": "supplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext.", - "fsGroup": "fsGroup is the strategy that will dictate what fs group is used by the SecurityContext.", - "readOnlyRootFilesystem": "readOnlyRootFilesystem when set to true will force containers to run with a read only root file system. If the container specifically requests to run with a non-read only root file system the PSP should deny the pod. If set to false the container may run with a read only root file system if it wishes but it will not be forced to.", - "defaultAllowPrivilegeEscalation": "defaultAllowPrivilegeEscalation controls the default setting for whether a process can gain more privileges than its parent process.", - "allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.", - "allowedHostPaths": "allowedHostPaths is an allowlist of host paths. Empty indicates that all host paths may be used.", - "allowedFlexVolumes": "allowedFlexVolumes is an allowlist of Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.", - "allowedCSIDrivers": "AllowedCSIDrivers is an allowlist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. An empty value indicates that any CSI driver can be used for inline ephemeral volumes.", - "allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to allowlist all unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.", - "forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.", - "allowedProcMountTypes": "AllowedProcMountTypes is an allowlist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.", - "runtimeClass": "runtimeClass is the strategy that will dictate the allowable RuntimeClasses for a pod. If this field is omitted, the pod's runtimeClassName field is unrestricted. Enforcement of this field depends on the RuntimeClass feature gate being enabled.", -} - -func (PodSecurityPolicySpec) SwaggerDoc() map[string]string { - return map_PodSecurityPolicySpec -} - var map_ReplicaSet = map[string]string{ "": "DEPRECATED - This group version of ReplicaSet is deprecated by apps/v1beta2/ReplicaSet. See the release notes for more information. ReplicaSet ensures that a specified number of pod replicas are running at any given time.", "metadata": "If the Labels of a ReplicaSet are empty, they are defaulted to be the same as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", @@ -617,46 +507,6 @@ func (RollingUpdateDeployment) SwaggerDoc() map[string]string { return map_RollingUpdateDeployment } -var map_RunAsGroupStrategyOptions = map[string]string{ - "": "RunAsGroupStrategyOptions defines the strategy type and any options used to create the strategy. Deprecated: use RunAsGroupStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate the allowable RunAsGroup values that may be set.", - "ranges": "ranges are the allowed ranges of gids that may be used. If you would like to force a single gid then supply a single range with the same start and end. Required for MustRunAs.", -} - -func (RunAsGroupStrategyOptions) SwaggerDoc() map[string]string { - return map_RunAsGroupStrategyOptions -} - -var map_RunAsUserStrategyOptions = map[string]string{ - "": "RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy. Deprecated: use RunAsUserStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate the allowable RunAsUser values that may be set.", - "ranges": "ranges are the allowed ranges of uids that may be used. If you would like to force a single uid then supply a single range with the same start and end. Required for MustRunAs.", -} - -func (RunAsUserStrategyOptions) SwaggerDoc() map[string]string { - return map_RunAsUserStrategyOptions -} - -var map_RuntimeClassStrategyOptions = map[string]string{ - "": "RuntimeClassStrategyOptions define the strategy that will dictate the allowable RuntimeClasses for a pod.", - "allowedRuntimeClassNames": "allowedRuntimeClassNames is an allowlist of RuntimeClass names that may be specified on a pod. A value of \"*\" means that any RuntimeClass name is allowed, and must be the only item in the list. An empty list requires the RuntimeClassName field to be unset.", - "defaultRuntimeClassName": "defaultRuntimeClassName is the default RuntimeClassName to set on the pod. The default MUST be allowed by the allowedRuntimeClassNames list. A value of nil does not mutate the Pod.", -} - -func (RuntimeClassStrategyOptions) SwaggerDoc() map[string]string { - return map_RuntimeClassStrategyOptions -} - -var map_SELinuxStrategyOptions = map[string]string{ - "": "SELinuxStrategyOptions defines the strategy type and any options used to create the strategy. Deprecated: use SELinuxStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate the allowable labels that may be set.", - "seLinuxOptions": "seLinuxOptions required to run as; required for MustRunAs More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", -} - -func (SELinuxStrategyOptions) SwaggerDoc() map[string]string { - return map_SELinuxStrategyOptions -} - var map_Scale = map[string]string{ "": "represents a scaling request for a resource.", "metadata": "Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata.", @@ -680,7 +530,7 @@ func (ScaleSpec) SwaggerDoc() map[string]string { var map_ScaleStatus = map[string]string{ "": "represents the current status of a scale subresource.", "replicas": "actual number of observed instances of the scaled object.", - "selector": "label query over pods that should match the replicas count. More info: http://kubernetes.io/docs/user-guide/labels#label-selectors", + "selector": "selector is a label query over pods that should match the replicas count. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/", "targetSelector": "label selector for pods that should match the replicas count. This is a serializated version of both map-based and more expressive set-based selectors. This is done to avoid introspection in the clients. The string will be in the same format as the query-param syntax. If the target type only supports map-based selectors, both this field and map-based selector field are populated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", } @@ -688,14 +538,4 @@ func (ScaleStatus) SwaggerDoc() map[string]string { return map_ScaleStatus } -var map_SupplementalGroupsStrategyOptions = map[string]string{ - "": "SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy. Deprecated: use SupplementalGroupsStrategyOptions from policy API Group instead.", - "rule": "rule is the strategy that will dictate what supplemental groups is used in the SecurityContext.", - "ranges": "ranges are the allowed ranges of supplemental groups. If you would like to force a single supplemental group then supply a single range with the same start and end. Required for MustRunAs.", -} - -func (SupplementalGroupsStrategyOptions) SwaggerDoc() map[string]string { - return map_SupplementalGroupsStrategyOptions -} - // AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go index 671aa2d9d..b6e927299 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go @@ -28,54 +28,6 @@ import ( intstr "k8s.io/apimachinery/pkg/util/intstr" ) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedCSIDriver) DeepCopyInto(out *AllowedCSIDriver) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedCSIDriver. -func (in *AllowedCSIDriver) DeepCopy() *AllowedCSIDriver { - if in == nil { - return nil - } - out := new(AllowedCSIDriver) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedFlexVolume) DeepCopyInto(out *AllowedFlexVolume) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedFlexVolume. -func (in *AllowedFlexVolume) DeepCopy() *AllowedFlexVolume { - if in == nil { - return nil - } - out := new(AllowedFlexVolume) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AllowedHostPath) DeepCopyInto(out *AllowedHostPath) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedHostPath. -func (in *AllowedHostPath) DeepCopy() *AllowedHostPath { - if in == nil { - return nil - } - out := new(AllowedHostPath) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DaemonSet) DeepCopyInto(out *DaemonSet) { *out = *in @@ -435,27 +387,6 @@ func (in *DeploymentStrategy) DeepCopy() *DeploymentStrategy { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FSGroupStrategyOptions) DeepCopyInto(out *FSGroupStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FSGroupStrategyOptions. -func (in *FSGroupStrategyOptions) DeepCopy() *FSGroupStrategyOptions { - if in == nil { - return nil - } - out := new(FSGroupStrategyOptions) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPIngressPath) DeepCopyInto(out *HTTPIngressPath) { *out = *in @@ -501,38 +432,6 @@ 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 *HostPortRange) DeepCopyInto(out *HostPortRange) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPortRange. -func (in *HostPortRange) DeepCopy() *HostPortRange { - if in == nil { - return nil - } - out := new(HostPortRange) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IDRange) DeepCopyInto(out *IDRange) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IDRange. -func (in *IDRange) DeepCopy() *IDRange { - if in == nil { - return nil - } - out := new(IDRange) - 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 @@ -1062,161 +961,6 @@ func (in *NetworkPolicyStatus) DeepCopy() *NetworkPolicyStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodSecurityPolicy) DeepCopyInto(out *PodSecurityPolicy) { - *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 PodSecurityPolicy. -func (in *PodSecurityPolicy) DeepCopy() *PodSecurityPolicy { - if in == nil { - return nil - } - out := new(PodSecurityPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodSecurityPolicy) 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 *PodSecurityPolicyList) DeepCopyInto(out *PodSecurityPolicyList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PodSecurityPolicy, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityPolicyList. -func (in *PodSecurityPolicyList) DeepCopy() *PodSecurityPolicyList { - if in == nil { - return nil - } - out := new(PodSecurityPolicyList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodSecurityPolicyList) 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 *PodSecurityPolicySpec) DeepCopyInto(out *PodSecurityPolicySpec) { - *out = *in - if in.DefaultAddCapabilities != nil { - in, out := &in.DefaultAddCapabilities, &out.DefaultAddCapabilities - *out = make([]corev1.Capability, len(*in)) - copy(*out, *in) - } - if in.RequiredDropCapabilities != nil { - in, out := &in.RequiredDropCapabilities, &out.RequiredDropCapabilities - *out = make([]corev1.Capability, len(*in)) - copy(*out, *in) - } - if in.AllowedCapabilities != nil { - in, out := &in.AllowedCapabilities, &out.AllowedCapabilities - *out = make([]corev1.Capability, len(*in)) - copy(*out, *in) - } - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make([]FSType, len(*in)) - copy(*out, *in) - } - if in.HostPorts != nil { - in, out := &in.HostPorts, &out.HostPorts - *out = make([]HostPortRange, len(*in)) - copy(*out, *in) - } - in.SELinux.DeepCopyInto(&out.SELinux) - in.RunAsUser.DeepCopyInto(&out.RunAsUser) - if in.RunAsGroup != nil { - in, out := &in.RunAsGroup, &out.RunAsGroup - *out = new(RunAsGroupStrategyOptions) - (*in).DeepCopyInto(*out) - } - in.SupplementalGroups.DeepCopyInto(&out.SupplementalGroups) - in.FSGroup.DeepCopyInto(&out.FSGroup) - if in.DefaultAllowPrivilegeEscalation != nil { - in, out := &in.DefaultAllowPrivilegeEscalation, &out.DefaultAllowPrivilegeEscalation - *out = new(bool) - **out = **in - } - if in.AllowPrivilegeEscalation != nil { - in, out := &in.AllowPrivilegeEscalation, &out.AllowPrivilegeEscalation - *out = new(bool) - **out = **in - } - if in.AllowedHostPaths != nil { - in, out := &in.AllowedHostPaths, &out.AllowedHostPaths - *out = make([]AllowedHostPath, len(*in)) - copy(*out, *in) - } - if in.AllowedFlexVolumes != nil { - in, out := &in.AllowedFlexVolumes, &out.AllowedFlexVolumes - *out = make([]AllowedFlexVolume, len(*in)) - copy(*out, *in) - } - if in.AllowedCSIDrivers != nil { - in, out := &in.AllowedCSIDrivers, &out.AllowedCSIDrivers - *out = make([]AllowedCSIDriver, len(*in)) - copy(*out, *in) - } - if in.AllowedUnsafeSysctls != nil { - in, out := &in.AllowedUnsafeSysctls, &out.AllowedUnsafeSysctls - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ForbiddenSysctls != nil { - in, out := &in.ForbiddenSysctls, &out.ForbiddenSysctls - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.AllowedProcMountTypes != nil { - in, out := &in.AllowedProcMountTypes, &out.AllowedProcMountTypes - *out = make([]corev1.ProcMountType, len(*in)) - copy(*out, *in) - } - if in.RuntimeClass != nil { - in, out := &in.RuntimeClass, &out.RuntimeClass - *out = new(RuntimeClassStrategyOptions) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityPolicySpec. -func (in *PodSecurityPolicySpec) DeepCopy() *PodSecurityPolicySpec { - if in == nil { - return nil - } - out := new(PodSecurityPolicySpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicaSet) DeepCopyInto(out *ReplicaSet) { *out = *in @@ -1413,95 +1157,6 @@ func (in *RollingUpdateDeployment) DeepCopy() *RollingUpdateDeployment { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RunAsGroupStrategyOptions) DeepCopyInto(out *RunAsGroupStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunAsGroupStrategyOptions. -func (in *RunAsGroupStrategyOptions) DeepCopy() *RunAsGroupStrategyOptions { - if in == nil { - return nil - } - out := new(RunAsGroupStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RunAsUserStrategyOptions) DeepCopyInto(out *RunAsUserStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RunAsUserStrategyOptions. -func (in *RunAsUserStrategyOptions) DeepCopy() *RunAsUserStrategyOptions { - if in == nil { - return nil - } - out := new(RunAsUserStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RuntimeClassStrategyOptions) DeepCopyInto(out *RuntimeClassStrategyOptions) { - *out = *in - if in.AllowedRuntimeClassNames != nil { - in, out := &in.AllowedRuntimeClassNames, &out.AllowedRuntimeClassNames - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.DefaultRuntimeClassName != nil { - in, out := &in.DefaultRuntimeClassName, &out.DefaultRuntimeClassName - *out = new(string) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeClassStrategyOptions. -func (in *RuntimeClassStrategyOptions) DeepCopy() *RuntimeClassStrategyOptions { - if in == nil { - return nil - } - out := new(RuntimeClassStrategyOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SELinuxStrategyOptions) DeepCopyInto(out *SELinuxStrategyOptions) { - *out = *in - if in.SELinuxOptions != nil { - in, out := &in.SELinuxOptions, &out.SELinuxOptions - *out = new(corev1.SELinuxOptions) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SELinuxStrategyOptions. -func (in *SELinuxStrategyOptions) DeepCopy() *SELinuxStrategyOptions { - if in == nil { - return nil - } - out := new(SELinuxStrategyOptions) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Scale) DeepCopyInto(out *Scale) { *out = *in @@ -1568,24 +1223,3 @@ func (in *ScaleStatus) DeepCopy() *ScaleStatus { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SupplementalGroupsStrategyOptions) DeepCopyInto(out *SupplementalGroupsStrategyOptions) { - *out = *in - if in.Ranges != nil { - in, out := &in.Ranges, &out.Ranges - *out = make([]IDRange, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SupplementalGroupsStrategyOptions. -func (in *SupplementalGroupsStrategyOptions) DeepCopy() *SupplementalGroupsStrategyOptions { - if in == nil { - return nil - } - out := new(SupplementalGroupsStrategyOptions) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.prerelease-lifecycle.go index 963aaffba..5c9354228 100644 --- a/vendor/k8s.io/api/extensions/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/extensions/v1beta1/zz_generated.prerelease-lifecycle.go @@ -235,54 +235,6 @@ func (in *NetworkPolicyList) APILifecycleRemoved() (major, minor int) { return 1, 16 } -// 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 *PodSecurityPolicy) APILifecycleIntroduced() (major, minor int) { - return 1, 2 -} - -// 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 *PodSecurityPolicy) APILifecycleDeprecated() (major, minor int) { - return 1, 11 -} - -// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. -// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. -func (in *PodSecurityPolicy) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "PodSecurityPolicy"} -} - -// 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 *PodSecurityPolicy) APILifecycleRemoved() (major, minor int) { - return 1, 16 -} - -// 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 *PodSecurityPolicyList) APILifecycleIntroduced() (major, minor int) { - return 1, 2 -} - -// 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 *PodSecurityPolicyList) APILifecycleDeprecated() (major, minor int) { - return 1, 11 -} - -// APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. -// It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. -func (in *PodSecurityPolicyList) APILifecycleReplacement() schema.GroupVersionKind { - return schema.GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "PodSecurityPolicyList"} -} - -// 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 *PodSecurityPolicyList) APILifecycleRemoved() (major, minor int) { - return 1, 16 -} - // 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 *ReplicaSet) APILifecycleIntroduced() (major, minor int) { diff --git a/vendor/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go index ac6f7179a..c95999fa5 100644 --- a/vendor/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/flowcontrol/v1alpha1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_FlowDistinguisherMethod = map[string]string{ diff --git a/vendor/k8s.io/api/flowcontrol/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/flowcontrol/v1beta1/types_swagger_doc_generated.go index fe4f8022a..fc08e128d 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_FlowDistinguisherMethod = map[string]string{ diff --git a/vendor/k8s.io/api/flowcontrol/v1beta2/types_swagger_doc_generated.go b/vendor/k8s.io/api/flowcontrol/v1beta2/types_swagger_doc_generated.go index 4bedcce3e..b2eff7f96 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta2/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta2/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta2 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_FlowDistinguisherMethod = map[string]string{ diff --git a/vendor/k8s.io/api/flowcontrol/v1beta3/types_swagger_doc_generated.go b/vendor/k8s.io/api/flowcontrol/v1beta3/types_swagger_doc_generated.go index e2bd27e8c..728252c0c 100644 --- a/vendor/k8s.io/api/flowcontrol/v1beta3/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/flowcontrol/v1beta3/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta3 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_FlowDistinguisherMethod = map[string]string{ diff --git a/vendor/k8s.io/api/networking/v1/generated.proto b/vendor/k8s.io/api/networking/v1/generated.proto index 8196a14b9..ed194a89d 100644 --- a/vendor/k8s.io/api/networking/v1/generated.proto +++ b/vendor/k8s.io/api/networking/v1/generated.proto @@ -33,14 +33,14 @@ option go_package = "k8s.io/api/networking/v1"; // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. message HTTPIngressPath { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional optional string path = 1; - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of the following values: // * Exact: Matches the URL path exactly. // * Prefix: Matches based on a URL path prefix split by '/'. Matching is @@ -56,7 +56,7 @@ message HTTPIngressPath { // Implementations are required to support all path types. optional string pathType = 3; - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. optional IngressBackend backend = 2; } @@ -67,7 +67,7 @@ message HTTPIngressPath { // to match against everything after the last '/' and before the first '?' // or '#'. message HTTPIngressRuleValue { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. // +listType=atomic repeated HTTPIngressPath paths = 1; } @@ -76,13 +76,13 @@ message HTTPIngressRuleValue { // to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs // that should not be included within this rule. message IPBlock { - // CIDR is a string representing the IP Block + // cidr is a string representing the IPBlock // Valid examples are "192.168.1.0/24" or "2001:db8::/64" optional string cidr = 1; - // Except is a slice of CIDRs that should not be included within an IP Block + // except is a slice of CIDRs that should not be included within an IPBlock // Valid examples are "192.168.1.0/24" or "2001:db8::/64" - // Except values will be rejected if they are outside the CIDR range + // Except values will be rejected if they are outside the cidr range // +optional repeated string except = 2; } @@ -97,12 +97,12 @@ message Ingress { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressSpec spec = 2; - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressStatus status = 3; @@ -110,12 +110,12 @@ message Ingress { // IngressBackend describes all endpoints for a given service and port. message IngressBackend { - // Service references a Service as a Backend. + // service references a service as a backend. // This is a mutually exclusive setting with "Resource". // +optional optional IngressServiceBackend service = 4; - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, a service.Name and // service.Port must not be specified. // This is a mutually exclusive setting with "Service". @@ -134,7 +134,7 @@ message IngressClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressClassSpec spec = 2; @@ -146,31 +146,31 @@ message IngressClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of IngressClasses. + // items is the list of IngressClasses. repeated IngressClass items = 2; } // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. message IngressClassParametersReference { - // APIGroup is the group for the resource being referenced. If APIGroup is + // apiGroup is the group for the resource being referenced. If APIGroup is // not specified, the specified Kind must be in the core API group. For any // other third-party types, APIGroup is required. // +optional optional string aPIGroup = 1; - // Kind is the type of resource being referenced. + // kind is the type of resource being referenced. optional string kind = 2; - // Name is the name of resource being referenced. + // name is the name of resource being referenced. optional string name = 3; - // Scope represents if this refers to a cluster or namespace scoped resource. + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". // +optional optional string scope = 4; - // Namespace is the namespace of the resource being referenced. This field is + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -179,15 +179,15 @@ message IngressClassParametersReference { // IngressClassSpec provides information about the class of an Ingress. message IngressClassSpec { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. optional string controller = 1; - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -201,21 +201,21 @@ message IngressList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of Ingress. + // items is the list of Ingress. repeated Ingress items = 2; } // IngressLoadBalancerIngress represents the status of a load-balancer ingress point. message IngressLoadBalancerIngress { - // IP is set for load-balancer ingress points that are IP based. + // ip is set for load-balancer ingress points that are IP based. // +optional optional string ip = 1; - // Hostname is set for load-balancer ingress points that are DNS based. + // hostname is set for load-balancer ingress points that are DNS based. // +optional optional string hostname = 2; - // Ports provides information about the ports exposed by this LoadBalancer. + // ports provides information about the ports exposed by this LoadBalancer. // +listType=atomic // +optional repeated IngressPortStatus ports = 4; @@ -223,21 +223,21 @@ message IngressLoadBalancerIngress { // IngressLoadBalancerStatus represents the status of a load-balancer. message IngressLoadBalancerStatus { - // Ingress is a list containing ingress points for the load-balancer. + // ingress is a list containing ingress points for the load-balancer. // +optional repeated IngressLoadBalancerIngress ingress = 1; } // IngressPortStatus represents the error condition of a service port message IngressPortStatus { - // Port is the port number of the ingress port. + // port is the port number of the ingress port. optional int32 port = 1; - // Protocol is the protocol of the ingress port. + // protocol is the protocol of the ingress port. // The supported values are: "TCP", "UDP", "SCTP" optional string protocol = 2; - // Error is to record the problem with the service port + // error is to record the problem with the service port // The format of the error shall comply with the following rules: // - built-in error values shall be specified in this file and those shall use // CamelCase names @@ -256,7 +256,7 @@ message IngressPortStatus { // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. message IngressRule { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -269,14 +269,14 @@ message IngressRule { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and // matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*"). // Requests will be matched against the Host field in the following way: - // 1. If Host is precise, the request matches this rule if the http host header is equal to Host. - // 2. If Host is a wildcard, then the request matches this rule if the http host header + // 1. If host is precise, the request matches this rule if the http host header is equal to Host. + // 2. If host is a wildcard, then the request matches this rule if the http host header // is to equal to the suffix (removing the first label) of the wildcard rule. // +optional optional string host = 1; @@ -301,18 +301,18 @@ message IngressRuleValue { // IngressServiceBackend references a Kubernetes Service as a Backend. message IngressServiceBackend { - // Name is the referenced service. The service must exist in + // name is the referenced service. The service must exist in // the same namespace as the Ingress object. optional string name = 1; - // Port of the referenced service. A port name or port number + // port of the referenced service. A port name or port number // is required for a IngressServiceBackend. optional ServiceBackendPort port = 2; } // IngressSpec describes the Ingress the user wishes to exist. message IngressSpec { - // IngressClassName is the name of an IngressClass cluster resource. Ingress + // ingressClassName is the name of an IngressClass cluster resource. Ingress // controller implementations use this field to know whether they should be // serving this Ingress resource, by a transitive connection // (controller -> IngressClass -> Ingress resource). Although the @@ -325,24 +325,24 @@ message IngressSpec { // +optional optional string ingressClassName = 4; - // DefaultBackend is the backend that should handle requests that don't + // defaultBackend is the backend that should handle requests that don't // match any rule. If Rules are not specified, DefaultBackend must be specified. // If DefaultBackend is not set, the handling of requests that do not match any // of the rules will be up to the Ingress controller. // +optional optional IngressBackend defaultBackend = 1; - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the Ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +listType=atomic // +optional repeated IngressTLS tls = 2; - // A list of host rules used to configure the Ingress. If unspecified, or - // no rule matches, all traffic is sent to the default backend. + // rules is a list of host rules used to configure the Ingress. If unspecified, + // or no rule matches, all traffic is sent to the default backend. // +listType=atomic // +optional repeated IngressRule rules = 3; @@ -350,14 +350,14 @@ message IngressSpec { // IngressStatus describe the current state of the Ingress. message IngressStatus { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. // +optional optional IngressLoadBalancerStatus loadBalancer = 1; } -// IngressTLS describes the transport layer security associated with an Ingress. +// IngressTLS describes the transport layer security associated with an ingress. message IngressTLS { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. @@ -365,11 +365,11 @@ message IngressTLS { // +optional repeated string hosts = 1; - // SecretName is the name of the secret used to terminate TLS traffic on + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination - // and value of the Host header is used for routing. + // and value of the "Host" header is used for routing. // +optional optional string secretName = 2; } @@ -381,11 +381,11 @@ message NetworkPolicy { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired behavior for this NetworkPolicy. + // spec represents the specification of the desired behavior for this NetworkPolicy. // +optional optional NetworkPolicySpec spec = 2; - // Status is the current state of the NetworkPolicy. + // status represents the current state of the NetworkPolicy. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional NetworkPolicyStatus status = 3; @@ -395,7 +395,7 @@ message NetworkPolicy { // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. // This type is beta-level in 1.8 message NetworkPolicyEgressRule { - // List of destination ports for outgoing traffic. + // ports is a list of destination ports for outgoing traffic. // Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows @@ -403,7 +403,7 @@ message NetworkPolicyEgressRule { // +optional repeated NetworkPolicyPort ports = 1; - // List of destinations for outgoing traffic of pods selected for this rule. + // to is a list of destinations for outgoing traffic of pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all destinations (traffic not restricted by // destination). If this field is present and contains at least one item, this rule @@ -415,15 +415,15 @@ message NetworkPolicyEgressRule { // NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from. message NetworkPolicyIngressRule { - // List of ports which should be made accessible on the pods selected for this - // rule. Each item in this list is combined using a logical OR. If this field is + // ports is a list of ports which should be made accessible on the pods selected for + // this rule. Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows // traffic only if the traffic matches at least one port in the list. // +optional repeated NetworkPolicyPort ports = 1; - // List of sources which should be able to access the pods selected for this rule. + // from is a list of sources which should be able to access the pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all sources (traffic not restricted by // source). If this field is present and contains at least one item, this rule @@ -439,32 +439,32 @@ message NetworkPolicyList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated NetworkPolicy items = 2; } // NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of // fields are allowed message NetworkPolicyPeer { - // This is a label selector which selects Pods. This field follows standard label + // podSelector is a label selector which selects pods. This field follows standard label // selector semantics; if present but empty, it selects all pods. // - // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. + // If namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the Namespaces selected by NamespaceSelector. + // Otherwise it selects the pods matching podSelector in the policy's own namespace. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector podSelector = 1; - // Selects Namespaces using cluster-scoped labels. This field follows standard label - // selector semantics; if present but empty, it selects all namespaces. + // namespaceSelector selects namespaces using cluster-scoped labels. This field follows + // standard label selector semantics; if present but empty, it selects all namespaces. // - // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. + // If podSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the namespaces selected by namespaceSelector. + // Otherwise it selects all pods in the namespaces selected by namespaceSelector. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 2; - // IPBlock defines policy on a particular IPBlock. If this field is set then + // ipBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional optional IPBlock ipBlock = 3; @@ -472,19 +472,19 @@ message NetworkPolicyPeer { // NetworkPolicyPort describes a port to allow traffic on message NetworkPolicyPort { - // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this - // field defaults to TCP. + // protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. + // If not specified, this field defaults to TCP. // +optional optional string protocol = 1; - // The port on the given protocol. This can either be a numerical or named + // port represents the port on the given protocol. This can either be a numerical or named // port on a pod. If this field is not provided, this matches all port names and // numbers. // If present, only traffic on the specified protocol AND port will be matched. // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString port = 2; - // If set, indicates that the range of ports from port to endPort, inclusive, + // endPort indicates that the range of ports from port to endPort if set, inclusive, // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. @@ -494,16 +494,16 @@ message NetworkPolicyPort { // NetworkPolicySpec provides the specification of a NetworkPolicy message NetworkPolicySpec { - // Selects the pods to which this NetworkPolicy object applies. The array of - // ingress rules is applied to any pods selected by this field. Multiple network - // policies can select the same set of pods. In this case, the ingress rules for - // each are combined additively. This field is NOT optional and follows standard - // label selector semantics. An empty podSelector matches all pods in this - // namespace. + // podSelector selects the pods to which this NetworkPolicy object applies. + // The array of ingress rules is applied to any pods selected by this field. + // Multiple network policies can select the same set of pods. In this case, + // the ingress rules for each are combined additively. + // This field is NOT optional and follows standard label selector semantics. + // An empty podSelector matches all pods in this namespace. optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector podSelector = 1; - // List of ingress rules to be applied to the selected pods. Traffic is allowed to - // a pod if there are no NetworkPolicies selecting the pod + // ingress is a list of ingress rules to be applied to the selected pods. + // Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod // (and cluster policy otherwise allows the traffic), OR if the traffic source is // the pod's local node, OR if the traffic matches at least one ingress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If @@ -512,8 +512,8 @@ message NetworkPolicySpec { // +optional repeated NetworkPolicyIngressRule ingress = 2; - // List of egress rules to be applied to the selected pods. Outgoing traffic is - // allowed if there are no NetworkPolicies selecting the pod (and cluster policy + // egress is a list of egress rules to be applied to the selected pods. Outgoing traffic + // is allowed if there are no NetworkPolicies selecting the pod (and cluster policy // otherwise allows the traffic), OR if the traffic matches at least one egress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If // this field is empty then this NetworkPolicy limits all outgoing traffic (and serves @@ -522,23 +522,23 @@ message NetworkPolicySpec { // +optional repeated NetworkPolicyEgressRule egress = 3; - // List of rule types that the NetworkPolicy relates to. + // policyTypes is a list of rule types that the NetworkPolicy relates to. // Valid options are ["Ingress"], ["Egress"], or ["Ingress", "Egress"]. - // If this field is not specified, it will default based on the existence of Ingress or Egress rules; - // policies that contain an Egress section are assumed to affect Egress, and all policies - // (whether or not they contain an Ingress section) are assumed to affect Ingress. + // If this field is not specified, it will default based on the existence of ingress or egress rules; + // policies that contain an egress section are assumed to affect egress, and all policies + // (whether or not they contain an ingress section) are assumed to affect ingress. // If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. // Likewise, if you want to write a policy that specifies that no egress is allowed, // you must specify a policyTypes value that include "Egress" (since such a policy would not include - // an Egress section and would otherwise default to just [ "Ingress" ]). + // an egress section and would otherwise default to just [ "Ingress" ]). // This field is beta-level in 1.8 // +optional repeated string policyTypes = 4; } -// NetworkPolicyStatus describe the current state of the NetworkPolicy. +// NetworkPolicyStatus describes the current state of the NetworkPolicy. message NetworkPolicyStatus { - // Conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. + // conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. // Current service state // +optional // +patchMergeKey=type @@ -550,12 +550,12 @@ message NetworkPolicyStatus { // ServiceBackendPort is the service port being referenced. message ServiceBackendPort { - // Name is the name of the port on the Service. + // name is the name of the port on the Service. // This is a mutually exclusive setting with "Number". // +optional optional string name = 1; - // Number is the numerical port number (e.g. 80) on the Service. + // number is the numerical port number (e.g. 80) on the Service. // This is a mutually exclusive setting with "Name". // +optional optional int32 number = 2; diff --git a/vendor/k8s.io/api/networking/v1/types.go b/vendor/k8s.io/api/networking/v1/types.go index a9deb900a..fa7cf1bd7 100644 --- a/vendor/k8s.io/api/networking/v1/types.go +++ b/vendor/k8s.io/api/networking/v1/types.go @@ -28,16 +28,17 @@ import ( // NetworkPolicy describes what network traffic is allowed for a set of Pods type NetworkPolicy 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"` - // Specification of the desired behavior for this NetworkPolicy. + // spec represents the specification of the desired behavior for this NetworkPolicy. // +optional Spec NetworkPolicySpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // Status is the current state of the NetworkPolicy. + // status represents the current state of the NetworkPolicy. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status NetworkPolicyStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` @@ -57,16 +58,16 @@ const ( // NetworkPolicySpec provides the specification of a NetworkPolicy type NetworkPolicySpec struct { - // Selects the pods to which this NetworkPolicy object applies. The array of - // ingress rules is applied to any pods selected by this field. Multiple network - // policies can select the same set of pods. In this case, the ingress rules for - // each are combined additively. This field is NOT optional and follows standard - // label selector semantics. An empty podSelector matches all pods in this - // namespace. + // podSelector selects the pods to which this NetworkPolicy object applies. + // The array of ingress rules is applied to any pods selected by this field. + // Multiple network policies can select the same set of pods. In this case, + // the ingress rules for each are combined additively. + // This field is NOT optional and follows standard label selector semantics. + // An empty podSelector matches all pods in this namespace. PodSelector metav1.LabelSelector `json:"podSelector" protobuf:"bytes,1,opt,name=podSelector"` - // List of ingress rules to be applied to the selected pods. Traffic is allowed to - // a pod if there are no NetworkPolicies selecting the pod + // ingress is a list of ingress rules to be applied to the selected pods. + // Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod // (and cluster policy otherwise allows the traffic), OR if the traffic source is // the pod's local node, OR if the traffic matches at least one ingress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If @@ -75,8 +76,8 @@ type NetworkPolicySpec struct { // +optional Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty" protobuf:"bytes,2,rep,name=ingress"` - // List of egress rules to be applied to the selected pods. Outgoing traffic is - // allowed if there are no NetworkPolicies selecting the pod (and cluster policy + // egress is a list of egress rules to be applied to the selected pods. Outgoing traffic + // is allowed if there are no NetworkPolicies selecting the pod (and cluster policy // otherwise allows the traffic), OR if the traffic matches at least one egress rule // across all of the NetworkPolicy objects whose podSelector matches the pod. If // this field is empty then this NetworkPolicy limits all outgoing traffic (and serves @@ -85,15 +86,15 @@ type NetworkPolicySpec struct { // +optional Egress []NetworkPolicyEgressRule `json:"egress,omitempty" protobuf:"bytes,3,rep,name=egress"` - // List of rule types that the NetworkPolicy relates to. + // policyTypes is a list of rule types that the NetworkPolicy relates to. // Valid options are ["Ingress"], ["Egress"], or ["Ingress", "Egress"]. - // If this field is not specified, it will default based on the existence of Ingress or Egress rules; - // policies that contain an Egress section are assumed to affect Egress, and all policies - // (whether or not they contain an Ingress section) are assumed to affect Ingress. + // If this field is not specified, it will default based on the existence of ingress or egress rules; + // policies that contain an egress section are assumed to affect egress, and all policies + // (whether or not they contain an ingress section) are assumed to affect ingress. // If you want to write an egress-only policy, you must explicitly specify policyTypes [ "Egress" ]. // Likewise, if you want to write a policy that specifies that no egress is allowed, // you must specify a policyTypes value that include "Egress" (since such a policy would not include - // an Egress section and would otherwise default to just [ "Ingress" ]). + // an egress section and would otherwise default to just [ "Ingress" ]). // This field is beta-level in 1.8 // +optional PolicyTypes []PolicyType `json:"policyTypes,omitempty" protobuf:"bytes,4,rep,name=policyTypes,casttype=PolicyType"` @@ -102,15 +103,15 @@ type NetworkPolicySpec struct { // NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from. type NetworkPolicyIngressRule struct { - // List of ports which should be made accessible on the pods selected for this - // rule. Each item in this list is combined using a logical OR. If this field is + // ports is a list of ports which should be made accessible on the pods selected for + // this rule. Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows // traffic only if the traffic matches at least one port in the list. // +optional Ports []NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` - // List of sources which should be able to access the pods selected for this rule. + // from is a list of sources which should be able to access the pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all sources (traffic not restricted by // source). If this field is present and contains at least one item, this rule @@ -123,7 +124,7 @@ type NetworkPolicyIngressRule struct { // matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. // This type is beta-level in 1.8 type NetworkPolicyEgressRule struct { - // List of destination ports for outgoing traffic. + // ports is a list of destination ports for outgoing traffic. // Each item in this list is combined using a logical OR. If this field is // empty or missing, this rule matches all ports (traffic not restricted by port). // If this field is present and contains at least one item, then this rule allows @@ -131,7 +132,7 @@ type NetworkPolicyEgressRule struct { // +optional Ports []NetworkPolicyPort `json:"ports,omitempty" protobuf:"bytes,1,rep,name=ports"` - // List of destinations for outgoing traffic of pods selected for this rule. + // to is a list of destinations for outgoing traffic of pods selected for this rule. // Items in this list are combined using a logical OR operation. If this field is // empty or missing, this rule matches all destinations (traffic not restricted by // destination). If this field is present and contains at least one item, this rule @@ -142,19 +143,19 @@ type NetworkPolicyEgressRule struct { // NetworkPolicyPort describes a port to allow traffic on type NetworkPolicyPort struct { - // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this - // field defaults to TCP. + // protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. + // If not specified, this field defaults to TCP. // +optional Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,1,opt,name=protocol,casttype=k8s.io/api/core/v1.Protocol"` - // The port on the given protocol. This can either be a numerical or named + // port represents the port on the given protocol. This can either be a numerical or named // port on a pod. If this field is not provided, this matches all port names and // numbers. // If present, only traffic on the specified protocol AND port will be matched. // +optional Port *intstr.IntOrString `json:"port,omitempty" protobuf:"bytes,2,opt,name=port"` - // If set, indicates that the range of ports from port to endPort, inclusive, + // endPort indicates that the range of ports from port to endPort if set, inclusive, // should be allowed by the policy. This field cannot be defined if the port field // is not defined or if the port field is defined as a named (string) port. // The endPort must be equal or greater than port. @@ -166,12 +167,13 @@ type NetworkPolicyPort struct { // to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs // that should not be included within this rule. type IPBlock struct { - // CIDR is a string representing the IP Block + // cidr is a string representing the IPBlock // Valid examples are "192.168.1.0/24" or "2001:db8::/64" CIDR string `json:"cidr" protobuf:"bytes,1,name=cidr"` - // Except is a slice of CIDRs that should not be included within an IP Block + + // except is a slice of CIDRs that should not be included within an IPBlock // Valid examples are "192.168.1.0/24" or "2001:db8::/64" - // Except values will be rejected if they are outside the CIDR range + // Except values will be rejected if they are outside the cidr range // +optional Except []string `json:"except,omitempty" protobuf:"bytes,2,rep,name=except"` } @@ -179,25 +181,25 @@ type IPBlock struct { // NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of // fields are allowed type NetworkPolicyPeer struct { - // This is a label selector which selects Pods. This field follows standard label + // podSelector is a label selector which selects pods. This field follows standard label // selector semantics; if present but empty, it selects all pods. // - // If NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects the Pods matching PodSelector in the policy's own Namespace. + // If namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the Namespaces selected by NamespaceSelector. + // Otherwise it selects the pods matching podSelector in the policy's own namespace. // +optional PodSelector *metav1.LabelSelector `json:"podSelector,omitempty" protobuf:"bytes,1,opt,name=podSelector"` - // Selects Namespaces using cluster-scoped labels. This field follows standard label - // selector semantics; if present but empty, it selects all namespaces. + // namespaceSelector selects namespaces using cluster-scoped labels. This field follows + // standard label selector semantics; if present but empty, it selects all namespaces. // - // If PodSelector is also set, then the NetworkPolicyPeer as a whole selects - // the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. - // Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector. + // If podSelector is also set, then the NetworkPolicyPeer as a whole selects + // the pods matching podSelector in the namespaces selected by namespaceSelector. + // Otherwise it selects all pods in the namespaces selected by namespaceSelector. // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"` - // IPBlock defines policy on a particular IPBlock. If this field is set then + // ipBlock defines policy on a particular IPBlock. If this field is set then // neither of the other fields can be. // +optional IPBlock *IPBlock `json:"ipBlock,omitempty" protobuf:"bytes,3,rep,name=ipBlock"` @@ -233,9 +235,9 @@ const ( NetworkPolicyConditionReasonFeatureNotSupported NetworkPolicyConditionReason = "FeatureNotSupported" ) -// NetworkPolicyStatus describe the current state of the NetworkPolicy. +// NetworkPolicyStatus describes the current state of the NetworkPolicy. type NetworkPolicyStatus struct { - // Conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. + // conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. // Current service state // +optional // +patchMergeKey=type @@ -250,12 +252,13 @@ type NetworkPolicyStatus struct { // NetworkPolicyList is a list of NetworkPolicy objects. type NetworkPolicyList 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 is a list of schema objects. Items []NetworkPolicy `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -268,17 +271,18 @@ type NetworkPolicyList struct { // based virtual hosting etc. type Ingress 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 Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status IngressStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` @@ -289,18 +293,19 @@ type Ingress struct { // IngressList is a collection of Ingress. type IngressList 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 Ingress. + // items is the list of Ingress. Items []Ingress `json:"items" protobuf:"bytes,2,rep,name=items"` } // IngressSpec describes the Ingress the user wishes to exist. type IngressSpec struct { - // IngressClassName is the name of an IngressClass cluster resource. Ingress + // ingressClassName is the name of an IngressClass cluster resource. Ingress // controller implementations use this field to know whether they should be // serving this Ingress resource, by a transitive connection // (controller -> IngressClass -> Ingress resource). Although the @@ -313,72 +318,73 @@ type IngressSpec struct { // +optional IngressClassName *string `json:"ingressClassName,omitempty" protobuf:"bytes,4,opt,name=ingressClassName"` - // DefaultBackend is the backend that should handle requests that don't + // defaultBackend is the backend that should handle requests that don't // match any rule. If Rules are not specified, DefaultBackend must be specified. // If DefaultBackend is not set, the handling of requests that do not match any // of the rules will be up to the Ingress controller. // +optional DefaultBackend *IngressBackend `json:"defaultBackend,omitempty" protobuf:"bytes,1,opt,name=defaultBackend"` - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the Ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +listType=atomic // +optional TLS []IngressTLS `json:"tls,omitempty" protobuf:"bytes,2,rep,name=tls"` - // A list of host rules used to configure the Ingress. If unspecified, or - // no rule matches, all traffic is sent to the default backend. + // rules is a list of host rules used to configure the Ingress. If unspecified, + // or no rule matches, all traffic is sent to the default backend. // +listType=atomic // +optional Rules []IngressRule `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"` } -// IngressTLS describes the transport layer security associated with an Ingress. +// IngressTLS describes the transport layer security associated with an ingress. type IngressTLS struct { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. // +listType=atomic // +optional Hosts []string `json:"hosts,omitempty" protobuf:"bytes,1,rep,name=hosts"` - // SecretName is the name of the secret used to terminate TLS traffic on + + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination - // and value of the Host header is used for routing. + // and value of the "Host" header is used for routing. // +optional SecretName string `json:"secretName,omitempty" protobuf:"bytes,2,opt,name=secretName"` } // IngressStatus describe the current state of the Ingress. type IngressStatus struct { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. // +optional LoadBalancer IngressLoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"` } // IngressLoadBalancerStatus represents the status of a load-balancer. type IngressLoadBalancerStatus struct { - // Ingress is a list containing ingress points for the load-balancer. + // ingress is a list containing ingress points for the load-balancer. // +optional Ingress []IngressLoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,1,rep,name=ingress"` } // IngressLoadBalancerIngress represents the status of a load-balancer ingress point. type IngressLoadBalancerIngress struct { - // IP is set for load-balancer ingress points that are IP based. + // ip is set for load-balancer ingress points that are IP based. // +optional IP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"` - // Hostname is set for load-balancer ingress points that are DNS based. + // hostname is set for load-balancer ingress points that are DNS based. // +optional Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"` - // Ports provides information about the ports exposed by this LoadBalancer. + // ports provides information about the ports exposed by this LoadBalancer. // +listType=atomic // +optional Ports []IngressPortStatus `json:"ports,omitempty" protobuf:"bytes,4,rep,name=ports"` @@ -386,14 +392,14 @@ type IngressLoadBalancerIngress struct { // IngressPortStatus represents the error condition of a service port type IngressPortStatus struct { - // Port is the port number of the ingress port. + // port is the port number of the ingress port. Port int32 `json:"port" protobuf:"varint,1,opt,name=port"` - // Protocol is the protocol of the ingress port. + // protocol is the protocol of the ingress port. // The supported values are: "TCP", "UDP", "SCTP" Protocol v1.Protocol `json:"protocol" protobuf:"bytes,2,opt,name=protocol,casttype=Protocol"` - // Error is to record the problem with the service port + // error is to record the problem with the service port // The format of the error shall comply with the following rules: // - built-in error values shall be specified in this file and those shall use // CamelCase names @@ -412,7 +418,7 @@ type IngressPortStatus struct { // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. type IngressRule struct { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -425,14 +431,14 @@ type IngressRule struct { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and // matches only a single label. You cannot have a wildcard label by itself (e.g. Host == "*"). // Requests will be matched against the Host field in the following way: - // 1. If Host is precise, the request matches this rule if the http host header is equal to Host. - // 2. If Host is a wildcard, then the request matches this rule if the http host header + // 1. If host is precise, the request matches this rule if the http host header is equal to Host. + // 2. If host is a wildcard, then the request matches this rule if the http host header // is to equal to the suffix (removing the first label) of the wildcard rule. // +optional Host string `json:"host,omitempty" protobuf:"bytes,1,opt,name=host"` @@ -460,7 +466,7 @@ type IngressRuleValue struct { // to match against everything after the last '/' and before the first '?' // or '#'. type HTTPIngressRuleValue struct { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. // +listType=atomic Paths []HTTPIngressPath `json:"paths" protobuf:"bytes,1,rep,name=paths"` } @@ -499,14 +505,14 @@ const ( // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. type HTTPIngressPath struct { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"` - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of the following values: // * Exact: Matches the URL path exactly. // * Prefix: Matches based on a URL path prefix split by '/'. Matching is @@ -522,19 +528,19 @@ type HTTPIngressPath struct { // Implementations are required to support all path types. PathType *PathType `json:"pathType" protobuf:"bytes,3,opt,name=pathType"` - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. Backend IngressBackend `json:"backend" protobuf:"bytes,2,opt,name=backend"` } // IngressBackend describes all endpoints for a given service and port. type IngressBackend struct { - // Service references a Service as a Backend. + // service references a service as a backend. // This is a mutually exclusive setting with "Resource". // +optional Service *IngressServiceBackend `json:"service,omitempty" protobuf:"bytes,4,opt,name=service"` - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, a service.Name and // service.Port must not be specified. // This is a mutually exclusive setting with "Service". @@ -544,23 +550,23 @@ type IngressBackend struct { // IngressServiceBackend references a Kubernetes Service as a Backend. type IngressServiceBackend struct { - // Name is the referenced service. The service must exist in + // name is the referenced service. The service must exist in // the same namespace as the Ingress object. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Port of the referenced service. A port name or port number + // port of the referenced service. A port name or port number // is required for a IngressServiceBackend. Port ServiceBackendPort `json:"port,omitempty" protobuf:"bytes,2,opt,name=port"` } // ServiceBackendPort is the service port being referenced. type ServiceBackendPort struct { - // Name is the name of the port on the Service. + // name is the name of the port on the Service. // This is a mutually exclusive setting with "Number". // +optional Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` - // Number is the numerical port number (e.g. 80) on the Service. + // number is the numerical port number (e.g. 80) on the Service. // This is a mutually exclusive setting with "Name". // +optional Number int32 `json:"number,omitempty" protobuf:"bytes,2,opt,name=number"` @@ -577,12 +583,13 @@ type ServiceBackendPort struct { // resources without a class specified will be assigned this default class. type IngressClass 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 IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressClassSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -590,15 +597,15 @@ type IngressClass struct { // IngressClassSpec provides information about the class of an Ingress. type IngressClassSpec struct { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. Controller string `json:"controller,omitempty" protobuf:"bytes,1,opt,name=controller"` - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -617,20 +624,24 @@ const ( // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. type IngressClassParametersReference struct { - // APIGroup is the group for the resource being referenced. If APIGroup is + // apiGroup is the group for the resource being referenced. If APIGroup is // not specified, the specified Kind must be in the core API group. For any // other third-party types, APIGroup is required. // +optional APIGroup *string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=aPIGroup"` - // Kind is the type of resource being referenced. + + // kind is the type of resource being referenced. Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` - // Name is the name of resource being referenced. + + // name is the name of resource being referenced. Name string `json:"name" protobuf:"bytes,3,opt,name=name"` - // Scope represents if this refers to a cluster or namespace scoped resource. + + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". // +optional Scope *string `json:"scope" protobuf:"bytes,4,opt,name=scope"` - // Namespace is the namespace of the resource being referenced. This field is + + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -642,10 +653,11 @@ type IngressClassParametersReference struct { // IngressClassList is a collection of IngressClasses. type IngressClassList 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 IngressClasses. + // items is the list of IngressClasses. Items []IngressClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go index 94ccf964b..91161d5ca 100644 --- a/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go @@ -24,14 +24,14 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_HTTPIngressPath = map[string]string{ "": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", - "path": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value \"Exact\" or \"Prefix\".", - "pathType": "PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types.", - "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", + "path": "path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value \"Exact\" or \"Prefix\".", + "pathType": "pathType determines the interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types.", + "backend": "backend defines the referenced service endpoint to which the traffic will be forwarded to.", } func (HTTPIngressPath) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (HTTPIngressPath) SwaggerDoc() map[string]string { var map_HTTPIngressRuleValue = map[string]string{ "": "HTTPIngressRuleValue is a list of http selectors pointing to backends. In the example: http:///? -> backend where where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last '/' and before the first '?' or '#'.", - "paths": "A collection of paths that map requests to backends.", + "paths": "paths is a collection of paths that map requests to backends.", } func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { @@ -49,8 +49,8 @@ func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { 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 IP Block Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"", - "except": "Except is a slice of CIDRs that should not be included within an IP Block Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\" Except values will be rejected if they are outside the CIDR range", + "cidr": "cidr is a string representing the IPBlock Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"", + "except": "except is a slice of CIDRs that should not be included within an IPBlock Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\" Except values will be rejected if they are outside the cidr range", } func (IPBlock) SwaggerDoc() map[string]string { @@ -60,8 +60,8 @@ func (IPBlock) SwaggerDoc() map[string]string { var map_Ingress = map[string]string{ "": "Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.", "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 Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", - "status": "Status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "status": "status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (Ingress) SwaggerDoc() map[string]string { @@ -70,8 +70,8 @@ func (Ingress) SwaggerDoc() map[string]string { var map_IngressBackend = map[string]string{ "": "IngressBackend describes all endpoints for a given service and port.", - "service": "Service references a Service as a Backend. This is a mutually exclusive setting with \"Resource\".", - "resource": "Resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive setting with \"Service\".", + "service": "service references a service as a backend. This is a mutually exclusive setting with \"Resource\".", + "resource": "resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, a service.Name and service.Port must not be specified. This is a mutually exclusive setting with \"Service\".", } func (IngressBackend) SwaggerDoc() map[string]string { @@ -81,7 +81,7 @@ func (IngressBackend) SwaggerDoc() map[string]string { var map_IngressClass = map[string]string{ "": "IngressClass represents the class of the Ingress, referenced by the Ingress Spec. The `ingressclass.kubernetes.io/is-default-class` annotation can be used to indicate that an IngressClass should be considered default. When a single IngressClass resource has this annotation set to true, new Ingress resources without a class specified will be assigned this default class.", "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 IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (IngressClass) SwaggerDoc() map[string]string { @@ -91,7 +91,7 @@ func (IngressClass) SwaggerDoc() map[string]string { var map_IngressClassList = map[string]string{ "": "IngressClassList is a collection of IngressClasses.", "metadata": "Standard list metadata.", - "items": "Items is the list of IngressClasses.", + "items": "items is the list of IngressClasses.", } func (IngressClassList) SwaggerDoc() map[string]string { @@ -100,11 +100,11 @@ func (IngressClassList) SwaggerDoc() map[string]string { var map_IngressClassParametersReference = map[string]string{ "": "IngressClassParametersReference identifies an API object. This can be used to specify a cluster or namespace-scoped resource.", - "apiGroup": "APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", - "kind": "Kind is the type of resource being referenced.", - "name": "Name is the name of resource being referenced.", - "scope": "Scope represents if this refers to a cluster or namespace scoped resource. This may be set to \"Cluster\" (default) or \"Namespace\".", - "namespace": "Namespace is the namespace of the resource being referenced. This field is required when scope is set to \"Namespace\" and must be unset when scope is set to \"Cluster\".", + "apiGroup": "apiGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", + "kind": "kind is the type of resource being referenced.", + "name": "name is the name of resource being referenced.", + "scope": "scope represents if this refers to a cluster or namespace scoped resource. This may be set to \"Cluster\" (default) or \"Namespace\".", + "namespace": "namespace is the namespace of the resource being referenced. This field is required when scope is set to \"Namespace\" and must be unset when scope is set to \"Cluster\".", } func (IngressClassParametersReference) SwaggerDoc() map[string]string { @@ -113,8 +113,8 @@ func (IngressClassParametersReference) SwaggerDoc() map[string]string { var map_IngressClassSpec = map[string]string{ "": "IngressClassSpec provides information about the class of an Ingress.", - "controller": "Controller refers to the name of the controller that should handle this class. This allows for different \"flavors\" that are controlled by the same controller. For example, you may have different Parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. \"acme.io/ingress-controller\". This field is immutable.", - "parameters": "Parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.", + "controller": "controller refers to the name of the controller that should handle this class. This allows for different \"flavors\" that are controlled by the same controller. For example, you may have different parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. \"acme.io/ingress-controller\". This field is immutable.", + "parameters": "parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.", } func (IngressClassSpec) SwaggerDoc() map[string]string { @@ -124,7 +124,7 @@ func (IngressClassSpec) SwaggerDoc() map[string]string { var map_IngressList = map[string]string{ "": "IngressList is a collection of Ingress.", "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 Ingress.", + "items": "items is the list of Ingress.", } func (IngressList) SwaggerDoc() map[string]string { @@ -133,9 +133,9 @@ func (IngressList) SwaggerDoc() map[string]string { var map_IngressLoadBalancerIngress = map[string]string{ "": "IngressLoadBalancerIngress represents the status of a load-balancer ingress point.", - "ip": "IP is set for load-balancer ingress points that are IP based.", - "hostname": "Hostname is set for load-balancer ingress points that are DNS based.", - "ports": "Ports provides information about the ports exposed by this LoadBalancer.", + "ip": "ip is set for load-balancer ingress points that are IP based.", + "hostname": "hostname is set for load-balancer ingress points that are DNS based.", + "ports": "ports provides information about the ports exposed by this LoadBalancer.", } func (IngressLoadBalancerIngress) SwaggerDoc() map[string]string { @@ -144,7 +144,7 @@ func (IngressLoadBalancerIngress) SwaggerDoc() map[string]string { var map_IngressLoadBalancerStatus = map[string]string{ "": "IngressLoadBalancerStatus represents the status of a load-balancer.", - "ingress": "Ingress is a list containing ingress points for the load-balancer.", + "ingress": "ingress is a list containing ingress points for the load-balancer.", } func (IngressLoadBalancerStatus) SwaggerDoc() map[string]string { @@ -153,9 +153,9 @@ func (IngressLoadBalancerStatus) SwaggerDoc() map[string]string { var map_IngressPortStatus = map[string]string{ "": "IngressPortStatus represents the error condition of a service port", - "port": "Port is the port number of the ingress port.", - "protocol": "Protocol is the protocol of the ingress port. The supported values are: \"TCP\", \"UDP\", \"SCTP\"", - "error": "Error is to record the problem with the service port The format of the error shall comply with the following rules: - built-in error values shall be specified in this file and those shall use\n CamelCase names\n- cloud provider specific error values must have names that comply with the\n format foo.example.com/CamelCase.", + "port": "port is the port number of the ingress port.", + "protocol": "protocol is the protocol of the ingress port. The supported values are: \"TCP\", \"UDP\", \"SCTP\"", + "error": "error is to record the problem with the service port The format of the error shall comply with the following rules: - built-in error values shall be specified in this file and those shall use\n CamelCase names\n- cloud provider specific error values must have names that comply with the\n format foo.example.com/CamelCase.", } func (IngressPortStatus) SwaggerDoc() map[string]string { @@ -164,7 +164,7 @@ func (IngressPortStatus) SwaggerDoc() map[string]string { var map_IngressRule = map[string]string{ "": "IngressRule represents the rules mapping the paths under a specified host to the related backend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.", - "host": "Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nHost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", + "host": "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nhost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If host is precise, the request matches this rule if the http host header is equal to Host. 2. If host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", } func (IngressRule) SwaggerDoc() map[string]string { @@ -181,8 +181,8 @@ func (IngressRuleValue) SwaggerDoc() map[string]string { var map_IngressServiceBackend = map[string]string{ "": "IngressServiceBackend references a Kubernetes Service as a Backend.", - "name": "Name is the referenced service. The service must exist in the same namespace as the Ingress object.", - "port": "Port of the referenced service. A port name or port number is required for a IngressServiceBackend.", + "name": "name is the referenced service. The service must exist in the same namespace as the Ingress object.", + "port": "port of the referenced service. A port name or port number is required for a IngressServiceBackend.", } func (IngressServiceBackend) SwaggerDoc() map[string]string { @@ -191,10 +191,10 @@ func (IngressServiceBackend) SwaggerDoc() map[string]string { var map_IngressSpec = map[string]string{ "": "IngressSpec describes the Ingress the user wishes to exist.", - "ingressClassName": "IngressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` annotation (simple constant name) was never formally defined, it was widely supported by Ingress controllers to create a direct binding between Ingress controller and Ingress resources. Newly created Ingress resources should prefer using the field. However, even though the annotation is officially deprecated, for backwards compatibility reasons, ingress controllers should still honor that annotation if present.", - "defaultBackend": "DefaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests that do not match any of the rules will be up to the Ingress controller.", - "tls": "TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", - "rules": "A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", + "ingressClassName": "ingressClassName is the name of an IngressClass cluster resource. Ingress controller implementations use this field to know whether they should be serving this Ingress resource, by a transitive connection (controller -> IngressClass -> Ingress resource). Although the `kubernetes.io/ingress.class` annotation (simple constant name) was never formally defined, it was widely supported by Ingress controllers to create a direct binding between Ingress controller and Ingress resources. Newly created Ingress resources should prefer using the field. However, even though the annotation is officially deprecated, for backwards compatibility reasons, ingress controllers should still honor that annotation if present.", + "defaultBackend": "defaultBackend is the backend that should handle requests that don't match any rule. If Rules are not specified, DefaultBackend must be specified. If DefaultBackend is not set, the handling of requests that do not match any of the rules will be up to the Ingress controller.", + "tls": "tls represents the TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", + "rules": "rules is a list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", } func (IngressSpec) SwaggerDoc() map[string]string { @@ -203,7 +203,7 @@ func (IngressSpec) SwaggerDoc() map[string]string { var map_IngressStatus = map[string]string{ "": "IngressStatus describe the current state of the Ingress.", - "loadBalancer": "LoadBalancer contains the current status of the load-balancer.", + "loadBalancer": "loadBalancer contains the current status of the load-balancer.", } func (IngressStatus) SwaggerDoc() map[string]string { @@ -211,9 +211,9 @@ func (IngressStatus) SwaggerDoc() map[string]string { } var map_IngressTLS = map[string]string{ - "": "IngressTLS describes the transport layer security associated with an Ingress.", - "hosts": "Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", - "secretName": "SecretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.", + "": "IngressTLS describes the transport layer security associated with an ingress.", + "hosts": "hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", + "secretName": "secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the \"Host\" header is used for routing.", } func (IngressTLS) SwaggerDoc() map[string]string { @@ -223,8 +223,8 @@ func (IngressTLS) SwaggerDoc() map[string]string { var map_NetworkPolicy = map[string]string{ "": "NetworkPolicy describes what network traffic is allowed for a set of Pods", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the desired behavior for this NetworkPolicy.", - "status": "Status is the current state of the NetworkPolicy. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec represents the specification of the desired behavior for this NetworkPolicy.", + "status": "status represents the current state of the NetworkPolicy. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (NetworkPolicy) SwaggerDoc() map[string]string { @@ -233,8 +233,8 @@ func (NetworkPolicy) SwaggerDoc() map[string]string { var map_NetworkPolicyEgressRule = map[string]string{ "": "NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. This type is beta-level in 1.8", - "ports": "List of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", - "to": "List of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list.", + "ports": "ports is a list of destination ports for outgoing traffic. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", + "to": "to is a list of destinations for outgoing traffic of pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all destinations (traffic not restricted by destination). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the to list.", } func (NetworkPolicyEgressRule) SwaggerDoc() map[string]string { @@ -243,8 +243,8 @@ func (NetworkPolicyEgressRule) SwaggerDoc() map[string]string { var map_NetworkPolicyIngressRule = map[string]string{ "": "NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from.", - "ports": "List of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", - "from": "List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list.", + "ports": "ports is a list of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.", + "from": "from is a list of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list.", } func (NetworkPolicyIngressRule) SwaggerDoc() map[string]string { @@ -254,7 +254,7 @@ func (NetworkPolicyIngressRule) SwaggerDoc() map[string]string { var map_NetworkPolicyList = map[string]string{ "": "NetworkPolicyList is a list of NetworkPolicy 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.", + "items": "items is a list of schema objects.", } func (NetworkPolicyList) SwaggerDoc() map[string]string { @@ -263,9 +263,9 @@ func (NetworkPolicyList) SwaggerDoc() map[string]string { var map_NetworkPolicyPeer = map[string]string{ "": "NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of fields are allowed", - "podSelector": "This is a label selector which selects Pods. This field follows standard label selector semantics; if present but empty, it selects all pods.\n\nIf NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the Pods matching PodSelector in the policy's own Namespace.", - "namespaceSelector": "Selects Namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces.\n\nIf PodSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector.", - "ipBlock": "IPBlock defines policy on a particular IPBlock. If this field is set then neither of the other fields can be.", + "podSelector": "podSelector is a label selector which selects pods. This field follows standard label selector semantics; if present but empty, it selects all pods.\n\nIf namespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the pods matching podSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the pods matching podSelector in the policy's own namespace.", + "namespaceSelector": "namespaceSelector selects namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces.\n\nIf podSelector is also set, then the NetworkPolicyPeer as a whole selects the pods matching podSelector in the namespaces selected by namespaceSelector. Otherwise it selects all pods in the namespaces selected by namespaceSelector.", + "ipBlock": "ipBlock defines policy on a particular IPBlock. If this field is set then neither of the other fields can be.", } func (NetworkPolicyPeer) SwaggerDoc() map[string]string { @@ -274,9 +274,9 @@ func (NetworkPolicyPeer) SwaggerDoc() map[string]string { var map_NetworkPolicyPort = map[string]string{ "": "NetworkPolicyPort describes a port to allow traffic on", - "protocol": "The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP.", - "port": "The port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched.", - "endPort": "If set, indicates that the range of ports from port to endPort, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port.", + "protocol": "protocol represents the protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP.", + "port": "port represents the port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched.", + "endPort": "endPort indicates that the range of ports from port to endPort if set, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port.", } func (NetworkPolicyPort) SwaggerDoc() map[string]string { @@ -285,10 +285,10 @@ func (NetworkPolicyPort) SwaggerDoc() map[string]string { var map_NetworkPolicySpec = map[string]string{ "": "NetworkPolicySpec provides the specification of a NetworkPolicy", - "podSelector": "Selects the pods to which this NetworkPolicy object applies. The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace.", - "ingress": "List of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default)", - "egress": "List of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8", - "policyTypes": "List of rule types that the NetworkPolicy relates to. Valid options are [\"Ingress\"], [\"Egress\"], or [\"Ingress\", \"Egress\"]. If this field is not specified, it will default based on the existence of Ingress or Egress rules; policies that contain an Egress section are assumed to affect Egress, and all policies (whether or not they contain an Ingress section) are assumed to affect Ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ \"Egress\" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include \"Egress\" (since such a policy would not include an Egress section and would otherwise default to just [ \"Ingress\" ]). This field is beta-level in 1.8", + "podSelector": "podSelector selects the pods to which this NetworkPolicy object applies. The array of ingress rules is applied to any pods selected by this field. Multiple network policies can select the same set of pods. In this case, the ingress rules for each are combined additively. This field is NOT optional and follows standard label selector semantics. An empty podSelector matches all pods in this namespace.", + "ingress": "ingress is a list of ingress rules to be applied to the selected pods. Traffic is allowed to a pod if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic source is the pod's local node, OR if the traffic matches at least one ingress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy does not allow any traffic (and serves solely to ensure that the pods it selects are isolated by default)", + "egress": "egress is a list of egress rules to be applied to the selected pods. Outgoing traffic is allowed if there are no NetworkPolicies selecting the pod (and cluster policy otherwise allows the traffic), OR if the traffic matches at least one egress rule across all of the NetworkPolicy objects whose podSelector matches the pod. If this field is empty then this NetworkPolicy limits all outgoing traffic (and serves solely to ensure that the pods it selects are isolated by default). This field is beta-level in 1.8", + "policyTypes": "policyTypes is a list of rule types that the NetworkPolicy relates to. Valid options are [\"Ingress\"], [\"Egress\"], or [\"Ingress\", \"Egress\"]. If this field is not specified, it will default based on the existence of ingress or egress rules; policies that contain an egress section are assumed to affect egress, and all policies (whether or not they contain an ingress section) are assumed to affect ingress. If you want to write an egress-only policy, you must explicitly specify policyTypes [ \"Egress\" ]. Likewise, if you want to write a policy that specifies that no egress is allowed, you must specify a policyTypes value that include \"Egress\" (since such a policy would not include an egress section and would otherwise default to just [ \"Ingress\" ]). This field is beta-level in 1.8", } func (NetworkPolicySpec) SwaggerDoc() map[string]string { @@ -296,8 +296,8 @@ func (NetworkPolicySpec) SwaggerDoc() map[string]string { } var map_NetworkPolicyStatus = map[string]string{ - "": "NetworkPolicyStatus describe the current state of the NetworkPolicy.", - "conditions": "Conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. Current service state", + "": "NetworkPolicyStatus describes the current state of the NetworkPolicy.", + "conditions": "conditions holds an array of metav1.Condition that describe the state of the NetworkPolicy. Current service state", } func (NetworkPolicyStatus) SwaggerDoc() map[string]string { @@ -306,8 +306,8 @@ func (NetworkPolicyStatus) SwaggerDoc() map[string]string { 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\".", - "number": "Number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with \"Name\".", + "name": "name is the name of the port on the Service. This is a mutually exclusive setting with \"Number\".", + "number": "number is the numerical port number (e.g. 80) on the Service. This is a mutually exclusive setting with \"Name\".", } func (ServiceBackendPort) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/networking/v1alpha1/generated.pb.go b/vendor/k8s.io/api/networking/v1alpha1/generated.pb.go index 48d401db8..f54d1f824 100644 --- a/vendor/k8s.io/api/networking/v1alpha1/generated.pb.go +++ b/vendor/k8s.io/api/networking/v1alpha1/generated.pb.go @@ -31,6 +31,8 @@ import ( math_bits "math/bits" reflect "reflect" strings "strings" + + k8s_io_apimachinery_pkg_types "k8s.io/apimachinery/pkg/types" ) // Reference imports to suppress errors if they are not otherwise used. @@ -128,10 +130,126 @@ func (m *ClusterCIDRSpec) XXX_DiscardUnknown() { var xxx_messageInfo_ClusterCIDRSpec proto.InternalMessageInfo +func (m *IPAddress) Reset() { *m = IPAddress{} } +func (*IPAddress) ProtoMessage() {} +func (*IPAddress) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{3} +} +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_c1b7ac8d7d97acec, []int{4} +} +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_c1b7ac8d7d97acec, []int{5} +} +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 *ParentReference) Reset() { *m = ParentReference{} } +func (*ParentReference) ProtoMessage() {} +func (*ParentReference) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b7ac8d7d97acec, []int{6} +} +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 init() { proto.RegisterType((*ClusterCIDR)(nil), "k8s.io.api.networking.v1alpha1.ClusterCIDR") proto.RegisterType((*ClusterCIDRList)(nil), "k8s.io.api.networking.v1alpha1.ClusterCIDRList") proto.RegisterType((*ClusterCIDRSpec)(nil), "k8s.io.api.networking.v1alpha1.ClusterCIDRSpec") + proto.RegisterType((*IPAddress)(nil), "k8s.io.api.networking.v1alpha1.IPAddress") + proto.RegisterType((*IPAddressList)(nil), "k8s.io.api.networking.v1alpha1.IPAddressList") + proto.RegisterType((*IPAddressSpec)(nil), "k8s.io.api.networking.v1alpha1.IPAddressSpec") + proto.RegisterType((*ParentReference)(nil), "k8s.io.api.networking.v1alpha1.ParentReference") } func init() { @@ -139,39 +257,51 @@ func init() { } var fileDescriptor_c1b7ac8d7d97acec = []byte{ - // 506 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x4f, 0x8f, 0xd2, 0x40, - 0x18, 0xc6, 0xe9, 0x2e, 0x24, 0x6b, 0xc1, 0xb0, 0xe9, 0x45, 0xc2, 0x61, 0x20, 0x9c, 0x48, 0x8c, - 0x33, 0xb2, 0x21, 0xc4, 0xab, 0xdd, 0x4d, 0x94, 0xc4, 0x3f, 0xd8, 0x4d, 0x3c, 0x18, 0x0f, 0x0e, - 0xe5, 0xb5, 0x8c, 0xd0, 0xce, 0x64, 0x66, 0xa8, 0xf1, 0xe6, 0x47, 0xf0, 0x2b, 0xe9, 0x89, 0xe3, - 0x1e, 0xf7, 0x44, 0xa4, 0x7e, 0x01, 0x3f, 0x82, 0x99, 0xa1, 0xbb, 0x94, 0x45, 0x57, 0xbd, 0x75, - 0xde, 0xf9, 0x3d, 0xcf, 0xfb, 0x3e, 0x7d, 0x5b, 0xf7, 0xc9, 0xec, 0x91, 0xc2, 0x8c, 0x93, 0xd9, - 0x62, 0x0c, 0x32, 0x01, 0x0d, 0x8a, 0xa4, 0x90, 0x4c, 0xb8, 0x24, 0xf9, 0x05, 0x15, 0x8c, 0x24, - 0xa0, 0x3f, 0x72, 0x39, 0x63, 0x49, 0x44, 0xd2, 0x1e, 0x9d, 0x8b, 0x29, 0xed, 0x91, 0x08, 0x12, - 0x90, 0x54, 0xc3, 0x04, 0x0b, 0xc9, 0x35, 0xf7, 0xd0, 0x86, 0xc7, 0x54, 0x30, 0xbc, 0xe5, 0xf1, - 0x15, 0xdf, 0x7c, 0x10, 0x31, 0x3d, 0x5d, 0x8c, 0x71, 0xc8, 0x63, 0x12, 0xf1, 0x88, 0x13, 0x2b, - 0x1b, 0x2f, 0xde, 0xdb, 0x93, 0x3d, 0xd8, 0xa7, 0x8d, 0x5d, 0xb3, 0x53, 0x68, 0x1f, 0x72, 0x09, - 0x24, 0xdd, 0x6b, 0xd9, 0xec, 0x6f, 0x99, 0x98, 0x86, 0x53, 0x96, 0x80, 0xfc, 0x44, 0xc4, 0x2c, - 0x32, 0x05, 0x45, 0x62, 0xd0, 0xf4, 0x77, 0x2a, 0xf2, 0x27, 0x95, 0x5c, 0x24, 0x9a, 0xc5, 0xb0, - 0x27, 0x18, 0xfc, 0x4d, 0xa0, 0xc2, 0x29, 0xc4, 0xf4, 0xa6, 0xae, 0xf3, 0xcd, 0x71, 0xab, 0xa7, - 0xf3, 0x85, 0xd2, 0x20, 0x4f, 0x87, 0x67, 0x81, 0xf7, 0xce, 0x3d, 0x32, 0x33, 0x4d, 0xa8, 0xa6, - 0x0d, 0xa7, 0xed, 0x74, 0xab, 0x27, 0x0f, 0xf1, 0xf6, 0xa5, 0x5d, 0x5b, 0x63, 0x31, 0x8b, 0x4c, - 0x41, 0x61, 0x43, 0xe3, 0xb4, 0x87, 0x5f, 0x8e, 0x3f, 0x40, 0xa8, 0x9f, 0x83, 0xa6, 0xbe, 0xb7, - 0x5c, 0xb5, 0x4a, 0xd9, 0xaa, 0xe5, 0x6e, 0x6b, 0xc1, 0xb5, 0xab, 0xf7, 0xca, 0x2d, 0x2b, 0x01, - 0x61, 0xe3, 0xc0, 0xba, 0x13, 0x7c, 0xfb, 0x4a, 0x70, 0x61, 0xb8, 0x73, 0x01, 0xa1, 0x5f, 0xcb, - 0xcd, 0xcb, 0xe6, 0x14, 0x58, 0xab, 0xce, 0x57, 0xc7, 0xad, 0x17, 0xb8, 0x67, 0x4c, 0x69, 0xef, - 0xed, 0x5e, 0x10, 0xfc, 0x6f, 0x41, 0x8c, 0xda, 0xc6, 0x38, 0xce, 0x3b, 0x1d, 0x5d, 0x55, 0x0a, - 0x21, 0x46, 0x6e, 0x85, 0x69, 0x88, 0x55, 0xe3, 0xa0, 0x7d, 0xd8, 0xad, 0x9e, 0xdc, 0xff, 0x8f, - 0x14, 0xfe, 0xdd, 0xdc, 0xb7, 0x32, 0x34, 0x0e, 0xc1, 0xc6, 0xa8, 0xf3, 0x73, 0x37, 0x83, 0x49, - 0xe7, 0xbd, 0x76, 0x6b, 0x09, 0x9f, 0xc0, 0x39, 0xcc, 0x21, 0xd4, 0x5c, 0xe6, 0x39, 0xda, 0xc5, - 0x66, 0xe6, 0xb3, 0x33, 0x53, 0xbf, 0x28, 0x70, 0xfe, 0x71, 0xb6, 0x6a, 0xd5, 0x8a, 0x95, 0x60, - 0xc7, 0xc7, 0x7b, 0xec, 0xd6, 0x05, 0x48, 0x03, 0x3c, 0xe5, 0x4a, 0xfb, 0x4c, 0x2b, 0xbb, 0x8d, - 0x8a, 0x7f, 0x2f, 0x1f, 0xad, 0x3e, 0xda, 0xbd, 0x0e, 0x6e, 0xf2, 0x5e, 0xdb, 0x2d, 0x33, 0x91, - 0xf6, 0x1b, 0x87, 0x6d, 0xa7, 0x7b, 0x67, 0xbb, 0x94, 0xe1, 0x28, 0xed, 0x07, 0xf6, 0x26, 0x27, - 0x06, 0x8d, 0xf2, 0x1e, 0x31, 0xb0, 0xc4, 0xc0, 0x3f, 0x5b, 0xae, 0x51, 0xe9, 0x62, 0x8d, 0x4a, - 0x97, 0x6b, 0x54, 0xfa, 0x9c, 0x21, 0x67, 0x99, 0x21, 0xe7, 0x22, 0x43, 0xce, 0x65, 0x86, 0x9c, - 0xef, 0x19, 0x72, 0xbe, 0xfc, 0x40, 0xa5, 0x37, 0xe8, 0xf6, 0x7f, 0xfc, 0x57, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xdf, 0x1d, 0xe9, 0x86, 0x1d, 0x04, 0x00, 0x00, + // 698 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x95, 0xcf, 0x4e, 0xdb, 0x4a, + 0x14, 0xc6, 0x63, 0x92, 0x48, 0x78, 0x00, 0x85, 0xeb, 0xcd, 0x8d, 0x58, 0x38, 0xb9, 0xb9, 0x1b, + 0xae, 0x6e, 0x19, 0x03, 0x42, 0x51, 0xb7, 0x98, 0x48, 0x34, 0x52, 0x0b, 0xe9, 0x20, 0xba, 0xa8, + 0x58, 0xd4, 0xb1, 0x0f, 0x8e, 0x1b, 0xfc, 0x47, 0x33, 0xe3, 0x54, 0xec, 0xfa, 0x08, 0x7d, 0xa1, + 0x56, 0x6a, 0x57, 0x2c, 0x59, 0xb2, 0x8a, 0x8a, 0xfb, 0x02, 0x5d, 0xb7, 0x9b, 0x6a, 0x26, 0x4e, + 0xec, 0x24, 0x0d, 0xd0, 0x0d, 0xbb, 0xcc, 0x39, 0xbf, 0xf3, 0xcd, 0x39, 0x73, 0xbe, 0x24, 0xe8, + 0xb0, 0xff, 0x94, 0x61, 0x2f, 0x34, 0xfa, 0x71, 0x17, 0x68, 0x00, 0x1c, 0x98, 0x31, 0x80, 0xc0, + 0x09, 0xa9, 0x91, 0x26, 0xac, 0xc8, 0x33, 0x02, 0xe0, 0xef, 0x42, 0xda, 0xf7, 0x02, 0xd7, 0x18, + 0xec, 0x58, 0x17, 0x51, 0xcf, 0xda, 0x31, 0x5c, 0x08, 0x80, 0x5a, 0x1c, 0x1c, 0x1c, 0xd1, 0x90, + 0x87, 0x9a, 0x3e, 0xe2, 0xb1, 0x15, 0x79, 0x38, 0xe3, 0xf1, 0x98, 0xdf, 0xd8, 0x72, 0x3d, 0xde, + 0x8b, 0xbb, 0xd8, 0x0e, 0x7d, 0xc3, 0x0d, 0xdd, 0xd0, 0x90, 0x65, 0xdd, 0xf8, 0x5c, 0x9e, 0xe4, + 0x41, 0x7e, 0x1a, 0xc9, 0x6d, 0x34, 0x72, 0xd7, 0xdb, 0x21, 0x05, 0x63, 0x30, 0x77, 0xe5, 0xc6, + 0x5e, 0xc6, 0xf8, 0x96, 0xdd, 0xf3, 0x02, 0xa0, 0x97, 0x46, 0xd4, 0x77, 0x45, 0x80, 0x19, 0x3e, + 0x70, 0xeb, 0x77, 0x55, 0xc6, 0xa2, 0x2a, 0x1a, 0x07, 0xdc, 0xf3, 0x61, 0xae, 0xa0, 0x79, 0x5f, + 0x01, 0xb3, 0x7b, 0xe0, 0x5b, 0xb3, 0x75, 0x8d, 0x2f, 0x0a, 0x5a, 0x39, 0xb8, 0x88, 0x19, 0x07, + 0x7a, 0xd0, 0x6e, 0x11, 0xed, 0x0d, 0x5a, 0x16, 0x3d, 0x39, 0x16, 0xb7, 0xaa, 0x4a, 0x5d, 0xd9, + 0x5c, 0xd9, 0xdd, 0xc6, 0xd9, 0xa3, 0x4d, 0xa4, 0x71, 0xd4, 0x77, 0x45, 0x80, 0x61, 0x41, 0xe3, + 0xc1, 0x0e, 0x3e, 0xee, 0xbe, 0x05, 0x9b, 0xbf, 0x00, 0x6e, 0x99, 0xda, 0xd5, 0xb0, 0x56, 0x48, + 0x86, 0x35, 0x94, 0xc5, 0xc8, 0x44, 0x55, 0x7b, 0x89, 0x4a, 0x2c, 0x02, 0xbb, 0xba, 0x24, 0xd5, + 0x0d, 0x7c, 0xf7, 0x4a, 0x70, 0xae, 0xb9, 0x93, 0x08, 0x6c, 0x73, 0x35, 0x15, 0x2f, 0x89, 0x13, + 0x91, 0x52, 0x8d, 0xcf, 0x0a, 0xaa, 0xe4, 0xb8, 0xe7, 0x1e, 0xe3, 0xda, 0xd9, 0xdc, 0x20, 0xf8, + 0x61, 0x83, 0x88, 0x6a, 0x39, 0xc6, 0x7a, 0x7a, 0xd3, 0xf2, 0x38, 0x92, 0x1b, 0xa2, 0x83, 0xca, + 0x1e, 0x07, 0x9f, 0x55, 0x97, 0xea, 0xc5, 0xcd, 0x95, 0xdd, 0xff, 0xff, 0x60, 0x0a, 0x73, 0x2d, + 0xd5, 0x2d, 0xb7, 0x85, 0x02, 0x19, 0x09, 0x35, 0xbe, 0x4f, 0xcf, 0x20, 0xa6, 0xd3, 0x5e, 0xa1, + 0xd5, 0x20, 0x74, 0xe0, 0x04, 0x2e, 0xc0, 0xe6, 0x21, 0x4d, 0xe7, 0xa8, 0xe7, 0x2f, 0x13, 0xb6, + 0x13, 0x5d, 0x1f, 0xe5, 0x38, 0x73, 0x3d, 0x19, 0xd6, 0x56, 0xf3, 0x11, 0x32, 0xa5, 0xa3, 0xed, + 0xa3, 0x4a, 0x04, 0x54, 0x00, 0xcf, 0x42, 0xc6, 0x4d, 0x8f, 0x33, 0xb9, 0x8d, 0xb2, 0xf9, 0x77, + 0xda, 0x5a, 0xa5, 0x33, 0x9d, 0x26, 0xb3, 0xbc, 0x56, 0x47, 0x25, 0x2f, 0x1a, 0xec, 0x55, 0x8b, + 0x75, 0x65, 0x53, 0xcd, 0x96, 0xd2, 0xee, 0x0c, 0xf6, 0x88, 0xcc, 0xa4, 0x44, 0xb3, 0x5a, 0x9a, + 0x23, 0x9a, 0x92, 0x68, 0x36, 0x3e, 0x29, 0x48, 0x6d, 0x77, 0xf6, 0x1d, 0x87, 0x02, 0x63, 0x8f, + 0xe0, 0xbc, 0xe3, 0x29, 0xe7, 0x6d, 0xdd, 0xb7, 0xb3, 0x49, 0x6b, 0x0b, 0x7d, 0xf7, 0x51, 0x41, + 0x6b, 0x13, 0xea, 0x11, 0x5c, 0x77, 0x34, 0xed, 0xba, 0xff, 0x1e, 0x3c, 0xc1, 0x02, 0xcf, 0xf9, + 0xb9, 0xf6, 0xa5, 0xe1, 0xce, 0x90, 0x1a, 0x59, 0x14, 0x02, 0x4e, 0xe0, 0x3c, 0xed, 0xff, 0xde, + 0x2f, 0x68, 0x67, 0x5c, 0x00, 0x14, 0x02, 0x1b, 0xcc, 0xb5, 0x64, 0x58, 0x53, 0x27, 0x41, 0x92, + 0x09, 0x36, 0x7e, 0x2a, 0xa8, 0x32, 0x43, 0x6b, 0xff, 0xa2, 0xb2, 0x4b, 0xc3, 0x38, 0x92, 0xb7, + 0xa9, 0x59, 0x9f, 0x87, 0x22, 0x48, 0x46, 0x39, 0xed, 0x09, 0x5a, 0xa6, 0xc0, 0xc2, 0x98, 0xda, + 0x20, 0x97, 0xa7, 0x66, 0xaf, 0x44, 0xd2, 0x38, 0x99, 0x10, 0x9a, 0x81, 0xd4, 0xc0, 0xf2, 0x81, + 0x45, 0x96, 0x0d, 0xa9, 0x3f, 0xff, 0x4a, 0x71, 0xf5, 0x68, 0x9c, 0x20, 0x19, 0x23, 0x9c, 0x2a, + 0x0e, 0xb3, 0x4e, 0x15, 0x2c, 0x91, 0x19, 0xcd, 0x44, 0xc5, 0xd8, 0x73, 0xaa, 0x65, 0x09, 0x6c, + 0xa7, 0x40, 0xf1, 0xb4, 0xdd, 0xfa, 0x31, 0xac, 0xfd, 0xb3, 0xe8, 0x97, 0x97, 0x5f, 0x46, 0xc0, + 0xf0, 0x69, 0xbb, 0x45, 0x44, 0xb1, 0xd9, 0xba, 0xba, 0xd5, 0x0b, 0xd7, 0xb7, 0x7a, 0xe1, 0xe6, + 0x56, 0x2f, 0xbc, 0x4f, 0x74, 0xe5, 0x2a, 0xd1, 0x95, 0xeb, 0x44, 0x57, 0x6e, 0x12, 0x5d, 0xf9, + 0x9a, 0xe8, 0xca, 0x87, 0x6f, 0x7a, 0xe1, 0xb5, 0x7e, 0xf7, 0x3f, 0xda, 0xaf, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xf9, 0x9d, 0x9e, 0xc6, 0x0b, 0x07, 0x00, 0x00, } func (m *ClusterCIDR) Marshal() (dAtA []byte, err error) { @@ -312,6 +442,179 @@ func (m *ClusterCIDRSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *IPAddress) 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 *IPAddress) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IPAddress) 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 *IPAddressList) 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 *IPAddressList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IPAddressList) 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 *IPAddressSpec) 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 *IPAddressSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IPAddressSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ParentRef != nil { + { + size, err := m.ParentRef.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 *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.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.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 encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { offset -= sovGenerated(v) base := offset @@ -371,6 +674,68 @@ func (m *ClusterCIDRSpec) Size() (n int) { 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 *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)) + l = len(m.UID) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func sovGenerated(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -417,6 +782,57 @@ func (this *ClusterCIDRSpec) String() string { }, "") 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 *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) + `,`, + `UID:` + fmt.Sprintf("%v", this.UID) + `,`, + `}`, + }, "") + return s +} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -827,6 +1243,535 @@ func (m *ClusterCIDRSpec) Unmarshal(dAtA []byte) error { } return nil } +func (m *IPAddress) 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: IPAddress: wiretype end group for non-group") + } + if fieldNum <= 0 { + 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 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 *IPAddressList) 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: IPAddressList: wiretype end group for non-group") + } + if fieldNum <= 0 { + 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 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, IPAddress{}) + 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 *IPAddressSpec) 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: IPAddressSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IPAddressSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParentRef", 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.ParentRef == nil { + m.ParentRef = &ParentReference{} + } + if err := m.ParentRef.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 *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 + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UID", 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.UID = k8s_io_apimachinery_pkg_types.UID(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 skipGenerated(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/networking/v1alpha1/generated.proto b/vendor/k8s.io/api/networking/v1alpha1/generated.proto index bbda585b8..0f1f30d70 100644 --- a/vendor/k8s.io/api/networking/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/networking/v1alpha1/generated.proto @@ -44,7 +44,7 @@ message ClusterCIDR { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the ClusterCIDR. + // spec is the desired state of the ClusterCIDR. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional ClusterCIDRSpec spec = 2; @@ -57,19 +57,19 @@ message ClusterCIDRList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of ClusterCIDRs. + // items is the list of ClusterCIDRs. repeated ClusterCIDR items = 2; } // ClusterCIDRSpec defines the desired state of ClusterCIDR. message ClusterCIDRSpec { - // NodeSelector defines which nodes the config is applicable to. - // An empty or nil NodeSelector selects all nodes. + // nodeSelector defines which nodes the config is applicable to. + // An empty or nil nodeSelector selects all nodes. // This field is immutable. // +optional optional k8s.io.api.core.v1.NodeSelector nodeSelector = 1; - // PerNodeHostBits defines the number of host bits to be configured per node. + // perNodeHostBits defines the number of host bits to be configured per node. // A subnet mask determines how much of the address is used for network bits // and host bits. For example an IPv4 address of 192.168.0.0/24, splits the // address into 24 bits for the network portion and 8 bits for the host portion. @@ -79,16 +79,77 @@ message ClusterCIDRSpec { // +required optional int32 perNodeHostBits = 2; - // IPv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8"). - // At least one of IPv4 and IPv6 must be specified. + // ipv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8"). + // At least one of ipv4 and ipv6 must be specified. // This field is immutable. // +optional optional string ipv4 = 3; - // IPv6 defines an IPv6 IP block in CIDR notation(e.g. "2001:db8::/64"). - // At least one of IPv4 and IPv6 must be specified. + // ipv6 defines an IPv6 IP block in CIDR notation(e.g. "2001:db8::/64"). + // At least one of ipv4 and ipv6 must be specified. // This field is immutable. // +optional optional string ipv6 = 4; } +// 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; +} + +// 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; + + // UID is the uid of the object being referenced. + // +optional + optional string uid = 5; +} + diff --git a/vendor/k8s.io/api/networking/v1alpha1/register.go b/vendor/k8s.io/api/networking/v1alpha1/register.go index 12c0cf7bd..8dda6394d 100644 --- a/vendor/k8s.io/api/networking/v1alpha1/register.go +++ b/vendor/k8s.io/api/networking/v1alpha1/register.go @@ -22,12 +22,17 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -// GroupName is the group name use in this package. +// GroupName is the group name used in this package. const GroupName = "networking.k8s.io" -// SchemeGroupVersion is group version used to register these objects. +// SchemeGroupVersion is group version used to register objects in this package. var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} +// Kind takes an unqualified kind and returns a Group qualified GroupKind. +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + // Resource takes an unqualified resource and returns a Group qualified GroupResource. func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() @@ -49,8 +54,9 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &ClusterCIDR{}, &ClusterCIDRList{}, + &IPAddress{}, + &IPAddressList{}, ) - // Add the watch version that applies. metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } diff --git a/vendor/k8s.io/api/networking/v1alpha1/types.go b/vendor/k8s.io/api/networking/v1alpha1/types.go index 734e9bf8a..52e4a11e8 100644 --- a/vendor/k8s.io/api/networking/v1alpha1/types.go +++ b/vendor/k8s.io/api/networking/v1alpha1/types.go @@ -19,6 +19,7 @@ package v1alpha1 import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" ) // +genclient @@ -37,12 +38,13 @@ import ( // selector matches the Node may be used. type ClusterCIDR 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 ClusterCIDR. + // spec is the desired state of the ClusterCIDR. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec ClusterCIDRSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -50,13 +52,13 @@ type ClusterCIDR struct { // ClusterCIDRSpec defines the desired state of ClusterCIDR. type ClusterCIDRSpec struct { - // NodeSelector defines which nodes the config is applicable to. - // An empty or nil NodeSelector selects all nodes. + // nodeSelector defines which nodes the config is applicable to. + // An empty or nil nodeSelector selects all nodes. // This field is immutable. // +optional NodeSelector *v1.NodeSelector `json:"nodeSelector,omitempty" protobuf:"bytes,1,opt,name=nodeSelector"` - // PerNodeHostBits defines the number of host bits to be configured per node. + // perNodeHostBits defines the number of host bits to be configured per node. // A subnet mask determines how much of the address is used for network bits // and host bits. For example an IPv4 address of 192.168.0.0/24, splits the // address into 24 bits for the network portion and 8 bits for the host portion. @@ -66,14 +68,14 @@ type ClusterCIDRSpec struct { // +required PerNodeHostBits int32 `json:"perNodeHostBits" protobuf:"varint,2,opt,name=perNodeHostBits"` - // IPv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8"). - // At least one of IPv4 and IPv6 must be specified. + // ipv4 defines an IPv4 IP block in CIDR notation(e.g. "10.0.0.0/8"). + // At least one of ipv4 and ipv6 must be specified. // This field is immutable. // +optional IPv4 string `json:"ipv4" protobuf:"bytes,3,opt,name=ipv4"` - // IPv6 defines an IPv6 IP block in CIDR notation(e.g. "2001:db8::/64"). - // At least one of IPv4 and IPv6 must be specified. + // ipv6 defines an IPv6 IP block in CIDR notation(e.g. "2001:db8::/64"). + // At least one of ipv4 and ipv6 must be specified. // This field is immutable. // +optional IPv6 string `json:"ipv6" protobuf:"bytes,4,opt,name=ipv6"` @@ -85,11 +87,77 @@ type ClusterCIDRSpec struct { // ClusterCIDRList contains a list of ClusterCIDR. type ClusterCIDRList 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 ClusterCIDRs. + // items is the list of ClusterCIDRs. Items []ClusterCIDR `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.27 + +// 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"` + // UID is the uid of the object being referenced. + // +optional + UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.27 + +// 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"` +} diff --git a/vendor/k8s.io/api/networking/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/networking/v1alpha1/types_swagger_doc_generated.go index e0d4a4786..85304784f 100644 --- a/vendor/k8s.io/api/networking/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/networking/v1alpha1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_ClusterCIDR = map[string]string{ "": "ClusterCIDR represents a single configuration for per-Node Pod CIDR allocations when the MultiCIDRRangeAllocator is enabled (see the config for kube-controller-manager). A cluster may have any number of ClusterCIDR resources, all of which will be considered when allocating a CIDR for a Node. A ClusterCIDR is eligible to be used for a given Node when the node selector matches the node in question and has free CIDRs to allocate. In case of multiple matching ClusterCIDR resources, the allocator will attempt to break ties using internal heuristics, but any ClusterCIDR whose node selector matches the Node may be used.", "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 ClusterCIDR. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the ClusterCIDR. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (ClusterCIDR) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (ClusterCIDR) SwaggerDoc() map[string]string { var map_ClusterCIDRList = map[string]string{ "": "ClusterCIDRList contains a list of ClusterCIDR.", "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 ClusterCIDRs.", + "items": "items is the list of ClusterCIDRs.", } func (ClusterCIDRList) SwaggerDoc() map[string]string { @@ -49,14 +49,56 @@ func (ClusterCIDRList) SwaggerDoc() map[string]string { var map_ClusterCIDRSpec = map[string]string{ "": "ClusterCIDRSpec defines the desired state of ClusterCIDR.", - "nodeSelector": "NodeSelector defines which nodes the config is applicable to. An empty or nil NodeSelector selects all nodes. This field is immutable.", - "perNodeHostBits": "PerNodeHostBits defines the number of host bits to be configured per node. A subnet mask determines how much of the address is used for network bits and host bits. For example an IPv4 address of 192.168.0.0/24, splits the address into 24 bits for the network portion and 8 bits for the host portion. To allocate 256 IPs, set this field to 8 (a /24 mask for IPv4 or a /120 for IPv6). Minimum value is 4 (16 IPs). This field is immutable.", - "ipv4": "IPv4 defines an IPv4 IP block in CIDR notation(e.g. \"10.0.0.0/8\"). At least one of IPv4 and IPv6 must be specified. This field is immutable.", - "ipv6": "IPv6 defines an IPv6 IP block in CIDR notation(e.g. \"2001:db8::/64\"). At least one of IPv4 and IPv6 must be specified. This field is immutable.", + "nodeSelector": "nodeSelector defines which nodes the config is applicable to. An empty or nil nodeSelector selects all nodes. This field is immutable.", + "perNodeHostBits": "perNodeHostBits defines the number of host bits to be configured per node. A subnet mask determines how much of the address is used for network bits and host bits. For example an IPv4 address of 192.168.0.0/24, splits the address into 24 bits for the network portion and 8 bits for the host portion. To allocate 256 IPs, set this field to 8 (a /24 mask for IPv4 or a /120 for IPv6). Minimum value is 4 (16 IPs). This field is immutable.", + "ipv4": "ipv4 defines an IPv4 IP block in CIDR notation(e.g. \"10.0.0.0/8\"). At least one of ipv4 and ipv6 must be specified. This field is immutable.", + "ipv6": "ipv6 defines an IPv6 IP block in CIDR notation(e.g. \"2001:db8::/64\"). At least one of ipv4 and ipv6 must be specified. This field is immutable.", } func (ClusterCIDRSpec) SwaggerDoc() map[string]string { return map_ClusterCIDRSpec } +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_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.", + "uid": "UID is the uid of the object being referenced.", +} + +func (ParentReference) SwaggerDoc() map[string]string { + return map_ParentReference +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/networking/v1alpha1/well_known_labels.go b/vendor/k8s.io/api/networking/v1alpha1/well_known_labels.go new file mode 100644 index 000000000..5f9c23f70 --- /dev/null +++ b/vendor/k8s.io/api/networking/v1alpha1/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 v1alpha1 + +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/vendor/k8s.io/api/networking/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/networking/v1alpha1/zz_generated.deepcopy.go index e549f3166..97db2eacc 100644 --- a/vendor/k8s.io/api/networking/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/networking/v1alpha1/zz_generated.deepcopy.go @@ -106,3 +106,100 @@ func (in *ClusterCIDRSpec) DeepCopy() *ClusterCIDRSpec { in.DeepCopyInto(out) 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 *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 +} diff --git a/vendor/k8s.io/api/networking/v1alpha1/zz_generated.prerelease-lifecycle.go b/vendor/k8s.io/api/networking/v1alpha1/zz_generated.prerelease-lifecycle.go index dd6e3b26c..60438ba59 100644 --- a/vendor/k8s.io/api/networking/v1alpha1/zz_generated.prerelease-lifecycle.go +++ b/vendor/k8s.io/api/networking/v1alpha1/zz_generated.prerelease-lifecycle.go @@ -56,3 +56,39 @@ func (in *ClusterCIDRList) APILifecycleDeprecated() (major, minor int) { func (in *ClusterCIDRList) APILifecycleRemoved() (major, minor int) { return 1, 31 } + +// 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, 27 +} + +// 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 *IPAddress) APILifecycleDeprecated() (major, minor int) { + return 1, 30 +} + +// 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 *IPAddress) APILifecycleRemoved() (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, 27 +} + +// 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 *IPAddressList) APILifecycleDeprecated() (major, minor int) { + return 1, 30 +} + +// 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 *IPAddressList) APILifecycleRemoved() (major, minor int) { + return 1, 33 +} diff --git a/vendor/k8s.io/api/networking/v1beta1/generated.proto b/vendor/k8s.io/api/networking/v1beta1/generated.proto index 78ecf9fae..46bb7f66f 100644 --- a/vendor/k8s.io/api/networking/v1beta1/generated.proto +++ b/vendor/k8s.io/api/networking/v1beta1/generated.proto @@ -33,14 +33,14 @@ option go_package = "k8s.io/api/networking/v1beta1"; // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. message HTTPIngressPath { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional optional string path = 1; - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of the following values: // * Exact: Matches the URL path exactly. // * Prefix: Matches based on a URL path prefix split by '/'. Matching is @@ -57,7 +57,7 @@ message HTTPIngressPath { // Defaults to ImplementationSpecific. optional string pathType = 3; - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. optional IngressBackend backend = 2; } @@ -68,7 +68,7 @@ message HTTPIngressPath { // to match against everything after the last '/' and before the first '?' // or '#'. message HTTPIngressRuleValue { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. repeated HTTPIngressPath paths = 1; } @@ -82,12 +82,12 @@ message Ingress { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressSpec spec = 2; - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressStatus status = 3; @@ -95,15 +95,15 @@ message Ingress { // IngressBackend describes all endpoints for a given service and port. message IngressBackend { - // Specifies the name of the referenced service. + // serviceName specifies the name of the referenced service. // +optional optional string serviceName = 1; - // Specifies the port of the referenced service. + // servicePort Specifies the port of the referenced service. // +optional optional k8s.io.apimachinery.pkg.util.intstr.IntOrString servicePort = 2; - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, serviceName and servicePort // must not be specified. // +optional @@ -121,7 +121,7 @@ message IngressClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Spec is the desired state of the IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional optional IngressClassSpec spec = 2; @@ -133,30 +133,30 @@ message IngressClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of IngressClasses. + // items is the list of IngressClasses. repeated IngressClass items = 2; } // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. message IngressClassParametersReference { - // APIGroup is the group for the resource being referenced. If APIGroup is + // apiGroup is the group for the resource being referenced. If APIGroup is // not specified, the specified Kind must be in the core API group. For any // other third-party types, APIGroup is required. // +optional optional string aPIGroup = 1; - // Kind is the type of resource being referenced. + // kind is the type of resource being referenced. optional string kind = 2; - // Name is the name of resource being referenced. + // name is the name of resource being referenced. optional string name = 3; - // Scope represents if this refers to a cluster or namespace scoped resource. + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". optional string scope = 4; - // Namespace is the namespace of the resource being referenced. This field is + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -165,15 +165,15 @@ message IngressClassParametersReference { // IngressClassSpec provides information about the class of an Ingress. message IngressClassSpec { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. optional string controller = 1; - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -187,21 +187,21 @@ message IngressList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of Ingress. + // items is the list of Ingress. repeated Ingress items = 2; } // IngressLoadBalancerIngress represents the status of a load-balancer ingress point. message IngressLoadBalancerIngress { - // IP is set for load-balancer ingress points that are IP based. + // ip is set for load-balancer ingress points that are IP based. // +optional optional string ip = 1; - // Hostname is set for load-balancer ingress points that are DNS based. + // hostname is set for load-balancer ingress points that are DNS based. // +optional optional string hostname = 2; - // Ports provides information about the ports exposed by this LoadBalancer. + // ports provides information about the ports exposed by this LoadBalancer. // +listType=atomic // +optional repeated IngressPortStatus ports = 4; @@ -209,21 +209,21 @@ message IngressLoadBalancerIngress { // LoadBalancerStatus represents the status of a load-balancer. message IngressLoadBalancerStatus { - // Ingress is a list containing ingress points for the load-balancer. + // ingress is a list containing ingress points for the load-balancer. // +optional repeated IngressLoadBalancerIngress ingress = 1; } // IngressPortStatus represents the error condition of a service port message IngressPortStatus { - // Port is the port number of the ingress port. + // port is the port number of the ingress port. optional int32 port = 1; - // Protocol is the protocol of the ingress port. + // protocol is the protocol of the ingress port. // The supported values are: "TCP", "UDP", "SCTP" optional string protocol = 2; - // Error is to record the problem with the service port + // error is to record the problem with the service port // The format of the error shall comply with the following rules: // - built-in error values shall be specified in this file and those shall use // CamelCase names @@ -242,7 +242,7 @@ message IngressPortStatus { // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. message IngressRule { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -255,7 +255,7 @@ message IngressRule { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and @@ -287,7 +287,7 @@ message IngressRuleValue { // IngressSpec describes the Ingress the user wishes to exist. message IngressSpec { - // IngressClassName is the name of the IngressClass cluster resource. The + // ingressClassName is the name of the IngressClass cluster resource. The // associated IngressClass defines which controller will implement the // resource. This replaces the deprecated `kubernetes.io/ingress.class` // annotation. For backwards compatibility, when that annotation is set, it @@ -300,44 +300,44 @@ message IngressSpec { // +optional optional string ingressClassName = 4; - // A default backend capable of servicing requests that don't match any + // backend is the default backend capable of servicing requests that don't match any // rule. At least one of 'backend' or 'rules' must be specified. This field // is optional to allow the loadbalancer controller or defaulting logic to // specify a global default. // +optional optional IngressBackend backend = 1; - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the Ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +optional repeated IngressTLS tls = 2; - // A list of host rules used to configure the Ingress. If unspecified, or + // rules is a list of host rules used to configure the Ingress. If unspecified, or // no rule matches, all traffic is sent to the default backend. // +optional repeated IngressRule rules = 3; } -// IngressStatus describe the current state of the Ingress. +// IngressStatus describes the current state of the Ingress. message IngressStatus { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. // +optional optional IngressLoadBalancerStatus loadBalancer = 1; } // IngressTLS describes the transport layer security associated with an Ingress. message IngressTLS { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. // +optional repeated string hosts = 1; - // SecretName is the name of the secret used to terminate TLS traffic on + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination diff --git a/vendor/k8s.io/api/networking/v1beta1/types.go b/vendor/k8s.io/api/networking/v1beta1/types.go index 49c82123d..87cc91654 100644 --- a/vendor/k8s.io/api/networking/v1beta1/types.go +++ b/vendor/k8s.io/api/networking/v1beta1/types.go @@ -34,17 +34,18 @@ import ( // based virtual hosting etc. type Ingress 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 Ingress. + // spec is the desired state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` - // Status is the current state of the Ingress. + // status is the current state of the Ingress. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Status IngressStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` @@ -58,18 +59,19 @@ type Ingress struct { // IngressList is a collection of Ingress. type IngressList 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 Ingress. + // items is the list of Ingress. Items []Ingress `json:"items" protobuf:"bytes,2,rep,name=items"` } // IngressSpec describes the Ingress the user wishes to exist. type IngressSpec struct { - // IngressClassName is the name of the IngressClass cluster resource. The + // ingressClassName is the name of the IngressClass cluster resource. The // associated IngressClass defines which controller will implement the // resource. This replaces the deprecated `kubernetes.io/ingress.class` // annotation. For backwards compatibility, when that annotation is set, it @@ -82,22 +84,22 @@ type IngressSpec struct { // +optional IngressClassName *string `json:"ingressClassName,omitempty" protobuf:"bytes,4,opt,name=ingressClassName"` - // A default backend capable of servicing requests that don't match any + // backend is the default backend capable of servicing requests that don't match any // rule. At least one of 'backend' or 'rules' must be specified. This field // is optional to allow the loadbalancer controller or defaulting logic to // specify a global default. // +optional Backend *IngressBackend `json:"backend,omitempty" protobuf:"bytes,1,opt,name=backend"` - // TLS configuration. Currently the Ingress only supports a single TLS - // port, 443. If multiple members of this list specify different hosts, they - // will be multiplexed on the same port according to the hostname specified + // tls represents the TLS configuration. Currently the Ingress only supports a + // single TLS port, 443. If multiple members of this list specify different hosts, + // they will be multiplexed on the same port according to the hostname specified // through the SNI TLS extension, if the ingress controller fulfilling the // ingress supports SNI. // +optional TLS []IngressTLS `json:"tls,omitempty" protobuf:"bytes,2,rep,name=tls"` - // A list of host rules used to configure the Ingress. If unspecified, or + // rules is a list of host rules used to configure the Ingress. If unspecified, or // no rule matches, all traffic is sent to the default backend. // +optional Rules []IngressRule `json:"rules,omitempty" protobuf:"bytes,3,rep,name=rules"` @@ -106,13 +108,14 @@ type IngressSpec struct { // IngressTLS describes the transport layer security associated with an Ingress. type IngressTLS struct { - // Hosts are a list of hosts included in the TLS certificate. The values in + // hosts is a list of hosts included in the TLS certificate. The values in // this list must match the name/s used in the tlsSecret. Defaults to the // wildcard host setting for the loadbalancer controller fulfilling this // Ingress, if left unspecified. // +optional Hosts []string `json:"hosts,omitempty" protobuf:"bytes,1,rep,name=hosts"` - // SecretName is the name of the secret used to terminate TLS traffic on + + // secretName is the name of the secret used to terminate TLS traffic on // port 443. Field is left optional to allow TLS routing based on SNI // hostname alone. If the SNI host in a listener conflicts with the "Host" // header field used by an IngressRule, the SNI host is used for termination @@ -122,31 +125,31 @@ type IngressTLS struct { // TODO: Consider specifying different modes of termination, protocols etc. } -// IngressStatus describe the current state of the Ingress. +// IngressStatus describes the current state of the Ingress. type IngressStatus struct { - // LoadBalancer contains the current status of the load-balancer. + // loadBalancer contains the current status of the load-balancer. // +optional LoadBalancer IngressLoadBalancerStatus `json:"loadBalancer,omitempty" protobuf:"bytes,1,opt,name=loadBalancer"` } // LoadBalancerStatus represents the status of a load-balancer. type IngressLoadBalancerStatus struct { - // Ingress is a list containing ingress points for the load-balancer. + // ingress is a list containing ingress points for the load-balancer. // +optional Ingress []IngressLoadBalancerIngress `json:"ingress,omitempty" protobuf:"bytes,1,rep,name=ingress"` } // IngressLoadBalancerIngress represents the status of a load-balancer ingress point. type IngressLoadBalancerIngress struct { - // IP is set for load-balancer ingress points that are IP based. + // ip is set for load-balancer ingress points that are IP based. // +optional IP string `json:"ip,omitempty" protobuf:"bytes,1,opt,name=ip"` - // Hostname is set for load-balancer ingress points that are DNS based. + // hostname is set for load-balancer ingress points that are DNS based. // +optional Hostname string `json:"hostname,omitempty" protobuf:"bytes,2,opt,name=hostname"` - // Ports provides information about the ports exposed by this LoadBalancer. + // ports provides information about the ports exposed by this LoadBalancer. // +listType=atomic // +optional Ports []IngressPortStatus `json:"ports,omitempty" protobuf:"bytes,4,rep,name=ports"` @@ -154,14 +157,14 @@ type IngressLoadBalancerIngress struct { // IngressPortStatus represents the error condition of a service port type IngressPortStatus struct { - // Port is the port number of the ingress port. + // port is the port number of the ingress port. Port int32 `json:"port" protobuf:"varint,1,opt,name=port"` - // Protocol is the protocol of the ingress port. + // protocol is the protocol of the ingress port. // The supported values are: "TCP", "UDP", "SCTP" Protocol v1.Protocol `json:"protocol" protobuf:"bytes,2,opt,name=protocol,casttype=Protocol"` - // Error is to record the problem with the service port + // error is to record the problem with the service port // The format of the error shall comply with the following rules: // - built-in error values shall be specified in this file and those shall use // CamelCase names @@ -180,7 +183,7 @@ type IngressPortStatus struct { // the related backend services. Incoming requests are first evaluated for a host // match, then routed to the backend associated with the matching IngressRuleValue. type IngressRule struct { - // Host is the fully qualified domain name of a network host, as defined by RFC 3986. + // host is the fully qualified domain name of a network host, as defined by RFC 3986. // Note the following deviations from the "host" part of the // URI as defined in RFC 3986: // 1. IPs are not allowed. Currently an IngressRuleValue can only apply to @@ -193,7 +196,7 @@ type IngressRule struct { // IngressRuleValue. If the host is unspecified, the Ingress routes all // traffic based on the specified IngressRuleValue. // - // Host can be "precise" which is a domain name without the terminating dot of + // host can be "precise" which is a domain name without the terminating dot of // a network host (e.g. "foo.bar.com") or "wildcard", which is a domain name // prefixed with a single wildcard label (e.g. "*.foo.com"). // The wildcard character '*' must appear by itself as the first DNS label and @@ -204,6 +207,7 @@ type IngressRule struct { // is to equal to the suffix (removing the first label) of the wildcard rule. // +optional Host string `json:"host,omitempty" protobuf:"bytes,1,opt,name=host"` + // IngressRuleValue represents a rule to route requests for this IngressRule. // If unspecified, the rule defaults to a http catch-all. Whether that sends // just traffic matching the host to the default backend or all traffic to the @@ -234,7 +238,7 @@ type IngressRuleValue struct { // to match against everything after the last '/' and before the first '?' // or '#'. type HTTPIngressRuleValue struct { - // A collection of paths that map requests to backends. + // paths is a collection of paths that map requests to backends. Paths []HTTPIngressPath `json:"paths" protobuf:"bytes,1,rep,name=paths"` // TODO: Consider adding fields for ingress-type specific global // options usable by a loadbalancer, like http keep-alive. @@ -273,14 +277,14 @@ const ( // HTTPIngressPath associates a path with a backend. Incoming urls matching the // path are forwarded to the backend. type HTTPIngressPath struct { - // Path is matched against the path of an incoming request. Currently it can + // path is matched against the path of an incoming request. Currently it can // contain characters disallowed from the conventional "path" part of a URL // as defined by RFC 3986. Paths must begin with a '/' and must be present // when using PathType with value "Exact" or "Prefix". // +optional Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"` - // PathType determines the interpretation of the Path matching. PathType can + // pathType determines the interpretation of the path matching. PathType can // be one of the following values: // * Exact: Matches the URL path exactly. // * Prefix: Matches based on a URL path prefix split by '/'. Matching is @@ -297,22 +301,22 @@ type HTTPIngressPath struct { // Defaults to ImplementationSpecific. PathType *PathType `json:"pathType,omitempty" protobuf:"bytes,3,opt,name=pathType"` - // Backend defines the referenced service endpoint to which the traffic + // backend defines the referenced service endpoint to which the traffic // will be forwarded to. Backend IngressBackend `json:"backend" protobuf:"bytes,2,opt,name=backend"` } // IngressBackend describes all endpoints for a given service and port. type IngressBackend struct { - // Specifies the name of the referenced service. + // serviceName specifies the name of the referenced service. // +optional ServiceName string `json:"serviceName,omitempty" protobuf:"bytes,1,opt,name=serviceName"` - // Specifies the port of the referenced service. + // servicePort Specifies the port of the referenced service. // +optional ServicePort intstr.IntOrString `json:"servicePort,omitempty" protobuf:"bytes,2,opt,name=servicePort"` - // Resource is an ObjectRef to another Kubernetes resource in the namespace + // resource is an ObjectRef to another Kubernetes resource in the namespace // of the Ingress object. If resource is specified, serviceName and servicePort // must not be specified. // +optional @@ -333,12 +337,13 @@ type IngressBackend struct { // resources without a class specified will be assigned this default class. type IngressClass 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 IngressClass. + // spec is the desired state of the IngressClass. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status // +optional Spec IngressClassSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` @@ -346,15 +351,15 @@ type IngressClass struct { // IngressClassSpec provides information about the class of an Ingress. type IngressClassSpec struct { - // Controller refers to the name of the controller that should handle this + // controller refers to the name of the controller that should handle this // class. This allows for different "flavors" that are controlled by the - // same controller. For example, you may have different Parameters for the + // same controller. For example, you may have different parameters for the // same implementing controller. This should be specified as a // domain-prefixed path no more than 250 characters in length, e.g. // "acme.io/ingress-controller". This field is immutable. Controller string `json:"controller,omitempty" protobuf:"bytes,1,opt,name=controller"` - // Parameters is a link to a custom resource containing additional + // parameters is a link to a custom resource containing additional // configuration for the controller. This is optional if the controller does // not require extra parameters. // +optional @@ -373,19 +378,23 @@ const ( // IngressClassParametersReference identifies an API object. This can be used // to specify a cluster or namespace-scoped resource. type IngressClassParametersReference struct { - // APIGroup is the group for the resource being referenced. If APIGroup is + // apiGroup is the group for the resource being referenced. If APIGroup is // not specified, the specified Kind must be in the core API group. For any // other third-party types, APIGroup is required. // +optional APIGroup *string `json:"apiGroup,omitempty" protobuf:"bytes,1,opt,name=aPIGroup"` - // Kind is the type of resource being referenced. + + // kind is the type of resource being referenced. Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"` - // Name is the name of resource being referenced. + + // name is the name of resource being referenced. Name string `json:"name" protobuf:"bytes,3,opt,name=name"` - // Scope represents if this refers to a cluster or namespace scoped resource. + + // scope represents if this refers to a cluster or namespace scoped resource. // This may be set to "Cluster" (default) or "Namespace". Scope *string `json:"scope" protobuf:"bytes,4,opt,name=scope"` - // Namespace is the namespace of the resource being referenced. This field is + + // namespace is the namespace of the resource being referenced. This field is // required when scope is set to "Namespace" and must be unset when scope is set to // "Cluster". // +optional @@ -404,6 +413,6 @@ type IngressClassList struct { // +optional metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Items is the list of IngressClasses. + // items is the list of IngressClasses. Items []IngressClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go index 195d535c5..b2373669f 100644 --- a/vendor/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/networking/v1beta1/types_swagger_doc_generated.go @@ -24,14 +24,14 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_HTTPIngressPath = map[string]string{ "": "HTTPIngressPath associates a path with a backend. Incoming urls matching the path are forwarded to the backend.", - "path": "Path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value \"Exact\" or \"Prefix\".", - "pathType": "PathType determines the interpretation of the Path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types. Defaults to ImplementationSpecific.", - "backend": "Backend defines the referenced service endpoint to which the traffic will be forwarded to.", + "path": "path is matched against the path of an incoming request. Currently it can contain characters disallowed from the conventional \"path\" part of a URL as defined by RFC 3986. Paths must begin with a '/' and must be present when using PathType with value \"Exact\" or \"Prefix\".", + "pathType": "pathType determines the interpretation of the path matching. PathType can be one of the following values: * Exact: Matches the URL path exactly. * Prefix: Matches based on a URL path prefix split by '/'. Matching is\n done on a path element by element basis. A path element refers is the\n list of labels in the path split by the '/' separator. A request is a\n match for path p if every p is an element-wise prefix of p of the\n request path. Note that if the last element of the path is a substring\n of the last element in request path, it is not a match (e.g. /foo/bar\n matches /foo/bar/baz, but does not match /foo/barbaz).\n* ImplementationSpecific: Interpretation of the Path matching is up to\n the IngressClass. Implementations can treat this as a separate PathType\n or treat it identically to Prefix or Exact path types.\nImplementations are required to support all path types. Defaults to ImplementationSpecific.", + "backend": "backend defines the referenced service endpoint to which the traffic will be forwarded to.", } func (HTTPIngressPath) SwaggerDoc() map[string]string { @@ -40,7 +40,7 @@ func (HTTPIngressPath) SwaggerDoc() map[string]string { var map_HTTPIngressRuleValue = map[string]string{ "": "HTTPIngressRuleValue is a list of http selectors pointing to backends. In the example: http:///? -> backend where where parts of the url correspond to RFC 3986, this resource will be used to match against everything after the last '/' and before the first '?' or '#'.", - "paths": "A collection of paths that map requests to backends.", + "paths": "paths is a collection of paths that map requests to backends.", } func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { @@ -50,8 +50,8 @@ func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { var map_Ingress = map[string]string{ "": "Ingress is a collection of rules that allow inbound connections to reach the endpoints defined by a backend. An Ingress can be configured to give services externally-reachable urls, load balance traffic, terminate SSL, offer name based virtual hosting etc.", "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 Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", - "status": "Status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "status": "status is the current state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (Ingress) SwaggerDoc() map[string]string { @@ -60,9 +60,9 @@ func (Ingress) SwaggerDoc() map[string]string { var map_IngressBackend = map[string]string{ "": "IngressBackend describes all endpoints for a given service and port.", - "serviceName": "Specifies the name of the referenced service.", - "servicePort": "Specifies the port of the referenced service.", - "resource": "Resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, serviceName and servicePort must not be specified.", + "serviceName": "serviceName specifies the name of the referenced service.", + "servicePort": "servicePort Specifies the port of the referenced service.", + "resource": "resource is an ObjectRef to another Kubernetes resource in the namespace of the Ingress object. If resource is specified, serviceName and servicePort must not be specified.", } func (IngressBackend) SwaggerDoc() map[string]string { @@ -72,7 +72,7 @@ func (IngressBackend) SwaggerDoc() map[string]string { var map_IngressClass = map[string]string{ "": "IngressClass represents the class of the Ingress, referenced by the Ingress Spec. The `ingressclass.kubernetes.io/is-default-class` annotation can be used to indicate that an IngressClass should be considered default. When a single IngressClass resource has this annotation set to true, new Ingress resources without a class specified will be assigned this default class.", "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 IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec is the desired state of the IngressClass. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (IngressClass) SwaggerDoc() map[string]string { @@ -82,7 +82,7 @@ func (IngressClass) SwaggerDoc() map[string]string { var map_IngressClassList = map[string]string{ "": "IngressClassList is a collection of IngressClasses.", "metadata": "Standard list metadata.", - "items": "Items is the list of IngressClasses.", + "items": "items is the list of IngressClasses.", } func (IngressClassList) SwaggerDoc() map[string]string { @@ -91,11 +91,11 @@ func (IngressClassList) SwaggerDoc() map[string]string { var map_IngressClassParametersReference = map[string]string{ "": "IngressClassParametersReference identifies an API object. This can be used to specify a cluster or namespace-scoped resource.", - "apiGroup": "APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", - "kind": "Kind is the type of resource being referenced.", - "name": "Name is the name of resource being referenced.", - "scope": "Scope represents if this refers to a cluster or namespace scoped resource. This may be set to \"Cluster\" (default) or \"Namespace\".", - "namespace": "Namespace is the namespace of the resource being referenced. This field is required when scope is set to \"Namespace\" and must be unset when scope is set to \"Cluster\".", + "apiGroup": "apiGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", + "kind": "kind is the type of resource being referenced.", + "name": "name is the name of resource being referenced.", + "scope": "scope represents if this refers to a cluster or namespace scoped resource. This may be set to \"Cluster\" (default) or \"Namespace\".", + "namespace": "namespace is the namespace of the resource being referenced. This field is required when scope is set to \"Namespace\" and must be unset when scope is set to \"Cluster\".", } func (IngressClassParametersReference) SwaggerDoc() map[string]string { @@ -104,8 +104,8 @@ func (IngressClassParametersReference) SwaggerDoc() map[string]string { var map_IngressClassSpec = map[string]string{ "": "IngressClassSpec provides information about the class of an Ingress.", - "controller": "Controller refers to the name of the controller that should handle this class. This allows for different \"flavors\" that are controlled by the same controller. For example, you may have different Parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. \"acme.io/ingress-controller\". This field is immutable.", - "parameters": "Parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.", + "controller": "controller refers to the name of the controller that should handle this class. This allows for different \"flavors\" that are controlled by the same controller. For example, you may have different parameters for the same implementing controller. This should be specified as a domain-prefixed path no more than 250 characters in length, e.g. \"acme.io/ingress-controller\". This field is immutable.", + "parameters": "parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters.", } func (IngressClassSpec) SwaggerDoc() map[string]string { @@ -115,7 +115,7 @@ func (IngressClassSpec) SwaggerDoc() map[string]string { var map_IngressList = map[string]string{ "": "IngressList is a collection of Ingress.", "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 Ingress.", + "items": "items is the list of Ingress.", } func (IngressList) SwaggerDoc() map[string]string { @@ -124,9 +124,9 @@ func (IngressList) SwaggerDoc() map[string]string { var map_IngressLoadBalancerIngress = map[string]string{ "": "IngressLoadBalancerIngress represents the status of a load-balancer ingress point.", - "ip": "IP is set for load-balancer ingress points that are IP based.", - "hostname": "Hostname is set for load-balancer ingress points that are DNS based.", - "ports": "Ports provides information about the ports exposed by this LoadBalancer.", + "ip": "ip is set for load-balancer ingress points that are IP based.", + "hostname": "hostname is set for load-balancer ingress points that are DNS based.", + "ports": "ports provides information about the ports exposed by this LoadBalancer.", } func (IngressLoadBalancerIngress) SwaggerDoc() map[string]string { @@ -135,7 +135,7 @@ func (IngressLoadBalancerIngress) SwaggerDoc() map[string]string { var map_IngressLoadBalancerStatus = map[string]string{ "": "LoadBalancerStatus represents the status of a load-balancer.", - "ingress": "Ingress is a list containing ingress points for the load-balancer.", + "ingress": "ingress is a list containing ingress points for the load-balancer.", } func (IngressLoadBalancerStatus) SwaggerDoc() map[string]string { @@ -144,9 +144,9 @@ func (IngressLoadBalancerStatus) SwaggerDoc() map[string]string { var map_IngressPortStatus = map[string]string{ "": "IngressPortStatus represents the error condition of a service port", - "port": "Port is the port number of the ingress port.", - "protocol": "Protocol is the protocol of the ingress port. The supported values are: \"TCP\", \"UDP\", \"SCTP\"", - "error": "Error is to record the problem with the service port The format of the error shall comply with the following rules: - built-in error values shall be specified in this file and those shall use\n CamelCase names\n- cloud provider specific error values must have names that comply with the\n format foo.example.com/CamelCase.", + "port": "port is the port number of the ingress port.", + "protocol": "protocol is the protocol of the ingress port. The supported values are: \"TCP\", \"UDP\", \"SCTP\"", + "error": "error is to record the problem with the service port The format of the error shall comply with the following rules: - built-in error values shall be specified in this file and those shall use\n CamelCase names\n- cloud provider specific error values must have names that comply with the\n format foo.example.com/CamelCase.", } func (IngressPortStatus) SwaggerDoc() map[string]string { @@ -155,7 +155,7 @@ func (IngressPortStatus) SwaggerDoc() map[string]string { var map_IngressRule = map[string]string{ "": "IngressRule represents the rules mapping the paths under a specified host to the related backend services. Incoming requests are first evaluated for a host match, then routed to the backend associated with the matching IngressRuleValue.", - "host": "Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nHost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", + "host": "host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the \"host\" part of the URI as defined in RFC 3986: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to\n the IP in the Spec of the parent Ingress.\n2. The `:` delimiter is not respected because ports are not allowed.\n\t Currently the port of an Ingress is implicitly :80 for http and\n\t :443 for https.\nBoth these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.\n\nhost can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.bar.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. \"*.foo.com\"). The wildcard character '*' must appear by itself as the first DNS label and matches only a single label. You cannot have a wildcard label by itself (e.g. Host == \"*\"). Requests will be matched against the Host field in the following way: 1. If Host is precise, the request matches this rule if the http host header is equal to Host. 2. If Host is a wildcard, then the request matches this rule if the http host header is to equal to the suffix (removing the first label) of the wildcard rule.", } func (IngressRule) SwaggerDoc() map[string]string { @@ -172,10 +172,10 @@ func (IngressRuleValue) SwaggerDoc() map[string]string { var map_IngressSpec = map[string]string{ "": "IngressSpec describes the Ingress the user wishes to exist.", - "ingressClassName": "IngressClassName is the name of the IngressClass cluster resource. The associated IngressClass defines which controller will implement the resource. This replaces the deprecated `kubernetes.io/ingress.class` annotation. For backwards compatibility, when that annotation is set, it must be given precedence over this field. The controller may emit a warning if the field and annotation have different values. Implementations of this API should ignore Ingresses without a class specified. An IngressClass resource may be marked as default, which can be used to set a default value for this field. For more information, refer to the IngressClass documentation.", - "backend": "A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default.", - "tls": "TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", - "rules": "A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", + "ingressClassName": "ingressClassName is the name of the IngressClass cluster resource. The associated IngressClass defines which controller will implement the resource. This replaces the deprecated `kubernetes.io/ingress.class` annotation. For backwards compatibility, when that annotation is set, it must be given precedence over this field. The controller may emit a warning if the field and annotation have different values. Implementations of this API should ignore Ingresses without a class specified. An IngressClass resource may be marked as default, which can be used to set a default value for this field. For more information, refer to the IngressClass documentation.", + "backend": "backend is the default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default.", + "tls": "tls represents the TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.", + "rules": "rules is a list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend.", } func (IngressSpec) SwaggerDoc() map[string]string { @@ -183,8 +183,8 @@ func (IngressSpec) SwaggerDoc() map[string]string { } var map_IngressStatus = map[string]string{ - "": "IngressStatus describe the current state of the Ingress.", - "loadBalancer": "LoadBalancer contains the current status of the load-balancer.", + "": "IngressStatus describes the current state of the Ingress.", + "loadBalancer": "loadBalancer contains the current status of the load-balancer.", } func (IngressStatus) SwaggerDoc() map[string]string { @@ -193,8 +193,8 @@ func (IngressStatus) SwaggerDoc() map[string]string { var map_IngressTLS = map[string]string{ "": "IngressTLS describes the transport layer security associated with an Ingress.", - "hosts": "Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", - "secretName": "SecretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.", + "hosts": "hosts is a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified.", + "secretName": "secretName is the name of the secret used to terminate TLS traffic on port 443. Field is left optional to allow TLS routing based on SNI hostname alone. If the SNI host in a listener conflicts with the \"Host\" header field used by an IngressRule, the SNI host is used for termination and value of the Host header is used for routing.", } func (IngressTLS) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/node/v1/generated.proto b/vendor/k8s.io/api/node/v1/generated.proto index 294be85b6..0152d5e3a 100644 --- a/vendor/k8s.io/api/node/v1/generated.proto +++ b/vendor/k8s.io/api/node/v1/generated.proto @@ -32,7 +32,7 @@ option go_package = "k8s.io/api/node/v1"; // Overhead structure represents the resource overhead associated with running a pod. message Overhead { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional map podFixed = 1; } @@ -49,7 +49,7 @@ message RuntimeClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Handler specifies the underlying runtime and configuration that the CRI + // handler specifies the underlying runtime and configuration that the CRI // implementation will use to handle pods of this class. The possible values // are specific to the node & CRI configuration. It is assumed that all // handlers are available on every node, and handlers of the same name are @@ -61,13 +61,13 @@ message RuntimeClass { // and is immutable. optional string handler = 2; - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/ // +optional optional Overhead overhead = 3; - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -82,7 +82,7 @@ message RuntimeClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated RuntimeClass items = 2; } diff --git a/vendor/k8s.io/api/node/v1/types.go b/vendor/k8s.io/api/node/v1/types.go index 984696d98..b00f58772 100644 --- a/vendor/k8s.io/api/node/v1/types.go +++ b/vendor/k8s.io/api/node/v1/types.go @@ -34,11 +34,12 @@ import ( // https://kubernetes.io/docs/concepts/containers/runtime-class/ type RuntimeClass 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"` - // Handler specifies the underlying runtime and configuration that the CRI + // handler specifies the underlying runtime and configuration that the CRI // implementation will use to handle pods of this class. The possible values // are specific to the node & CRI configuration. It is assumed that all // handlers are available on every node, and handlers of the same name are @@ -50,13 +51,13 @@ type RuntimeClass struct { // and is immutable. Handler string `json:"handler" protobuf:"bytes,2,opt,name=handler"` - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/ // +optional Overhead *Overhead `json:"overhead,omitempty" protobuf:"bytes,3,opt,name=overhead"` - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -66,7 +67,7 @@ type RuntimeClass struct { // Overhead structure represents the resource overhead associated with running a pod. type Overhead struct { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional PodFixed corev1.ResourceList `json:"podFixed,omitempty" protobuf:"bytes,1,opt,name=podFixed,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"` } @@ -96,11 +97,12 @@ type Scheduling struct { // RuntimeClassList is a list of RuntimeClass objects. type RuntimeClassList 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 is a list of schema objects. Items []RuntimeClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/node/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/node/v1/types_swagger_doc_generated.go index a9eddc60e..f5e6b3277 100644 --- a/vendor/k8s.io/api/node/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/node/v1/types_swagger_doc_generated.go @@ -24,12 +24,12 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Overhead = map[string]string{ "": "Overhead structure represents the resource overhead associated with running a pod.", - "podFixed": "PodFixed represents the fixed resource overhead associated with running a pod.", + "podFixed": "podFixed represents the fixed resource overhead associated with running a pod.", } func (Overhead) SwaggerDoc() map[string]string { @@ -39,9 +39,9 @@ func (Overhead) SwaggerDoc() map[string]string { var map_RuntimeClass = map[string]string{ "": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://kubernetes.io/docs/concepts/containers/runtime-class/", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "handler": "Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", - "overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see\n https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/", - "scheduling": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", + "handler": "handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", + "overhead": "overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see\n https://kubernetes.io/docs/concepts/scheduling-eviction/pod-overhead/", + "scheduling": "scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", } func (RuntimeClass) SwaggerDoc() map[string]string { @@ -51,7 +51,7 @@ func (RuntimeClass) SwaggerDoc() map[string]string { var map_RuntimeClassList = map[string]string{ "": "RuntimeClassList is a list of RuntimeClass 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.", + "items": "items is a list of schema objects.", } func (RuntimeClassList) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/node/v1alpha1/generated.proto b/vendor/k8s.io/api/node/v1alpha1/generated.proto index d46e0ec6a..4673e9261 100644 --- a/vendor/k8s.io/api/node/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/node/v1alpha1/generated.proto @@ -32,7 +32,7 @@ option go_package = "k8s.io/api/node/v1alpha1"; // Overhead structure represents the resource overhead associated with running a pod. message Overhead { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional map podFixed = 1; } @@ -49,7 +49,7 @@ message RuntimeClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the RuntimeClass + // spec represents specification of the RuntimeClass // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status optional RuntimeClassSpec spec = 2; } @@ -61,7 +61,7 @@ message RuntimeClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated RuntimeClass items = 2; } @@ -70,7 +70,7 @@ message RuntimeClassList { // Interface (CRI) implementation, as well as any other components that need to // understand how the pod will be run. The RuntimeClassSpec is immutable. message RuntimeClassSpec { - // RuntimeHandler specifies the underlying runtime and configuration that the + // runtimeHandler specifies the underlying runtime and configuration that the // CRI implementation will use to handle pods of this class. The possible // values are specific to the node & CRI configuration. It is assumed that // all handlers are available on every node, and handlers of the same name are @@ -78,17 +78,17 @@ message RuntimeClassSpec { // For example, a handler called "runc" might specify that the runc OCI // runtime (using native Linux containers) will be used to run the containers // in a pod. - // The RuntimeHandler must be lowercase, conform to the DNS Label (RFC 1123) + // The runtimeHandler must be lowercase, conform to the DNS Label (RFC 1123) // requirements, and is immutable. optional string runtimeHandler = 1; - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md // +optional optional Overhead overhead = 2; - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. diff --git a/vendor/k8s.io/api/node/v1alpha1/types.go b/vendor/k8s.io/api/node/v1alpha1/types.go index 588c8e4c0..bf9e284bf 100644 --- a/vendor/k8s.io/api/node/v1alpha1/types.go +++ b/vendor/k8s.io/api/node/v1alpha1/types.go @@ -34,11 +34,12 @@ import ( // https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class type RuntimeClass 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"` - // Specification of the RuntimeClass + // spec represents specification of the RuntimeClass // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status Spec RuntimeClassSpec `json:"spec" protobuf:"bytes,2,name=spec"` } @@ -48,7 +49,7 @@ type RuntimeClass struct { // Interface (CRI) implementation, as well as any other components that need to // understand how the pod will be run. The RuntimeClassSpec is immutable. type RuntimeClassSpec struct { - // RuntimeHandler specifies the underlying runtime and configuration that the + // runtimeHandler specifies the underlying runtime and configuration that the // CRI implementation will use to handle pods of this class. The possible // values are specific to the node & CRI configuration. It is assumed that // all handlers are available on every node, and handlers of the same name are @@ -56,17 +57,17 @@ type RuntimeClassSpec struct { // For example, a handler called "runc" might specify that the runc OCI // runtime (using native Linux containers) will be used to run the containers // in a pod. - // The RuntimeHandler must be lowercase, conform to the DNS Label (RFC 1123) + // The runtimeHandler must be lowercase, conform to the DNS Label (RFC 1123) // requirements, and is immutable. RuntimeHandler string `json:"runtimeHandler" protobuf:"bytes,1,opt,name=runtimeHandler"` - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md // +optional Overhead *Overhead `json:"overhead,omitempty" protobuf:"bytes,2,opt,name=overhead"` - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -76,7 +77,7 @@ type RuntimeClassSpec struct { // Overhead structure represents the resource overhead associated with running a pod. type Overhead struct { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional PodFixed corev1.ResourceList `json:"podFixed,omitempty" protobuf:"bytes,1,opt,name=podFixed,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"` } @@ -106,11 +107,12 @@ type Scheduling struct { // RuntimeClassList is a list of RuntimeClass objects. type RuntimeClassList 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 is a list of schema objects. Items []RuntimeClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go index 96413754f..ccc1b7085 100644 --- a/vendor/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/node/v1alpha1/types_swagger_doc_generated.go @@ -24,12 +24,12 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Overhead = map[string]string{ "": "Overhead structure represents the resource overhead associated with running a pod.", - "podFixed": "PodFixed represents the fixed resource overhead associated with running a pod.", + "podFixed": "podFixed represents the fixed resource overhead associated with running a pod.", } func (Overhead) SwaggerDoc() map[string]string { @@ -39,7 +39,7 @@ func (Overhead) SwaggerDoc() map[string]string { var map_RuntimeClass = map[string]string{ "": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the RuntimeClass More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "spec": "spec represents specification of the RuntimeClass More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", } func (RuntimeClass) SwaggerDoc() map[string]string { @@ -49,7 +49,7 @@ func (RuntimeClass) SwaggerDoc() map[string]string { var map_RuntimeClassList = map[string]string{ "": "RuntimeClassList is a list of RuntimeClass 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.", + "items": "items is a list of schema objects.", } func (RuntimeClassList) SwaggerDoc() map[string]string { @@ -58,9 +58,9 @@ func (RuntimeClassList) SwaggerDoc() map[string]string { var map_RuntimeClassSpec = map[string]string{ "": "RuntimeClassSpec is a specification of a RuntimeClass. It contains parameters that are required to describe the RuntimeClass to the Container Runtime Interface (CRI) implementation, as well as any other components that need to understand how the pod will be run. The RuntimeClassSpec is immutable.", - "runtimeHandler": "RuntimeHandler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The RuntimeHandler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", - "overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", - "scheduling": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", + "runtimeHandler": "runtimeHandler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The runtimeHandler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", + "overhead": "overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", + "scheduling": "scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", } func (RuntimeClassSpec) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/node/v1beta1/generated.proto b/vendor/k8s.io/api/node/v1beta1/generated.proto index 8ffad6973..54dbc0995 100644 --- a/vendor/k8s.io/api/node/v1beta1/generated.proto +++ b/vendor/k8s.io/api/node/v1beta1/generated.proto @@ -32,7 +32,7 @@ option go_package = "k8s.io/api/node/v1beta1"; // Overhead structure represents the resource overhead associated with running a pod. message Overhead { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional map podFixed = 1; } @@ -49,7 +49,7 @@ message RuntimeClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Handler specifies the underlying runtime and configuration that the CRI + // handler specifies the underlying runtime and configuration that the CRI // implementation will use to handle pods of this class. The possible values // are specific to the node & CRI configuration. It is assumed that all // handlers are available on every node, and handlers of the same name are @@ -57,17 +57,17 @@ message RuntimeClass { // For example, a handler called "runc" might specify that the runc OCI // runtime (using native Linux containers) will be used to run the containers // in a pod. - // The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, + // The handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, // and is immutable. optional string handler = 2; - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md // +optional optional Overhead overhead = 3; - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -82,7 +82,7 @@ message RuntimeClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is a list of schema objects. + // items is a list of schema objects. repeated RuntimeClass items = 2; } diff --git a/vendor/k8s.io/api/node/v1beta1/types.go b/vendor/k8s.io/api/node/v1beta1/types.go index b924cb421..74ecca26a 100644 --- a/vendor/k8s.io/api/node/v1beta1/types.go +++ b/vendor/k8s.io/api/node/v1beta1/types.go @@ -36,11 +36,12 @@ import ( // https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class type RuntimeClass 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"` - // Handler specifies the underlying runtime and configuration that the CRI + // handler specifies the underlying runtime and configuration that the CRI // implementation will use to handle pods of this class. The possible values // are specific to the node & CRI configuration. It is assumed that all // handlers are available on every node, and handlers of the same name are @@ -48,17 +49,17 @@ type RuntimeClass struct { // For example, a handler called "runc" might specify that the runc OCI // runtime (using native Linux containers) will be used to run the containers // in a pod. - // The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, + // The handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, // and is immutable. Handler string `json:"handler" protobuf:"bytes,2,opt,name=handler"` - // Overhead represents the resource overhead associated with running a pod for a + // overhead represents the resource overhead associated with running a pod for a // given RuntimeClass. For more details, see // https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md // +optional Overhead *Overhead `json:"overhead,omitempty" protobuf:"bytes,3,opt,name=overhead"` - // Scheduling holds the scheduling constraints to ensure that pods running + // scheduling holds the scheduling constraints to ensure that pods running // with this RuntimeClass are scheduled to nodes that support it. // If scheduling is nil, this RuntimeClass is assumed to be supported by all // nodes. @@ -68,7 +69,7 @@ type RuntimeClass struct { // Overhead structure represents the resource overhead associated with running a pod. type Overhead struct { - // PodFixed represents the fixed resource overhead associated with running a pod. + // podFixed represents the fixed resource overhead associated with running a pod. // +optional PodFixed corev1.ResourceList `json:"podFixed,omitempty" protobuf:"bytes,1,opt,name=podFixed,casttype=k8s.io/api/core/v1.ResourceList,castkey=k8s.io/api/core/v1.ResourceName,castvalue=k8s.io/apimachinery/pkg/api/resource.Quantity"` } @@ -100,11 +101,12 @@ type Scheduling struct { // RuntimeClassList is a list of RuntimeClass objects. type RuntimeClassList 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 is a list of schema objects. Items []RuntimeClass `json:"items" protobuf:"bytes,2,rep,name=items"` } diff --git a/vendor/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go index fec4398b2..086105ecc 100644 --- a/vendor/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/node/v1beta1/types_swagger_doc_generated.go @@ -24,12 +24,12 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Overhead = map[string]string{ "": "Overhead structure represents the resource overhead associated with running a pod.", - "podFixed": "PodFixed represents the fixed resource overhead associated with running a pod.", + "podFixed": "podFixed represents the fixed resource overhead associated with running a pod.", } func (Overhead) SwaggerDoc() map[string]string { @@ -39,9 +39,9 @@ func (Overhead) SwaggerDoc() map[string]string { var map_RuntimeClass = map[string]string{ "": "RuntimeClass defines a class of container runtime supported in the cluster. The RuntimeClass is used to determine which container runtime is used to run all containers in a pod. RuntimeClasses are (currently) manually defined by a user or cluster provisioner, and referenced in the PodSpec. The Kubelet is responsible for resolving the RuntimeClassName reference before running the pod. For more details, see https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class", "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "handler": "Handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The Handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", - "overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", - "scheduling": "Scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", + "handler": "handler specifies the underlying runtime and configuration that the CRI implementation will use to handle pods of this class. The possible values are specific to the node & CRI configuration. It is assumed that all handlers are available on every node, and handlers of the same name are equivalent on every node. For example, a handler called \"runc\" might specify that the runc OCI runtime (using native Linux containers) will be used to run the containers in a pod. The handler must be lowercase, conform to the DNS Label (RFC 1123) requirements, and is immutable.", + "overhead": "overhead represents the resource overhead associated with running a pod for a given RuntimeClass. For more details, see https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md", + "scheduling": "scheduling holds the scheduling constraints to ensure that pods running with this RuntimeClass are scheduled to nodes that support it. If scheduling is nil, this RuntimeClass is assumed to be supported by all nodes.", } func (RuntimeClass) SwaggerDoc() map[string]string { @@ -51,7 +51,7 @@ func (RuntimeClass) SwaggerDoc() map[string]string { var map_RuntimeClassList = map[string]string{ "": "RuntimeClassList is a list of RuntimeClass 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.", + "items": "items is a list of schema objects.", } func (RuntimeClassList) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/policy/v1/generated.proto b/vendor/k8s.io/api/policy/v1/generated.proto index 0a1e010b9..a79e71028 100644 --- a/vendor/k8s.io/api/policy/v1/generated.proto +++ b/vendor/k8s.io/api/policy/v1/generated.proto @@ -116,8 +116,8 @@ message PodDisruptionBudgetSpec { // Clients making eviction decisions should disallow eviction of unhealthy pods // if they encounter an unrecognized policy in this field. // - // This field is alpha-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (disabled by default). + // 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/vendor/k8s.io/api/policy/v1/types.go b/vendor/k8s.io/api/policy/v1/types.go index 6aec30b89..45b9550f4 100644 --- a/vendor/k8s.io/api/policy/v1/types.go +++ b/vendor/k8s.io/api/policy/v1/types.go @@ -71,8 +71,8 @@ type PodDisruptionBudgetSpec struct { // Clients making eviction decisions should disallow eviction of unhealthy pods // if they encounter an unrecognized policy in this field. // - // This field is alpha-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (disabled by default). + // 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/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go index 582b28c15..799b0794a 100644 --- a/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Eviction = map[string]string{ @@ -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 alpha-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (disabled 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.\n\nThis field is beta-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default).", } func (PodDisruptionBudgetSpec) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/policy/v1beta1/generated.proto b/vendor/k8s.io/api/policy/v1beta1/generated.proto index 989b48458..16301c236 100644 --- a/vendor/k8s.io/api/policy/v1beta1/generated.proto +++ b/vendor/k8s.io/api/policy/v1beta1/generated.proto @@ -177,8 +177,8 @@ message PodDisruptionBudgetSpec { // Clients making eviction decisions should disallow eviction of unhealthy pods // if they encounter an unrecognized policy in this field. // - // This field is alpha-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (disabled by default). + // 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/vendor/k8s.io/api/policy/v1beta1/types.go b/vendor/k8s.io/api/policy/v1beta1/types.go index 863b2b873..1e6b075e3 100644 --- a/vendor/k8s.io/api/policy/v1beta1/types.go +++ b/vendor/k8s.io/api/policy/v1beta1/types.go @@ -69,8 +69,8 @@ type PodDisruptionBudgetSpec struct { // Clients making eviction decisions should disallow eviction of unhealthy pods // if they encounter an unrecognized policy in this field. // - // This field is alpha-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (disabled by default). + // 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/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go index cebba07f4..266a9a853 100644 --- a/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AllowedCSIDriver = map[string]string{ @@ -121,7 +121,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 alpha-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (disabled 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.\n\nThis field is beta-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default).", } func (PodDisruptionBudgetSpec) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go index 63aa4ed7b..370398198 100644 --- a/vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/rbac/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AggregationRule = map[string]string{ diff --git a/vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go index 08578aba9..6708f3e58 100644 --- a/vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/rbac/v1alpha1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AggregationRule = map[string]string{ diff --git a/vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go index db9525832..fff1fe40f 100644 --- a/vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AggregationRule = map[string]string{ diff --git a/vendor/k8s.io/api/resource/v1alpha1/doc.go b/vendor/k8s.io/api/resource/v1alpha2/doc.go similarity index 84% rename from vendor/k8s.io/api/resource/v1alpha1/doc.go rename to vendor/k8s.io/api/resource/v1alpha2/doc.go index 8fa577fab..d9c20e089 100644 --- a/vendor/k8s.io/api/resource/v1alpha1/doc.go +++ b/vendor/k8s.io/api/resource/v1alpha2/doc.go @@ -20,5 +20,5 @@ limitations under the License. // +groupName=resource.k8s.io -// Package v1alpha1 is the v1alpha1 version of the resource API. -package v1alpha1 // import "k8s.io/api/resource/v1alpha1" +// Package v1alpha2 is the v1alpha2 version of the resource API. +package v1alpha2 // import "k8s.io/api/resource/v1alpha2" diff --git a/vendor/k8s.io/api/resource/v1alpha1/generated.pb.go b/vendor/k8s.io/api/resource/v1alpha2/generated.pb.go similarity index 83% rename from vendor/k8s.io/api/resource/v1alpha1/generated.pb.go rename to vendor/k8s.io/api/resource/v1alpha2/generated.pb.go index 632ad0425..2e8f9c724 100644 --- a/vendor/k8s.io/api/resource/v1alpha1/generated.pb.go +++ b/vendor/k8s.io/api/resource/v1alpha2/generated.pb.go @@ -15,9 +15,9 @@ limitations under the License. */ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: k8s.io/kubernetes/vendor/k8s.io/api/resource/v1alpha1/generated.proto +// source: k8s.io/kubernetes/vendor/k8s.io/api/resource/v1alpha2/generated.proto -package v1alpha1 +package v1alpha2 import ( fmt "fmt" @@ -49,7 +49,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package func (m *AllocationResult) Reset() { *m = AllocationResult{} } func (*AllocationResult) ProtoMessage() {} func (*AllocationResult) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{0} + return fileDescriptor_3add37bbd52889e0, []int{0} } func (m *AllocationResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -74,15 +74,15 @@ func (m *AllocationResult) XXX_DiscardUnknown() { var xxx_messageInfo_AllocationResult proto.InternalMessageInfo -func (m *PodScheduling) Reset() { *m = PodScheduling{} } -func (*PodScheduling) ProtoMessage() {} -func (*PodScheduling) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{1} +func (m *PodSchedulingContext) Reset() { *m = PodSchedulingContext{} } +func (*PodSchedulingContext) ProtoMessage() {} +func (*PodSchedulingContext) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{1} } -func (m *PodScheduling) XXX_Unmarshal(b []byte) error { +func (m *PodSchedulingContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *PodScheduling) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *PodSchedulingContext) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) if err != nil { @@ -90,27 +90,27 @@ func (m *PodScheduling) XXX_Marshal(b []byte, deterministic bool) ([]byte, error } return b[:n], nil } -func (m *PodScheduling) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodScheduling.Merge(m, src) +func (m *PodSchedulingContext) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingContext.Merge(m, src) } -func (m *PodScheduling) XXX_Size() int { +func (m *PodSchedulingContext) XXX_Size() int { return m.Size() } -func (m *PodScheduling) XXX_DiscardUnknown() { - xxx_messageInfo_PodScheduling.DiscardUnknown(m) +func (m *PodSchedulingContext) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingContext.DiscardUnknown(m) } -var xxx_messageInfo_PodScheduling proto.InternalMessageInfo +var xxx_messageInfo_PodSchedulingContext proto.InternalMessageInfo -func (m *PodSchedulingList) Reset() { *m = PodSchedulingList{} } -func (*PodSchedulingList) ProtoMessage() {} -func (*PodSchedulingList) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{2} +func (m *PodSchedulingContextList) Reset() { *m = PodSchedulingContextList{} } +func (*PodSchedulingContextList) ProtoMessage() {} +func (*PodSchedulingContextList) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{2} } -func (m *PodSchedulingList) XXX_Unmarshal(b []byte) error { +func (m *PodSchedulingContextList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *PodSchedulingList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *PodSchedulingContextList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) if err != nil { @@ -118,27 +118,27 @@ func (m *PodSchedulingList) XXX_Marshal(b []byte, deterministic bool) ([]byte, e } return b[:n], nil } -func (m *PodSchedulingList) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSchedulingList.Merge(m, src) +func (m *PodSchedulingContextList) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingContextList.Merge(m, src) } -func (m *PodSchedulingList) XXX_Size() int { +func (m *PodSchedulingContextList) XXX_Size() int { return m.Size() } -func (m *PodSchedulingList) XXX_DiscardUnknown() { - xxx_messageInfo_PodSchedulingList.DiscardUnknown(m) +func (m *PodSchedulingContextList) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingContextList.DiscardUnknown(m) } -var xxx_messageInfo_PodSchedulingList proto.InternalMessageInfo +var xxx_messageInfo_PodSchedulingContextList proto.InternalMessageInfo -func (m *PodSchedulingSpec) Reset() { *m = PodSchedulingSpec{} } -func (*PodSchedulingSpec) ProtoMessage() {} -func (*PodSchedulingSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{3} +func (m *PodSchedulingContextSpec) Reset() { *m = PodSchedulingContextSpec{} } +func (*PodSchedulingContextSpec) ProtoMessage() {} +func (*PodSchedulingContextSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{3} } -func (m *PodSchedulingSpec) XXX_Unmarshal(b []byte) error { +func (m *PodSchedulingContextSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *PodSchedulingSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *PodSchedulingContextSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) if err != nil { @@ -146,27 +146,27 @@ func (m *PodSchedulingSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, e } return b[:n], nil } -func (m *PodSchedulingSpec) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSchedulingSpec.Merge(m, src) +func (m *PodSchedulingContextSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingContextSpec.Merge(m, src) } -func (m *PodSchedulingSpec) XXX_Size() int { +func (m *PodSchedulingContextSpec) XXX_Size() int { return m.Size() } -func (m *PodSchedulingSpec) XXX_DiscardUnknown() { - xxx_messageInfo_PodSchedulingSpec.DiscardUnknown(m) +func (m *PodSchedulingContextSpec) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingContextSpec.DiscardUnknown(m) } -var xxx_messageInfo_PodSchedulingSpec proto.InternalMessageInfo +var xxx_messageInfo_PodSchedulingContextSpec proto.InternalMessageInfo -func (m *PodSchedulingStatus) Reset() { *m = PodSchedulingStatus{} } -func (*PodSchedulingStatus) ProtoMessage() {} -func (*PodSchedulingStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{4} +func (m *PodSchedulingContextStatus) Reset() { *m = PodSchedulingContextStatus{} } +func (*PodSchedulingContextStatus) ProtoMessage() {} +func (*PodSchedulingContextStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{4} } -func (m *PodSchedulingStatus) XXX_Unmarshal(b []byte) error { +func (m *PodSchedulingContextStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *PodSchedulingStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *PodSchedulingContextStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) if err != nil { @@ -174,22 +174,22 @@ func (m *PodSchedulingStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, } return b[:n], nil } -func (m *PodSchedulingStatus) XXX_Merge(src proto.Message) { - xxx_messageInfo_PodSchedulingStatus.Merge(m, src) +func (m *PodSchedulingContextStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_PodSchedulingContextStatus.Merge(m, src) } -func (m *PodSchedulingStatus) XXX_Size() int { +func (m *PodSchedulingContextStatus) XXX_Size() int { return m.Size() } -func (m *PodSchedulingStatus) XXX_DiscardUnknown() { - xxx_messageInfo_PodSchedulingStatus.DiscardUnknown(m) +func (m *PodSchedulingContextStatus) XXX_DiscardUnknown() { + xxx_messageInfo_PodSchedulingContextStatus.DiscardUnknown(m) } -var xxx_messageInfo_PodSchedulingStatus proto.InternalMessageInfo +var xxx_messageInfo_PodSchedulingContextStatus proto.InternalMessageInfo func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } func (*ResourceClaim) ProtoMessage() {} func (*ResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{5} + return fileDescriptor_3add37bbd52889e0, []int{5} } func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -217,7 +217,7 @@ var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo func (m *ResourceClaimConsumerReference) Reset() { *m = ResourceClaimConsumerReference{} } func (*ResourceClaimConsumerReference) ProtoMessage() {} func (*ResourceClaimConsumerReference) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{6} + return fileDescriptor_3add37bbd52889e0, []int{6} } func (m *ResourceClaimConsumerReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -245,7 +245,7 @@ var xxx_messageInfo_ResourceClaimConsumerReference proto.InternalMessageInfo func (m *ResourceClaimList) Reset() { *m = ResourceClaimList{} } func (*ResourceClaimList) ProtoMessage() {} func (*ResourceClaimList) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{7} + return fileDescriptor_3add37bbd52889e0, []int{7} } func (m *ResourceClaimList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -273,7 +273,7 @@ var xxx_messageInfo_ResourceClaimList proto.InternalMessageInfo func (m *ResourceClaimParametersReference) Reset() { *m = ResourceClaimParametersReference{} } func (*ResourceClaimParametersReference) ProtoMessage() {} func (*ResourceClaimParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{8} + return fileDescriptor_3add37bbd52889e0, []int{8} } func (m *ResourceClaimParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -301,7 +301,7 @@ var xxx_messageInfo_ResourceClaimParametersReference proto.InternalMessageInfo func (m *ResourceClaimSchedulingStatus) Reset() { *m = ResourceClaimSchedulingStatus{} } func (*ResourceClaimSchedulingStatus) ProtoMessage() {} func (*ResourceClaimSchedulingStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{9} + return fileDescriptor_3add37bbd52889e0, []int{9} } func (m *ResourceClaimSchedulingStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -329,7 +329,7 @@ var xxx_messageInfo_ResourceClaimSchedulingStatus proto.InternalMessageInfo func (m *ResourceClaimSpec) Reset() { *m = ResourceClaimSpec{} } func (*ResourceClaimSpec) ProtoMessage() {} func (*ResourceClaimSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{10} + return fileDescriptor_3add37bbd52889e0, []int{10} } func (m *ResourceClaimSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -357,7 +357,7 @@ var xxx_messageInfo_ResourceClaimSpec proto.InternalMessageInfo func (m *ResourceClaimStatus) Reset() { *m = ResourceClaimStatus{} } func (*ResourceClaimStatus) ProtoMessage() {} func (*ResourceClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{11} + return fileDescriptor_3add37bbd52889e0, []int{11} } func (m *ResourceClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -385,7 +385,7 @@ var xxx_messageInfo_ResourceClaimStatus proto.InternalMessageInfo func (m *ResourceClaimTemplate) Reset() { *m = ResourceClaimTemplate{} } func (*ResourceClaimTemplate) ProtoMessage() {} func (*ResourceClaimTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{12} + return fileDescriptor_3add37bbd52889e0, []int{12} } func (m *ResourceClaimTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -413,7 +413,7 @@ var xxx_messageInfo_ResourceClaimTemplate proto.InternalMessageInfo func (m *ResourceClaimTemplateList) Reset() { *m = ResourceClaimTemplateList{} } func (*ResourceClaimTemplateList) ProtoMessage() {} func (*ResourceClaimTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{13} + return fileDescriptor_3add37bbd52889e0, []int{13} } func (m *ResourceClaimTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -441,7 +441,7 @@ var xxx_messageInfo_ResourceClaimTemplateList proto.InternalMessageInfo func (m *ResourceClaimTemplateSpec) Reset() { *m = ResourceClaimTemplateSpec{} } func (*ResourceClaimTemplateSpec) ProtoMessage() {} func (*ResourceClaimTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{14} + return fileDescriptor_3add37bbd52889e0, []int{14} } func (m *ResourceClaimTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -469,7 +469,7 @@ var xxx_messageInfo_ResourceClaimTemplateSpec proto.InternalMessageInfo func (m *ResourceClass) Reset() { *m = ResourceClass{} } func (*ResourceClass) ProtoMessage() {} func (*ResourceClass) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{15} + return fileDescriptor_3add37bbd52889e0, []int{15} } func (m *ResourceClass) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -497,7 +497,7 @@ var xxx_messageInfo_ResourceClass proto.InternalMessageInfo func (m *ResourceClassList) Reset() { *m = ResourceClassList{} } func (*ResourceClassList) ProtoMessage() {} func (*ResourceClassList) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{16} + return fileDescriptor_3add37bbd52889e0, []int{16} } func (m *ResourceClassList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -525,7 +525,7 @@ var xxx_messageInfo_ResourceClassList proto.InternalMessageInfo func (m *ResourceClassParametersReference) Reset() { *m = ResourceClassParametersReference{} } func (*ResourceClassParametersReference) ProtoMessage() {} func (*ResourceClassParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_a66b2ee03d862be2, []int{17} + return fileDescriptor_3add37bbd52889e0, []int{17} } func (m *ResourceClassParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -550,107 +550,140 @@ func (m *ResourceClassParametersReference) XXX_DiscardUnknown() { var xxx_messageInfo_ResourceClassParametersReference proto.InternalMessageInfo +func (m *ResourceHandle) Reset() { *m = ResourceHandle{} } +func (*ResourceHandle) ProtoMessage() {} +func (*ResourceHandle) Descriptor() ([]byte, []int) { + return fileDescriptor_3add37bbd52889e0, []int{18} +} +func (m *ResourceHandle) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ResourceHandle) 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 *ResourceHandle) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResourceHandle.Merge(m, src) +} +func (m *ResourceHandle) XXX_Size() int { + return m.Size() +} +func (m *ResourceHandle) XXX_DiscardUnknown() { + xxx_messageInfo_ResourceHandle.DiscardUnknown(m) +} + +var xxx_messageInfo_ResourceHandle proto.InternalMessageInfo + func init() { - proto.RegisterType((*AllocationResult)(nil), "k8s.io.api.resource.v1alpha1.AllocationResult") - proto.RegisterType((*PodScheduling)(nil), "k8s.io.api.resource.v1alpha1.PodScheduling") - proto.RegisterType((*PodSchedulingList)(nil), "k8s.io.api.resource.v1alpha1.PodSchedulingList") - proto.RegisterType((*PodSchedulingSpec)(nil), "k8s.io.api.resource.v1alpha1.PodSchedulingSpec") - proto.RegisterType((*PodSchedulingStatus)(nil), "k8s.io.api.resource.v1alpha1.PodSchedulingStatus") - proto.RegisterType((*ResourceClaim)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaim") - proto.RegisterType((*ResourceClaimConsumerReference)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimConsumerReference") - proto.RegisterType((*ResourceClaimList)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimList") - proto.RegisterType((*ResourceClaimParametersReference)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimParametersReference") - proto.RegisterType((*ResourceClaimSchedulingStatus)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimSchedulingStatus") - proto.RegisterType((*ResourceClaimSpec)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimSpec") - proto.RegisterType((*ResourceClaimStatus)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimStatus") - proto.RegisterType((*ResourceClaimTemplate)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimTemplate") - proto.RegisterType((*ResourceClaimTemplateList)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimTemplateList") - proto.RegisterType((*ResourceClaimTemplateSpec)(nil), "k8s.io.api.resource.v1alpha1.ResourceClaimTemplateSpec") - proto.RegisterType((*ResourceClass)(nil), "k8s.io.api.resource.v1alpha1.ResourceClass") - proto.RegisterType((*ResourceClassList)(nil), "k8s.io.api.resource.v1alpha1.ResourceClassList") - proto.RegisterType((*ResourceClassParametersReference)(nil), "k8s.io.api.resource.v1alpha1.ResourceClassParametersReference") + proto.RegisterType((*AllocationResult)(nil), "k8s.io.api.resource.v1alpha2.AllocationResult") + proto.RegisterType((*PodSchedulingContext)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContext") + proto.RegisterType((*PodSchedulingContextList)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextList") + proto.RegisterType((*PodSchedulingContextSpec)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextSpec") + proto.RegisterType((*PodSchedulingContextStatus)(nil), "k8s.io.api.resource.v1alpha2.PodSchedulingContextStatus") + proto.RegisterType((*ResourceClaim)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaim") + proto.RegisterType((*ResourceClaimConsumerReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimConsumerReference") + proto.RegisterType((*ResourceClaimList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimList") + proto.RegisterType((*ResourceClaimParametersReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimParametersReference") + proto.RegisterType((*ResourceClaimSchedulingStatus)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimSchedulingStatus") + proto.RegisterType((*ResourceClaimSpec)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimSpec") + proto.RegisterType((*ResourceClaimStatus)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimStatus") + proto.RegisterType((*ResourceClaimTemplate)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimTemplate") + proto.RegisterType((*ResourceClaimTemplateList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimTemplateList") + proto.RegisterType((*ResourceClaimTemplateSpec)(nil), "k8s.io.api.resource.v1alpha2.ResourceClaimTemplateSpec") + proto.RegisterType((*ResourceClass)(nil), "k8s.io.api.resource.v1alpha2.ResourceClass") + proto.RegisterType((*ResourceClassList)(nil), "k8s.io.api.resource.v1alpha2.ResourceClassList") + proto.RegisterType((*ResourceClassParametersReference)(nil), "k8s.io.api.resource.v1alpha2.ResourceClassParametersReference") + proto.RegisterType((*ResourceHandle)(nil), "k8s.io.api.resource.v1alpha2.ResourceHandle") } func init() { - proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/resource/v1alpha1/generated.proto", fileDescriptor_a66b2ee03d862be2) + proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/api/resource/v1alpha2/generated.proto", fileDescriptor_3add37bbd52889e0) } -var fileDescriptor_a66b2ee03d862be2 = []byte{ - // 1174 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0xcd, 0x6f, 0x1b, 0x45, - 0x14, 0xcf, 0xc6, 0x6e, 0x95, 0x8c, 0x1b, 0x37, 0xd9, 0x34, 0xc8, 0x8d, 0x5a, 0xdb, 0xec, 0xc9, - 0x12, 0xb0, 0xdb, 0x04, 0x04, 0x15, 0x1f, 0x95, 0xb2, 0x0d, 0x94, 0x08, 0x9a, 0x9a, 0x31, 0x91, - 0x08, 0x42, 0x88, 0xf1, 0xee, 0xab, 0xbd, 0x64, 0xbf, 0xd8, 0xd9, 0x35, 0xaa, 0xb8, 0xf4, 0xca, - 0x0d, 0x21, 0xee, 0x1c, 0xf9, 0x43, 0x10, 0x52, 0x8e, 0x91, 0xe0, 0xd0, 0x93, 0x45, 0xcc, 0x81, - 0x3f, 0x80, 0x13, 0x3d, 0xa1, 0x19, 0xef, 0xae, 0x77, 0xd6, 0x1f, 0xc4, 0x11, 0x8a, 0xc2, 0x29, - 0x99, 0x79, 0xbf, 0xf7, 0x9b, 0xf7, 0x31, 0xef, 0xcd, 0x5b, 0xa3, 0x77, 0x8f, 0xee, 0x52, 0xd5, - 0xf2, 0xb4, 0xa3, 0xa8, 0x0d, 0x81, 0x0b, 0x21, 0x50, 0xad, 0x07, 0xae, 0xe9, 0x05, 0x5a, 0x2c, - 0x20, 0xbe, 0xa5, 0x05, 0x40, 0xbd, 0x28, 0x30, 0x40, 0xeb, 0x6d, 0x11, 0xdb, 0xef, 0x92, 0x2d, - 0xad, 0x03, 0x2e, 0x04, 0x24, 0x04, 0x53, 0xf5, 0x03, 0x2f, 0xf4, 0xe4, 0x5b, 0x43, 0xb4, 0x4a, - 0x7c, 0x4b, 0x4d, 0xd0, 0x6a, 0x82, 0xde, 0x7c, 0xa5, 0x63, 0x85, 0xdd, 0xa8, 0xad, 0x1a, 0x9e, - 0xa3, 0x75, 0xbc, 0x8e, 0xa7, 0x71, 0xa5, 0x76, 0xf4, 0x98, 0xaf, 0xf8, 0x82, 0xff, 0x37, 0x24, - 0xdb, 0x54, 0x32, 0x47, 0x1b, 0x5e, 0xc0, 0x8e, 0xcd, 0x1f, 0xb8, 0xf9, 0xda, 0x08, 0xe3, 0x10, - 0xa3, 0x6b, 0xb9, 0x10, 0x3c, 0xd1, 0xfc, 0xa3, 0x0e, 0xdb, 0xa0, 0x9a, 0x03, 0x21, 0x99, 0xa4, - 0xa5, 0x4d, 0xd3, 0x0a, 0x22, 0x37, 0xb4, 0x1c, 0x18, 0x53, 0x78, 0xfd, 0xdf, 0x14, 0xa8, 0xd1, - 0x05, 0x87, 0xe4, 0xf5, 0x94, 0x3f, 0x25, 0xb4, 0xba, 0x63, 0xdb, 0x9e, 0x41, 0x42, 0xcb, 0x73, - 0x31, 0xd0, 0xc8, 0x0e, 0xe5, 0x7b, 0xa8, 0x9c, 0xc4, 0xe6, 0x7d, 0xe2, 0x9a, 0x36, 0x54, 0xa4, - 0xba, 0xd4, 0x58, 0xd6, 0x5f, 0x38, 0xee, 0xd7, 0x16, 0x06, 0xfd, 0x5a, 0x19, 0x0b, 0x52, 0x9c, - 0x43, 0xcb, 0x6d, 0xb4, 0x4a, 0x7a, 0xc4, 0xb2, 0x49, 0xdb, 0x86, 0x47, 0xee, 0xbe, 0x67, 0x02, - 0xad, 0x2c, 0xd6, 0xa5, 0x46, 0x69, 0xbb, 0xae, 0x66, 0xe2, 0xcf, 0x42, 0xa6, 0xf6, 0xb6, 0x54, - 0x06, 0x68, 0x81, 0x0d, 0x46, 0xe8, 0x05, 0xfa, 0x8d, 0x41, 0xbf, 0xb6, 0xba, 0x93, 0xd3, 0xc6, - 0x63, 0x7c, 0xb2, 0x86, 0x96, 0x69, 0x97, 0x04, 0xc0, 0xf6, 0x2a, 0x85, 0xba, 0xd4, 0x58, 0xd2, - 0xd7, 0x62, 0xf3, 0x96, 0x5b, 0x89, 0x00, 0x8f, 0x30, 0xca, 0x8f, 0x8b, 0x68, 0xa5, 0xe9, 0x99, - 0x2d, 0xa3, 0x0b, 0x66, 0x64, 0x5b, 0x6e, 0x47, 0xfe, 0x02, 0x2d, 0xb1, 0xf8, 0x9b, 0x24, 0x24, - 0xdc, 0xc1, 0xd2, 0xf6, 0x9d, 0x8c, 0x79, 0x69, 0x18, 0x55, 0xff, 0xa8, 0xc3, 0x36, 0xa8, 0xca, - 0xd0, 0xcc, 0xe0, 0x47, 0xed, 0x2f, 0xc1, 0x08, 0x1f, 0x42, 0x48, 0x74, 0x39, 0x3e, 0x13, 0x8d, - 0xf6, 0x70, 0xca, 0x2a, 0x7f, 0x84, 0x8a, 0xd4, 0x07, 0x23, 0x76, 0x5e, 0x53, 0x67, 0x5d, 0x3e, - 0x55, 0x30, 0xae, 0xe5, 0x83, 0xa1, 0x5f, 0x8b, 0xc9, 0x8b, 0x6c, 0x85, 0x39, 0x95, 0x7c, 0x88, - 0xae, 0xd2, 0x90, 0x84, 0x11, 0xe5, 0x4e, 0x97, 0xb6, 0xb7, 0xe6, 0x21, 0xe5, 0x8a, 0x7a, 0x39, - 0xa6, 0xbd, 0x3a, 0x5c, 0xe3, 0x98, 0x50, 0xf9, 0x59, 0x42, 0x6b, 0x02, 0xfe, 0x43, 0x8b, 0x86, - 0xf2, 0x67, 0x63, 0x51, 0x52, 0xcf, 0x16, 0x25, 0xa6, 0xcd, 0x63, 0xb4, 0x1a, 0x9f, 0xb7, 0x94, - 0xec, 0x64, 0x22, 0xd4, 0x44, 0x57, 0xac, 0x10, 0x1c, 0x76, 0x3f, 0x0a, 0x8d, 0xd2, 0xf6, 0x4b, - 0x73, 0x78, 0xa3, 0xaf, 0xc4, 0xbc, 0x57, 0xf6, 0x18, 0x03, 0x1e, 0x12, 0x29, 0xdf, 0xe6, 0xbd, - 0x60, 0xc1, 0x93, 0xef, 0xa2, 0x6b, 0x94, 0x5f, 0x31, 0x30, 0xd9, 0xfd, 0x89, 0x2f, 0xf4, 0x8d, - 0x98, 0xe1, 0x5a, 0x2b, 0x23, 0xc3, 0x02, 0x52, 0x7e, 0x13, 0x95, 0x7d, 0x2f, 0x04, 0x37, 0xb4, - 0x88, 0x9d, 0x5c, 0xe5, 0x42, 0x63, 0x59, 0x97, 0x59, 0x21, 0x34, 0x05, 0x09, 0xce, 0x21, 0x95, - 0xef, 0x25, 0xb4, 0x3e, 0x21, 0x03, 0xf2, 0x37, 0xa3, 0x02, 0xbb, 0x6f, 0x13, 0xcb, 0xa1, 0x15, - 0x89, 0xbb, 0xff, 0xd6, 0x6c, 0xf7, 0x71, 0x56, 0x67, 0x2c, 0xad, 0x63, 0xd5, 0x39, 0xa4, 0xc6, - 0xb9, 0xa3, 0x78, 0x21, 0x08, 0x90, 0xcb, 0x56, 0x08, 0xa2, 0x9b, 0xff, 0x51, 0x21, 0x88, 0xa4, - 0xb3, 0x0b, 0x61, 0x20, 0xa1, 0xaa, 0x80, 0xbf, 0xef, 0xb9, 0x34, 0x72, 0x20, 0xc0, 0xf0, 0x18, - 0x02, 0x70, 0x0d, 0x90, 0x5f, 0x46, 0x4b, 0xc4, 0xb7, 0x1e, 0x04, 0x5e, 0xe4, 0xc7, 0x77, 0x29, - 0xbd, 0xe5, 0x3b, 0xcd, 0x3d, 0xbe, 0x8f, 0x53, 0x04, 0x43, 0x27, 0x16, 0x71, 0x6b, 0x33, 0xe8, - 0xe4, 0x1c, 0x9c, 0x22, 0xe4, 0x3a, 0x2a, 0xba, 0xc4, 0x81, 0x4a, 0x91, 0x23, 0x53, 0xdf, 0xf7, - 0x89, 0x03, 0x98, 0x4b, 0x64, 0x1d, 0x15, 0x22, 0xcb, 0xac, 0x5c, 0xe1, 0x80, 0x3b, 0x31, 0xa0, - 0x70, 0xb0, 0xb7, 0xfb, 0xbc, 0x5f, 0x7b, 0x71, 0xda, 0x4b, 0x10, 0x3e, 0xf1, 0x81, 0xaa, 0x07, - 0x7b, 0xbb, 0x98, 0x29, 0xf3, 0x6a, 0x17, 0x9c, 0xbc, 0x74, 0xd5, 0x2e, 0x58, 0x37, 0xa5, 0xda, - 0x7f, 0x90, 0x50, 0x5d, 0xc0, 0x35, 0x49, 0x40, 0x1c, 0x08, 0x21, 0xa0, 0xe7, 0x4d, 0x56, 0x1d, - 0x15, 0x8f, 0x2c, 0xd7, 0xe4, 0x77, 0x35, 0x13, 0xfe, 0x0f, 0x2c, 0xd7, 0xc4, 0x5c, 0x92, 0x26, - 0xa8, 0x30, 0x2d, 0x41, 0xca, 0x53, 0x09, 0xdd, 0x9e, 0x59, 0xad, 0x29, 0x87, 0x34, 0x35, 0xc9, - 0xef, 0xa0, 0xeb, 0x91, 0x4b, 0x23, 0x2b, 0x64, 0xcf, 0x57, 0xb6, 0xf3, 0xac, 0x0f, 0xfa, 0xb5, - 0xeb, 0x07, 0xa2, 0x08, 0xe7, 0xb1, 0xca, 0x4f, 0x8b, 0xb9, 0xfc, 0xf2, 0x3e, 0xf8, 0x00, 0xad, - 0x65, 0xda, 0x01, 0xa5, 0xfb, 0x23, 0x1b, 0x6e, 0xc6, 0x36, 0x64, 0xb5, 0x86, 0x00, 0x3c, 0xae, - 0x23, 0x7f, 0x8d, 0x56, 0xfc, 0x6c, 0xa8, 0xe3, 0xd2, 0xbe, 0x37, 0x47, 0x4a, 0x27, 0xa4, 0x4a, - 0x5f, 0x1b, 0xf4, 0x6b, 0x2b, 0x82, 0x00, 0x8b, 0xe7, 0xc8, 0x4d, 0x54, 0x26, 0xe9, 0xc0, 0xf2, - 0x90, 0xf5, 0xf2, 0x61, 0x1a, 0x1a, 0x49, 0xfb, 0xdb, 0x11, 0xa4, 0xcf, 0xc7, 0x76, 0x70, 0x4e, - 0x5f, 0xf9, 0x6b, 0x11, 0xad, 0x4f, 0x68, 0x0f, 0xf2, 0x36, 0x42, 0x66, 0x60, 0xf5, 0x20, 0xc8, - 0x04, 0x29, 0x6d, 0x73, 0xbb, 0xa9, 0x04, 0x67, 0x50, 0xf2, 0xe7, 0x08, 0x8d, 0xd8, 0xe3, 0x98, - 0xa8, 0xb3, 0x63, 0x92, 0x1f, 0xbf, 0xf4, 0x32, 0xe3, 0xcf, 0xec, 0x66, 0x18, 0x65, 0x8a, 0x4a, - 0x01, 0x50, 0x08, 0x7a, 0x60, 0xbe, 0xe7, 0x05, 0x95, 0x02, 0xaf, 0xa3, 0xb7, 0xe7, 0x08, 0xfa, - 0x58, 0x2b, 0xd3, 0xd7, 0x63, 0x97, 0x4a, 0x78, 0x44, 0x8c, 0xb3, 0xa7, 0xc8, 0x2d, 0xb4, 0x61, - 0x02, 0xc9, 0x98, 0xf9, 0x55, 0x04, 0x34, 0x04, 0x93, 0x77, 0xa8, 0x25, 0xfd, 0x76, 0x4c, 0xb0, - 0xb1, 0x3b, 0x09, 0x84, 0x27, 0xeb, 0x2a, 0xbf, 0x49, 0x68, 0x43, 0xb0, 0xec, 0x63, 0x70, 0x7c, - 0x9b, 0x84, 0x70, 0x01, 0xcf, 0xd1, 0xa1, 0xf0, 0x1c, 0xbd, 0x31, 0x47, 0xf8, 0x12, 0x23, 0xa7, - 0x3d, 0x4b, 0xca, 0xaf, 0x12, 0xba, 0x39, 0x51, 0xe3, 0x02, 0xda, 0xeb, 0x27, 0x62, 0x7b, 0x7d, - 0xf5, 0x1c, 0x7e, 0x4d, 0x69, 0xb3, 0x27, 0xd3, 0xbc, 0xe2, 0x4d, 0xe5, 0xff, 0x38, 0x3f, 0x28, - 0x7f, 0x8b, 0x63, 0x10, 0xa5, 0x17, 0xe0, 0x86, 0xd8, 0x51, 0x16, 0xcf, 0xd4, 0x51, 0xc6, 0x1a, - 0x6d, 0x61, 0xce, 0x46, 0x4b, 0xe9, 0xf9, 0x1a, 0xed, 0x21, 0x5a, 0x11, 0x5f, 0x9f, 0xe2, 0x19, - 0x3f, 0xe1, 0x38, 0x75, 0x4b, 0x78, 0x9d, 0x44, 0xa6, 0xfc, 0xec, 0x41, 0xe9, 0x65, 0x9e, 0x3d, - 0x28, 0x9d, 0x52, 0x14, 0xbf, 0x88, 0xb3, 0xc7, 0xc4, 0x38, 0x5f, 0xfc, 0xec, 0xc1, 0xbe, 0x8c, - 0xd9, 0x5f, 0xea, 0x13, 0x23, 0x99, 0x21, 0xd3, 0x2f, 0xe3, 0xfd, 0x44, 0x80, 0x47, 0x18, 0x5d, - 0x3f, 0x3e, 0xad, 0x2e, 0x9c, 0x9c, 0x56, 0x17, 0x9e, 0x9d, 0x56, 0x17, 0x9e, 0x0e, 0xaa, 0xd2, - 0xf1, 0xa0, 0x2a, 0x9d, 0x0c, 0xaa, 0xd2, 0xb3, 0x41, 0x55, 0xfa, 0x7d, 0x50, 0x95, 0xbe, 0xfb, - 0xa3, 0xba, 0xf0, 0xe9, 0xad, 0x59, 0xbf, 0xb3, 0xfc, 0x13, 0x00, 0x00, 0xff, 0xff, 0xe7, 0x0a, - 0x8b, 0x49, 0x9f, 0x11, 0x00, 0x00, +var fileDescriptor_3add37bbd52889e0 = []byte{ + // 1233 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0x4f, 0x6f, 0x1b, 0x45, + 0x14, 0xcf, 0xda, 0x6e, 0x95, 0x4c, 0x1a, 0x37, 0xd9, 0xb6, 0xe0, 0x46, 0xad, 0x63, 0xf6, 0x14, + 0x89, 0xb2, 0xdb, 0x06, 0x54, 0x2a, 0xfe, 0x49, 0xd9, 0x06, 0x4a, 0x04, 0x4d, 0xc3, 0x98, 0x8a, + 0x16, 0x21, 0xd4, 0xc9, 0xee, 0xab, 0xbd, 0x64, 0xff, 0xb1, 0x33, 0x6b, 0xa8, 0xb8, 0xf4, 0x23, + 0xf4, 0xc0, 0x01, 0x4e, 0x1c, 0xf9, 0x02, 0x7c, 0x03, 0x84, 0xd4, 0x63, 0x11, 0x1c, 0x7a, 0xb2, + 0xa8, 0xf9, 0x08, 0x9c, 0xe8, 0x09, 0xcd, 0x78, 0x77, 0xbd, 0xb3, 0xf6, 0x9a, 0x38, 0x07, 0x0b, + 0x4e, 0xc9, 0xcc, 0xfb, 0xbd, 0xdf, 0xfb, 0x37, 0xef, 0xcd, 0xac, 0xd1, 0xbb, 0x87, 0xd7, 0xa8, + 0xee, 0x04, 0xc6, 0x61, 0x7c, 0x00, 0x91, 0x0f, 0x0c, 0xa8, 0xd1, 0x03, 0xdf, 0x0e, 0x22, 0x23, + 0x11, 0x90, 0xd0, 0x31, 0x22, 0xa0, 0x41, 0x1c, 0x59, 0x60, 0xf4, 0xae, 0x10, 0x37, 0xec, 0x92, + 0x2d, 0xa3, 0x03, 0x3e, 0x44, 0x84, 0x81, 0xad, 0x87, 0x51, 0xc0, 0x02, 0xf5, 0xc2, 0x10, 0xad, + 0x93, 0xd0, 0xd1, 0x53, 0xb4, 0x9e, 0xa2, 0xd7, 0x5f, 0xe9, 0x38, 0xac, 0x1b, 0x1f, 0xe8, 0x56, + 0xe0, 0x19, 0x9d, 0xa0, 0x13, 0x18, 0x42, 0xe9, 0x20, 0xbe, 0x2f, 0x56, 0x62, 0x21, 0xfe, 0x1b, + 0x92, 0xad, 0x6b, 0x39, 0xd3, 0x56, 0x10, 0x71, 0xb3, 0x45, 0x83, 0xeb, 0xaf, 0x8d, 0x30, 0x1e, + 0xb1, 0xba, 0x8e, 0x0f, 0xd1, 0x03, 0x23, 0x3c, 0xec, 0xf0, 0x0d, 0x6a, 0x78, 0xc0, 0xc8, 0x24, + 0x2d, 0xa3, 0x4c, 0x2b, 0x8a, 0x7d, 0xe6, 0x78, 0x30, 0xa6, 0x70, 0xf5, 0xdf, 0x14, 0xa8, 0xd5, + 0x05, 0x8f, 0x14, 0xf5, 0xb4, 0xef, 0x2a, 0x68, 0x75, 0xdb, 0x75, 0x03, 0x8b, 0x30, 0x27, 0xf0, + 0x31, 0xd0, 0xd8, 0x65, 0x6a, 0x80, 0x4e, 0xa7, 0xb9, 0x79, 0x9f, 0xf8, 0xb6, 0x0b, 0xb4, 0xa1, + 0xb4, 0xaa, 0x9b, 0xcb, 0x5b, 0x97, 0xf4, 0x69, 0xe9, 0xd3, 0xb1, 0xa4, 0x64, 0xbe, 0xf8, 0xb8, + 0xbf, 0xb1, 0x30, 0xe8, 0x6f, 0x9c, 0x96, 0xf7, 0x29, 0x2e, 0xb2, 0xab, 0x07, 0x68, 0x95, 0xf4, + 0x88, 0xe3, 0x92, 0x03, 0x17, 0x6e, 0xf9, 0x7b, 0x81, 0x0d, 0xb4, 0x51, 0x69, 0x29, 0x9b, 0xcb, + 0x5b, 0xad, 0xbc, 0x45, 0x9e, 0x63, 0xbd, 0x77, 0x45, 0xe7, 0x80, 0x36, 0xb8, 0x60, 0xb1, 0x20, + 0x32, 0xcf, 0x0e, 0xfa, 0x1b, 0xab, 0xdb, 0x05, 0x6d, 0x3c, 0xc6, 0xa7, 0x1a, 0x68, 0x89, 0x76, + 0x49, 0x04, 0x7c, 0xaf, 0x51, 0x6d, 0x29, 0x9b, 0x8b, 0xe6, 0x5a, 0xe2, 0xe0, 0x52, 0x3b, 0x15, + 0xe0, 0x11, 0x46, 0xfb, 0xa9, 0x82, 0xce, 0xee, 0x07, 0x76, 0xdb, 0xea, 0x82, 0x1d, 0xbb, 0x8e, + 0xdf, 0xb9, 0x1e, 0xf8, 0x0c, 0xbe, 0x66, 0xea, 0x3d, 0xb4, 0xc8, 0xeb, 0x66, 0x13, 0x46, 0x1a, + 0x8a, 0xf0, 0xf2, 0x72, 0xce, 0xcb, 0x2c, 0xfd, 0x7a, 0x78, 0xd8, 0xe1, 0x1b, 0x54, 0xe7, 0x68, + 0xee, 0xf7, 0xad, 0x83, 0x2f, 0xc0, 0x62, 0x37, 0x81, 0x11, 0x53, 0x4d, 0x4c, 0xa3, 0xd1, 0x1e, + 0xce, 0x58, 0xd5, 0x3b, 0xa8, 0x46, 0x43, 0xb0, 0x92, 0x1c, 0x5c, 0x9d, 0x9e, 0xf5, 0x49, 0x3e, + 0xb6, 0x43, 0xb0, 0xcc, 0x53, 0x89, 0x8d, 0x1a, 0x5f, 0x61, 0xc1, 0xa8, 0xde, 0x43, 0x27, 0x29, + 0x23, 0x2c, 0xa6, 0x22, 0x05, 0xcb, 0x5b, 0xd7, 0x8e, 0xc1, 0x2d, 0xf4, 0xcd, 0x7a, 0xc2, 0x7e, + 0x72, 0xb8, 0xc6, 0x09, 0xaf, 0xf6, 0xab, 0x82, 0x1a, 0x93, 0xd4, 0x3e, 0x74, 0x28, 0x53, 0x3f, + 0x1b, 0x4b, 0x9d, 0x7e, 0xb4, 0xd4, 0x71, 0x6d, 0x91, 0xb8, 0xd5, 0xc4, 0xec, 0x62, 0xba, 0x93, + 0x4b, 0xdb, 0x27, 0xe8, 0x84, 0xc3, 0xc0, 0xe3, 0x67, 0x87, 0x9f, 0xd6, 0xad, 0xd9, 0x63, 0x33, + 0x57, 0x12, 0xfa, 0x13, 0xbb, 0x9c, 0x08, 0x0f, 0xf9, 0xb4, 0x47, 0x25, 0x31, 0xf1, 0xc4, 0xaa, + 0xd7, 0xd0, 0x29, 0x2a, 0x0e, 0x23, 0xd8, 0xfc, 0xa4, 0x89, 0xb8, 0x96, 0xcc, 0xb3, 0x09, 0xd1, + 0xa9, 0x76, 0x4e, 0x86, 0x25, 0xa4, 0xfa, 0x06, 0xaa, 0x87, 0x01, 0x03, 0x9f, 0x39, 0xc4, 0x4d, + 0x0f, 0x7d, 0x75, 0x73, 0xc9, 0x54, 0x07, 0xfd, 0x8d, 0xfa, 0xbe, 0x24, 0xc1, 0x05, 0xa4, 0xf6, + 0xbd, 0x82, 0xd6, 0xcb, 0xab, 0xa3, 0x7e, 0x83, 0xea, 0x69, 0xc4, 0xd7, 0x5d, 0xe2, 0x78, 0x69, + 0x07, 0xbf, 0x79, 0xb4, 0x0e, 0x16, 0x3a, 0x23, 0xee, 0xa4, 0xe4, 0x2f, 0x24, 0x31, 0xd5, 0x25, + 0x18, 0xc5, 0x05, 0x53, 0xda, 0x0f, 0x15, 0xb4, 0x22, 0x41, 0xe6, 0xd0, 0x32, 0x1f, 0x49, 0x2d, + 0x63, 0xcc, 0x12, 0x66, 0x59, 0xaf, 0xdc, 0x2d, 0xf4, 0xca, 0x95, 0x59, 0x48, 0xa7, 0x37, 0xc9, + 0x40, 0x41, 0x4d, 0x09, 0x7f, 0x3d, 0xf0, 0x69, 0xec, 0x41, 0x84, 0xe1, 0x3e, 0x44, 0xe0, 0x5b, + 0xa0, 0x5e, 0x42, 0x8b, 0x24, 0x74, 0x6e, 0x44, 0x41, 0x1c, 0x26, 0x47, 0x2a, 0x3b, 0xfa, 0xdb, + 0xfb, 0xbb, 0x62, 0x1f, 0x67, 0x08, 0x8e, 0x4e, 0x3d, 0x12, 0xde, 0xe6, 0xd0, 0xa9, 0x1d, 0x9c, + 0x21, 0xd4, 0x16, 0xaa, 0xf9, 0xc4, 0x83, 0x46, 0x4d, 0x20, 0xb3, 0xd8, 0xf7, 0x88, 0x07, 0x58, + 0x48, 0x54, 0x13, 0x55, 0x63, 0xc7, 0x6e, 0x9c, 0x10, 0x80, 0xcb, 0x09, 0xa0, 0x7a, 0x7b, 0x77, + 0xe7, 0x79, 0x7f, 0xe3, 0xa5, 0xb2, 0xbb, 0x86, 0x3d, 0x08, 0x81, 0xea, 0xb7, 0x77, 0x77, 0x30, + 0x57, 0xd6, 0x7e, 0x56, 0xd0, 0x9a, 0x14, 0xe4, 0x1c, 0x46, 0xc0, 0xbe, 0x3c, 0x02, 0x5e, 0x9e, + 0xa1, 0x64, 0x25, 0xbd, 0xff, 0xad, 0x82, 0x5a, 0x12, 0x6e, 0x9f, 0x44, 0xc4, 0x03, 0x06, 0x11, + 0x3d, 0x6e, 0xb1, 0x5a, 0xa8, 0x76, 0xe8, 0xf8, 0xb6, 0x38, 0xab, 0xb9, 0xf4, 0x7f, 0xe0, 0xf8, + 0x36, 0x16, 0x92, 0xac, 0x40, 0xd5, 0xb2, 0x02, 0x69, 0x0f, 0x15, 0x74, 0x71, 0x6a, 0xb7, 0x66, + 0x1c, 0x4a, 0x69, 0x91, 0xdf, 0x46, 0xa7, 0x63, 0x9f, 0xc6, 0x0e, 0xe3, 0xf7, 0x5d, 0x7e, 0x00, + 0x9d, 0xe1, 0xb7, 0xf6, 0x6d, 0x59, 0x84, 0x8b, 0x58, 0xed, 0xc7, 0x4a, 0xa1, 0xbe, 0x62, 0x1c, + 0xde, 0x40, 0x6b, 0xb9, 0x71, 0x40, 0xe9, 0xde, 0xc8, 0x87, 0xf3, 0x89, 0x0f, 0x79, 0xad, 0x21, + 0x00, 0x8f, 0xeb, 0xa8, 0x5f, 0xa1, 0x95, 0x30, 0x9f, 0xea, 0xa4, 0xb5, 0xdf, 0x99, 0xa1, 0xa4, + 0x13, 0x4a, 0x65, 0xae, 0x0d, 0xfa, 0x1b, 0x2b, 0x92, 0x00, 0xcb, 0x76, 0xd4, 0x7d, 0x54, 0x27, + 0xd9, 0x93, 0xe8, 0x26, 0x1f, 0xe9, 0xc3, 0x32, 0x6c, 0xa6, 0xe3, 0x6f, 0x5b, 0x92, 0x3e, 0x1f, + 0xdb, 0xc1, 0x05, 0x7d, 0xed, 0xaf, 0x0a, 0x3a, 0x33, 0x61, 0x3c, 0xa8, 0x5b, 0x08, 0xd9, 0x91, + 0xd3, 0x83, 0x28, 0x97, 0xa4, 0x6c, 0xcc, 0xed, 0x64, 0x12, 0x9c, 0x43, 0xa9, 0x9f, 0x23, 0x34, + 0x62, 0x4f, 0x72, 0xa2, 0x4f, 0xcf, 0x49, 0xf1, 0x81, 0x67, 0xd6, 0x39, 0x7f, 0x6e, 0x37, 0xc7, + 0xa8, 0x52, 0xb4, 0x1c, 0x01, 0x85, 0xa8, 0x07, 0xf6, 0x7b, 0x41, 0xd4, 0xa8, 0x8a, 0x3e, 0x7a, + 0x6b, 0x86, 0xa4, 0x8f, 0x8d, 0x32, 0xf3, 0x4c, 0x12, 0xd2, 0x32, 0x1e, 0x11, 0xe3, 0xbc, 0x15, + 0xb5, 0x8d, 0xce, 0xd9, 0x40, 0x72, 0x6e, 0x7e, 0x19, 0x03, 0x65, 0x60, 0x8b, 0x09, 0xb5, 0x68, + 0x5e, 0x4c, 0x08, 0xce, 0xed, 0x4c, 0x02, 0xe1, 0xc9, 0xba, 0xda, 0xef, 0x0a, 0x3a, 0x27, 0x79, + 0xf6, 0x31, 0x78, 0xa1, 0x4b, 0x18, 0xcc, 0xe1, 0x3a, 0xba, 0x2b, 0x5d, 0x47, 0xaf, 0xcf, 0x90, + 0xbe, 0xd4, 0xc9, 0xb2, 0x6b, 0x49, 0xfb, 0x4d, 0x41, 0xe7, 0x27, 0x6a, 0xcc, 0x61, 0xbc, 0xde, + 0x91, 0xc7, 0xeb, 0xab, 0xc7, 0x88, 0xab, 0x64, 0xcc, 0x3e, 0x29, 0x8b, 0xaa, 0x3d, 0x7c, 0xb6, + 0xfe, 0xff, 0xde, 0x0f, 0xda, 0xdf, 0xf2, 0x33, 0x88, 0xd2, 0x39, 0x84, 0x21, 0x4f, 0x94, 0xca, + 0x91, 0x26, 0xca, 0xd8, 0xa0, 0xad, 0xce, 0x38, 0x68, 0x29, 0x3d, 0xde, 0xa0, 0xbd, 0x8b, 0x56, + 0xe4, 0xdb, 0xa7, 0x76, 0xc4, 0x6f, 0x3e, 0x41, 0xdd, 0x96, 0x6e, 0x27, 0x99, 0xa9, 0xf8, 0xf6, + 0xa0, 0xf4, 0xbf, 0xfc, 0xf6, 0xa0, 0xb4, 0xa4, 0x29, 0x7e, 0x91, 0xdf, 0x1e, 0x13, 0xf3, 0x3c, + 0xff, 0xb7, 0x07, 0xff, 0x94, 0xe6, 0x7f, 0x69, 0x48, 0xac, 0xf4, 0x0d, 0x99, 0x7d, 0x4a, 0xef, + 0xa5, 0x02, 0x3c, 0xc2, 0x68, 0xf7, 0x51, 0x5d, 0xfe, 0x0d, 0xe0, 0x58, 0x37, 0x5f, 0x0b, 0xd5, + 0x44, 0xe5, 0x0a, 0xae, 0xef, 0x10, 0x46, 0xb0, 0x90, 0x98, 0xe6, 0xe3, 0x67, 0xcd, 0x85, 0x27, + 0xcf, 0x9a, 0x0b, 0x4f, 0x9f, 0x35, 0x17, 0x1e, 0x0e, 0x9a, 0xca, 0xe3, 0x41, 0x53, 0x79, 0x32, + 0x68, 0x2a, 0x4f, 0x07, 0x4d, 0xe5, 0x8f, 0x41, 0x53, 0x79, 0xf4, 0x67, 0x73, 0xe1, 0xd3, 0x0b, + 0xd3, 0x7e, 0x31, 0xfa, 0x27, 0x00, 0x00, 0xff, 0xff, 0x67, 0xe4, 0xf6, 0x18, 0x69, 0x12, 0x00, + 0x00, } func (m *AllocationResult) Marshal() (dAtA []byte, err error) { @@ -693,15 +726,24 @@ func (m *AllocationResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - i -= len(m.ResourceHandle) - copy(dAtA[i:], m.ResourceHandle) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceHandle))) - i-- - dAtA[i] = 0xa + if len(m.ResourceHandles) > 0 { + for iNdEx := len(m.ResourceHandles) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ResourceHandles[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 (m *PodScheduling) Marshal() (dAtA []byte, err error) { +func (m *PodSchedulingContext) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -711,12 +753,12 @@ func (m *PodScheduling) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PodScheduling) MarshalTo(dAtA []byte) (int, error) { +func (m *PodSchedulingContext) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PodScheduling) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *PodSchedulingContext) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -754,7 +796,7 @@ func (m *PodScheduling) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *PodSchedulingList) Marshal() (dAtA []byte, err error) { +func (m *PodSchedulingContextList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -764,12 +806,12 @@ func (m *PodSchedulingList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PodSchedulingList) MarshalTo(dAtA []byte) (int, error) { +func (m *PodSchedulingContextList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PodSchedulingList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *PodSchedulingContextList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -801,7 +843,7 @@ func (m *PodSchedulingList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *PodSchedulingSpec) Marshal() (dAtA []byte, err error) { +func (m *PodSchedulingContextSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -811,12 +853,12 @@ func (m *PodSchedulingSpec) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PodSchedulingSpec) MarshalTo(dAtA []byte) (int, error) { +func (m *PodSchedulingContextSpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PodSchedulingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *PodSchedulingContextSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -838,7 +880,7 @@ func (m *PodSchedulingSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *PodSchedulingStatus) Marshal() (dAtA []byte, err error) { +func (m *PodSchedulingContextStatus) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -848,12 +890,12 @@ func (m *PodSchedulingStatus) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PodSchedulingStatus) MarshalTo(dAtA []byte) (int, error) { +func (m *PodSchedulingContextStatus) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PodSchedulingStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *PodSchedulingContextStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1485,6 +1527,39 @@ func (m *ResourceClassParametersReference) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } +func (m *ResourceHandle) 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 *ResourceHandle) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceHandle) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x12 + i -= len(m.DriverName) + copy(dAtA[i:], m.DriverName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DriverName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { offset -= sovGenerated(v) base := offset @@ -1502,8 +1577,12 @@ func (m *AllocationResult) Size() (n int) { } var l int _ = l - l = len(m.ResourceHandle) - n += 1 + l + sovGenerated(uint64(l)) + if len(m.ResourceHandles) > 0 { + for _, e := range m.ResourceHandles { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } if m.AvailableOnNodes != nil { l = m.AvailableOnNodes.Size() n += 1 + l + sovGenerated(uint64(l)) @@ -1512,7 +1591,7 @@ func (m *AllocationResult) Size() (n int) { return n } -func (m *PodScheduling) Size() (n int) { +func (m *PodSchedulingContext) Size() (n int) { if m == nil { return 0 } @@ -1527,7 +1606,7 @@ func (m *PodScheduling) Size() (n int) { return n } -func (m *PodSchedulingList) Size() (n int) { +func (m *PodSchedulingContextList) Size() (n int) { if m == nil { return 0 } @@ -1544,7 +1623,7 @@ func (m *PodSchedulingList) Size() (n int) { return n } -func (m *PodSchedulingSpec) Size() (n int) { +func (m *PodSchedulingContextSpec) Size() (n int) { if m == nil { return 0 } @@ -1561,7 +1640,7 @@ func (m *PodSchedulingSpec) Size() (n int) { return n } -func (m *PodSchedulingStatus) Size() (n int) { +func (m *PodSchedulingContextStatus) Size() (n int) { if m == nil { return 0 } @@ -1794,6 +1873,19 @@ func (m *ResourceClassParametersReference) Size() (n int) { return n } +func (m *ResourceHandle) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DriverName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Data) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func sovGenerated(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1804,54 +1896,59 @@ func (this *AllocationResult) String() string { if this == nil { return "nil" } + repeatedStringForResourceHandles := "[]ResourceHandle{" + for _, f := range this.ResourceHandles { + repeatedStringForResourceHandles += strings.Replace(strings.Replace(f.String(), "ResourceHandle", "ResourceHandle", 1), `&`, ``, 1) + "," + } + repeatedStringForResourceHandles += "}" s := strings.Join([]string{`&AllocationResult{`, - `ResourceHandle:` + fmt.Sprintf("%v", this.ResourceHandle) + `,`, + `ResourceHandles:` + repeatedStringForResourceHandles + `,`, `AvailableOnNodes:` + strings.Replace(fmt.Sprintf("%v", this.AvailableOnNodes), "NodeSelector", "v1.NodeSelector", 1) + `,`, `Shareable:` + fmt.Sprintf("%v", this.Shareable) + `,`, `}`, }, "") return s } -func (this *PodScheduling) String() string { +func (this *PodSchedulingContext) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&PodScheduling{`, + s := strings.Join([]string{`&PodSchedulingContext{`, `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v11.ObjectMeta", 1), `&`, ``, 1) + `,`, - `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "PodSchedulingSpec", "PodSchedulingSpec", 1), `&`, ``, 1) + `,`, - `Status:` + strings.Replace(strings.Replace(this.Status.String(), "PodSchedulingStatus", "PodSchedulingStatus", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "PodSchedulingContextSpec", "PodSchedulingContextSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "PodSchedulingContextStatus", "PodSchedulingContextStatus", 1), `&`, ``, 1) + `,`, `}`, }, "") return s } -func (this *PodSchedulingList) String() string { +func (this *PodSchedulingContextList) String() string { if this == nil { return "nil" } - repeatedStringForItems := "[]PodScheduling{" + repeatedStringForItems := "[]PodSchedulingContext{" for _, f := range this.Items { - repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "PodScheduling", "PodScheduling", 1), `&`, ``, 1) + "," + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "PodSchedulingContext", "PodSchedulingContext", 1), `&`, ``, 1) + "," } repeatedStringForItems += "}" - s := strings.Join([]string{`&PodSchedulingList{`, + s := strings.Join([]string{`&PodSchedulingContextList{`, `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v11.ListMeta", 1), `&`, ``, 1) + `,`, `Items:` + repeatedStringForItems + `,`, `}`, }, "") return s } -func (this *PodSchedulingSpec) String() string { +func (this *PodSchedulingContextSpec) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&PodSchedulingSpec{`, + s := strings.Join([]string{`&PodSchedulingContextSpec{`, `SelectedNode:` + fmt.Sprintf("%v", this.SelectedNode) + `,`, `PotentialNodes:` + fmt.Sprintf("%v", this.PotentialNodes) + `,`, `}`, }, "") return s } -func (this *PodSchedulingStatus) String() string { +func (this *PodSchedulingContextStatus) String() string { if this == nil { return "nil" } @@ -1860,7 +1957,7 @@ func (this *PodSchedulingStatus) String() string { repeatedStringForResourceClaims += strings.Replace(strings.Replace(f.String(), "ResourceClaimSchedulingStatus", "ResourceClaimSchedulingStatus", 1), `&`, ``, 1) + "," } repeatedStringForResourceClaims += "}" - s := strings.Join([]string{`&PodSchedulingStatus{`, + s := strings.Join([]string{`&PodSchedulingContextStatus{`, `ResourceClaims:` + repeatedStringForResourceClaims + `,`, `}`, }, "") @@ -2040,6 +2137,17 @@ func (this *ResourceClassParametersReference) String() string { }, "") return s } +func (this *ResourceHandle) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ResourceHandle{`, + `DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`, + `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `}`, + }, "") + return s +} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -2079,9 +2187,9 @@ func (m *AllocationResult) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ResourceHandle", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ResourceHandles", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -2091,23 +2199,25 @@ func (m *AllocationResult) 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.ResourceHandle = string(dAtA[iNdEx:postIndex]) + m.ResourceHandles = append(m.ResourceHandles, ResourceHandle{}) + if err := m.ResourceHandles[len(m.ResourceHandles)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { @@ -2186,7 +2296,7 @@ func (m *AllocationResult) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodScheduling) Unmarshal(dAtA []byte) error { +func (m *PodSchedulingContext) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2209,10 +2319,10 @@ func (m *PodScheduling) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodScheduling: wiretype end group for non-group") + return fmt.Errorf("proto: PodSchedulingContext: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodScheduling: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PodSchedulingContext: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2335,7 +2445,7 @@ func (m *PodScheduling) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodSchedulingList) Unmarshal(dAtA []byte) error { +func (m *PodSchedulingContextList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2358,10 +2468,10 @@ func (m *PodSchedulingList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodSchedulingList: wiretype end group for non-group") + return fmt.Errorf("proto: PodSchedulingContextList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodSchedulingList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PodSchedulingContextList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2426,7 +2536,7 @@ func (m *PodSchedulingList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, PodScheduling{}) + m.Items = append(m.Items, PodSchedulingContext{}) if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -2452,7 +2562,7 @@ func (m *PodSchedulingList) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodSchedulingSpec) Unmarshal(dAtA []byte) error { +func (m *PodSchedulingContextSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2475,10 +2585,10 @@ func (m *PodSchedulingSpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodSchedulingSpec: wiretype end group for non-group") + return fmt.Errorf("proto: PodSchedulingContextSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodSchedulingSpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PodSchedulingContextSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2566,7 +2676,7 @@ func (m *PodSchedulingSpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *PodSchedulingStatus) Unmarshal(dAtA []byte) error { +func (m *PodSchedulingContextStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2589,10 +2699,10 @@ func (m *PodSchedulingStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PodSchedulingStatus: wiretype end group for non-group") + return fmt.Errorf("proto: PodSchedulingContextStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PodSchedulingStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PodSchedulingContextStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -4507,6 +4617,120 @@ func (m *ResourceClassParametersReference) Unmarshal(dAtA []byte) error { } return nil } +func (m *ResourceHandle) 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: ResourceHandle: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ResourceHandle: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DriverName", 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.DriverName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", 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.Data = 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 skipGenerated(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/vendor/k8s.io/api/resource/v1alpha1/generated.proto b/vendor/k8s.io/api/resource/v1alpha2/generated.proto similarity index 79% rename from vendor/k8s.io/api/resource/v1alpha1/generated.proto rename to vendor/k8s.io/api/resource/v1alpha2/generated.proto index 2e814d155..02412398c 100644 --- a/vendor/k8s.io/api/resource/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/resource/v1alpha2/generated.proto @@ -19,7 +19,7 @@ limitations under the License. syntax = "proto2"; -package k8s.io.api.resource.v1alpha1; +package k8s.io.api.resource.v1alpha2; import "k8s.io/api/core/v1/generated.proto"; import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto"; @@ -27,23 +27,30 @@ import "k8s.io/apimachinery/pkg/runtime/generated.proto"; import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto"; // Package-wide variables from generator "generated". -option go_package = "k8s.io/api/resource/v1alpha1"; +option go_package = "k8s.io/api/resource/v1alpha2"; -// AllocationResult contains attributed of an allocated resource. +// AllocationResult contains attributes of an allocated resource. message AllocationResult { - // ResourceHandle contains arbitrary data returned by the driver after a - // successful allocation. This is opaque for - // Kubernetes. Driver documentation may explain to users how to - // interpret this data if needed. + // ResourceHandles contain the state associated with an allocation that + // should be maintained throughout the lifetime of a claim. Each + // ResourceHandle contains data that should be passed to a specific kubelet + // plugin once it lands on a node. This data is returned by the driver + // after a successful allocation and is opaque to Kubernetes. Driver + // documentation may explain to users how to interpret this data if needed. // - // The maximum size of this field is 16KiB. This may get - // increased in the future, but not reduced. + // Setting this field is optional. It has a maximum size of 32 entries. + // If null (or empty), it is assumed this allocation will be processed by a + // single kubelet plugin with no ResourceHandle data attached. The name of + // the kubelet plugin invoked will match the DriverName set in the + // ResourceClaimStatus this AllocationResult is embedded in. + // + // +listType=atomic // +optional - optional string resourceHandle = 1; + repeated ResourceHandle resourceHandles = 1; - // This field will get set by the resource driver after it has - // allocated the resource driver to inform the scheduler where it can - // schedule Pods using the ResourceClaim. + // This field will get set by the resource driver after it has allocated + // the resource to inform the scheduler where it can schedule Pods using + // the ResourceClaim. // // Setting this field is optional. If null, the resource is available // everywhere. @@ -56,37 +63,37 @@ message AllocationResult { optional bool shareable = 3; } -// PodScheduling objects hold information that is needed to schedule +// PodSchedulingContext objects hold information that is needed to schedule // a Pod with ResourceClaims that use "WaitForFirstConsumer" allocation // mode. // // This is an alpha type and requires enabling the DynamicResourceAllocation // feature gate. -message PodScheduling { +message PodSchedulingContext { // Standard object metadata // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; // Spec describes where resources for the Pod are needed. - optional PodSchedulingSpec spec = 2; + optional PodSchedulingContextSpec spec = 2; // Status describes where resources for the Pod can be allocated. // +optional - optional PodSchedulingStatus status = 3; + optional PodSchedulingContextStatus status = 3; } -// PodSchedulingList is a collection of Pod scheduling objects. -message PodSchedulingList { +// PodSchedulingContextList is a collection of Pod scheduling objects. +message PodSchedulingContextList { // Standard list metadata // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of PodScheduling objects. - repeated PodScheduling items = 2; + // Items is the list of PodSchedulingContext objects. + repeated PodSchedulingContext items = 2; } -// PodSchedulingSpec describes where resources for the Pod are needed. -message PodSchedulingSpec { +// PodSchedulingContextSpec describes where resources for the Pod are needed. +message PodSchedulingContextSpec { // SelectedNode is the node for which allocation of ResourceClaims that // are referenced by the Pod and that use "WaitForFirstConsumer" // allocation is to be attempted. @@ -105,8 +112,8 @@ message PodSchedulingSpec { repeated string potentialNodes = 2; } -// PodSchedulingStatus describes where resources for the Pod can be allocated. -message PodSchedulingStatus { +// PodSchedulingContextStatus describes where resources for the Pod can be allocated. +message PodSchedulingContextStatus { // ResourceClaims describes resource availability for each // pod.spec.resourceClaim entry where the corresponding ResourceClaim // uses "WaitForFirstConsumer" allocation mode. @@ -235,9 +242,9 @@ message ResourceClaimStatus { // +optional optional string driverName = 1; - // Allocation is set by the resource driver once a resource has been - // allocated successfully. If this is not specified, the resource is - // not yet allocated. + // Allocation is set by the resource driver once a resource or set of + // resources has been allocated successfully. If this is not specified, the + // resources have not been allocated yet. // +optional optional AllocationResult allocation = 2; @@ -370,3 +377,24 @@ message ResourceClassParametersReference { optional string namespace = 4; } +// ResourceHandle holds opaque resource data for processing by a specific kubelet plugin. +message ResourceHandle { + // DriverName specifies the name of the resource driver whose kubelet + // plugin should be invoked to process this ResourceHandle's data once it + // lands on a node. This may differ from the DriverName set in + // ResourceClaimStatus this ResourceHandle is embedded in. + optional string driverName = 1; + + // Data contains the opaque data associated with this ResourceHandle. It is + // set by the controller component of the resource driver whose name + // matches the DriverName set in the ResourceClaimStatus this + // ResourceHandle is embedded in. It is set at allocation time and is + // intended for processing by the kubelet plugin whose name matches + // the DriverName set in this ResourceHandle. + // + // The maximum size of this field is 16KiB. This may get increased in the + // future, but not reduced. + // +optional + optional string data = 2; +} + diff --git a/vendor/k8s.io/api/resource/v1alpha1/register.go b/vendor/k8s.io/api/resource/v1alpha2/register.go similarity index 95% rename from vendor/k8s.io/api/resource/v1alpha1/register.go rename to vendor/k8s.io/api/resource/v1alpha2/register.go index 8245b9aee..6e0d7ceb9 100644 --- a/vendor/k8s.io/api/resource/v1alpha1/register.go +++ b/vendor/k8s.io/api/resource/v1alpha2/register.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha1 +package v1alpha2 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,7 +26,7 @@ import ( const GroupName = "resource.k8s.io" // SchemeGroupVersion is group version used to register these objects -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"} // Resource takes an unqualified resource and returns a Group qualified GroupResource func Resource(resource string) schema.GroupResource { @@ -50,8 +50,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ResourceClaimList{}, &ResourceClaimTemplate{}, &ResourceClaimTemplateList{}, - &PodScheduling{}, - &PodSchedulingList{}, + &PodSchedulingContext{}, + &PodSchedulingContextList{}, ) // Add common types diff --git a/vendor/k8s.io/api/resource/v1alpha1/types.go b/vendor/k8s.io/api/resource/v1alpha2/types.go similarity index 81% rename from vendor/k8s.io/api/resource/v1alpha1/types.go rename to vendor/k8s.io/api/resource/v1alpha2/types.go index af5703840..21936bfe3 100644 --- a/vendor/k8s.io/api/resource/v1alpha1/types.go +++ b/vendor/k8s.io/api/resource/v1alpha2/types.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha1 +package v1alpha2 import ( v1 "k8s.io/api/core/v1" @@ -99,9 +99,9 @@ type ResourceClaimStatus struct { // +optional DriverName string `json:"driverName,omitempty" protobuf:"bytes,1,opt,name=driverName"` - // Allocation is set by the resource driver once a resource has been - // allocated successfully. If this is not specified, the resource is - // not yet allocated. + // Allocation is set by the resource driver once a resource or set of + // resources has been allocated successfully. If this is not specified, the + // resources have not been allocated yet. // +optional Allocation *AllocationResult `json:"allocation,omitempty" protobuf:"bytes,2,opt,name=allocation"` @@ -133,21 +133,28 @@ type ResourceClaimStatus struct { // claim.status.reservedFor. const ResourceClaimReservedForMaxSize = 32 -// AllocationResult contains attributed of an allocated resource. +// AllocationResult contains attributes of an allocated resource. type AllocationResult struct { - // ResourceHandle contains arbitrary data returned by the driver after a - // successful allocation. This is opaque for - // Kubernetes. Driver documentation may explain to users how to - // interpret this data if needed. + // ResourceHandles contain the state associated with an allocation that + // should be maintained throughout the lifetime of a claim. Each + // ResourceHandle contains data that should be passed to a specific kubelet + // plugin once it lands on a node. This data is returned by the driver + // after a successful allocation and is opaque to Kubernetes. Driver + // documentation may explain to users how to interpret this data if needed. // - // The maximum size of this field is 16KiB. This may get - // increased in the future, but not reduced. + // Setting this field is optional. It has a maximum size of 32 entries. + // If null (or empty), it is assumed this allocation will be processed by a + // single kubelet plugin with no ResourceHandle data attached. The name of + // the kubelet plugin invoked will match the DriverName set in the + // ResourceClaimStatus this AllocationResult is embedded in. + // + // +listType=atomic // +optional - ResourceHandle string `json:"resourceHandle,omitempty" protobuf:"bytes,1,opt,name=resourceHandle"` + ResourceHandles []ResourceHandle `json:"resourceHandles,omitempty" protobuf:"bytes,1,opt,name=resourceHandles"` - // This field will get set by the resource driver after it has - // allocated the resource driver to inform the scheduler where it can - // schedule Pods using the ResourceClaim. + // This field will get set by the resource driver after it has allocated + // the resource to inform the scheduler where it can schedule Pods using + // the ResourceClaim. // // Setting this field is optional. If null, the resource is available // everywhere. @@ -160,8 +167,33 @@ type AllocationResult struct { Shareable bool `json:"shareable,omitempty" protobuf:"varint,3,opt,name=shareable"` } -// ResourceHandleMaxSize is the maximum size of allocation.resourceHandle. -const ResourceHandleMaxSize = 16 * 1024 +// AllocationResultResourceHandlesMaxSize represents the maximum number of +// entries in allocation.resourceHandles. +const AllocationResultResourceHandlesMaxSize = 32 + +// ResourceHandle holds opaque resource data for processing by a specific kubelet plugin. +type ResourceHandle struct { + // DriverName specifies the name of the resource driver whose kubelet + // plugin should be invoked to process this ResourceHandle's data once it + // lands on a node. This may differ from the DriverName set in + // ResourceClaimStatus this ResourceHandle is embedded in. + DriverName string `json:"driverName,omitempty" protobuf:"bytes,1,opt,name=driverName"` + + // Data contains the opaque data associated with this ResourceHandle. It is + // set by the controller component of the resource driver whose name + // matches the DriverName set in the ResourceClaimStatus this + // ResourceHandle is embedded in. It is set at allocation time and is + // intended for processing by the kubelet plugin whose name matches + // the DriverName set in this ResourceHandle. + // + // The maximum size of this field is 16KiB. This may get increased in the + // future, but not reduced. + // +optional + Data string `json:"data,omitempty" protobuf:"bytes,2,opt,name=data"` +} + +// ResourceHandleDataMaxSize represents the maximum size of resourceHandle.data. +const ResourceHandleDataMaxSize = 16 * 1024 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.26 @@ -181,28 +213,28 @@ type ResourceClaimList struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.26 -// PodScheduling objects hold information that is needed to schedule +// PodSchedulingContext objects hold information that is needed to schedule // a Pod with ResourceClaims that use "WaitForFirstConsumer" allocation // mode. // // This is an alpha type and requires enabling the DynamicResourceAllocation // feature gate. -type PodScheduling struct { +type PodSchedulingContext struct { metav1.TypeMeta `json:",inline"` // Standard object metadata // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // Spec describes where resources for the Pod are needed. - Spec PodSchedulingSpec `json:"spec" protobuf:"bytes,2,name=spec"` + Spec PodSchedulingContextSpec `json:"spec" protobuf:"bytes,2,name=spec"` // Status describes where resources for the Pod can be allocated. // +optional - Status PodSchedulingStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` + Status PodSchedulingContextStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` } -// PodSchedulingSpec describes where resources for the Pod are needed. -type PodSchedulingSpec struct { +// PodSchedulingContextSpec describes where resources for the Pod are needed. +type PodSchedulingContextSpec struct { // SelectedNode is the node for which allocation of ResourceClaims that // are referenced by the Pod and that use "WaitForFirstConsumer" // allocation is to be attempted. @@ -221,8 +253,8 @@ type PodSchedulingSpec struct { PotentialNodes []string `json:"potentialNodes,omitempty" protobuf:"bytes,2,opt,name=potentialNodes"` } -// PodSchedulingStatus describes where resources for the Pod can be allocated. -type PodSchedulingStatus struct { +// PodSchedulingContextStatus describes where resources for the Pod can be allocated. +type PodSchedulingContextStatus struct { // ResourceClaims describes resource availability for each // pod.spec.resourceClaim entry where the corresponding ResourceClaim // uses "WaitForFirstConsumer" allocation mode. @@ -257,22 +289,22 @@ type ResourceClaimSchedulingStatus struct { } // PodSchedulingNodeListMaxSize defines the maximum number of entries in the -// node lists that are stored in PodScheduling objects. This limit is part +// node lists that are stored in PodSchedulingContext objects. This limit is part // of the API. const PodSchedulingNodeListMaxSize = 128 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.26 -// PodSchedulingList is a collection of Pod scheduling objects. -type PodSchedulingList struct { +// PodSchedulingContextList is a collection of Pod scheduling objects. +type PodSchedulingContextList 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 PodScheduling objects. - Items []PodScheduling `json:"items" protobuf:"bytes,2,rep,name=items"` + // Items is the list of PodSchedulingContext objects. + Items []PodSchedulingContext `json:"items" protobuf:"bytes,2,rep,name=items"` } // +genclient diff --git a/vendor/k8s.io/api/resource/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go similarity index 76% rename from vendor/k8s.io/api/resource/v1alpha1/types_swagger_doc_generated.go rename to vendor/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go index 6836dbfb6..474be8c85 100644 --- a/vendor/k8s.io/api/resource/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/resource/v1alpha2/types_swagger_doc_generated.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha1 +package v1alpha2 // This file contains a collection of methods that can be used from go-restful to // generate Swagger API documentation for its models. Please read this PR for more @@ -24,13 +24,13 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AllocationResult = map[string]string{ - "": "AllocationResult contains attributed of an allocated resource.", - "resourceHandle": "ResourceHandle contains arbitrary data returned by the driver after a successful allocation. This is opaque for Kubernetes. Driver documentation may explain to users how to interpret this data if needed.\n\nThe maximum size of this field is 16KiB. This may get increased in the future, but not reduced.", - "availableOnNodes": "This field will get set by the resource driver after it has allocated the resource driver to inform the scheduler where it can schedule Pods using the ResourceClaim.\n\nSetting this field is optional. If null, the resource is available everywhere.", + "": "AllocationResult contains attributes of an allocated resource.", + "resourceHandles": "ResourceHandles contain the state associated with an allocation that should be maintained throughout the lifetime of a claim. Each ResourceHandle contains data that should be passed to a specific kubelet plugin once it lands on a node. This data is returned by the driver after a successful allocation and is opaque to Kubernetes. Driver documentation may explain to users how to interpret this data if needed.\n\nSetting this field is optional. It has a maximum size of 32 entries. If null (or empty), it is assumed this allocation will be processed by a single kubelet plugin with no ResourceHandle data attached. The name of the kubelet plugin invoked will match the DriverName set in the ResourceClaimStatus this AllocationResult is embedded in.", + "availableOnNodes": "This field will get set by the resource driver after it has allocated the resource to inform the scheduler where it can schedule Pods using the ResourceClaim.\n\nSetting this field is optional. If null, the resource is available everywhere.", "shareable": "Shareable determines whether the resource supports more than one consumer at a time.", } @@ -38,44 +38,44 @@ func (AllocationResult) SwaggerDoc() map[string]string { return map_AllocationResult } -var map_PodScheduling = map[string]string{ - "": "PodScheduling objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", +var map_PodSchedulingContext = map[string]string{ + "": "PodSchedulingContext objects hold information that is needed to schedule a Pod with ResourceClaims that use \"WaitForFirstConsumer\" allocation mode.\n\nThis is an alpha type and requires enabling the DynamicResourceAllocation feature gate.", "metadata": "Standard object metadata", "spec": "Spec describes where resources for the Pod are needed.", "status": "Status describes where resources for the Pod can be allocated.", } -func (PodScheduling) SwaggerDoc() map[string]string { - return map_PodScheduling +func (PodSchedulingContext) SwaggerDoc() map[string]string { + return map_PodSchedulingContext } -var map_PodSchedulingList = map[string]string{ - "": "PodSchedulingList is a collection of Pod scheduling objects.", +var map_PodSchedulingContextList = map[string]string{ + "": "PodSchedulingContextList is a collection of Pod scheduling objects.", "metadata": "Standard list metadata", - "items": "Items is the list of PodScheduling objects.", + "items": "Items is the list of PodSchedulingContext objects.", } -func (PodSchedulingList) SwaggerDoc() map[string]string { - return map_PodSchedulingList +func (PodSchedulingContextList) SwaggerDoc() map[string]string { + return map_PodSchedulingContextList } -var map_PodSchedulingSpec = map[string]string{ - "": "PodSchedulingSpec describes where resources for the Pod are needed.", +var map_PodSchedulingContextSpec = map[string]string{ + "": "PodSchedulingContextSpec describes where resources for the Pod are needed.", "selectedNode": "SelectedNode is the node for which allocation of ResourceClaims that are referenced by the Pod and that use \"WaitForFirstConsumer\" allocation is to be attempted.", "potentialNodes": "PotentialNodes lists nodes where the Pod might be able to run.\n\nThe size of this field is limited to 128. This is large enough for many clusters. Larger clusters may need more attempts to find a node that suits all pending resources. This may get increased in the future, but not reduced.", } -func (PodSchedulingSpec) SwaggerDoc() map[string]string { - return map_PodSchedulingSpec +func (PodSchedulingContextSpec) SwaggerDoc() map[string]string { + return map_PodSchedulingContextSpec } -var map_PodSchedulingStatus = map[string]string{ - "": "PodSchedulingStatus describes where resources for the Pod can be allocated.", +var map_PodSchedulingContextStatus = map[string]string{ + "": "PodSchedulingContextStatus describes where resources for the Pod can be allocated.", "resourceClaims": "ResourceClaims describes resource availability for each pod.spec.resourceClaim entry where the corresponding ResourceClaim uses \"WaitForFirstConsumer\" allocation mode.", } -func (PodSchedulingStatus) SwaggerDoc() map[string]string { - return map_PodSchedulingStatus +func (PodSchedulingContextStatus) SwaggerDoc() map[string]string { + return map_PodSchedulingContextStatus } var map_ResourceClaim = map[string]string{ @@ -146,7 +146,7 @@ func (ResourceClaimSpec) SwaggerDoc() map[string]string { var map_ResourceClaimStatus = map[string]string{ "": "ResourceClaimStatus tracks whether the resource has been allocated and what the resulting attributes are.", "driverName": "DriverName is a copy of the driver name from the ResourceClass at the time when allocation started.", - "allocation": "Allocation is set by the resource driver once a resource has been allocated successfully. If this is not specified, the resource is not yet allocated.", + "allocation": "Allocation is set by the resource driver once a resource or set of resources has been allocated successfully. If this is not specified, the resources have not been allocated yet.", "reservedFor": "ReservedFor indicates which entities are currently allowed to use the claim. A Pod which references a ResourceClaim which is not reserved for that Pod will not be started.\n\nThere can be at most 32 such reservations. This may get increased in the future, but not reduced.", "deallocationRequested": "DeallocationRequested indicates that a ResourceClaim is to be deallocated.\n\nThe driver then must deallocate this claim and reset the field together with clearing the Allocation field.\n\nWhile DeallocationRequested is set, no new consumers may be added to ReservedFor.", } @@ -219,4 +219,14 @@ func (ResourceClassParametersReference) SwaggerDoc() map[string]string { return map_ResourceClassParametersReference } +var map_ResourceHandle = map[string]string{ + "": "ResourceHandle holds opaque resource data for processing by a specific kubelet plugin.", + "driverName": "DriverName specifies the name of the resource driver whose kubelet plugin should be invoked to process this ResourceHandle's data once it lands on a node. This may differ from the DriverName set in ResourceClaimStatus this ResourceHandle is embedded in.", + "data": "Data contains the opaque data associated with this ResourceHandle. It is set by the controller component of the resource driver whose name matches the DriverName set in the ResourceClaimStatus this ResourceHandle is embedded in. It is set at allocation time and is intended for processing by the kubelet plugin whose name matches the DriverName set in this ResourceHandle.\n\nThe maximum size of this field is 16KiB. This may get increased in the future, but not reduced.", +} + +func (ResourceHandle) SwaggerDoc() map[string]string { + return map_ResourceHandle +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/vendor/k8s.io/api/resource/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go similarity index 88% rename from vendor/k8s.io/api/resource/v1alpha1/zz_generated.deepcopy.go rename to vendor/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go index c00fbfd1d..89d521bf0 100644 --- a/vendor/k8s.io/api/resource/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/api/resource/v1alpha2/zz_generated.deepcopy.go @@ -19,7 +19,7 @@ limitations under the License. // Code generated by deepcopy-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( v1 "k8s.io/api/core/v1" @@ -29,6 +29,11 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AllocationResult) DeepCopyInto(out *AllocationResult) { *out = *in + if in.ResourceHandles != nil { + in, out := &in.ResourceHandles, &out.ResourceHandles + *out = make([]ResourceHandle, len(*in)) + copy(*out, *in) + } if in.AvailableOnNodes != nil { in, out := &in.AvailableOnNodes, &out.AvailableOnNodes *out = new(v1.NodeSelector) @@ -48,7 +53,7 @@ func (in *AllocationResult) DeepCopy() *AllocationResult { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodScheduling) DeepCopyInto(out *PodScheduling) { +func (in *PodSchedulingContext) DeepCopyInto(out *PodSchedulingContext) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -57,18 +62,18 @@ func (in *PodScheduling) DeepCopyInto(out *PodScheduling) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodScheduling. -func (in *PodScheduling) DeepCopy() *PodScheduling { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingContext. +func (in *PodSchedulingContext) DeepCopy() *PodSchedulingContext { if in == nil { return nil } - out := new(PodScheduling) + out := new(PodSchedulingContext) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodScheduling) DeepCopyObject() runtime.Object { +func (in *PodSchedulingContext) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -76,13 +81,13 @@ func (in *PodScheduling) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodSchedulingList) DeepCopyInto(out *PodSchedulingList) { +func (in *PodSchedulingContextList) DeepCopyInto(out *PodSchedulingContextList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]PodScheduling, len(*in)) + *out = make([]PodSchedulingContext, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -90,18 +95,18 @@ func (in *PodSchedulingList) DeepCopyInto(out *PodSchedulingList) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingList. -func (in *PodSchedulingList) DeepCopy() *PodSchedulingList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingContextList. +func (in *PodSchedulingContextList) DeepCopy() *PodSchedulingContextList { if in == nil { return nil } - out := new(PodSchedulingList) + out := new(PodSchedulingContextList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodSchedulingList) DeepCopyObject() runtime.Object { +func (in *PodSchedulingContextList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -109,7 +114,7 @@ func (in *PodSchedulingList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodSchedulingSpec) DeepCopyInto(out *PodSchedulingSpec) { +func (in *PodSchedulingContextSpec) DeepCopyInto(out *PodSchedulingContextSpec) { *out = *in if in.PotentialNodes != nil { in, out := &in.PotentialNodes, &out.PotentialNodes @@ -119,18 +124,18 @@ func (in *PodSchedulingSpec) DeepCopyInto(out *PodSchedulingSpec) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingSpec. -func (in *PodSchedulingSpec) DeepCopy() *PodSchedulingSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingContextSpec. +func (in *PodSchedulingContextSpec) DeepCopy() *PodSchedulingContextSpec { if in == nil { return nil } - out := new(PodSchedulingSpec) + out := new(PodSchedulingContextSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodSchedulingStatus) DeepCopyInto(out *PodSchedulingStatus) { +func (in *PodSchedulingContextStatus) DeepCopyInto(out *PodSchedulingContextStatus) { *out = *in if in.ResourceClaims != nil { in, out := &in.ResourceClaims, &out.ResourceClaims @@ -142,12 +147,12 @@ func (in *PodSchedulingStatus) DeepCopyInto(out *PodSchedulingStatus) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingStatus. -func (in *PodSchedulingStatus) DeepCopy() *PodSchedulingStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSchedulingContextStatus. +func (in *PodSchedulingContextStatus) DeepCopy() *PodSchedulingContextStatus { if in == nil { return nil } - out := new(PodSchedulingStatus) + out := new(PodSchedulingContextStatus) in.DeepCopyInto(out) return out } @@ -475,3 +480,19 @@ func (in *ResourceClassParametersReference) DeepCopy() *ResourceClassParametersR in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceHandle) DeepCopyInto(out *ResourceHandle) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceHandle. +func (in *ResourceHandle) DeepCopy() *ResourceHandle { + if in == nil { + return nil + } + out := new(ResourceHandle) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/api/scheduling/v1/generated.proto b/vendor/k8s.io/api/scheduling/v1/generated.proto index afc090777..c1a27e8ba 100644 --- a/vendor/k8s.io/api/scheduling/v1/generated.proto +++ b/vendor/k8s.io/api/scheduling/v1/generated.proto @@ -37,7 +37,7 @@ message PriorityClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. optional int32 value = 2; @@ -54,7 +54,7 @@ message PriorityClass { // +optional optional string description = 4; - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1/types.go b/vendor/k8s.io/api/scheduling/v1/types.go index 0f2989424..146bae40d 100644 --- a/vendor/k8s.io/api/scheduling/v1/types.go +++ b/vendor/k8s.io/api/scheduling/v1/types.go @@ -34,7 +34,7 @@ type PriorityClass struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` @@ -51,7 +51,7 @@ type PriorityClass struct { // +optional Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"` - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/scheduling/v1/types_swagger_doc_generated.go index ac34c531f..f167e1970 100644 --- a/vendor/k8s.io/api/scheduling/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/scheduling/v1/types_swagger_doc_generated.go @@ -24,16 +24,16 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_PriorityClass = map[string]string{ "": "PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "value": "The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", + "value": "value represents the integer value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", "globalDefault": "globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as `globalDefault`. However, if more than one PriorityClasses exists with their `globalDefault` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.", "description": "description is an arbitrary string that usually provides guidelines on when this priority class should be used.", - "preemptionPolicy": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", + "preemptionPolicy": "preemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", } func (PriorityClass) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto b/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto index 5c60b7ab4..f0878fb16 100644 --- a/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/scheduling/v1alpha1/generated.proto @@ -38,7 +38,7 @@ message PriorityClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. optional int32 value = 2; @@ -55,7 +55,7 @@ message PriorityClass { // +optional optional string description = 4; - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/types.go b/vendor/k8s.io/api/scheduling/v1alpha1/types.go index 7b0df4864..26ba8ff5d 100644 --- a/vendor/k8s.io/api/scheduling/v1alpha1/types.go +++ b/vendor/k8s.io/api/scheduling/v1alpha1/types.go @@ -35,7 +35,7 @@ type PriorityClass struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` @@ -52,7 +52,7 @@ type PriorityClass struct { // +optional Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"` - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go index fa25f969c..557005db6 100644 --- a/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/scheduling/v1alpha1/types_swagger_doc_generated.go @@ -24,16 +24,16 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_PriorityClass = map[string]string{ "": "DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "value": "The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", + "value": "value represents the integer value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", "globalDefault": "globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as `globalDefault`. However, if more than one PriorityClasses exists with their `globalDefault` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.", "description": "description is an arbitrary string that usually provides guidelines on when this priority class should be used.", - "preemptionPolicy": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", + "preemptionPolicy": "preemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", } func (PriorityClass) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/scheduling/v1beta1/generated.proto b/vendor/k8s.io/api/scheduling/v1beta1/generated.proto index 44b49ea24..43878184d 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/generated.proto +++ b/vendor/k8s.io/api/scheduling/v1beta1/generated.proto @@ -38,7 +38,7 @@ message PriorityClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. optional int32 value = 2; @@ -55,7 +55,7 @@ message PriorityClass { // +optional optional string description = 4; - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1beta1/types.go b/vendor/k8s.io/api/scheduling/v1beta1/types.go index e315e1b35..6f88592cf 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/types.go +++ b/vendor/k8s.io/api/scheduling/v1beta1/types.go @@ -39,7 +39,7 @@ type PriorityClass struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // The value of this priority class. This is the actual priority that pods + // value represents the integer value of this priority class. This is the actual priority that pods // receive when they have the name of this class in their pod spec. Value int32 `json:"value" protobuf:"bytes,2,opt,name=value"` @@ -56,7 +56,7 @@ type PriorityClass struct { // +optional Description string `json:"description,omitempty" protobuf:"bytes,4,opt,name=description"` - // PreemptionPolicy is the Policy for preempting pods with lower priority. + // preemptionPolicy is the Policy for preempting pods with lower priority. // One of Never, PreemptLowerPriority. // Defaults to PreemptLowerPriority if unset. // +optional diff --git a/vendor/k8s.io/api/scheduling/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/scheduling/v1beta1/types_swagger_doc_generated.go index cbc140f44..f42008eb9 100644 --- a/vendor/k8s.io/api/scheduling/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/scheduling/v1beta1/types_swagger_doc_generated.go @@ -24,16 +24,16 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_PriorityClass = map[string]string{ "": "DEPRECATED - This group version of PriorityClass is deprecated by scheduling.k8s.io/v1/PriorityClass. PriorityClass defines mapping from a priority class name to the priority integer value. The value can be any valid integer.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "value": "The value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", + "value": "value represents the integer value of this priority class. This is the actual priority that pods receive when they have the name of this class in their pod spec.", "globalDefault": "globalDefault specifies whether this PriorityClass should be considered as the default priority for pods that do not have any priority class. Only one PriorityClass can be marked as `globalDefault`. However, if more than one PriorityClasses exists with their `globalDefault` field set to true, the smallest value of such global default PriorityClasses will be used as the default priority.", "description": "description is an arbitrary string that usually provides guidelines on when this priority class should be used.", - "preemptionPolicy": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", + "preemptionPolicy": "preemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset.", } func (PriorityClass) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1/generated.proto b/vendor/k8s.io/api/storage/v1/generated.proto index d3c425c04..5f8eccaef 100644 --- a/vendor/k8s.io/api/storage/v1/generated.proto +++ b/vendor/k8s.io/api/storage/v1/generated.proto @@ -46,7 +46,7 @@ message CSIDriver { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the CSI Driver. + // spec represents the specification of the CSI Driver. optional CSIDriverSpec spec = 2; } @@ -79,16 +79,15 @@ message CSIDriverSpec { // +optional optional bool attachRequired = 1; - // If set to true, podInfoOnMount indicates this CSI volume driver - // requires additional pod information (like podName, podUID, etc.) during - // mount operations. + // podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) + // during mount operations, if set to true. // If set to false, pod information will not be passed on mount. // Default is false. + // // The CSI driver specifies podInfoOnMount as part of driver deployment. - // If true, Kubelet will pass pod information as VolumeContext in the CSI - // NodePublishVolume() calls. - // The CSI driver is responsible for parsing and validating the information - // passed in as VolumeContext. + // If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. + // The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. + // // The following VolumeConext will be passed if podInfoOnMount is set to true. // This list might grow, but the prefix will be used. // "csi.storage.k8s.io/pod.name": pod.Name @@ -110,29 +109,27 @@ message CSIDriverSpec { optional bool podInfoOnMount = 2; // volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. - // The default if the list is empty is "Persistent", which is the usage - // defined by the CSI specification and implemented in Kubernetes via the usual - // PV/PVC mechanism. - // The other mode is "Ephemeral". In this mode, volumes are defined inline - // inside the pod spec with CSIVolumeSource and their lifecycle is tied to - // the lifecycle of that pod. A driver has to be aware of this - // because it is only going to get a NodePublishVolume call for such a volume. + // The default if the list is empty is "Persistent", which is the usage defined by the + // CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. + // + // The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec + // with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. + // A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. + // // For more information about implementing this mode, see // https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html - // A driver can support one or more of these modes and - // more modes may be added in the future. - // This field is beta. + // A driver can support one or more of these modes and more modes may be added in the future. // + // This field is beta. // This field is immutable. // // +optional // +listType=set repeated string volumeLifecycleModes = 3; - // If set to true, storageCapacity indicates that the CSI - // volume driver wants pod scheduling to consider the storage + // storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage // capacity that the driver deployment will report by creating - // CSIStorageCapacity objects with capacity information. + // CSIStorageCapacity objects with capacity information, if set to true. // // The check can be enabled immediately when deploying a driver. // In that case, provisioning new volumes with late binding @@ -149,7 +146,7 @@ message CSIDriverSpec { // +featureGate=CSIStorageCapacity optional bool storageCapacity = 4; - // Defines if the underlying volume supports changing ownership and + // fsGroupPolicy defines if the underlying volume supports changing ownership and // permission of the volume before being mounted. // Refer to the specific FSGroupPolicy values for additional details. // @@ -159,10 +156,11 @@ message CSIDriverSpec { // to determine if Kubernetes should modify ownership and permissions of the volume. // With the default policy the defined fsGroup will only be applied // if a fstype is defined and the volume's access mode contains ReadWriteOnce. + // // +optional optional string fsGroupPolicy = 5; - // TokenRequests indicates the CSI driver needs pods' service account + // tokenRequests indicates the CSI driver needs pods' service account // tokens it is mounting volume for to do necessary authentication. Kubelet // will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. // The CSI driver should parse and validate the following VolumeContext: @@ -182,7 +180,7 @@ message CSIDriverSpec { // +listType=atomic repeated TokenRequest tokenRequests = 6; - // RequiresRepublish indicates the CSI driver wants `NodePublishVolume` + // requiresRepublish indicates the CSI driver wants `NodePublishVolume` // being periodically called to reflect any possible change in the mounted // volume. This field defaults to false. // @@ -193,7 +191,7 @@ message CSIDriverSpec { // +optional optional bool requiresRepublish = 7; - // SELinuxMount specifies if the CSI driver supports "-o context" + // seLinuxMount specifies if the CSI driver supports "-o context" // mount option. // // When "true", the CSI driver must ensure that all volumes provided by this CSI @@ -211,6 +209,7 @@ message CSIDriverSpec { // // Default is "false". // + // +featureGate=SELinuxMountReadWriteOncePod // +optional optional bool seLinuxMount = 8; } @@ -225,6 +224,7 @@ message CSIDriverSpec { // enough that it doesn't create this object. // CSINode has an OwnerReference that points to the corresponding node object. message CSINode { + // Standard object's metadata. // metadata.name must be the Kubernetes node name. optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; @@ -234,7 +234,7 @@ message CSINode { // CSINodeDriver holds information about the specification of one CSI driver installed on a node message CSINodeDriver { - // This is the name of the CSI driver that this object refers to. + // name represents the name of the CSI driver that this object refers to. // This MUST be the same name returned by the CSI GetPluginName() call for // that driver. optional string name = 1; @@ -314,11 +314,11 @@ message CSINodeSpec { // the scheduler assumes that capacity is insufficient and tries some other // node. message CSIStorageCapacity { - // Standard object's metadata. The name has no particular meaning. It must be - // be a DNS subdomain (dots allowed, 253 characters). To ensure that - // there are no conflicts with other CSI drivers on the cluster, the recommendation - // is to use csisc-, a generated name, or a reverse-domain name which ends - // with the unique CSI driver name. + // Standard object's metadata. + // The name has no particular meaning. It must be a DNS subdomain (dots allowed, 253 characters). + // To ensure that there are no conflicts with other CSI drivers on the cluster, + // the recommendation is to use csisc-, a generated name, or a reverse-domain name + // which ends with the unique CSI driver name. // // Objects are namespaced. // @@ -326,7 +326,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -335,7 +335,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector nodeTopology = 2; - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -343,7 +343,7 @@ message CSIStorageCapacity { // This field is immutable. optional string storageClassName = 3; - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -355,7 +355,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -377,7 +377,7 @@ message CSIStorageCapacityList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name repeated CSIStorageCapacity items = 2; @@ -394,36 +394,36 @@ message StorageClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Provisioner indicates the type of the provisioner. + // provisioner indicates the type of the provisioner. optional string provisioner = 2; - // Parameters holds the parameters for the provisioner that should + // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional map parameters = 3; - // Dynamically provisioned PersistentVolumes of this storage class are - // created with this reclaimPolicy. Defaults to Delete. + // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. + // Defaults to Delete. // +optional optional string reclaimPolicy = 4; - // Dynamically provisioned PersistentVolumes of this storage class are - // created with these mountOptions, e.g. ["ro", "soft"]. Not validated - + // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. + // e.g. ["ro", "soft"]. Not validated - // mount of the PVs will simply fail if one is invalid. // +optional repeated string mountOptions = 5; - // AllowVolumeExpansion shows whether the storage class allow volume expand + // allowVolumeExpansion shows whether the storage class allow volume expand. // +optional optional bool allowVolumeExpansion = 6; - // VolumeBindingMode indicates how PersistentVolumeClaims should be + // volumeBindingMode indicates how PersistentVolumeClaims should be // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional optional string volumeBindingMode = 7; - // Restrict the node topologies where volumes can be dynamically provisioned. + // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. // Each volume plugin defines its own supported topology specifications. // An empty TopologySelectorTerm list means there is no topology restriction. // This field is only honored by servers that enable the VolumeScheduling feature. @@ -439,17 +439,17 @@ message StorageClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of StorageClasses + // items is the list of StorageClasses repeated StorageClass items = 2; } // TokenRequest contains parameters of a service account token. message TokenRequest { - // Audience is the intended audience of the token in "TokenRequestSpec". + // audience is the intended audience of the token in "TokenRequestSpec". // It will default to the audiences of kube apiserver. optional string audience = 1; - // ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". + // expirationSeconds is the duration of validity of the token in "TokenRequestSpec". // It has the same default value of "ExpirationSeconds" in "TokenRequestSpec". // // +optional @@ -466,11 +466,11 @@ message VolumeAttachment { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. optional VolumeAttachmentSpec spec = 2; - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -484,7 +484,7 @@ message VolumeAttachmentList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments repeated VolumeAttachment items = 2; } @@ -493,7 +493,7 @@ message VolumeAttachmentList { // in future we may allow also inline volumes in pods. // Exactly one member can be set. message VolumeAttachmentSource { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional optional string persistentVolumeName = 1; @@ -509,39 +509,39 @@ message VolumeAttachmentSource { // VolumeAttachmentSpec is the specification of a VolumeAttachment request. message VolumeAttachmentSpec { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). optional string attacher = 1; - // Source represents the volume that should be attached. + // source represents the volume that should be attached. optional VolumeAttachmentSource source = 2; - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. optional string nodeName = 3; } // VolumeAttachmentStatus is the status of a VolumeAttachment request. message VolumeAttachmentStatus { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. optional bool attached = 1; - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional map attachmentMetadata = 2; - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional optional VolumeError attachError = 3; - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -550,11 +550,11 @@ message VolumeAttachmentStatus { // VolumeError captures an error encountered during a volume operation. message VolumeError { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.Time time = 1; - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string may be logged, so it should not contain sensitive // information. // +optional @@ -563,7 +563,7 @@ message VolumeError { // VolumeNodeResources is a set of resource limits for scheduling of volumes. message VolumeNodeResources { - // Maximum number of unique volumes managed by the CSI driver that can be used on a node. + // count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. // A volume that is both attached and mounted on a node is considered to be used once, not twice. // The same rule applies for a unique volume that is shared among multiple pods on the same node. // If this field is not specified, then the supported number of volumes on this node is unbounded. diff --git a/vendor/k8s.io/api/storage/v1/types.go b/vendor/k8s.io/api/storage/v1/types.go index f57099df6..c785f368e 100644 --- a/vendor/k8s.io/api/storage/v1/types.go +++ b/vendor/k8s.io/api/storage/v1/types.go @@ -33,41 +33,42 @@ import ( // according to etcd is in ObjectMeta.Name. type StorageClass 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"` - // Provisioner indicates the type of the provisioner. + // provisioner indicates the type of the provisioner. Provisioner string `json:"provisioner" protobuf:"bytes,2,opt,name=provisioner"` - // Parameters holds the parameters for the provisioner that should + // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"` - // Dynamically provisioned PersistentVolumes of this storage class are - // created with this reclaimPolicy. Defaults to Delete. + // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. + // Defaults to Delete. // +optional ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"` - // Dynamically provisioned PersistentVolumes of this storage class are - // created with these mountOptions, e.g. ["ro", "soft"]. Not validated - + // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. + // e.g. ["ro", "soft"]. Not validated - // mount of the PVs will simply fail if one is invalid. // +optional MountOptions []string `json:"mountOptions,omitempty" protobuf:"bytes,5,opt,name=mountOptions"` - // AllowVolumeExpansion shows whether the storage class allow volume expand + // allowVolumeExpansion shows whether the storage class allow volume expand. // +optional AllowVolumeExpansion *bool `json:"allowVolumeExpansion,omitempty" protobuf:"varint,6,opt,name=allowVolumeExpansion"` - // VolumeBindingMode indicates how PersistentVolumeClaims should be + // volumeBindingMode indicates how PersistentVolumeClaims should be // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional VolumeBindingMode *VolumeBindingMode `json:"volumeBindingMode,omitempty" protobuf:"bytes,7,opt,name=volumeBindingMode"` - // Restrict the node topologies where volumes can be dynamically provisioned. + // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. // Each volume plugin defines its own supported topology specifications. // An empty TopologySelectorTerm list means there is no topology restriction. // This field is only honored by servers that enable the VolumeScheduling feature. @@ -81,12 +82,13 @@ type StorageClass struct { // StorageClassList is a collection of storage classes. type StorageClassList 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 the list of StorageClasses + // items is the list of StorageClasses Items []StorageClass `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -122,11 +124,11 @@ type VolumeAttachment struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -138,25 +140,26 @@ type VolumeAttachment struct { // VolumeAttachmentList is a collection of VolumeAttachment objects. type VolumeAttachmentList 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 the list of VolumeAttachments + // items is the list of VolumeAttachments Items []VolumeAttachment `json:"items" protobuf:"bytes,2,rep,name=items"` } // VolumeAttachmentSpec is the specification of a VolumeAttachment request. type VolumeAttachmentSpec struct { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` - // Source represents the volume that should be attached. + // source represents the volume that should be attached. Source VolumeAttachmentSource `json:"source" protobuf:"bytes,2,opt,name=source"` - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. NodeName string `json:"nodeName" protobuf:"bytes,3,opt,name=nodeName"` } @@ -165,7 +168,7 @@ type VolumeAttachmentSpec struct { // in future we may allow also inline volumes in pods. // Exactly one member can be set. type VolumeAttachmentSource struct { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional PersistentVolumeName *string `json:"persistentVolumeName,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeName"` @@ -181,26 +184,26 @@ type VolumeAttachmentSource struct { // VolumeAttachmentStatus is the status of a VolumeAttachment request. type VolumeAttachmentStatus struct { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. Attached bool `json:"attached" protobuf:"varint,1,opt,name=attached"` - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachmentMetadata map[string]string `json:"attachmentMetadata,omitempty" protobuf:"bytes,2,rep,name=attachmentMetadata"` - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachError *VolumeError `json:"attachError,omitempty" protobuf:"bytes,3,opt,name=attachError,casttype=VolumeError"` - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -209,11 +212,11 @@ type VolumeAttachmentStatus struct { // VolumeError captures an error encountered during a volume operation. type VolumeError struct { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional Time metav1.Time `json:"time,omitempty" protobuf:"bytes,1,opt,name=time"` - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string may be logged, so it should not contain sensitive // information. // +optional @@ -242,7 +245,7 @@ type CSIDriver struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the CSI Driver. + // spec represents the specification of the CSI Driver. Spec CSIDriverSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` } @@ -279,16 +282,15 @@ type CSIDriverSpec struct { // +optional AttachRequired *bool `json:"attachRequired,omitempty" protobuf:"varint,1,opt,name=attachRequired"` - // If set to true, podInfoOnMount indicates this CSI volume driver - // requires additional pod information (like podName, podUID, etc.) during - // mount operations. + // podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) + // during mount operations, if set to true. // If set to false, pod information will not be passed on mount. // Default is false. + // // The CSI driver specifies podInfoOnMount as part of driver deployment. - // If true, Kubelet will pass pod information as VolumeContext in the CSI - // NodePublishVolume() calls. - // The CSI driver is responsible for parsing and validating the information - // passed in as VolumeContext. + // If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. + // The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. + // // The following VolumeConext will be passed if podInfoOnMount is set to true. // This list might grow, but the prefix will be used. // "csi.storage.k8s.io/pod.name": pod.Name @@ -310,29 +312,27 @@ type CSIDriverSpec struct { PodInfoOnMount *bool `json:"podInfoOnMount,omitempty" protobuf:"bytes,2,opt,name=podInfoOnMount"` // volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. - // The default if the list is empty is "Persistent", which is the usage - // defined by the CSI specification and implemented in Kubernetes via the usual - // PV/PVC mechanism. - // The other mode is "Ephemeral". In this mode, volumes are defined inline - // inside the pod spec with CSIVolumeSource and their lifecycle is tied to - // the lifecycle of that pod. A driver has to be aware of this - // because it is only going to get a NodePublishVolume call for such a volume. + // The default if the list is empty is "Persistent", which is the usage defined by the + // CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. + // + // The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec + // with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. + // A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. + // // For more information about implementing this mode, see // https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html - // A driver can support one or more of these modes and - // more modes may be added in the future. - // This field is beta. + // A driver can support one or more of these modes and more modes may be added in the future. // + // This field is beta. // This field is immutable. // // +optional // +listType=set VolumeLifecycleModes []VolumeLifecycleMode `json:"volumeLifecycleModes,omitempty" protobuf:"bytes,3,opt,name=volumeLifecycleModes"` - // If set to true, storageCapacity indicates that the CSI - // volume driver wants pod scheduling to consider the storage + // storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage // capacity that the driver deployment will report by creating - // CSIStorageCapacity objects with capacity information. + // CSIStorageCapacity objects with capacity information, if set to true. // // The check can be enabled immediately when deploying a driver. // In that case, provisioning new volumes with late binding @@ -349,7 +349,7 @@ type CSIDriverSpec struct { // +featureGate=CSIStorageCapacity StorageCapacity *bool `json:"storageCapacity,omitempty" protobuf:"bytes,4,opt,name=storageCapacity"` - // Defines if the underlying volume supports changing ownership and + // fsGroupPolicy defines if the underlying volume supports changing ownership and // permission of the volume before being mounted. // Refer to the specific FSGroupPolicy values for additional details. // @@ -359,10 +359,11 @@ type CSIDriverSpec struct { // to determine if Kubernetes should modify ownership and permissions of the volume. // With the default policy the defined fsGroup will only be applied // if a fstype is defined and the volume's access mode contains ReadWriteOnce. + // // +optional FSGroupPolicy *FSGroupPolicy `json:"fsGroupPolicy,omitempty" protobuf:"bytes,5,opt,name=fsGroupPolicy"` - // TokenRequests indicates the CSI driver needs pods' service account + // tokenRequests indicates the CSI driver needs pods' service account // tokens it is mounting volume for to do necessary authentication. Kubelet // will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. // The CSI driver should parse and validate the following VolumeContext: @@ -382,7 +383,7 @@ type CSIDriverSpec struct { // +listType=atomic TokenRequests []TokenRequest `json:"tokenRequests,omitempty" protobuf:"bytes,6,opt,name=tokenRequests"` - // RequiresRepublish indicates the CSI driver wants `NodePublishVolume` + // requiresRepublish indicates the CSI driver wants `NodePublishVolume` // being periodically called to reflect any possible change in the mounted // volume. This field defaults to false. // @@ -393,7 +394,7 @@ type CSIDriverSpec struct { // +optional RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"` - // SELinuxMount specifies if the CSI driver supports "-o context" + // seLinuxMount specifies if the CSI driver supports "-o context" // mount option. // // When "true", the CSI driver must ensure that all volumes provided by this CSI @@ -411,6 +412,7 @@ type CSIDriverSpec struct { // // Default is "false". // + // +featureGate=SELinuxMountReadWriteOncePod // +optional SELinuxMount *bool `json:"seLinuxMount,omitempty" protobuf:"varint,8,opt,name=seLinuxMount"` } @@ -453,12 +455,11 @@ type VolumeLifecycleMode string // TokenRequest contains parameters of a service account token. type TokenRequest struct { - // Audience is the intended audience of the token in "TokenRequestSpec". + // audience is the intended audience of the token in "TokenRequestSpec". // It will default to the audiences of kube apiserver. - // Audience string `json:"audience" protobuf:"bytes,1,opt,name=audience"` - // ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". + // expirationSeconds is the duration of validity of the token in "TokenRequestSpec". // It has the same default value of "ExpirationSeconds" in "TokenRequestSpec". // // +optional @@ -502,6 +503,7 @@ const ( type CSINode struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. // metadata.name must be the Kubernetes node name. metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` @@ -520,7 +522,7 @@ type CSINodeSpec struct { // CSINodeDriver holds information about the specification of one CSI driver installed on a node type CSINodeDriver struct { - // This is the name of the CSI driver that this object refers to. + // name represents the name of the CSI driver that this object refers to. // This MUST be the same name returned by the CSI GetPluginName() call for // that driver. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` @@ -557,7 +559,7 @@ type CSINodeDriver struct { // VolumeNodeResources is a set of resource limits for scheduling of volumes. type VolumeNodeResources struct { - // Maximum number of unique volumes managed by the CSI driver that can be used on a node. + // count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. // A volume that is both attached and mounted on a node is considered to be used once, not twice. // The same rule applies for a unique volume that is shared among multiple pods on the same node. // If this field is not specified, then the supported number of volumes on this node is unbounded. @@ -609,11 +611,12 @@ type CSINodeList struct { // node. type CSIStorageCapacity struct { metav1.TypeMeta `json:",inline"` - // Standard object's metadata. The name has no particular meaning. It must be - // be a DNS subdomain (dots allowed, 253 characters). To ensure that - // there are no conflicts with other CSI drivers on the cluster, the recommendation - // is to use csisc-, a generated name, or a reverse-domain name which ends - // with the unique CSI driver name. + + // Standard object's metadata. + // The name has no particular meaning. It must be a DNS subdomain (dots allowed, 253 characters). + // To ensure that there are no conflicts with other CSI drivers on the cluster, + // the recommendation is to use csisc-, a generated name, or a reverse-domain name + // which ends with the unique CSI driver name. // // Objects are namespaced. // @@ -621,7 +624,7 @@ type CSIStorageCapacity struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -630,7 +633,7 @@ type CSIStorageCapacity struct { // +optional NodeTopology *metav1.LabelSelector `json:"nodeTopology,omitempty" protobuf:"bytes,2,opt,name=nodeTopology"` - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -638,7 +641,7 @@ type CSIStorageCapacity struct { // This field is immutable. StorageClassName string `json:"storageClassName" protobuf:"bytes,3,name=storageClassName"` - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -650,7 +653,7 @@ type CSIStorageCapacity struct { // +optional Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -670,12 +673,13 @@ type CSIStorageCapacity struct { // CSIStorageCapacityList is a collection of CSIStorageCapacity objects. type CSIStorageCapacityList 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 the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name Items []CSIStorageCapacity `json:"items" protobuf:"bytes,2,rep,name=items"` diff --git a/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go b/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go index 1a069bb40..c92a7f95a 100644 --- a/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/storage/v1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CSIDriver = map[string]string{ "": "CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. Kubernetes attach detach controller uses this object to determine whether attach is required. Kubelet uses this object to determine whether pod information needs to be passed on mount. CSIDriver objects are non-namespaced.", "metadata": "Standard object metadata. metadata.Name indicates the name of the CSI driver that this object refers to; it MUST be the same name returned by the CSI GetPluginName() call for that driver. The driver name must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the CSI Driver.", + "spec": "spec represents the specification of the CSI Driver.", } func (CSIDriver) SwaggerDoc() map[string]string { @@ -50,13 +50,13 @@ func (CSIDriverList) SwaggerDoc() map[string]string { var map_CSIDriverSpec = map[string]string{ "": "CSIDriverSpec is the specification of a CSIDriver.", "attachRequired": "attachRequired indicates this CSI volume driver requires an attach operation (because it implements the CSI ControllerPublishVolume() method), and that the Kubernetes attach detach controller should call the attach volume interface which checks the volumeattachment status and waits until the volume is attached before proceeding to mounting. The CSI external-attacher coordinates with CSI volume driver and updates the volumeattachment status when the attach operation is complete. If the CSIDriverRegistry feature gate is enabled and the value is specified to false, the attach operation will be skipped. Otherwise the attach operation will be called.\n\nThis field is immutable.", - "podInfoOnMount": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", - "volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future. This field is beta.\n\nThis field is immutable.", - "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", - "fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", - "tokenRequests": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", - "requiresRepublish": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", - "seLinuxMount": "SELinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", + "podInfoOnMount": "podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations, if set to true. If set to false, pod information will not be passed on mount. Default is false.\n\nThe CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext.\n\nThe following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", + "volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism.\n\nThe other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume.\n\nFor more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.\n\nThis field is beta. This field is immutable.", + "storageCapacity": "storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information, if set to true.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", + "fsGroupPolicy": "fsGroupPolicy defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", + "tokenRequests": "tokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", + "requiresRepublish": "requiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", + "seLinuxMount": "seLinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", } func (CSIDriverSpec) SwaggerDoc() map[string]string { @@ -65,7 +65,7 @@ func (CSIDriverSpec) SwaggerDoc() map[string]string { var map_CSINode = map[string]string{ "": "CSINode holds information about all CSI drivers installed on a node. CSI drivers do not need to create the CSINode object directly. As long as they use the node-driver-registrar sidecar container, the kubelet will automatically populate the CSINode object for the CSI driver as part of kubelet plugin registration. CSINode has the same name as a node. If the object is missing, it means either there are no CSI Drivers available on the node, or the Kubelet version is low enough that it doesn't create this object. CSINode has an OwnerReference that points to the corresponding node object.", - "metadata": "metadata.name must be the Kubernetes node name.", + "metadata": "Standard object's metadata. metadata.name must be the Kubernetes node name.", "spec": "spec is the specification of CSINode", } @@ -75,7 +75,7 @@ func (CSINode) SwaggerDoc() map[string]string { var map_CSINodeDriver = map[string]string{ "": "CSINodeDriver holds information about the specification of one CSI driver installed on a node", - "name": "This is the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.", + "name": "name represents the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.", "nodeID": "nodeID of the node from the driver point of view. This field enables Kubernetes to communicate with storage systems that do not share the same nomenclature for nodes. For example, Kubernetes may refer to a given node as \"node1\", but the storage system may refer to the same node as \"nodeA\". When Kubernetes issues a command to the storage system to attach a volume to a specific node, it can use this field to refer to the node name using the ID that the storage system will understand, e.g. \"nodeA\" instead of \"node1\". This field is required.", "topologyKeys": "topologyKeys is the list of keys supported by the driver. When a driver is initialized on a cluster, it provides a set of topology keys that it understands (e.g. \"company.com/zone\", \"company.com/region\"). When a driver is initialized on a node, it provides the same topology keys along with values. Kubelet will expose these topology keys as labels on its own node object. When Kubernetes does topology aware provisioning, it can use this list to determine which labels it should retrieve from the node object and pass back to the driver. It is possible for different nodes to use different topology keys. This can be empty if driver does not support topology.", "allocatable": "allocatable represents the volume resources of a node that are available for scheduling. This field is beta.", @@ -106,11 +106,11 @@ func (CSINodeSpec) SwaggerDoc() map[string]string { var map_CSIStorageCapacity = map[string]string{ "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", - "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", - "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", - "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", - "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", + "metadata": "Standard object's metadata. The name has no particular meaning. It must be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "nodeTopology": "nodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", + "storageClassName": "storageClassName represents the name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "capacity": "capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", + "maximumVolumeSize": "maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", } func (CSIStorageCapacity) SwaggerDoc() map[string]string { @@ -120,7 +120,7 @@ func (CSIStorageCapacity) SwaggerDoc() map[string]string { var map_CSIStorageCapacityList = map[string]string{ "": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of CSIStorageCapacity objects.", + "items": "items is the list of CSIStorageCapacity objects.", } func (CSIStorageCapacityList) SwaggerDoc() map[string]string { @@ -130,13 +130,13 @@ func (CSIStorageCapacityList) SwaggerDoc() map[string]string { var map_StorageClass = map[string]string{ "": "StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "provisioner": "Provisioner indicates the type of the provisioner.", - "parameters": "Parameters holds the parameters for the provisioner that should create volumes of this storage class.", - "reclaimPolicy": "Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete.", - "mountOptions": "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.", - "allowVolumeExpansion": "AllowVolumeExpansion shows whether the storage class allow volume expand", - "volumeBindingMode": "VolumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.", - "allowedTopologies": "Restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.", + "provisioner": "provisioner indicates the type of the provisioner.", + "parameters": "parameters holds the parameters for the provisioner that should create volumes of this storage class.", + "reclaimPolicy": "reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. Defaults to Delete.", + "mountOptions": "mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.", + "allowVolumeExpansion": "allowVolumeExpansion shows whether the storage class allow volume expand.", + "volumeBindingMode": "volumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.", + "allowedTopologies": "allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.", } func (StorageClass) SwaggerDoc() map[string]string { @@ -146,7 +146,7 @@ func (StorageClass) SwaggerDoc() map[string]string { var map_StorageClassList = map[string]string{ "": "StorageClassList is a collection of storage classes.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of StorageClasses", + "items": "items is the list of StorageClasses", } func (StorageClassList) SwaggerDoc() map[string]string { @@ -155,8 +155,8 @@ func (StorageClassList) SwaggerDoc() map[string]string { var map_TokenRequest = map[string]string{ "": "TokenRequest contains parameters of a service account token.", - "audience": "Audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.", - "expirationSeconds": "ExpirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\".", + "audience": "audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.", + "expirationSeconds": "expirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\".", } func (TokenRequest) SwaggerDoc() map[string]string { @@ -166,8 +166,8 @@ func (TokenRequest) SwaggerDoc() map[string]string { var map_VolumeAttachment = map[string]string{ "": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", - "status": "Status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", + "spec": "spec represents specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", + "status": "status represents status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", } func (VolumeAttachment) SwaggerDoc() map[string]string { @@ -177,7 +177,7 @@ func (VolumeAttachment) SwaggerDoc() map[string]string { var map_VolumeAttachmentList = map[string]string{ "": "VolumeAttachmentList is a collection of VolumeAttachment objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of VolumeAttachments", + "items": "items is the list of VolumeAttachments", } func (VolumeAttachmentList) SwaggerDoc() map[string]string { @@ -186,7 +186,7 @@ func (VolumeAttachmentList) SwaggerDoc() map[string]string { var map_VolumeAttachmentSource = map[string]string{ "": "VolumeAttachmentSource represents a volume that should be attached. Right now only PersistenVolumes can be attached via external attacher, in future we may allow also inline volumes in pods. Exactly one member can be set.", - "persistentVolumeName": "Name of the persistent volume to attach.", + "persistentVolumeName": "persistentVolumeName represents the name of the persistent volume to attach.", } func (VolumeAttachmentSource) SwaggerDoc() map[string]string { @@ -195,9 +195,9 @@ func (VolumeAttachmentSource) SwaggerDoc() map[string]string { var map_VolumeAttachmentSpec = map[string]string{ "": "VolumeAttachmentSpec is the specification of a VolumeAttachment request.", - "attacher": "Attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", - "source": "Source represents the volume that should be attached.", - "nodeName": "The node that the volume should be attached to.", + "attacher": "attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", + "source": "source represents the volume that should be attached.", + "nodeName": "nodeName represents the node that the volume should be attached to.", } func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { @@ -206,10 +206,10 @@ func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { var map_VolumeAttachmentStatus = map[string]string{ "": "VolumeAttachmentStatus is the status of a VolumeAttachment request.", - "attached": "Indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachmentMetadata": "Upon successful attach, this field is populated with any information returned by the attach operation that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachError": "The last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "detachError": "The last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", + "attached": "attached indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachmentMetadata": "attachmentMetadata is populated with any information returned by the attach operation, upon successful attach, that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachError": "attachError represents the last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "detachError": "detachError represents the last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", } func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { @@ -218,8 +218,8 @@ func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { var map_VolumeError = map[string]string{ "": "VolumeError captures an error encountered during a volume operation.", - "time": "Time the error was encountered.", - "message": "String detailing the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", + "time": "time represents the time the error was encountered.", + "message": "message represents the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", } func (VolumeError) SwaggerDoc() map[string]string { @@ -228,7 +228,7 @@ func (VolumeError) SwaggerDoc() map[string]string { var map_VolumeNodeResources = map[string]string{ "": "VolumeNodeResources is a set of resource limits for scheduling of volumes.", - "count": "Maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is not specified, then the supported number of volumes on this node is unbounded.", + "count": "count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is not specified, then the supported number of volumes on this node is unbounded.", } func (VolumeNodeResources) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1alpha1/generated.proto b/vendor/k8s.io/api/storage/v1alpha1/generated.proto index a53451226..88250a0f0 100644 --- a/vendor/k8s.io/api/storage/v1alpha1/generated.proto +++ b/vendor/k8s.io/api/storage/v1alpha1/generated.proto @@ -67,7 +67,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -76,7 +76,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector nodeTopology = 2; - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -84,7 +84,7 @@ message CSIStorageCapacity { // This field is immutable. optional string storageClassName = 3; - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -96,7 +96,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -118,7 +118,7 @@ message CSIStorageCapacityList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name repeated CSIStorageCapacity items = 2; @@ -134,11 +134,11 @@ message VolumeAttachment { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. optional VolumeAttachmentSpec spec = 2; - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -152,7 +152,7 @@ message VolumeAttachmentList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments repeated VolumeAttachment items = 2; } @@ -161,7 +161,7 @@ message VolumeAttachmentList { // in future we may allow also inline volumes in pods. // Exactly one member can be set. message VolumeAttachmentSource { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional optional string persistentVolumeName = 1; @@ -177,39 +177,39 @@ message VolumeAttachmentSource { // VolumeAttachmentSpec is the specification of a VolumeAttachment request. message VolumeAttachmentSpec { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). optional string attacher = 1; - // Source represents the volume that should be attached. + // source represents the volume that should be attached. optional VolumeAttachmentSource source = 2; - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. optional string nodeName = 3; } // VolumeAttachmentStatus is the status of a VolumeAttachment request. message VolumeAttachmentStatus { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. optional bool attached = 1; - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional map attachmentMetadata = 2; - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional optional VolumeError attachError = 3; - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -218,11 +218,11 @@ message VolumeAttachmentStatus { // VolumeError captures an error encountered during a volume operation. message VolumeError { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.Time time = 1; - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string maybe logged, so it should not contain sensitive // information. // +optional diff --git a/vendor/k8s.io/api/storage/v1alpha1/types.go b/vendor/k8s.io/api/storage/v1alpha1/types.go index fe8c9e3cd..59ef348a3 100644 --- a/vendor/k8s.io/api/storage/v1alpha1/types.go +++ b/vendor/k8s.io/api/storage/v1alpha1/types.go @@ -41,11 +41,11 @@ type VolumeAttachment struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -60,25 +60,26 @@ type VolumeAttachment struct { // VolumeAttachmentList is a collection of VolumeAttachment objects. type VolumeAttachmentList 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 the list of VolumeAttachments + // items is the list of VolumeAttachments Items []VolumeAttachment `json:"items" protobuf:"bytes,2,rep,name=items"` } // VolumeAttachmentSpec is the specification of a VolumeAttachment request. type VolumeAttachmentSpec struct { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` - // Source represents the volume that should be attached. + // source represents the volume that should be attached. Source VolumeAttachmentSource `json:"source" protobuf:"bytes,2,opt,name=source"` - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. NodeName string `json:"nodeName" protobuf:"bytes,3,opt,name=nodeName"` } @@ -87,7 +88,7 @@ type VolumeAttachmentSpec struct { // in future we may allow also inline volumes in pods. // Exactly one member can be set. type VolumeAttachmentSource struct { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional PersistentVolumeName *string `json:"persistentVolumeName,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeName"` @@ -103,26 +104,26 @@ type VolumeAttachmentSource struct { // VolumeAttachmentStatus is the status of a VolumeAttachment request. type VolumeAttachmentStatus struct { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. Attached bool `json:"attached" protobuf:"varint,1,opt,name=attached"` - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachmentMetadata map[string]string `json:"attachmentMetadata,omitempty" protobuf:"bytes,2,rep,name=attachmentMetadata"` - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachError *VolumeError `json:"attachError,omitempty" protobuf:"bytes,3,opt,name=attachError,casttype=VolumeError"` - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -131,11 +132,11 @@ type VolumeAttachmentStatus struct { // VolumeError captures an error encountered during a volume operation. type VolumeError struct { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional Time metav1.Time `json:"time,omitempty" protobuf:"bytes,1,opt,name=time"` - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string maybe logged, so it should not contain sensitive // information. // +optional @@ -174,6 +175,7 @@ type VolumeError struct { // node. type CSIStorageCapacity struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. The name has no particular meaning. It must be // be a DNS subdomain (dots allowed, 253 characters). To ensure that // there are no conflicts with other CSI drivers on the cluster, the recommendation @@ -186,7 +188,7 @@ type CSIStorageCapacity struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -195,7 +197,7 @@ type CSIStorageCapacity struct { // +optional NodeTopology *metav1.LabelSelector `json:"nodeTopology,omitempty" protobuf:"bytes,2,opt,name=nodeTopology"` - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -203,7 +205,7 @@ type CSIStorageCapacity struct { // This field is immutable. StorageClassName string `json:"storageClassName" protobuf:"bytes,3,name=storageClassName"` - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -215,7 +217,7 @@ type CSIStorageCapacity struct { // +optional Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -238,12 +240,13 @@ type CSIStorageCapacity struct { // CSIStorageCapacityList is a collection of CSIStorageCapacity objects. type CSIStorageCapacityList 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 the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name Items []CSIStorageCapacity `json:"items" protobuf:"bytes,2,rep,name=items"` diff --git a/vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go b/vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go index a228a3fec..ba6afbd59 100644 --- a/vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/storage/v1alpha1/types_swagger_doc_generated.go @@ -24,16 +24,16 @@ package v1alpha1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CSIStorageCapacity = map[string]string{ "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", - "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", - "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", - "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", + "nodeTopology": "nodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", + "storageClassName": "storageClassName represents the name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "capacity": "capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", + "maximumVolumeSize": "maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", } func (CSIStorageCapacity) SwaggerDoc() map[string]string { @@ -43,7 +43,7 @@ func (CSIStorageCapacity) SwaggerDoc() map[string]string { var map_CSIStorageCapacityList = map[string]string{ "": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of CSIStorageCapacity objects.", + "items": "items is the list of CSIStorageCapacity objects.", } func (CSIStorageCapacityList) SwaggerDoc() map[string]string { @@ -53,8 +53,8 @@ func (CSIStorageCapacityList) SwaggerDoc() map[string]string { var map_VolumeAttachment = map[string]string{ "": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", - "status": "Status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", + "spec": "spec represents specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", + "status": "status represents status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", } func (VolumeAttachment) SwaggerDoc() map[string]string { @@ -64,7 +64,7 @@ func (VolumeAttachment) SwaggerDoc() map[string]string { var map_VolumeAttachmentList = map[string]string{ "": "VolumeAttachmentList is a collection of VolumeAttachment objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of VolumeAttachments", + "items": "items is the list of VolumeAttachments", } func (VolumeAttachmentList) SwaggerDoc() map[string]string { @@ -73,7 +73,7 @@ func (VolumeAttachmentList) SwaggerDoc() map[string]string { var map_VolumeAttachmentSource = map[string]string{ "": "VolumeAttachmentSource represents a volume that should be attached. Right now only PersistenVolumes can be attached via external attacher, in future we may allow also inline volumes in pods. Exactly one member can be set.", - "persistentVolumeName": "Name of the persistent volume to attach.", + "persistentVolumeName": "persistentVolumeName represents the name of the persistent volume to attach.", } func (VolumeAttachmentSource) SwaggerDoc() map[string]string { @@ -82,9 +82,9 @@ func (VolumeAttachmentSource) SwaggerDoc() map[string]string { var map_VolumeAttachmentSpec = map[string]string{ "": "VolumeAttachmentSpec is the specification of a VolumeAttachment request.", - "attacher": "Attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", - "source": "Source represents the volume that should be attached.", - "nodeName": "The node that the volume should be attached to.", + "attacher": "attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", + "source": "source represents the volume that should be attached.", + "nodeName": "nodeName represents the node that the volume should be attached to.", } func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { @@ -93,10 +93,10 @@ func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { var map_VolumeAttachmentStatus = map[string]string{ "": "VolumeAttachmentStatus is the status of a VolumeAttachment request.", - "attached": "Indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachmentMetadata": "Upon successful attach, this field is populated with any information returned by the attach operation that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachError": "The last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "detachError": "The last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", + "attached": "attached indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachmentMetadata": "attachmentMetadata is populated with any information returned by the attach operation, upon successful attach, that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachError": "attachError represents the last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "detachError": "detachError represents the last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", } func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { @@ -105,8 +105,8 @@ func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { var map_VolumeError = map[string]string{ "": "VolumeError captures an error encountered during a volume operation.", - "time": "Time the error was encountered.", - "message": "String detailing the error encountered during Attach or Detach operation. This string maybe logged, so it should not contain sensitive information.", + "time": "time represents the time the error was encountered.", + "message": "message represents the error encountered during Attach or Detach operation. This string maybe logged, so it should not contain sensitive information.", } func (VolumeError) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/api/storage/v1beta1/generated.proto b/vendor/k8s.io/api/storage/v1beta1/generated.proto index bedbd3183..2b354dd47 100644 --- a/vendor/k8s.io/api/storage/v1beta1/generated.proto +++ b/vendor/k8s.io/api/storage/v1beta1/generated.proto @@ -49,7 +49,7 @@ message CSIDriver { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the CSI Driver. + // spec represents the specification of the CSI Driver. optional CSIDriverSpec spec = 2; } @@ -82,16 +82,15 @@ message CSIDriverSpec { // +optional optional bool attachRequired = 1; - // If set to true, podInfoOnMount indicates this CSI volume driver - // requires additional pod information (like podName, podUID, etc.) during - // mount operations. + // podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) + // during mount operations, if set to true. // If set to false, pod information will not be passed on mount. // Default is false. + // // The CSI driver specifies podInfoOnMount as part of driver deployment. - // If true, Kubelet will pass pod information as VolumeContext in the CSI - // NodePublishVolume() calls. - // The CSI driver is responsible for parsing and validating the information - // passed in as VolumeContext. + // If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. + // The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. + // // The following VolumeConext will be passed if podInfoOnMount is set to true. // This list might grow, but the prefix will be used. // "csi.storage.k8s.io/pod.name": pod.Name @@ -112,14 +111,14 @@ message CSIDriverSpec { // +optional optional bool podInfoOnMount = 2; - // VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. - // The default if the list is empty is "Persistent", which is the usage - // defined by the CSI specification and implemented in Kubernetes via the usual - // PV/PVC mechanism. - // The other mode is "Ephemeral". In this mode, volumes are defined inline - // inside the pod spec with CSIVolumeSource and their lifecycle is tied to - // the lifecycle of that pod. A driver has to be aware of this - // because it is only going to get a NodePublishVolume call for such a volume. + // volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. + // The default if the list is empty is "Persistent", which is the usage defined by the + // CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. + // + // The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec + // with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. + // A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. + // // For more information about implementing this mode, see // https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html // A driver can support one or more of these modes and @@ -130,10 +129,9 @@ message CSIDriverSpec { // +optional repeated string volumeLifecycleModes = 3; - // If set to true, storageCapacity indicates that the CSI - // volume driver wants pod scheduling to consider the storage + // storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage // capacity that the driver deployment will report by creating - // CSIStorageCapacity objects with capacity information. + // CSIStorageCapacity objects with capacity information, if set to true. // // The check can be enabled immediately when deploying a driver. // In that case, provisioning new volumes with late binding @@ -149,7 +147,7 @@ message CSIDriverSpec { // +optional optional bool storageCapacity = 4; - // Defines if the underlying volume supports changing ownership and + // fsGroupPolicy defines if the underlying volume supports changing ownership and // permission of the volume before being mounted. // Refer to the specific FSGroupPolicy values for additional details. // @@ -159,10 +157,11 @@ message CSIDriverSpec { // to determine if Kubernetes should modify ownership and permissions of the volume. // With the default policy the defined fsGroup will only be applied // if a fstype is defined and the volume's access mode contains ReadWriteOnce. + // // +optional optional string fsGroupPolicy = 5; - // TokenRequests indicates the CSI driver needs pods' service account + // tokenRequests indicates the CSI driver needs pods' service account // tokens it is mounting volume for to do necessary authentication. Kubelet // will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. // The CSI driver should parse and validate the following VolumeContext: @@ -182,7 +181,7 @@ message CSIDriverSpec { // +listType=atomic repeated TokenRequest tokenRequests = 6; - // RequiresRepublish indicates the CSI driver wants `NodePublishVolume` + // requiresRepublish indicates the CSI driver wants `NodePublishVolume` // being periodically called to reflect any possible change in the mounted // volume. This field defaults to false. // @@ -193,7 +192,7 @@ message CSIDriverSpec { // +optional optional bool requiresRepublish = 7; - // SELinuxMount specifies if the CSI driver supports "-o context" + // seLinuxMount specifies if the CSI driver supports "-o context" // mount option. // // When "true", the CSI driver must ensure that all volumes provided by this CSI @@ -211,6 +210,7 @@ message CSIDriverSpec { // // Default is "false". // + // +featureGate=SELinuxMountReadWriteOncePod // +optional optional bool seLinuxMount = 8; } @@ -236,7 +236,7 @@ message CSINode { // CSINodeDriver holds information about the specification of one CSI driver installed on a node message CSINodeDriver { - // This is the name of the CSI driver that this object refers to. + // name represents the name of the CSI driver that this object refers to. // This MUST be the same name returned by the CSI GetPluginName() call for // that driver. optional string name = 1; @@ -327,7 +327,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -336,7 +336,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector nodeTopology = 2; - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -344,7 +344,7 @@ message CSIStorageCapacity { // This field is immutable. optional string storageClassName = 3; - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -356,7 +356,7 @@ message CSIStorageCapacity { // +optional optional k8s.io.apimachinery.pkg.api.resource.Quantity capacity = 4; - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -378,7 +378,7 @@ message CSIStorageCapacityList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name repeated CSIStorageCapacity items = 2; @@ -395,36 +395,36 @@ message StorageClass { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Provisioner indicates the type of the provisioner. + // provisioner indicates the type of the provisioner. optional string provisioner = 2; - // Parameters holds the parameters for the provisioner that should + // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional map parameters = 3; - // Dynamically provisioned PersistentVolumes of this storage class are - // created with this reclaimPolicy. Defaults to Delete. + // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. + // Defaults to Delete. // +optional optional string reclaimPolicy = 4; - // Dynamically provisioned PersistentVolumes of this storage class are - // created with these mountOptions, e.g. ["ro", "soft"]. Not validated - + // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. + // e.g. ["ro", "soft"]. Not validated - // mount of the PVs will simply fail if one is invalid. // +optional repeated string mountOptions = 5; - // AllowVolumeExpansion shows whether the storage class allow volume expand + // allowVolumeExpansion shows whether the storage class allow volume expand // +optional optional bool allowVolumeExpansion = 6; - // VolumeBindingMode indicates how PersistentVolumeClaims should be + // volumeBindingMode indicates how PersistentVolumeClaims should be // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional optional string volumeBindingMode = 7; - // Restrict the node topologies where volumes can be dynamically provisioned. + // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. // Each volume plugin defines its own supported topology specifications. // An empty TopologySelectorTerm list means there is no topology restriction. // This field is only honored by servers that enable the VolumeScheduling feature. @@ -440,17 +440,17 @@ message StorageClassList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of StorageClasses + // items is the list of StorageClasses repeated StorageClass items = 2; } // TokenRequest contains parameters of a service account token. message TokenRequest { - // Audience is the intended audience of the token in "TokenRequestSpec". + // audience is the intended audience of the token in "TokenRequestSpec". // It will default to the audiences of kube apiserver. optional string audience = 1; - // ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". + // expirationSeconds is the duration of validity of the token in "TokenRequestSpec". // It has the same default value of "ExpirationSeconds" in "TokenRequestSpec" // // +optional @@ -467,11 +467,11 @@ message VolumeAttachment { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. optional VolumeAttachmentSpec spec = 2; - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -485,7 +485,7 @@ message VolumeAttachmentList { // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; - // Items is the list of VolumeAttachments + // items is the list of VolumeAttachments repeated VolumeAttachment items = 2; } @@ -494,7 +494,7 @@ message VolumeAttachmentList { // in future we may allow also inline volumes in pods. // Exactly one member can be set. message VolumeAttachmentSource { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional optional string persistentVolumeName = 1; @@ -510,39 +510,39 @@ message VolumeAttachmentSource { // VolumeAttachmentSpec is the specification of a VolumeAttachment request. message VolumeAttachmentSpec { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). optional string attacher = 1; - // Source represents the volume that should be attached. + // source represents the volume that should be attached. optional VolumeAttachmentSource source = 2; - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. optional string nodeName = 3; } // VolumeAttachmentStatus is the status of a VolumeAttachment request. message VolumeAttachmentStatus { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. optional bool attached = 1; - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional map attachmentMetadata = 2; - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional optional VolumeError attachError = 3; - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -551,11 +551,11 @@ message VolumeAttachmentStatus { // VolumeError captures an error encountered during a volume operation. message VolumeError { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional optional k8s.io.apimachinery.pkg.apis.meta.v1.Time time = 1; - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string may be logged, so it should not contain sensitive // information. // +optional @@ -564,7 +564,7 @@ message VolumeError { // VolumeNodeResources is a set of resource limits for scheduling of volumes. message VolumeNodeResources { - // Maximum number of unique volumes managed by the CSI driver that can be used on a node. + // count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. // A volume that is both attached and mounted on a node is considered to be used once, not twice. // The same rule applies for a unique volume that is shared among multiple pods on the same node. // If this field is nil, then the supported number of volumes on this node is unbounded. diff --git a/vendor/k8s.io/api/storage/v1beta1/types.go b/vendor/k8s.io/api/storage/v1beta1/types.go index f4d09b641..4c39b49cc 100644 --- a/vendor/k8s.io/api/storage/v1beta1/types.go +++ b/vendor/k8s.io/api/storage/v1beta1/types.go @@ -36,41 +36,42 @@ import ( // according to etcd is in ObjectMeta.Name. type StorageClass 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"` - // Provisioner indicates the type of the provisioner. + // provisioner indicates the type of the provisioner. Provisioner string `json:"provisioner" protobuf:"bytes,2,opt,name=provisioner"` - // Parameters holds the parameters for the provisioner that should + // parameters holds the parameters for the provisioner that should // create volumes of this storage class. // +optional Parameters map[string]string `json:"parameters,omitempty" protobuf:"bytes,3,rep,name=parameters"` - // Dynamically provisioned PersistentVolumes of this storage class are - // created with this reclaimPolicy. Defaults to Delete. + // reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. + // Defaults to Delete. // +optional ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty" protobuf:"bytes,4,opt,name=reclaimPolicy,casttype=k8s.io/api/core/v1.PersistentVolumeReclaimPolicy"` - // Dynamically provisioned PersistentVolumes of this storage class are - // created with these mountOptions, e.g. ["ro", "soft"]. Not validated - + // mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. + // e.g. ["ro", "soft"]. Not validated - // mount of the PVs will simply fail if one is invalid. // +optional MountOptions []string `json:"mountOptions,omitempty" protobuf:"bytes,5,opt,name=mountOptions"` - // AllowVolumeExpansion shows whether the storage class allow volume expand + // allowVolumeExpansion shows whether the storage class allow volume expand // +optional AllowVolumeExpansion *bool `json:"allowVolumeExpansion,omitempty" protobuf:"varint,6,opt,name=allowVolumeExpansion"` - // VolumeBindingMode indicates how PersistentVolumeClaims should be + // volumeBindingMode indicates how PersistentVolumeClaims should be // provisioned and bound. When unset, VolumeBindingImmediate is used. // This field is only honored by servers that enable the VolumeScheduling feature. // +optional VolumeBindingMode *VolumeBindingMode `json:"volumeBindingMode,omitempty" protobuf:"bytes,7,opt,name=volumeBindingMode"` - // Restrict the node topologies where volumes can be dynamically provisioned. + // allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. // Each volume plugin defines its own supported topology specifications. // An empty TopologySelectorTerm list means there is no topology restriction. // This field is only honored by servers that enable the VolumeScheduling feature. @@ -87,12 +88,13 @@ type StorageClass struct { // StorageClassList is a collection of storage classes. type StorageClassList 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 the list of StorageClasses + // items is the list of StorageClasses Items []StorageClass `json:"items" protobuf:"bytes,2,rep,name=items"` } @@ -130,11 +132,11 @@ type VolumeAttachment struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the desired attach/detach volume behavior. + // spec represents specification of the desired attach/detach volume behavior. // Populated by the Kubernetes system. Spec VolumeAttachmentSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` - // Status of the VolumeAttachment request. + // status represents status of the VolumeAttachment request. // Populated by the entity completing the attach or detach // operation, i.e. the external-attacher. // +optional @@ -149,25 +151,26 @@ type VolumeAttachment struct { // VolumeAttachmentList is a collection of VolumeAttachment objects. type VolumeAttachmentList 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 the list of VolumeAttachments + // items is the list of VolumeAttachments Items []VolumeAttachment `json:"items" protobuf:"bytes,2,rep,name=items"` } // VolumeAttachmentSpec is the specification of a VolumeAttachment request. type VolumeAttachmentSpec struct { - // Attacher indicates the name of the volume driver that MUST handle this + // attacher indicates the name of the volume driver that MUST handle this // request. This is the name returned by GetPluginName(). Attacher string `json:"attacher" protobuf:"bytes,1,opt,name=attacher"` - // Source represents the volume that should be attached. + // source represents the volume that should be attached. Source VolumeAttachmentSource `json:"source" protobuf:"bytes,2,opt,name=source"` - // The node that the volume should be attached to. + // nodeName represents the node that the volume should be attached to. NodeName string `json:"nodeName" protobuf:"bytes,3,opt,name=nodeName"` } @@ -176,7 +179,7 @@ type VolumeAttachmentSpec struct { // in future we may allow also inline volumes in pods. // Exactly one member can be set. type VolumeAttachmentSource struct { - // Name of the persistent volume to attach. + // persistentVolumeName represents the name of the persistent volume to attach. // +optional PersistentVolumeName *string `json:"persistentVolumeName,omitempty" protobuf:"bytes,1,opt,name=persistentVolumeName"` @@ -192,26 +195,26 @@ type VolumeAttachmentSource struct { // VolumeAttachmentStatus is the status of a VolumeAttachment request. type VolumeAttachmentStatus struct { - // Indicates the volume is successfully attached. + // attached indicates the volume is successfully attached. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. Attached bool `json:"attached" protobuf:"varint,1,opt,name=attached"` - // Upon successful attach, this field is populated with any - // information returned by the attach operation that must be passed + // attachmentMetadata is populated with any + // information returned by the attach operation, upon successful attach, that must be passed // into subsequent WaitForAttach or Mount calls. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachmentMetadata map[string]string `json:"attachmentMetadata,omitempty" protobuf:"bytes,2,rep,name=attachmentMetadata"` - // The last error encountered during attach operation, if any. + // attachError represents the last error encountered during attach operation, if any. // This field must only be set by the entity completing the attach // operation, i.e. the external-attacher. // +optional AttachError *VolumeError `json:"attachError,omitempty" protobuf:"bytes,3,opt,name=attachError,casttype=VolumeError"` - // The last error encountered during detach operation, if any. + // detachError represents the last error encountered during detach operation, if any. // This field must only be set by the entity completing the detach // operation, i.e. the external-attacher. // +optional @@ -220,11 +223,11 @@ type VolumeAttachmentStatus struct { // VolumeError captures an error encountered during a volume operation. type VolumeError struct { - // Time the error was encountered. + // time represents the time the error was encountered. // +optional Time metav1.Time `json:"time,omitempty" protobuf:"bytes,1,opt,name=time"` - // String detailing the error encountered during Attach or Detach operation. + // message represents the error encountered during Attach or Detach operation. // This string may be logged, so it should not contain sensitive // information. // +optional @@ -259,7 +262,7 @@ type CSIDriver struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // Specification of the CSI Driver. + // spec represents the specification of the CSI Driver. Spec CSIDriverSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` } @@ -299,16 +302,15 @@ type CSIDriverSpec struct { // +optional AttachRequired *bool `json:"attachRequired,omitempty" protobuf:"varint,1,opt,name=attachRequired"` - // If set to true, podInfoOnMount indicates this CSI volume driver - // requires additional pod information (like podName, podUID, etc.) during - // mount operations. + // podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) + // during mount operations, if set to true. // If set to false, pod information will not be passed on mount. // Default is false. + // // The CSI driver specifies podInfoOnMount as part of driver deployment. - // If true, Kubelet will pass pod information as VolumeContext in the CSI - // NodePublishVolume() calls. - // The CSI driver is responsible for parsing and validating the information - // passed in as VolumeContext. + // If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. + // The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. + // // The following VolumeConext will be passed if podInfoOnMount is set to true. // This list might grow, but the prefix will be used. // "csi.storage.k8s.io/pod.name": pod.Name @@ -329,14 +331,14 @@ type CSIDriverSpec struct { // +optional PodInfoOnMount *bool `json:"podInfoOnMount,omitempty" protobuf:"bytes,2,opt,name=podInfoOnMount"` - // VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. - // The default if the list is empty is "Persistent", which is the usage - // defined by the CSI specification and implemented in Kubernetes via the usual - // PV/PVC mechanism. - // The other mode is "Ephemeral". In this mode, volumes are defined inline - // inside the pod spec with CSIVolumeSource and their lifecycle is tied to - // the lifecycle of that pod. A driver has to be aware of this - // because it is only going to get a NodePublishVolume call for such a volume. + // volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. + // The default if the list is empty is "Persistent", which is the usage defined by the + // CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. + // + // The other mode is "Ephemeral". In this mode, volumes are defined inline inside the pod spec + // with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. + // A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. + // // For more information about implementing this mode, see // https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html // A driver can support one or more of these modes and @@ -347,11 +349,9 @@ type CSIDriverSpec struct { // +optional VolumeLifecycleModes []VolumeLifecycleMode `json:"volumeLifecycleModes,omitempty" protobuf:"bytes,3,opt,name=volumeLifecycleModes"` - // If set to true, storageCapacity indicates that the CSI - // volume driver wants pod scheduling to consider the storage + // storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage // capacity that the driver deployment will report by creating - // CSIStorageCapacity objects with capacity information. - // + // CSIStorageCapacity objects with capacity information, if set to true. // // The check can be enabled immediately when deploying a driver. // In that case, provisioning new volumes with late binding @@ -367,7 +367,7 @@ type CSIDriverSpec struct { // +optional StorageCapacity *bool `json:"storageCapacity,omitempty" protobuf:"bytes,4,opt,name=storageCapacity"` - // Defines if the underlying volume supports changing ownership and + // fsGroupPolicy defines if the underlying volume supports changing ownership and // permission of the volume before being mounted. // Refer to the specific FSGroupPolicy values for additional details. // @@ -377,10 +377,11 @@ type CSIDriverSpec struct { // to determine if Kubernetes should modify ownership and permissions of the volume. // With the default policy the defined fsGroup will only be applied // if a fstype is defined and the volume's access mode contains ReadWriteOnce. + // // +optional FSGroupPolicy *FSGroupPolicy `json:"fsGroupPolicy,omitempty" protobuf:"bytes,5,opt,name=fsGroupPolicy"` - // TokenRequests indicates the CSI driver needs pods' service account + // tokenRequests indicates the CSI driver needs pods' service account // tokens it is mounting volume for to do necessary authentication. Kubelet // will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. // The CSI driver should parse and validate the following VolumeContext: @@ -400,7 +401,7 @@ type CSIDriverSpec struct { // +listType=atomic TokenRequests []TokenRequest `json:"tokenRequests,omitempty" protobuf:"bytes,6,opt,name=tokenRequests"` - // RequiresRepublish indicates the CSI driver wants `NodePublishVolume` + // requiresRepublish indicates the CSI driver wants `NodePublishVolume` // being periodically called to reflect any possible change in the mounted // volume. This field defaults to false. // @@ -411,7 +412,7 @@ type CSIDriverSpec struct { // +optional RequiresRepublish *bool `json:"requiresRepublish,omitempty" protobuf:"varint,7,opt,name=requiresRepublish"` - // SELinuxMount specifies if the CSI driver supports "-o context" + // seLinuxMount specifies if the CSI driver supports "-o context" // mount option. // // When "true", the CSI driver must ensure that all volumes provided by this CSI @@ -429,6 +430,7 @@ type CSIDriverSpec struct { // // Default is "false". // + // +featureGate=SELinuxMountReadWriteOncePod // +optional SELinuxMount *bool `json:"seLinuxMount,omitempty" protobuf:"varint,8,opt,name=seLinuxMount"` } @@ -466,12 +468,11 @@ type VolumeLifecycleMode string // TokenRequest contains parameters of a service account token. type TokenRequest struct { - // Audience is the intended audience of the token in "TokenRequestSpec". + // audience is the intended audience of the token in "TokenRequestSpec". // It will default to the audiences of kube apiserver. - // Audience string `json:"audience" protobuf:"bytes,1,opt,name=audience"` - // ExpirationSeconds is the duration of validity of the token in "TokenRequestSpec". + // expirationSeconds is the duration of validity of the token in "TokenRequestSpec". // It has the same default value of "ExpirationSeconds" in "TokenRequestSpec" // // +optional @@ -539,7 +540,7 @@ type CSINodeSpec struct { // CSINodeDriver holds information about the specification of one CSI driver installed on a node type CSINodeDriver struct { - // This is the name of the CSI driver that this object refers to. + // name represents the name of the CSI driver that this object refers to. // This MUST be the same name returned by the CSI GetPluginName() call for // that driver. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` @@ -575,7 +576,7 @@ type CSINodeDriver struct { // VolumeNodeResources is a set of resource limits for scheduling of volumes. type VolumeNodeResources struct { - // Maximum number of unique volumes managed by the CSI driver that can be used on a node. + // count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. // A volume that is both attached and mounted on a node is considered to be used once, not twice. // The same rule applies for a unique volume that is shared among multiple pods on the same node. // If this field is nil, then the supported number of volumes on this node is unbounded. @@ -634,6 +635,7 @@ type CSINodeList struct { // node. type CSIStorageCapacity struct { metav1.TypeMeta `json:",inline"` + // Standard object's metadata. The name has no particular meaning. It must be // be a DNS subdomain (dots allowed, 253 characters). To ensure that // there are no conflicts with other CSI drivers on the cluster, the recommendation @@ -646,7 +648,7 @@ type CSIStorageCapacity struct { // +optional metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` - // NodeTopology defines which nodes have access to the storage + // nodeTopology defines which nodes have access to the storage // for which capacity was reported. If not set, the storage is // not accessible from any node in the cluster. If empty, the // storage is accessible from all nodes. This field is @@ -655,7 +657,7 @@ type CSIStorageCapacity struct { // +optional NodeTopology *metav1.LabelSelector `json:"nodeTopology,omitempty" protobuf:"bytes,2,opt,name=nodeTopology"` - // The name of the StorageClass that the reported capacity applies to. + // storageClassName represents the name of the StorageClass that the reported capacity applies to. // It must meet the same requirements as the name of a StorageClass // object (non-empty, DNS subdomain). If that object no longer exists, // the CSIStorageCapacity object is obsolete and should be removed by its @@ -663,7 +665,7 @@ type CSIStorageCapacity struct { // This field is immutable. StorageClassName string `json:"storageClassName" protobuf:"bytes,3,name=storageClassName"` - // Capacity is the value reported by the CSI driver in its GetCapacityResponse + // capacity is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -675,7 +677,7 @@ type CSIStorageCapacity struct { // +optional Capacity *resource.Quantity `json:"capacity,omitempty" protobuf:"bytes,4,opt,name=capacity"` - // MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse + // maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse // for a GetCapacityRequest with topology and parameters that match the // previous fields. // @@ -698,12 +700,13 @@ type CSIStorageCapacity struct { // CSIStorageCapacityList is a collection of CSIStorageCapacity objects. type CSIStorageCapacityList 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 the list of CSIStorageCapacity objects. + // items is the list of CSIStorageCapacity objects. // +listType=map // +listMapKey=name Items []CSIStorageCapacity `json:"items" protobuf:"bytes,2,rep,name=items"` diff --git a/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go index ea3c1e4c2..0f2718b9c 100644 --- a/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/api/storage/v1beta1/types_swagger_doc_generated.go @@ -24,13 +24,13 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_CSIDriver = map[string]string{ "": "CSIDriver captures information about a Container Storage Interface (CSI) volume driver deployed on the cluster. CSI drivers do not need to create the CSIDriver object directly. Instead they may use the cluster-driver-registrar sidecar container. When deployed with a CSI driver it automatically creates a CSIDriver object representing the driver. Kubernetes attach detach controller uses this object to determine whether attach is required. Kubelet uses this object to determine whether pod information needs to be passed on mount. CSIDriver objects are non-namespaced.", "metadata": "Standard object metadata. metadata.Name indicates the name of the CSI driver that this object refers to; it MUST be the same name returned by the CSI GetPluginName() call for that driver. The driver name must be 63 characters or less, beginning and ending with an alphanumeric character ([a-z0-9A-Z]) with dashes (-), dots (.), and alphanumerics between. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the CSI Driver.", + "spec": "spec represents the specification of the CSI Driver.", } func (CSIDriver) SwaggerDoc() map[string]string { @@ -50,13 +50,13 @@ func (CSIDriverList) SwaggerDoc() map[string]string { var map_CSIDriverSpec = map[string]string{ "": "CSIDriverSpec is the specification of a CSIDriver.", "attachRequired": "attachRequired indicates this CSI volume driver requires an attach operation (because it implements the CSI ControllerPublishVolume() method), and that the Kubernetes attach detach controller should call the attach volume interface which checks the volumeattachment status and waits until the volume is attached before proceeding to mounting. The CSI external-attacher coordinates with CSI volume driver and updates the volumeattachment status when the attach operation is complete. If the CSIDriverRegistry feature gate is enabled and the value is specified to false, the attach operation will be skipped. Otherwise the attach operation will be called.\n\nThis field is immutable.", - "podInfoOnMount": "If set to true, podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations. If set to false, pod information will not be passed on mount. Default is false. The CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext. The following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", - "volumeLifecycleModes": "VolumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism. The other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume. For more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.\n\nThis field is immutable.", - "storageCapacity": "If set to true, storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", - "fsGroupPolicy": "Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", - "tokenRequests": "TokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", - "requiresRepublish": "RequiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", - "seLinuxMount": "SELinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", + "podInfoOnMount": "podInfoOnMount indicates this CSI volume driver requires additional pod information (like podName, podUID, etc.) during mount operations, if set to true. If set to false, pod information will not be passed on mount. Default is false.\n\nThe CSI driver specifies podInfoOnMount as part of driver deployment. If true, Kubelet will pass pod information as VolumeContext in the CSI NodePublishVolume() calls. The CSI driver is responsible for parsing and validating the information passed in as VolumeContext.\n\nThe following VolumeConext will be passed if podInfoOnMount is set to true. This list might grow, but the prefix will be used. \"csi.storage.k8s.io/pod.name\": pod.Name \"csi.storage.k8s.io/pod.namespace\": pod.Namespace \"csi.storage.k8s.io/pod.uid\": string(pod.UID) \"csi.storage.k8s.io/ephemeral\": \"true\" if the volume is an ephemeral inline volume\n defined by a CSIVolumeSource, otherwise \"false\"\n\n\"csi.storage.k8s.io/ephemeral\" is a new feature in Kubernetes 1.16. It is only required for drivers which support both the \"Persistent\" and \"Ephemeral\" VolumeLifecycleMode. Other drivers can leave pod info disabled and/or ignore this field. As Kubernetes 1.15 doesn't support this field, drivers can only support one mode when deployed on such a cluster and the deployment determines which mode that is, for example via a command line parameter of the driver.\n\nThis field is immutable.", + "volumeLifecycleModes": "volumeLifecycleModes defines what kind of volumes this CSI volume driver supports. The default if the list is empty is \"Persistent\", which is the usage defined by the CSI specification and implemented in Kubernetes via the usual PV/PVC mechanism.\n\nThe other mode is \"Ephemeral\". In this mode, volumes are defined inline inside the pod spec with CSIVolumeSource and their lifecycle is tied to the lifecycle of that pod. A driver has to be aware of this because it is only going to get a NodePublishVolume call for such a volume.\n\nFor more information about implementing this mode, see https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html A driver can support one or more of these modes and more modes may be added in the future.\n\nThis field is immutable.", + "storageCapacity": "storageCapacity indicates that the CSI volume driver wants pod scheduling to consider the storage capacity that the driver deployment will report by creating CSIStorageCapacity objects with capacity information, if set to true.\n\nThe check can be enabled immediately when deploying a driver. In that case, provisioning new volumes with late binding will pause until the driver deployment has published some suitable CSIStorageCapacity object.\n\nAlternatively, the driver can be deployed with the field unset or false and it can be flipped later when storage capacity information has been published.\n\nThis field was immutable in Kubernetes <= 1.22 and now is mutable.", + "fsGroupPolicy": "fsGroupPolicy defines if the underlying volume supports changing ownership and permission of the volume before being mounted. Refer to the specific FSGroupPolicy values for additional details.\n\nThis field is immutable.\n\nDefaults to ReadWriteOnceWithFSType, which will examine each volume to determine if Kubernetes should modify ownership and permissions of the volume. With the default policy the defined fsGroup will only be applied if a fstype is defined and the volume's access mode contains ReadWriteOnce.", + "tokenRequests": "tokenRequests indicates the CSI driver needs pods' service account tokens it is mounting volume for to do necessary authentication. Kubelet will pass the tokens in VolumeContext in the CSI NodePublishVolume calls. The CSI driver should parse and validate the following VolumeContext: \"csi.storage.k8s.io/serviceAccount.tokens\": {\n \"\": {\n \"token\": ,\n \"expirationTimestamp\": ,\n },\n ...\n}\n\nNote: Audience in each TokenRequest should be different and at most one token is empty string. To receive a new token after expiry, RequiresRepublish can be used to trigger NodePublishVolume periodically.", + "requiresRepublish": "requiresRepublish indicates the CSI driver wants `NodePublishVolume` being periodically called to reflect any possible change in the mounted volume. This field defaults to false.\n\nNote: After a successful initial NodePublishVolume call, subsequent calls to NodePublishVolume should only update the contents of the volume. New mount points will not be seen by a running container.", + "seLinuxMount": "seLinuxMount specifies if the CSI driver supports \"-o context\" mount option.\n\nWhen \"true\", the CSI driver must ensure that all volumes provided by this CSI driver can be mounted separately with different `-o context` options. This is typical for storage backends that provide volumes as filesystems on block devices or as independent shared volumes. Kubernetes will call NodeStage / NodePublish with \"-o context=xyz\" mount option when mounting a ReadWriteOncePod volume used in Pod that has explicitly set SELinux context. In the future, it may be expanded to other volume AccessModes. In any case, Kubernetes will ensure that the volume is mounted only with a single SELinux context.\n\nWhen \"false\", Kubernetes won't pass any special SELinux mount options to the driver. This is typical for volumes that represent subdirectories of a bigger shared filesystem.\n\nDefault is \"false\".", } func (CSIDriverSpec) SwaggerDoc() map[string]string { @@ -75,7 +75,7 @@ func (CSINode) SwaggerDoc() map[string]string { var map_CSINodeDriver = map[string]string{ "": "CSINodeDriver holds information about the specification of one CSI driver installed on a node", - "name": "This is the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.", + "name": "name represents the name of the CSI driver that this object refers to. This MUST be the same name returned by the CSI GetPluginName() call for that driver.", "nodeID": "nodeID of the node from the driver point of view. This field enables Kubernetes to communicate with storage systems that do not share the same nomenclature for nodes. For example, Kubernetes may refer to a given node as \"node1\", but the storage system may refer to the same node as \"nodeA\". When Kubernetes issues a command to the storage system to attach a volume to a specific node, it can use this field to refer to the node name using the ID that the storage system will understand, e.g. \"nodeA\" instead of \"node1\". This field is required.", "topologyKeys": "topologyKeys is the list of keys supported by the driver. When a driver is initialized on a cluster, it provides a set of topology keys that it understands (e.g. \"company.com/zone\", \"company.com/region\"). When a driver is initialized on a node, it provides the same topology keys along with values. Kubelet will expose these topology keys as labels on its own node object. When Kubernetes does topology aware provisioning, it can use this list to determine which labels it should retrieve from the node object and pass back to the driver. It is possible for different nodes to use different topology keys. This can be empty if driver does not support topology.", "allocatable": "allocatable represents the volume resources of a node that are available for scheduling.", @@ -107,10 +107,10 @@ func (CSINodeSpec) SwaggerDoc() map[string]string { var map_CSIStorageCapacity = map[string]string{ "": "CSIStorageCapacity stores the result of one CSI GetCapacity call. For a given StorageClass, this describes the available capacity in a particular topology segment. This can be used when considering where to instantiate new PersistentVolumes.\n\nFor example this can express things like: - StorageClass \"standard\" has \"1234 GiB\" available in \"topology.kubernetes.io/zone=us-east1\" - StorageClass \"localssd\" has \"10 GiB\" available in \"kubernetes.io/hostname=knode-abc123\"\n\nThe following three cases all imply that no capacity is available for a certain combination: - no object exists with suitable topology and storage class name - such an object exists, but the capacity is unset - such an object exists, but the capacity is zero\n\nThe producer of these objects can decide which approach is more suitable.\n\nThey are consumed by the kube-scheduler when a CSI driver opts into capacity-aware scheduling with CSIDriverSpec.StorageCapacity. The scheduler compares the MaximumVolumeSize against the requested size of pending volumes to filter out unsuitable nodes. If MaximumVolumeSize is unset, it falls back to a comparison against the less precise Capacity. If that is also unset, the scheduler assumes that capacity is insufficient and tries some other node.", "metadata": "Standard object's metadata. The name has no particular meaning. It must be be a DNS subdomain (dots allowed, 253 characters). To ensure that there are no conflicts with other CSI drivers on the cluster, the recommendation is to use csisc-, a generated name, or a reverse-domain name which ends with the unique CSI driver name.\n\nObjects are namespaced.\n\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "nodeTopology": "NodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", - "storageClassName": "The name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", - "capacity": "Capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", - "maximumVolumeSize": "MaximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", + "nodeTopology": "nodeTopology defines which nodes have access to the storage for which capacity was reported. If not set, the storage is not accessible from any node in the cluster. If empty, the storage is accessible from all nodes. This field is immutable.", + "storageClassName": "storageClassName represents the name of the StorageClass that the reported capacity applies to. It must meet the same requirements as the name of a StorageClass object (non-empty, DNS subdomain). If that object no longer exists, the CSIStorageCapacity object is obsolete and should be removed by its creator. This field is immutable.", + "capacity": "capacity is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThe semantic is currently (CSI spec 1.2) defined as: The available capacity, in bytes, of the storage that can be used to provision volumes. If not set, that information is currently unavailable.", + "maximumVolumeSize": "maximumVolumeSize is the value reported by the CSI driver in its GetCapacityResponse for a GetCapacityRequest with topology and parameters that match the previous fields.\n\nThis is defined since CSI spec 1.4.0 as the largest size that may be used in a CreateVolumeRequest.capacity_range.required_bytes field to create a volume with the same parameters as those in GetCapacityRequest. The corresponding value in the Kubernetes API is ResourceRequirements.Requests in a volume claim.", } func (CSIStorageCapacity) SwaggerDoc() map[string]string { @@ -120,7 +120,7 @@ func (CSIStorageCapacity) SwaggerDoc() map[string]string { var map_CSIStorageCapacityList = map[string]string{ "": "CSIStorageCapacityList is a collection of CSIStorageCapacity objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of CSIStorageCapacity objects.", + "items": "items is the list of CSIStorageCapacity objects.", } func (CSIStorageCapacityList) SwaggerDoc() map[string]string { @@ -130,13 +130,13 @@ func (CSIStorageCapacityList) SwaggerDoc() map[string]string { var map_StorageClass = map[string]string{ "": "StorageClass describes the parameters for a class of storage for which PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class according to etcd is in ObjectMeta.Name.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "provisioner": "Provisioner indicates the type of the provisioner.", - "parameters": "Parameters holds the parameters for the provisioner that should create volumes of this storage class.", - "reclaimPolicy": "Dynamically provisioned PersistentVolumes of this storage class are created with this reclaimPolicy. Defaults to Delete.", - "mountOptions": "Dynamically provisioned PersistentVolumes of this storage class are created with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.", - "allowVolumeExpansion": "AllowVolumeExpansion shows whether the storage class allow volume expand", - "volumeBindingMode": "VolumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.", - "allowedTopologies": "Restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.", + "provisioner": "provisioner indicates the type of the provisioner.", + "parameters": "parameters holds the parameters for the provisioner that should create volumes of this storage class.", + "reclaimPolicy": "reclaimPolicy controls the reclaimPolicy for dynamically provisioned PersistentVolumes of this storage class. Defaults to Delete.", + "mountOptions": "mountOptions controls the mountOptions for dynamically provisioned PersistentVolumes of this storage class. e.g. [\"ro\", \"soft\"]. Not validated - mount of the PVs will simply fail if one is invalid.", + "allowVolumeExpansion": "allowVolumeExpansion shows whether the storage class allow volume expand", + "volumeBindingMode": "volumeBindingMode indicates how PersistentVolumeClaims should be provisioned and bound. When unset, VolumeBindingImmediate is used. This field is only honored by servers that enable the VolumeScheduling feature.", + "allowedTopologies": "allowedTopologies restrict the node topologies where volumes can be dynamically provisioned. Each volume plugin defines its own supported topology specifications. An empty TopologySelectorTerm list means there is no topology restriction. This field is only honored by servers that enable the VolumeScheduling feature.", } func (StorageClass) SwaggerDoc() map[string]string { @@ -146,7 +146,7 @@ func (StorageClass) SwaggerDoc() map[string]string { var map_StorageClassList = map[string]string{ "": "StorageClassList is a collection of storage classes.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of StorageClasses", + "items": "items is the list of StorageClasses", } func (StorageClassList) SwaggerDoc() map[string]string { @@ -155,8 +155,8 @@ func (StorageClassList) SwaggerDoc() map[string]string { var map_TokenRequest = map[string]string{ "": "TokenRequest contains parameters of a service account token.", - "audience": "Audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.", - "expirationSeconds": "ExpirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\"", + "audience": "audience is the intended audience of the token in \"TokenRequestSpec\". It will default to the audiences of kube apiserver.", + "expirationSeconds": "expirationSeconds is the duration of validity of the token in \"TokenRequestSpec\". It has the same default value of \"ExpirationSeconds\" in \"TokenRequestSpec\"", } func (TokenRequest) SwaggerDoc() map[string]string { @@ -166,8 +166,8 @@ func (TokenRequest) SwaggerDoc() map[string]string { var map_VolumeAttachment = map[string]string{ "": "VolumeAttachment captures the intent to attach or detach the specified volume to/from the specified node.\n\nVolumeAttachment objects are non-namespaced.", "metadata": "Standard object metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "spec": "Specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", - "status": "Status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", + "spec": "spec represents specification of the desired attach/detach volume behavior. Populated by the Kubernetes system.", + "status": "status represents status of the VolumeAttachment request. Populated by the entity completing the attach or detach operation, i.e. the external-attacher.", } func (VolumeAttachment) SwaggerDoc() map[string]string { @@ -177,7 +177,7 @@ func (VolumeAttachment) SwaggerDoc() map[string]string { var map_VolumeAttachmentList = map[string]string{ "": "VolumeAttachmentList is a collection of VolumeAttachment objects.", "metadata": "Standard list metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - "items": "Items is the list of VolumeAttachments", + "items": "items is the list of VolumeAttachments", } func (VolumeAttachmentList) SwaggerDoc() map[string]string { @@ -186,7 +186,7 @@ func (VolumeAttachmentList) SwaggerDoc() map[string]string { var map_VolumeAttachmentSource = map[string]string{ "": "VolumeAttachmentSource represents a volume that should be attached. Right now only PersistenVolumes can be attached via external attacher, in future we may allow also inline volumes in pods. Exactly one member can be set.", - "persistentVolumeName": "Name of the persistent volume to attach.", + "persistentVolumeName": "persistentVolumeName represents the name of the persistent volume to attach.", } func (VolumeAttachmentSource) SwaggerDoc() map[string]string { @@ -195,9 +195,9 @@ func (VolumeAttachmentSource) SwaggerDoc() map[string]string { var map_VolumeAttachmentSpec = map[string]string{ "": "VolumeAttachmentSpec is the specification of a VolumeAttachment request.", - "attacher": "Attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", - "source": "Source represents the volume that should be attached.", - "nodeName": "The node that the volume should be attached to.", + "attacher": "attacher indicates the name of the volume driver that MUST handle this request. This is the name returned by GetPluginName().", + "source": "source represents the volume that should be attached.", + "nodeName": "nodeName represents the node that the volume should be attached to.", } func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { @@ -206,10 +206,10 @@ func (VolumeAttachmentSpec) SwaggerDoc() map[string]string { var map_VolumeAttachmentStatus = map[string]string{ "": "VolumeAttachmentStatus is the status of a VolumeAttachment request.", - "attached": "Indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachmentMetadata": "Upon successful attach, this field is populated with any information returned by the attach operation that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "attachError": "The last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", - "detachError": "The last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", + "attached": "attached indicates the volume is successfully attached. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachmentMetadata": "attachmentMetadata is populated with any information returned by the attach operation, upon successful attach, that must be passed into subsequent WaitForAttach or Mount calls. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "attachError": "attachError represents the last error encountered during attach operation, if any. This field must only be set by the entity completing the attach operation, i.e. the external-attacher.", + "detachError": "detachError represents the last error encountered during detach operation, if any. This field must only be set by the entity completing the detach operation, i.e. the external-attacher.", } func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { @@ -218,8 +218,8 @@ func (VolumeAttachmentStatus) SwaggerDoc() map[string]string { var map_VolumeError = map[string]string{ "": "VolumeError captures an error encountered during a volume operation.", - "time": "Time the error was encountered.", - "message": "String detailing the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", + "time": "time represents the time the error was encountered.", + "message": "message represents the error encountered during Attach or Detach operation. This string may be logged, so it should not contain sensitive information.", } func (VolumeError) SwaggerDoc() map[string]string { @@ -228,7 +228,7 @@ func (VolumeError) SwaggerDoc() map[string]string { var map_VolumeNodeResources = map[string]string{ "": "VolumeNodeResources is a set of resource limits for scheduling of volumes.", - "count": "Maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is nil, then the supported number of volumes on this node is unbounded.", + "count": "count indicates the maximum number of unique volumes managed by the CSI driver that can be used on a node. A volume that is both attached and mounted on a node is considered to be used once, not twice. The same rule applies for a unique volume that is shared among multiple pods on the same node. If this field is nil, then the supported number of volumes on this node is unbounded.", } func (VolumeNodeResources) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go index f402c416d..04ce206bb 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types_jsonschema.go @@ -196,6 +196,18 @@ type ValidationRule struct { // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" Message string + // MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a rule, then messageExpression will be used if validation + // fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the rule; the only difference is the return type. + // Example: + // "x must be less than max ("+string(self.max)+")" + // +optional + MessageExpression string } // JSON represents any valid JSON value. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go index 68eb08082..5dbb38c8b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.pb.go @@ -814,198 +814,199 @@ func init() { } var fileDescriptor_f5a35c9667703937 = []byte{ - // 3047 bytes of a gzipped FileDescriptorProto + // 3072 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5a, 0xdf, 0x6f, 0x24, 0x47, 0xf1, 0xbf, 0x59, 0xff, 0x5a, 0xb7, 0xed, 0xb3, 0xdd, 0x77, 0xf6, 0x77, 0xce, 0xb9, 0xf3, 0xfa, 0x36, 0xdf, 0x1c, 0x4e, 0x72, 0x59, 0x27, 0x26, 0x21, 0x47, 0x84, 0x40, 0x5e, 0xdb, 0x97, 0x38, - 0x67, 0x9f, 0xad, 0xde, 0xbb, 0x8b, 0x93, 0x00, 0xc9, 0x78, 0xa7, 0xbd, 0x9e, 0x78, 0x7e, 0x5d, - 0xf7, 0xcc, 0xda, 0x96, 0x40, 0x8a, 0x40, 0x11, 0x10, 0x09, 0xc2, 0x03, 0x0a, 0x4f, 0x08, 0x21, - 0x94, 0x07, 0x78, 0x80, 0x37, 0xf8, 0x17, 0xf2, 0x82, 0x94, 0x27, 0x14, 0x09, 0x69, 0x45, 0x96, - 0x7f, 0x00, 0x09, 0x10, 0xc2, 0x0f, 0x08, 0xf5, 0x8f, 0xe9, 0xe9, 0x9d, 0xdd, 0xbd, 0x3b, 0xd9, - 0xeb, 0xe4, 0xcd, 0xae, 0xaa, 0xae, 0x4f, 0x75, 0x75, 0x75, 0x55, 0x75, 0xcd, 0x02, 0x6b, 0xff, - 0x06, 0x2d, 0x39, 0xc1, 0xc2, 0x7e, 0xbc, 0x83, 0x89, 0x8f, 0x23, 0x4c, 0x17, 0xea, 0xd8, 0xb7, - 0x03, 0xb2, 0x20, 0x19, 0x56, 0xe8, 0xe0, 0xc3, 0x08, 0xfb, 0xd4, 0x09, 0x7c, 0xfa, 0x8c, 0x15, - 0x3a, 0x14, 0x93, 0x3a, 0x26, 0x0b, 0xe1, 0x7e, 0x8d, 0xf1, 0x68, 0xab, 0xc0, 0x42, 0xfd, 0xb9, - 0x85, 0x1a, 0xf6, 0x31, 0xb1, 0x22, 0x6c, 0x97, 0x42, 0x12, 0x44, 0x01, 0xbc, 0x21, 0x34, 0x95, - 0x5a, 0x04, 0xdf, 0x52, 0x9a, 0x4a, 0xe1, 0x7e, 0x8d, 0xf1, 0x68, 0xab, 0x40, 0xa9, 0xfe, 0xdc, - 0xcc, 0x33, 0x35, 0x27, 0xda, 0x8b, 0x77, 0x4a, 0xd5, 0xc0, 0x5b, 0xa8, 0x05, 0xb5, 0x60, 0x81, - 0x2b, 0xdc, 0x89, 0x77, 0xf9, 0x7f, 0xfc, 0x1f, 0xfe, 0x97, 0x00, 0x9a, 0x79, 0x3e, 0x35, 0xd9, + 0x67, 0x9f, 0xad, 0xde, 0xbb, 0x8b, 0x93, 0x20, 0x92, 0xf1, 0x4e, 0x7b, 0x3d, 0xf1, 0xfc, 0xba, + 0xee, 0x99, 0xb5, 0x2d, 0x81, 0x14, 0x81, 0x22, 0x20, 0x12, 0x84, 0x07, 0x14, 0x9e, 0x10, 0x42, + 0x28, 0x48, 0xf0, 0x00, 0x6f, 0xf0, 0x2f, 0xe4, 0x05, 0x29, 0x4f, 0x28, 0x12, 0xd2, 0x8a, 0x2c, + 0xff, 0x00, 0x12, 0x20, 0x84, 0x1f, 0x10, 0xea, 0x1f, 0xd3, 0xd3, 0x3b, 0xbb, 0x7b, 0x77, 0xb2, + 0xd7, 0xc9, 0xdb, 0x6e, 0x55, 0x75, 0x7d, 0xaa, 0xab, 0xab, 0xab, 0xab, 0xab, 0x07, 0x58, 0xfb, + 0x37, 0x68, 0xc9, 0x09, 0x16, 0xf6, 0xe3, 0x1d, 0x4c, 0x7c, 0x1c, 0x61, 0xba, 0x50, 0xc7, 0xbe, + 0x1d, 0x90, 0x05, 0xc9, 0xb0, 0x42, 0x07, 0x1f, 0x46, 0xd8, 0xa7, 0x4e, 0xe0, 0xd3, 0x67, 0xac, + 0xd0, 0xa1, 0x98, 0xd4, 0x31, 0x59, 0x08, 0xf7, 0x6b, 0x8c, 0x47, 0x5b, 0x05, 0x16, 0xea, 0xcf, + 0x2d, 0xd4, 0xb0, 0x8f, 0x89, 0x15, 0x61, 0xbb, 0x14, 0x92, 0x20, 0x0a, 0xe0, 0x0d, 0xa1, 0xa9, + 0xd4, 0x22, 0xf8, 0x96, 0xd2, 0x54, 0x0a, 0xf7, 0x6b, 0x8c, 0x47, 0x5b, 0x05, 0x4a, 0xf5, 0xe7, + 0x66, 0x9e, 0xa9, 0x39, 0xd1, 0x5e, 0xbc, 0x53, 0xaa, 0x06, 0xde, 0x42, 0x2d, 0xa8, 0x05, 0x0b, + 0x5c, 0xe1, 0x4e, 0xbc, 0xcb, 0xff, 0xf1, 0x3f, 0xfc, 0x97, 0x00, 0x9a, 0x79, 0x3e, 0x35, 0xd9, 0xb3, 0xaa, 0x7b, 0x8e, 0x8f, 0xc9, 0x51, 0x6a, 0xa7, 0x87, 0x23, 0xab, 0x83, 0x79, 0x33, 0x0b, - 0xdd, 0x56, 0x91, 0xd8, 0x8f, 0x1c, 0x0f, 0xb7, 0x2d, 0xf8, 0xca, 0xc3, 0x16, 0xd0, 0xea, 0x1e, - 0xf6, 0xac, 0xec, 0xba, 0xe2, 0xb1, 0x01, 0x26, 0x97, 0x03, 0xbf, 0x8e, 0x09, 0xdb, 0x20, 0xc2, + 0xdd, 0x46, 0x91, 0xd8, 0x8f, 0x1c, 0x0f, 0xb7, 0x0d, 0xf8, 0xca, 0xc3, 0x06, 0xd0, 0xea, 0x1e, + 0xf6, 0xac, 0xec, 0xb8, 0xe2, 0xb1, 0x01, 0x26, 0x97, 0x03, 0xbf, 0x8e, 0x09, 0x9b, 0x20, 0xc2, 0xf7, 0x63, 0x4c, 0x23, 0x58, 0x06, 0x7d, 0xb1, 0x63, 0x9b, 0xc6, 0x9c, 0x31, 0x3f, 0x5c, 0x7e, 0xf6, 0xe3, 0x46, 0xe1, 0x5c, 0xb3, 0x51, 0xe8, 0xbb, 0xbb, 0xb6, 0x72, 0xdc, 0x28, 0x5c, 0xed, - 0x86, 0x14, 0x1d, 0x85, 0x98, 0x96, 0xee, 0xae, 0xad, 0x20, 0xb6, 0x18, 0xbe, 0x0c, 0x26, 0x6d, + 0x86, 0x14, 0x1d, 0x85, 0x98, 0x96, 0xee, 0xae, 0xad, 0x20, 0x36, 0x18, 0xbe, 0x0c, 0x26, 0x6d, 0x4c, 0x1d, 0x82, 0xed, 0xa5, 0xad, 0xb5, 0x7b, 0x42, 0xbf, 0x99, 0xe3, 0x1a, 0x2f, 0x49, 0x8d, - 0x93, 0x2b, 0x59, 0x01, 0xd4, 0xbe, 0x06, 0x6e, 0x83, 0xa1, 0x60, 0xe7, 0x1d, 0x5c, 0x8d, 0xa8, - 0xd9, 0x37, 0xd7, 0x37, 0x3f, 0xb2, 0xf8, 0x4c, 0x29, 0x3d, 0x3c, 0x65, 0x02, 0x3f, 0x31, 0xb9, - 0xd9, 0x12, 0xb2, 0x0e, 0x56, 0x93, 0x43, 0x2b, 0x8f, 0x4b, 0xb4, 0xa1, 0x4d, 0xa1, 0x05, 0x25, - 0xea, 0x8a, 0xbf, 0xce, 0x01, 0xa8, 0x6f, 0x9e, 0x86, 0x81, 0x4f, 0x71, 0x4f, 0x76, 0x4f, 0xc1, + 0x93, 0x2b, 0x59, 0x01, 0xd4, 0x3e, 0x06, 0x6e, 0x83, 0xa1, 0x60, 0xe7, 0x1d, 0x5c, 0x8d, 0xa8, + 0xd9, 0x37, 0xd7, 0x37, 0x3f, 0xb2, 0xf8, 0x4c, 0x29, 0x5d, 0x3c, 0x65, 0x02, 0x5f, 0x31, 0x39, + 0xd9, 0x12, 0xb2, 0x0e, 0x56, 0x93, 0x45, 0x2b, 0x8f, 0x4b, 0xb4, 0xa1, 0x4d, 0xa1, 0x05, 0x25, + 0xea, 0x8a, 0xbf, 0xca, 0x01, 0xa8, 0x4f, 0x9e, 0x86, 0x81, 0x4f, 0x71, 0x4f, 0x66, 0x4f, 0xc1, 0x44, 0x95, 0x6b, 0x8e, 0xb0, 0x2d, 0x71, 0xcd, 0xdc, 0x49, 0xac, 0x37, 0x25, 0xfe, 0xc4, 0x72, 0x46, 0x1d, 0x6a, 0x03, 0x80, 0x77, 0xc0, 0x20, 0xc1, 0x34, 0x76, 0x23, 0xb3, 0x6f, 0xce, 0x98, 0x1f, 0x59, 0xbc, 0xde, 0x15, 0x8a, 0x87, 0x36, 0x0b, 0xbe, 0x52, 0xfd, 0xb9, 0x52, 0x25, 0xb2, 0xa2, 0x98, 0x96, 0xcf, 0x4b, 0xa4, 0x41, 0xc4, 0x75, 0x20, 0xa9, 0xab, 0xf8, 0x5f, 0x03, 0x4c, 0xe8, 0x5e, 0xaa, 0x3b, 0xf8, 0x00, 0x12, 0x30, 0x44, 0x44, 0xb0, 0x70, 0x3f, 0x8d, 0x2c, 0xde, - 0x2a, 0x9d, 0xf4, 0x46, 0x95, 0xda, 0xe2, 0xaf, 0x3c, 0xc2, 0x8e, 0x4b, 0xfe, 0x83, 0x12, 0x20, - 0x58, 0x07, 0x79, 0x22, 0xcf, 0x88, 0x07, 0xd2, 0xc8, 0xe2, 0x7a, 0x6f, 0x40, 0x85, 0xce, 0xf2, - 0x68, 0xb3, 0x51, 0xc8, 0x27, 0xff, 0x21, 0x85, 0x55, 0xfc, 0x65, 0x0e, 0xcc, 0x2e, 0xc7, 0x34, - 0x0a, 0x3c, 0x84, 0x69, 0x10, 0x93, 0x2a, 0x5e, 0x0e, 0xdc, 0xd8, 0xf3, 0x57, 0xf0, 0xae, 0xe3, - 0x3b, 0x11, 0x8b, 0xd1, 0x39, 0xd0, 0xef, 0x5b, 0x1e, 0x96, 0x31, 0x33, 0x2a, 0x3d, 0xd9, 0x7f, - 0xdb, 0xf2, 0x30, 0xe2, 0x1c, 0x26, 0xc1, 0x42, 0x44, 0xde, 0x00, 0x25, 0x71, 0xe7, 0x28, 0xc4, - 0x88, 0x73, 0xe0, 0x35, 0x30, 0xb8, 0x1b, 0x10, 0xcf, 0x12, 0xa7, 0x37, 0x9c, 0x9e, 0xc7, 0x4d, - 0x4e, 0x45, 0x92, 0x0b, 0x5f, 0x00, 0x23, 0x36, 0xa6, 0x55, 0xe2, 0x84, 0x0c, 0xda, 0xec, 0xe7, - 0xc2, 0x17, 0xa4, 0xf0, 0xc8, 0x4a, 0xca, 0x42, 0xba, 0x1c, 0xbc, 0x0e, 0xf2, 0x21, 0x71, 0x02, - 0xe2, 0x44, 0x47, 0xe6, 0xc0, 0x9c, 0x31, 0x3f, 0x50, 0x9e, 0x90, 0x6b, 0xf2, 0x5b, 0x92, 0x8e, - 0x94, 0x04, 0x93, 0x7e, 0x87, 0x06, 0xfe, 0x96, 0x15, 0xed, 0x99, 0x83, 0x1c, 0x41, 0x49, 0xbf, - 0x5a, 0xd9, 0xbc, 0xcd, 0xe8, 0x48, 0x49, 0x14, 0xff, 0x6c, 0x00, 0x33, 0xeb, 0xa1, 0xc4, 0xbd, - 0xf0, 0x26, 0xc8, 0xd3, 0x88, 0xe5, 0x9c, 0xda, 0x91, 0xf4, 0xcf, 0x53, 0x89, 0xaa, 0x8a, 0xa4, - 0x1f, 0x37, 0x0a, 0xd3, 0xe9, 0x8a, 0x84, 0xca, 0x7d, 0xa3, 0xd6, 0xb2, 0x90, 0x3b, 0xc0, 0x3b, - 0x7b, 0x41, 0xb0, 0x2f, 0x4f, 0xff, 0x14, 0x21, 0xf7, 0x9a, 0x50, 0x94, 0x62, 0x8a, 0x90, 0x93, - 0x64, 0x94, 0x00, 0x15, 0xff, 0x93, 0xcb, 0x6e, 0x4c, 0x3b, 0xf4, 0xb7, 0x41, 0x9e, 0x5d, 0x21, - 0xdb, 0x8a, 0x2c, 0x79, 0x09, 0x9e, 0x7d, 0xb4, 0x0b, 0x27, 0xee, 0xeb, 0x06, 0x8e, 0xac, 0x32, - 0x94, 0xae, 0x00, 0x29, 0x0d, 0x29, 0xad, 0xf0, 0x10, 0xf4, 0xd3, 0x10, 0x57, 0xe5, 0x7e, 0xef, - 0x9d, 0x22, 0xda, 0xbb, 0xec, 0xa1, 0x12, 0xe2, 0x6a, 0x1a, 0x8c, 0xec, 0x3f, 0xc4, 0x11, 0xe1, - 0xbb, 0x06, 0x18, 0xa4, 0x3c, 0x2f, 0xc8, 0x5c, 0xb2, 0x7d, 0x06, 0xe0, 0x99, 0xbc, 0x23, 0xfe, - 0x47, 0x12, 0xb7, 0xf8, 0xcf, 0x1c, 0xb8, 0xda, 0x6d, 0xe9, 0x72, 0xe0, 0xdb, 0xe2, 0x10, 0xd6, - 0xe4, 0xbd, 0x12, 0x91, 0xf5, 0x82, 0x7e, 0xaf, 0x8e, 0x1b, 0x85, 0x27, 0x1e, 0xaa, 0x40, 0xbb, - 0x80, 0x5f, 0x55, 0x5b, 0x16, 0x97, 0xf4, 0x6a, 0xab, 0x61, 0xc7, 0x8d, 0xc2, 0xb8, 0x5a, 0xd6, - 0x6a, 0x2b, 0xac, 0x03, 0xe8, 0x5a, 0x34, 0xba, 0x43, 0x2c, 0x9f, 0x0a, 0xb5, 0x8e, 0x87, 0xa5, - 0xe7, 0x9e, 0x7a, 0xb4, 0xa0, 0x60, 0x2b, 0xca, 0x33, 0x12, 0x12, 0xae, 0xb7, 0x69, 0x43, 0x1d, - 0x10, 0x58, 0xce, 0x20, 0xd8, 0xa2, 0x2a, 0x0d, 0x68, 0x39, 0x9c, 0x51, 0x91, 0xe4, 0xc2, 0x27, - 0xc1, 0x90, 0x87, 0x29, 0xb5, 0x6a, 0x98, 0xdf, 0xfd, 0xe1, 0xb4, 0x28, 0x6e, 0x08, 0x32, 0x4a, - 0xf8, 0xc5, 0x7f, 0x19, 0xe0, 0x72, 0x37, 0xaf, 0xad, 0x3b, 0x34, 0x82, 0xdf, 0x6c, 0x0b, 0xfb, - 0xd2, 0xa3, 0xed, 0x90, 0xad, 0xe6, 0x41, 0xaf, 0x52, 0x49, 0x42, 0xd1, 0x42, 0xfe, 0x00, 0x0c, - 0x38, 0x11, 0xf6, 0x92, 0x6a, 0x89, 0x7a, 0x1f, 0x76, 0xe5, 0x31, 0x09, 0x3f, 0xb0, 0xc6, 0x80, - 0x90, 0xc0, 0x2b, 0x7e, 0x94, 0x03, 0x57, 0xba, 0x2d, 0x61, 0x79, 0x9c, 0x32, 0x67, 0x87, 0x6e, - 0x4c, 0x2c, 0x57, 0x06, 0x9b, 0x72, 0xf6, 0x16, 0xa7, 0x22, 0xc9, 0x65, 0xb9, 0x93, 0x3a, 0x7e, - 0x2d, 0x76, 0x2d, 0x22, 0x23, 0x49, 0x6d, 0xb8, 0x22, 0xe9, 0x48, 0x49, 0xc0, 0x12, 0x00, 0x74, - 0x2f, 0x20, 0x11, 0xc7, 0xe0, 0x1d, 0xce, 0x70, 0xf9, 0x3c, 0xcb, 0x08, 0x15, 0x45, 0x45, 0x9a, - 0x04, 0x2b, 0x24, 0xfb, 0x8e, 0x6f, 0xcb, 0x03, 0x57, 0x77, 0xf7, 0x96, 0xe3, 0xdb, 0x88, 0x73, - 0x18, 0xbe, 0xeb, 0xd0, 0x88, 0x51, 0xe4, 0x69, 0xb7, 0x38, 0x9c, 0x4b, 0x2a, 0x09, 0x86, 0x5f, - 0x65, 0x09, 0x36, 0x20, 0x0e, 0xa6, 0xe6, 0x60, 0x8a, 0xbf, 0xac, 0xa8, 0x48, 0x93, 0x28, 0xfe, - 0xa5, 0xbf, 0x7b, 0x7c, 0xb0, 0x04, 0x02, 0x1f, 0x07, 0x03, 0x35, 0x12, 0xc4, 0xa1, 0xf4, 0x92, - 0xf2, 0xf6, 0xcb, 0x8c, 0x88, 0x04, 0x0f, 0x7e, 0x07, 0x0c, 0xf8, 0x72, 0xc3, 0x2c, 0x82, 0x5e, - 0xeb, 0xfd, 0x31, 0x73, 0x6f, 0xa5, 0xe8, 0xc2, 0x91, 0x02, 0x14, 0x3e, 0x0f, 0x06, 0x68, 0x35, - 0x08, 0xb1, 0x74, 0xe2, 0x6c, 0x22, 0x54, 0x61, 0xc4, 0xe3, 0x46, 0x61, 0x2c, 0x51, 0xc7, 0x09, - 0x48, 0x08, 0xc3, 0x1f, 0x18, 0x20, 0x2f, 0xcb, 0x05, 0x35, 0x87, 0x78, 0x78, 0xbe, 0xde, 0x7b, - 0xbb, 0x65, 0xdb, 0x9b, 0x9e, 0x99, 0x24, 0x50, 0xa4, 0xc0, 0xe1, 0xf7, 0x0c, 0x00, 0xaa, 0xaa, - 0x76, 0x99, 0xc3, 0xdc, 0x87, 0x3d, 0xbb, 0x2a, 0x5a, 0x55, 0x14, 0x81, 0x90, 0xb6, 0x4a, 0x1a, - 0x2a, 0xac, 0x80, 0xa9, 0x90, 0x60, 0xae, 0xfb, 0xae, 0xbf, 0xef, 0x07, 0x07, 0xfe, 0x4d, 0x07, - 0xbb, 0x36, 0x35, 0xc1, 0x9c, 0x31, 0x9f, 0x2f, 0x5f, 0x91, 0xf6, 0x4f, 0x6d, 0x75, 0x12, 0x42, - 0x9d, 0xd7, 0x16, 0xdf, 0xeb, 0xcb, 0xf6, 0x5a, 0xd9, 0x7a, 0x01, 0x3f, 0x10, 0x9b, 0x17, 0x79, - 0x98, 0x9a, 0x06, 0x3f, 0x88, 0x37, 0x7b, 0x7f, 0x10, 0x2a, 0xd7, 0xa7, 0x45, 0x5a, 0x91, 0x28, - 0xd2, 0x4c, 0x80, 0x3f, 0x33, 0xc0, 0x98, 0x55, 0xad, 0xe2, 0x30, 0xc2, 0xb6, 0xb8, 0xc6, 0xb9, - 0xb3, 0x8d, 0xea, 0x29, 0x69, 0xd0, 0xd8, 0x92, 0x8e, 0x8a, 0x5a, 0x8d, 0x80, 0x2f, 0x81, 0xf3, - 0x34, 0x0a, 0x08, 0xb6, 0x93, 0x08, 0x92, 0xd9, 0x05, 0x36, 0x1b, 0x85, 0xf3, 0x95, 0x16, 0x0e, - 0xca, 0x48, 0x16, 0x3f, 0x19, 0x00, 0x85, 0x87, 0x44, 0xe8, 0x23, 0x34, 0xbd, 0xd7, 0xc0, 0x20, - 0xdf, 0xa9, 0xcd, 0x1d, 0x92, 0xd7, 0x4a, 0x3d, 0xa7, 0x22, 0xc9, 0x65, 0xe5, 0x89, 0xe1, 0xb3, - 0xf2, 0xd4, 0xc7, 0x05, 0x55, 0x79, 0xaa, 0x08, 0x32, 0x4a, 0xf8, 0x70, 0x11, 0x00, 0x1b, 0x87, - 0x04, 0xb3, 0x8c, 0x64, 0x9b, 0x43, 0x5c, 0x5a, 0x9d, 0xcf, 0x8a, 0xe2, 0x20, 0x4d, 0x0a, 0xde, - 0x04, 0x30, 0xf9, 0xcf, 0x09, 0xfc, 0xd7, 0x2c, 0xe2, 0x3b, 0x7e, 0xcd, 0xcc, 0x73, 0xb3, 0xa7, - 0x59, 0xb5, 0x5d, 0x69, 0xe3, 0xa2, 0x0e, 0x2b, 0x60, 0x1d, 0x0c, 0x8a, 0x67, 0x34, 0xcf, 0x1b, - 0x3d, 0xbc, 0x71, 0xf7, 0x2c, 0xd7, 0xb1, 0x39, 0x54, 0x19, 0x70, 0xf7, 0x70, 0x14, 0x24, 0xd1, - 0xe0, 0xfb, 0x06, 0x18, 0xa5, 0xf1, 0x0e, 0x91, 0xd2, 0x94, 0x67, 0xf5, 0x91, 0xc5, 0x3b, 0xbd, - 0x82, 0xaf, 0x68, 0xba, 0xcb, 0x13, 0xcd, 0x46, 0x61, 0x54, 0xa7, 0xa0, 0x16, 0x6c, 0xf8, 0x07, - 0x03, 0x98, 0x96, 0x2d, 0x42, 0xdf, 0x72, 0xb7, 0x88, 0xe3, 0x47, 0x98, 0x88, 0x07, 0x91, 0x28, - 0x1f, 0x3d, 0xec, 0x15, 0xb3, 0xef, 0xac, 0xf2, 0x9c, 0x3c, 0x69, 0x73, 0xa9, 0x8b, 0x05, 0xa8, - 0xab, 0x6d, 0xc5, 0x7f, 0x1b, 0xd9, 0xd4, 0xa2, 0xed, 0xb2, 0x52, 0xb5, 0x5c, 0x0c, 0x57, 0xc0, - 0x04, 0xeb, 0x7e, 0x11, 0x0e, 0x5d, 0xa7, 0x6a, 0x51, 0xfe, 0xfa, 0x11, 0xd1, 0xad, 0x9e, 0xe1, - 0x95, 0x0c, 0x1f, 0xb5, 0xad, 0x80, 0xaf, 0x02, 0x28, 0xda, 0xc2, 0x16, 0x3d, 0xa2, 0x13, 0x50, - 0x0d, 0x5e, 0xa5, 0x4d, 0x02, 0x75, 0x58, 0x05, 0x97, 0xc1, 0xa4, 0x6b, 0xed, 0x60, 0xb7, 0x82, - 0x5d, 0x5c, 0x8d, 0x02, 0xc2, 0x55, 0x89, 0xf7, 0xe1, 0x54, 0xb3, 0x51, 0x98, 0x5c, 0xcf, 0x32, - 0x51, 0xbb, 0x7c, 0xf1, 0x6a, 0xf6, 0x2e, 0xeb, 0x1b, 0x17, 0xcd, 0xf6, 0x87, 0x39, 0x30, 0xd3, - 0x3d, 0x28, 0xe0, 0x77, 0x55, 0x6b, 0x2c, 0x3a, 0xbe, 0xd7, 0xcf, 0x20, 0xf4, 0xe4, 0x73, 0x00, - 0xb4, 0x3f, 0x05, 0xe0, 0x11, 0xab, 0xd7, 0x96, 0x9b, 0x3c, 0xfb, 0xb7, 0xcf, 0x02, 0x9d, 0xe9, - 0x2f, 0x0f, 0x8b, 0x2e, 0xc0, 0x72, 0x79, 0xd1, 0xb7, 0x5c, 0x5c, 0xfc, 0xa8, 0xed, 0x69, 0x9b, - 0x5e, 0x56, 0xf8, 0x43, 0x03, 0x8c, 0x07, 0x21, 0xf6, 0x97, 0xb6, 0xd6, 0xee, 0x7d, 0x59, 0x5c, - 0x5a, 0xe9, 0xa0, 0xb5, 0x93, 0x9b, 0xc8, 0xde, 0xd7, 0x42, 0xd7, 0x16, 0x09, 0x42, 0x5a, 0xbe, - 0xd0, 0x6c, 0x14, 0xc6, 0x37, 0x5b, 0x51, 0x50, 0x16, 0xb6, 0xe8, 0x81, 0xa9, 0xd5, 0xc3, 0x08, - 0x13, 0xdf, 0x72, 0x57, 0x82, 0x6a, 0xec, 0x61, 0x3f, 0x12, 0x36, 0x66, 0xc6, 0x05, 0xc6, 0x23, - 0x8e, 0x0b, 0xae, 0x80, 0xbe, 0x98, 0xb8, 0x32, 0x6a, 0x47, 0xd4, 0x10, 0x0c, 0xad, 0x23, 0x46, - 0x2f, 0x5e, 0x05, 0xfd, 0xcc, 0x4e, 0x78, 0x09, 0xf4, 0x11, 0xeb, 0x80, 0x6b, 0x1d, 0x2d, 0x0f, - 0x31, 0x11, 0x64, 0x1d, 0x20, 0x46, 0x2b, 0xfe, 0x7d, 0x0e, 0x8c, 0x67, 0xf6, 0x02, 0x67, 0x40, - 0x4e, 0x4d, 0xd6, 0x80, 0x54, 0x9a, 0x5b, 0x5b, 0x41, 0x39, 0xc7, 0x86, 0x2f, 0xaa, 0xec, 0x2a, - 0x40, 0x0b, 0xaa, 0x58, 0x70, 0x2a, 0x6b, 0xcb, 0x52, 0x75, 0xcc, 0x90, 0x24, 0x3d, 0x32, 0x1b, - 0xf0, 0xae, 0xbc, 0x15, 0xc2, 0x06, 0xbc, 0x8b, 0x18, 0xed, 0xa4, 0xb3, 0x92, 0x64, 0x58, 0x33, - 0xf0, 0x08, 0xc3, 0x9a, 0xc1, 0x07, 0x0e, 0x6b, 0x1e, 0x07, 0x03, 0x91, 0x13, 0xb9, 0x98, 0x57, - 0x2a, 0xad, 0x19, 0xbe, 0xc3, 0x88, 0x48, 0xf0, 0x20, 0x06, 0x43, 0x36, 0xde, 0xb5, 0x62, 0x37, - 0xe2, 0x45, 0x69, 0x64, 0xf1, 0xeb, 0xa7, 0x8b, 0x1e, 0x31, 0xcc, 0x58, 0x11, 0x2a, 0x51, 0xa2, - 0x1b, 0x3e, 0x01, 0x86, 0x3c, 0xeb, 0xd0, 0xf1, 0x62, 0x8f, 0x77, 0x8c, 0x86, 0x10, 0xdb, 0x10, - 0x24, 0x94, 0xf0, 0x58, 0x12, 0xc4, 0x87, 0x55, 0x37, 0xa6, 0x4e, 0x1d, 0x4b, 0xa6, 0x6c, 0xe9, - 0x54, 0x12, 0x5c, 0xcd, 0xf0, 0x51, 0xdb, 0x0a, 0x0e, 0xe6, 0xf8, 0x7c, 0xf1, 0x88, 0x06, 0x26, - 0x48, 0x28, 0xe1, 0xb5, 0x82, 0x49, 0xf9, 0xd1, 0x6e, 0x60, 0x72, 0x71, 0xdb, 0x0a, 0xf8, 0x34, - 0x18, 0xf6, 0xac, 0xc3, 0x75, 0xec, 0xd7, 0xa2, 0x3d, 0x73, 0x6c, 0xce, 0x98, 0xef, 0x2b, 0x8f, - 0x35, 0x1b, 0x85, 0xe1, 0x8d, 0x84, 0x88, 0x52, 0x3e, 0x17, 0x76, 0x7c, 0x29, 0x7c, 0x5e, 0x13, - 0x4e, 0x88, 0x28, 0xe5, 0xb3, 0xce, 0x24, 0xb4, 0x22, 0x76, 0xaf, 0xcc, 0xf1, 0xd6, 0x87, 0xf3, - 0x96, 0x20, 0xa3, 0x84, 0x0f, 0xe7, 0x41, 0xde, 0xb3, 0x0e, 0xf9, 0x9b, 0xd2, 0x9c, 0xe0, 0x6a, - 0xf9, 0x40, 0x71, 0x43, 0xd2, 0x90, 0xe2, 0x72, 0x49, 0xc7, 0x17, 0x92, 0x93, 0x9a, 0xa4, 0xa4, - 0x21, 0xc5, 0x65, 0xf1, 0x1b, 0xfb, 0xce, 0xfd, 0x18, 0x0b, 0x61, 0xc8, 0x3d, 0xa3, 0xe2, 0xf7, - 0x6e, 0xca, 0x42, 0xba, 0x1c, 0x7b, 0xd3, 0x79, 0xb1, 0x1b, 0x39, 0xa1, 0x8b, 0x37, 0x77, 0xcd, - 0x0b, 0xdc, 0xff, 0xbc, 0x95, 0xdf, 0x50, 0x54, 0xa4, 0x49, 0xc0, 0xb7, 0x41, 0x3f, 0xf6, 0x63, - 0xcf, 0xbc, 0xc8, 0xcb, 0xf7, 0x69, 0xa3, 0x4f, 0xdd, 0x97, 0x55, 0x3f, 0xf6, 0x10, 0xd7, 0x0c, - 0x5f, 0x04, 0x63, 0x9e, 0x75, 0xc8, 0x92, 0x00, 0x26, 0x11, 0x7b, 0x68, 0x4e, 0xf1, 0x7d, 0x4f, - 0xb2, 0x26, 0x76, 0x43, 0x67, 0xa0, 0x56, 0x39, 0xbe, 0xd0, 0xf1, 0xb5, 0x85, 0xd3, 0xda, 0x42, - 0x9d, 0x81, 0x5a, 0xe5, 0x98, 0x93, 0x09, 0xbe, 0x1f, 0x3b, 0x04, 0xdb, 0xe6, 0xff, 0xf1, 0xbe, - 0x57, 0xce, 0x77, 0x05, 0x0d, 0x29, 0x2e, 0xbc, 0x9f, 0x8c, 0x1c, 0x4c, 0x7e, 0xf9, 0xb6, 0x7a, - 0x96, 0xba, 0x37, 0xc9, 0x12, 0x21, 0xd6, 0x91, 0xa8, 0x2a, 0xfa, 0xb0, 0x01, 0xfa, 0x60, 0xc0, - 0x72, 0xdd, 0xcd, 0x5d, 0xf3, 0x12, 0xf7, 0x78, 0x0f, 0xab, 0x85, 0xca, 0x30, 0x4b, 0x4c, 0x3f, - 0x12, 0x30, 0x0c, 0x2f, 0xf0, 0x59, 0x2c, 0xcc, 0x9c, 0x19, 0xde, 0x26, 0xd3, 0x8f, 0x04, 0x0c, - 0xdf, 0x9f, 0x7f, 0xb4, 0xb9, 0x6b, 0x3e, 0x76, 0x76, 0xfb, 0x63, 0xfa, 0x91, 0x80, 0x81, 0x36, - 0xe8, 0xf3, 0x83, 0xc8, 0xbc, 0xdc, 0xeb, 0xda, 0xcb, 0xab, 0xc9, 0xed, 0x20, 0x42, 0x4c, 0x3d, - 0xfc, 0xb1, 0x01, 0x40, 0x98, 0x46, 0xe2, 0x95, 0xd3, 0x8e, 0x00, 0x32, 0x68, 0xa5, 0x34, 0x7a, - 0x57, 0xfd, 0x88, 0x1c, 0xa5, 0xef, 0x1a, 0x2d, 0xca, 0x35, 0x03, 0xe0, 0x2f, 0x0c, 0x70, 0x51, - 0x6f, 0x77, 0x95, 0x65, 0xb3, 0xdc, 0x0f, 0x9b, 0x3d, 0x0c, 0xe4, 0x72, 0x10, 0xb8, 0x65, 0xb3, - 0xd9, 0x28, 0x5c, 0x5c, 0xea, 0x00, 0x88, 0x3a, 0x9a, 0x01, 0x7f, 0x63, 0x80, 0x49, 0x99, 0x1d, - 0x35, 0xe3, 0x0a, 0xdc, 0x6d, 0x6f, 0xf7, 0xd0, 0x6d, 0x59, 0x08, 0xe1, 0x3d, 0xf5, 0x95, 0xb1, - 0x8d, 0x8f, 0xda, 0xad, 0x82, 0xbf, 0x37, 0xc0, 0xa8, 0x8d, 0x43, 0xec, 0xdb, 0xd8, 0xaf, 0x32, - 0x33, 0xe7, 0x4e, 0x3b, 0x57, 0xc8, 0x9a, 0xb9, 0xa2, 0x69, 0x17, 0x16, 0x96, 0xa4, 0x85, 0xa3, - 0x3a, 0xeb, 0xb8, 0x51, 0x98, 0x4e, 0x97, 0xea, 0x1c, 0xd4, 0x62, 0x20, 0xfc, 0x89, 0x01, 0xc6, - 0x53, 0xb7, 0x8b, 0x02, 0x71, 0xf5, 0x6c, 0x0e, 0x9e, 0xb7, 0xa0, 0x4b, 0xad, 0x58, 0x28, 0x0b, - 0x0e, 0x7f, 0x6b, 0xb0, 0x6e, 0x2b, 0x79, 0xab, 0x51, 0xb3, 0xc8, 0x3d, 0xf8, 0x46, 0x2f, 0x3d, - 0xa8, 0x94, 0x0b, 0x07, 0x5e, 0x4f, 0x3b, 0x39, 0xc5, 0x39, 0x6e, 0x14, 0xa6, 0x74, 0xff, 0x29, - 0x06, 0xd2, 0x8d, 0x83, 0xef, 0x19, 0x60, 0x14, 0xa7, 0x0d, 0x33, 0x35, 0x1f, 0x3f, 0xad, 0xeb, - 0x3a, 0xb6, 0xdf, 0xe2, 0x39, 0xad, 0xb1, 0x28, 0x6a, 0x81, 0x65, 0xbd, 0x1f, 0x3e, 0xb4, 0xbc, - 0xd0, 0xc5, 0xe6, 0xff, 0xf7, 0xae, 0xf7, 0x5b, 0x15, 0x2a, 0x51, 0xa2, 0x1b, 0x5e, 0x07, 0x79, - 0x3f, 0x76, 0x5d, 0x6b, 0xc7, 0xc5, 0xe6, 0x13, 0xbc, 0x8b, 0x50, 0xf3, 0xc5, 0xdb, 0x92, 0x8e, - 0x94, 0x04, 0xdc, 0x05, 0x73, 0x87, 0xb7, 0xd4, 0x8f, 0x2f, 0x3a, 0x0e, 0xf0, 0xcc, 0x6b, 0x5c, - 0xcb, 0x4c, 0xb3, 0x51, 0x98, 0xde, 0xee, 0x3c, 0xe2, 0x7b, 0xa8, 0x0e, 0xf8, 0x26, 0x78, 0x4c, - 0x93, 0x59, 0xf5, 0x76, 0xb0, 0x6d, 0x63, 0x3b, 0x79, 0x68, 0x99, 0x5f, 0xe2, 0x10, 0xea, 0x1e, - 0x6f, 0x67, 0x05, 0xd0, 0x83, 0x56, 0xc3, 0x75, 0x30, 0xad, 0xb1, 0xd7, 0xfc, 0x68, 0x93, 0x54, - 0x22, 0xe2, 0xf8, 0x35, 0x73, 0x9e, 0xeb, 0xbd, 0x98, 0xdc, 0xbe, 0x6d, 0x8d, 0x87, 0xba, 0xac, - 0x81, 0xaf, 0xb4, 0x68, 0xe3, 0x1f, 0x2e, 0xac, 0xf0, 0x16, 0x3e, 0xa2, 0xe6, 0x93, 0xbc, 0xb9, - 0xe0, 0xe7, 0xbc, 0xad, 0xd1, 0x51, 0x17, 0x79, 0xf8, 0x0d, 0x70, 0x21, 0xc3, 0x61, 0xef, 0x0a, - 0xf3, 0x29, 0xf1, 0x40, 0x60, 0x9d, 0xe8, 0x76, 0x42, 0x44, 0x9d, 0x24, 0xe1, 0xd7, 0x00, 0xd4, - 0xc8, 0x1b, 0x56, 0xc8, 0xd7, 0x3f, 0x2d, 0xde, 0x2a, 0xec, 0x44, 0xb7, 0x25, 0x0d, 0x75, 0x90, - 0x83, 0x1f, 0x1a, 0x2d, 0x3b, 0x49, 0x5f, 0xb3, 0xd4, 0xbc, 0xce, 0x2f, 0xec, 0x2b, 0x27, 0x0f, - 0xc0, 0x54, 0x19, 0x8a, 0x5d, 0xac, 0x79, 0x58, 0x43, 0x41, 0x5d, 0xd0, 0x67, 0xd8, 0x63, 0x3a, - 0x93, 0xc3, 0xe1, 0x04, 0xe8, 0xdb, 0xc7, 0xf2, 0xb3, 0x31, 0x62, 0x7f, 0xc2, 0xb7, 0xc0, 0x40, - 0xdd, 0x72, 0xe3, 0x64, 0x14, 0xd0, 0xbb, 0x5a, 0x8f, 0x84, 0xde, 0x97, 0x72, 0x37, 0x8c, 0x99, - 0x0f, 0x0c, 0x30, 0xdd, 0xb9, 0xaa, 0x7c, 0x51, 0x16, 0xfd, 0xdc, 0x00, 0x93, 0x6d, 0x05, 0xa4, - 0x83, 0x31, 0x6e, 0xab, 0x31, 0xf7, 0x7a, 0x58, 0x09, 0xc4, 0x45, 0xe0, 0x1d, 0xad, 0x6e, 0xd9, - 0x8f, 0x0c, 0x30, 0x91, 0x4d, 0xcc, 0x5f, 0x90, 0x97, 0x8a, 0xef, 0xe7, 0xc0, 0x74, 0xe7, 0x1e, - 0x1c, 0x7a, 0x6a, 0xba, 0xd0, 0xf3, 0x01, 0x4d, 0xa7, 0x91, 0xed, 0xbb, 0x06, 0x18, 0x79, 0x47, - 0xc9, 0x25, 0x5f, 0x33, 0x7b, 0x39, 0x15, 0x4a, 0x4a, 0x5f, 0xca, 0xa0, 0x48, 0x87, 0x2c, 0xfe, - 0xce, 0x00, 0x53, 0x1d, 0xcb, 0x39, 0xbc, 0x06, 0x06, 0x2d, 0xd7, 0x0d, 0x0e, 0xc4, 0x34, 0x4f, - 0x1b, 0xcb, 0x2f, 0x71, 0x2a, 0x92, 0x5c, 0xcd, 0x67, 0xb9, 0xcf, 0xc1, 0x67, 0xc5, 0x3f, 0x1a, - 0xe0, 0xf2, 0x83, 0xa2, 0xee, 0xf3, 0x3e, 0xc3, 0x79, 0x90, 0x97, 0xcd, 0xf6, 0x11, 0x3f, 0x3f, - 0x99, 0x5d, 0x65, 0x46, 0xe0, 0xbf, 0x96, 0x11, 0x7f, 0x15, 0x7f, 0x65, 0x80, 0x89, 0x0a, 0x26, - 0x75, 0xa7, 0x8a, 0x11, 0xde, 0xc5, 0x04, 0xfb, 0x55, 0x0c, 0x17, 0xc0, 0x30, 0xff, 0xda, 0x18, - 0x5a, 0xd5, 0xe4, 0x1b, 0xc9, 0xa4, 0x74, 0xf4, 0xf0, 0xed, 0x84, 0x81, 0x52, 0x19, 0xf5, 0x3d, - 0x25, 0xd7, 0xf5, 0x7b, 0xca, 0x65, 0xd0, 0x1f, 0xa6, 0x03, 0xe0, 0x3c, 0xe3, 0xf2, 0x99, 0x2f, - 0xa7, 0x72, 0x6e, 0x40, 0x22, 0x3e, 0xe5, 0x1a, 0x90, 0xdc, 0x80, 0x44, 0x88, 0x53, 0x8b, 0xdf, - 0x02, 0xe7, 0x5b, 0xd3, 0x33, 0xc3, 0x23, 0xb1, 0xdb, 0xf6, 0xfd, 0x86, 0xf1, 0x10, 0xe7, 0xe8, - 0x3f, 0x1b, 0xc8, 0x3d, 0xe4, 0x67, 0x03, 0x7f, 0x32, 0xc0, 0x85, 0xe4, 0x57, 0x35, 0xae, 0x83, - 0xfd, 0x68, 0x39, 0xf0, 0x77, 0x9d, 0x1a, 0xbc, 0x24, 0xe6, 0x88, 0xda, 0x70, 0x2e, 0x99, 0x21, - 0xc2, 0xfb, 0x60, 0x88, 0x0a, 0xa7, 0xc9, 0xf3, 0x7c, 0xf5, 0xe4, 0xe7, 0x99, 0xf5, 0xbe, 0x68, - 0x83, 0x12, 0x6a, 0x82, 0xc3, 0x8e, 0xb4, 0x6a, 0x95, 0x63, 0xdf, 0x96, 0xb3, 0xe4, 0x51, 0x71, - 0xa4, 0xcb, 0x4b, 0x82, 0x86, 0x14, 0xb7, 0xf8, 0x0f, 0x03, 0x4c, 0xb6, 0xfd, 0x4a, 0x08, 0x7e, - 0xdf, 0x00, 0xa3, 0x55, 0x6d, 0x7b, 0xf2, 0x62, 0x6c, 0x9c, 0xfe, 0x97, 0x48, 0x9a, 0x52, 0xd1, - 0x4b, 0xe8, 0x14, 0xd4, 0x02, 0x0a, 0xb7, 0x81, 0x59, 0xcd, 0xfc, 0x20, 0x2f, 0xf3, 0x89, 0xef, - 0x72, 0xb3, 0x51, 0x30, 0x97, 0xbb, 0xc8, 0xa0, 0xae, 0xab, 0xcb, 0xdf, 0xfe, 0xf8, 0xb3, 0xd9, - 0x73, 0x9f, 0x7c, 0x36, 0x7b, 0xee, 0xd3, 0xcf, 0x66, 0xcf, 0xbd, 0xdb, 0x9c, 0x35, 0x3e, 0x6e, - 0xce, 0x1a, 0x9f, 0x34, 0x67, 0x8d, 0x4f, 0x9b, 0xb3, 0xc6, 0x5f, 0x9b, 0xb3, 0xc6, 0x4f, 0xff, - 0x36, 0x7b, 0xee, 0x8d, 0x1b, 0x27, 0xfd, 0x19, 0xee, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc0, - 0x20, 0xb3, 0x2b, 0xda, 0x2b, 0x00, 0x00, + 0x2a, 0x9d, 0x74, 0x47, 0x95, 0xda, 0xe2, 0xaf, 0x3c, 0xc2, 0x96, 0x4b, 0xfe, 0x41, 0x09, 0x10, + 0xac, 0x83, 0x3c, 0x91, 0x6b, 0xc4, 0x03, 0x69, 0x64, 0x71, 0xbd, 0x37, 0xa0, 0x42, 0x67, 0x79, + 0xb4, 0xd9, 0x28, 0xe4, 0x93, 0x7f, 0x48, 0x61, 0x15, 0x7f, 0x91, 0x03, 0xb3, 0xcb, 0x31, 0x8d, + 0x02, 0x0f, 0x61, 0x1a, 0xc4, 0xa4, 0x8a, 0x97, 0x03, 0x37, 0xf6, 0xfc, 0x15, 0xbc, 0xeb, 0xf8, + 0x4e, 0xc4, 0x62, 0x74, 0x0e, 0xf4, 0xfb, 0x96, 0x87, 0x65, 0xcc, 0x8c, 0x4a, 0x4f, 0xf6, 0xdf, + 0xb6, 0x3c, 0x8c, 0x38, 0x87, 0x49, 0xb0, 0x10, 0x91, 0x3b, 0x40, 0x49, 0xdc, 0x39, 0x0a, 0x31, + 0xe2, 0x1c, 0x78, 0x0d, 0x0c, 0xee, 0x06, 0xc4, 0xb3, 0xc4, 0xea, 0x0d, 0xa7, 0xeb, 0x71, 0x93, + 0x53, 0x91, 0xe4, 0xc2, 0x17, 0xc0, 0x88, 0x8d, 0x69, 0x95, 0x38, 0x21, 0x83, 0x36, 0xfb, 0xb9, + 0xf0, 0x05, 0x29, 0x3c, 0xb2, 0x92, 0xb2, 0x90, 0x2e, 0x07, 0xaf, 0x83, 0x7c, 0x48, 0x9c, 0x80, + 0x38, 0xd1, 0x91, 0x39, 0x30, 0x67, 0xcc, 0x0f, 0x94, 0x27, 0xe4, 0x98, 0xfc, 0x96, 0xa4, 0x23, + 0x25, 0xc1, 0xa4, 0xdf, 0xa1, 0x81, 0xbf, 0x65, 0x45, 0x7b, 0xe6, 0x20, 0x47, 0x50, 0xd2, 0xaf, + 0x56, 0x36, 0x6f, 0x33, 0x3a, 0x52, 0x12, 0xc5, 0x3f, 0x1b, 0xc0, 0xcc, 0x7a, 0x28, 0x71, 0x2f, + 0xbc, 0x09, 0xf2, 0x34, 0x62, 0x39, 0xa7, 0x76, 0x24, 0xfd, 0xf3, 0x54, 0xa2, 0xaa, 0x22, 0xe9, + 0xc7, 0x8d, 0xc2, 0x74, 0x3a, 0x22, 0xa1, 0x72, 0xdf, 0xa8, 0xb1, 0x2c, 0xe4, 0x0e, 0xf0, 0xce, + 0x5e, 0x10, 0xec, 0xcb, 0xd5, 0x3f, 0x45, 0xc8, 0xbd, 0x26, 0x14, 0xa5, 0x98, 0x22, 0xe4, 0x24, + 0x19, 0x25, 0x40, 0xc5, 0xff, 0xe4, 0xb2, 0x13, 0xd3, 0x16, 0xfd, 0x6d, 0x90, 0x67, 0x5b, 0xc8, + 0xb6, 0x22, 0x4b, 0x6e, 0x82, 0x67, 0x1f, 0x6d, 0xc3, 0x89, 0xfd, 0xba, 0x81, 0x23, 0xab, 0x0c, + 0xa5, 0x2b, 0x40, 0x4a, 0x43, 0x4a, 0x2b, 0x3c, 0x04, 0xfd, 0x34, 0xc4, 0x55, 0x39, 0xdf, 0x7b, + 0xa7, 0x88, 0xf6, 0x2e, 0x73, 0xa8, 0x84, 0xb8, 0x9a, 0x06, 0x23, 0xfb, 0x87, 0x38, 0x22, 0x7c, + 0xd7, 0x00, 0x83, 0x94, 0xe7, 0x05, 0x99, 0x4b, 0xb6, 0xcf, 0x00, 0x3c, 0x93, 0x77, 0xc4, 0x7f, + 0x24, 0x71, 0x8b, 0xff, 0xcc, 0x81, 0xab, 0xdd, 0x86, 0x2e, 0x07, 0xbe, 0x2d, 0x16, 0x61, 0x4d, + 0xee, 0x2b, 0x11, 0x59, 0x2f, 0xe8, 0xfb, 0xea, 0xb8, 0x51, 0x78, 0xe2, 0xa1, 0x0a, 0xb4, 0x0d, + 0xf8, 0x55, 0x35, 0x65, 0xb1, 0x49, 0xaf, 0xb6, 0x1a, 0x76, 0xdc, 0x28, 0x8c, 0xab, 0x61, 0xad, + 0xb6, 0xc2, 0x3a, 0x80, 0xae, 0x45, 0xa3, 0x3b, 0xc4, 0xf2, 0xa9, 0x50, 0xeb, 0x78, 0x58, 0x7a, + 0xee, 0xa9, 0x47, 0x0b, 0x0a, 0x36, 0xa2, 0x3c, 0x23, 0x21, 0xe1, 0x7a, 0x9b, 0x36, 0xd4, 0x01, + 0x81, 0xe5, 0x0c, 0x82, 0x2d, 0xaa, 0xd2, 0x80, 0x96, 0xc3, 0x19, 0x15, 0x49, 0x2e, 0x7c, 0x12, + 0x0c, 0x79, 0x98, 0x52, 0xab, 0x86, 0xf9, 0xde, 0x1f, 0x4e, 0x0f, 0xc5, 0x0d, 0x41, 0x46, 0x09, + 0xbf, 0xf8, 0x2f, 0x03, 0x5c, 0xee, 0xe6, 0xb5, 0x75, 0x87, 0x46, 0xf0, 0x9b, 0x6d, 0x61, 0x5f, + 0x7a, 0xb4, 0x19, 0xb2, 0xd1, 0x3c, 0xe8, 0x55, 0x2a, 0x49, 0x28, 0x5a, 0xc8, 0x1f, 0x80, 0x01, + 0x27, 0xc2, 0x5e, 0x72, 0x5a, 0xa2, 0xde, 0x87, 0x5d, 0x79, 0x4c, 0xc2, 0x0f, 0xac, 0x31, 0x20, + 0x24, 0xf0, 0x8a, 0x1f, 0xe5, 0xc0, 0x95, 0x6e, 0x43, 0x58, 0x1e, 0xa7, 0xcc, 0xd9, 0xa1, 0x1b, + 0x13, 0xcb, 0x95, 0xc1, 0xa6, 0x9c, 0xbd, 0xc5, 0xa9, 0x48, 0x72, 0x59, 0xee, 0xa4, 0x8e, 0x5f, + 0x8b, 0x5d, 0x8b, 0xc8, 0x48, 0x52, 0x13, 0xae, 0x48, 0x3a, 0x52, 0x12, 0xb0, 0x04, 0x00, 0xdd, + 0x0b, 0x48, 0xc4, 0x31, 0x78, 0x85, 0x33, 0x5c, 0x3e, 0xcf, 0x32, 0x42, 0x45, 0x51, 0x91, 0x26, + 0xc1, 0x0e, 0x92, 0x7d, 0xc7, 0xb7, 0xe5, 0x82, 0xab, 0xbd, 0x7b, 0xcb, 0xf1, 0x6d, 0xc4, 0x39, + 0x0c, 0xdf, 0x75, 0x68, 0xc4, 0x28, 0x72, 0xb5, 0x5b, 0x1c, 0xce, 0x25, 0x95, 0x04, 0xc3, 0xaf, + 0xb2, 0x04, 0x1b, 0x10, 0x07, 0x53, 0x73, 0x30, 0xc5, 0x5f, 0x56, 0x54, 0xa4, 0x49, 0x14, 0xff, + 0xd2, 0xdf, 0x3d, 0x3e, 0x58, 0x02, 0x81, 0x8f, 0x83, 0x81, 0x1a, 0x09, 0xe2, 0x50, 0x7a, 0x49, + 0x79, 0xfb, 0x65, 0x46, 0x44, 0x82, 0x07, 0xbf, 0x0d, 0x06, 0x7c, 0x39, 0x61, 0x16, 0x41, 0xaf, + 0xf5, 0x7e, 0x99, 0xb9, 0xb7, 0x52, 0x74, 0xe1, 0x48, 0x01, 0x0a, 0x9f, 0x07, 0x03, 0xb4, 0x1a, + 0x84, 0x58, 0x3a, 0x71, 0x36, 0x11, 0xaa, 0x30, 0xe2, 0x71, 0xa3, 0x30, 0x96, 0xa8, 0xe3, 0x04, + 0x24, 0x84, 0xe1, 0xf7, 0x0d, 0x90, 0x97, 0xc7, 0x05, 0x35, 0x87, 0x78, 0x78, 0xbe, 0xde, 0x7b, + 0xbb, 0x65, 0xd9, 0x9b, 0xae, 0x99, 0x24, 0x50, 0xa4, 0xc0, 0xe1, 0x77, 0x0d, 0x00, 0xaa, 0xea, + 0xec, 0x32, 0x87, 0xb9, 0x0f, 0x7b, 0xb6, 0x55, 0xb4, 0x53, 0x51, 0x04, 0x42, 0x5a, 0x2a, 0x69, + 0xa8, 0xb0, 0x02, 0xa6, 0x42, 0x82, 0xb9, 0xee, 0xbb, 0xfe, 0xbe, 0x1f, 0x1c, 0xf8, 0x37, 0x1d, + 0xec, 0xda, 0xd4, 0x04, 0x73, 0xc6, 0x7c, 0xbe, 0x7c, 0x45, 0xda, 0x3f, 0xb5, 0xd5, 0x49, 0x08, + 0x75, 0x1e, 0x5b, 0x7c, 0xaf, 0x2f, 0x5b, 0x6b, 0x65, 0xcf, 0x0b, 0xf8, 0x81, 0x98, 0xbc, 0xc8, + 0xc3, 0xd4, 0x34, 0xf8, 0x42, 0xbc, 0xd9, 0xfb, 0x85, 0x50, 0xb9, 0x3e, 0x3d, 0xa4, 0x15, 0x89, + 0x22, 0xcd, 0x04, 0xf8, 0x53, 0x03, 0x8c, 0x59, 0xd5, 0x2a, 0x0e, 0x23, 0x6c, 0x8b, 0x6d, 0x9c, + 0x3b, 0xdb, 0xa8, 0x9e, 0x92, 0x06, 0x8d, 0x2d, 0xe9, 0xa8, 0xa8, 0xd5, 0x08, 0xf8, 0x12, 0x38, + 0x4f, 0xa3, 0x80, 0x60, 0x3b, 0x89, 0x20, 0x99, 0x5d, 0x60, 0xb3, 0x51, 0x38, 0x5f, 0x69, 0xe1, + 0xa0, 0x8c, 0x64, 0xf1, 0x93, 0x01, 0x50, 0x78, 0x48, 0x84, 0x3e, 0x42, 0xd1, 0x7b, 0x0d, 0x0c, + 0xf2, 0x99, 0xda, 0xdc, 0x21, 0x79, 0xed, 0xa8, 0xe7, 0x54, 0x24, 0xb9, 0xec, 0x78, 0x62, 0xf8, + 0xec, 0x78, 0xea, 0xe3, 0x82, 0xea, 0x78, 0xaa, 0x08, 0x32, 0x4a, 0xf8, 0x70, 0x11, 0x00, 0x1b, + 0x87, 0x04, 0xb3, 0x8c, 0x64, 0x9b, 0x43, 0x5c, 0x5a, 0xad, 0xcf, 0x8a, 0xe2, 0x20, 0x4d, 0x0a, + 0xde, 0x04, 0x30, 0xf9, 0xe7, 0x04, 0xfe, 0x6b, 0x16, 0xf1, 0x1d, 0xbf, 0x66, 0xe6, 0xb9, 0xd9, + 0xd3, 0xec, 0xb4, 0x5d, 0x69, 0xe3, 0xa2, 0x0e, 0x23, 0x60, 0x1d, 0x0c, 0x8a, 0x6b, 0x34, 0xcf, + 0x1b, 0x3d, 0xdc, 0x71, 0xf7, 0x2c, 0xd7, 0xb1, 0x39, 0x54, 0x19, 0x70, 0xf7, 0x70, 0x14, 0x24, + 0xd1, 0xe0, 0xfb, 0x06, 0x18, 0xa5, 0xf1, 0x0e, 0x91, 0xd2, 0x94, 0x67, 0xf5, 0x91, 0xc5, 0x3b, + 0xbd, 0x82, 0xaf, 0x68, 0xba, 0xcb, 0x13, 0xcd, 0x46, 0x61, 0x54, 0xa7, 0xa0, 0x16, 0x6c, 0xf8, + 0x07, 0x03, 0x98, 0x96, 0x2d, 0x42, 0xdf, 0x72, 0xb7, 0x88, 0xe3, 0x47, 0x98, 0x88, 0x0b, 0x91, + 0x38, 0x3e, 0x7a, 0x58, 0x2b, 0x66, 0xef, 0x59, 0xe5, 0x39, 0xb9, 0xd2, 0xe6, 0x52, 0x17, 0x0b, + 0x50, 0x57, 0xdb, 0x8a, 0xff, 0x36, 0xb2, 0xa9, 0x45, 0x9b, 0x65, 0xa5, 0x6a, 0xb9, 0x18, 0xae, + 0x80, 0x09, 0x56, 0xfd, 0x22, 0x1c, 0xba, 0x4e, 0xd5, 0xa2, 0xfc, 0xf6, 0x23, 0xa2, 0x5b, 0x5d, + 0xc3, 0x2b, 0x19, 0x3e, 0x6a, 0x1b, 0x01, 0x5f, 0x05, 0x50, 0x94, 0x85, 0x2d, 0x7a, 0x44, 0x25, + 0xa0, 0x0a, 0xbc, 0x4a, 0x9b, 0x04, 0xea, 0x30, 0x0a, 0x2e, 0x83, 0x49, 0xd7, 0xda, 0xc1, 0x6e, + 0x05, 0xbb, 0xb8, 0x1a, 0x05, 0x84, 0xab, 0x12, 0xf7, 0xc3, 0xa9, 0x66, 0xa3, 0x30, 0xb9, 0x9e, + 0x65, 0xa2, 0x76, 0xf9, 0xe2, 0xd5, 0xec, 0x5e, 0xd6, 0x27, 0x2e, 0x8a, 0xed, 0x0f, 0x73, 0x60, + 0xa6, 0x7b, 0x50, 0xc0, 0xef, 0xa8, 0xd2, 0x58, 0x54, 0x7c, 0xaf, 0x9f, 0x41, 0xe8, 0xc9, 0xeb, + 0x00, 0x68, 0xbf, 0x0a, 0xc0, 0x23, 0x76, 0x5e, 0x5b, 0x6e, 0x72, 0xed, 0xdf, 0x3e, 0x0b, 0x74, + 0xa6, 0xbf, 0x3c, 0x2c, 0xaa, 0x00, 0xcb, 0xe5, 0x87, 0xbe, 0xe5, 0xe2, 0xe2, 0x47, 0x6d, 0x57, + 0xdb, 0x74, 0xb3, 0xc2, 0x1f, 0x18, 0x60, 0x3c, 0x08, 0xb1, 0xbf, 0xb4, 0xb5, 0x76, 0xef, 0xcb, + 0x62, 0xd3, 0x4a, 0x07, 0xad, 0x9d, 0xdc, 0x44, 0x76, 0xbf, 0x16, 0xba, 0xb6, 0x48, 0x10, 0xd2, + 0xf2, 0x85, 0x66, 0xa3, 0x30, 0xbe, 0xd9, 0x8a, 0x82, 0xb2, 0xb0, 0x45, 0x0f, 0x4c, 0xad, 0x1e, + 0x46, 0x98, 0xf8, 0x96, 0xbb, 0x12, 0x54, 0x63, 0x0f, 0xfb, 0x91, 0xb0, 0x31, 0xd3, 0x2e, 0x30, + 0x1e, 0xb1, 0x5d, 0x70, 0x05, 0xf4, 0xc5, 0xc4, 0x95, 0x51, 0x3b, 0xa2, 0x9a, 0x60, 0x68, 0x1d, + 0x31, 0x7a, 0xf1, 0x2a, 0xe8, 0x67, 0x76, 0xc2, 0x4b, 0xa0, 0x8f, 0x58, 0x07, 0x5c, 0xeb, 0x68, + 0x79, 0x88, 0x89, 0x20, 0xeb, 0x00, 0x31, 0x5a, 0xf1, 0xef, 0x73, 0x60, 0x3c, 0x33, 0x17, 0x38, + 0x03, 0x72, 0xaa, 0xb3, 0x06, 0xa4, 0xd2, 0xdc, 0xda, 0x0a, 0xca, 0x39, 0x36, 0x7c, 0x51, 0x65, + 0x57, 0x01, 0x5a, 0x50, 0x87, 0x05, 0xa7, 0xb2, 0xb2, 0x2c, 0x55, 0xc7, 0x0c, 0x49, 0xd2, 0x23, + 0xb3, 0x01, 0xef, 0xca, 0x5d, 0x21, 0x6c, 0xc0, 0xbb, 0x88, 0xd1, 0x4e, 0xda, 0x2b, 0x49, 0x9a, + 0x35, 0x03, 0x8f, 0xd0, 0xac, 0x19, 0x7c, 0x60, 0xb3, 0xe6, 0x71, 0x30, 0x10, 0x39, 0x91, 0x8b, + 0xf9, 0x49, 0xa5, 0x15, 0xc3, 0x77, 0x18, 0x11, 0x09, 0x1e, 0xc4, 0x60, 0xc8, 0xc6, 0xbb, 0x56, + 0xec, 0x46, 0xfc, 0x50, 0x1a, 0x59, 0xfc, 0xfa, 0xe9, 0xa2, 0x47, 0x34, 0x33, 0x56, 0x84, 0x4a, + 0x94, 0xe8, 0x86, 0x4f, 0x80, 0x21, 0xcf, 0x3a, 0x74, 0xbc, 0xd8, 0xe3, 0x15, 0xa3, 0x21, 0xc4, + 0x36, 0x04, 0x09, 0x25, 0x3c, 0x96, 0x04, 0xf1, 0x61, 0xd5, 0x8d, 0xa9, 0x53, 0xc7, 0x92, 0x29, + 0x4b, 0x3a, 0x95, 0x04, 0x57, 0x33, 0x7c, 0xd4, 0x36, 0x82, 0x83, 0x39, 0x3e, 0x1f, 0x3c, 0xa2, + 0x81, 0x09, 0x12, 0x4a, 0x78, 0xad, 0x60, 0x52, 0x7e, 0xb4, 0x1b, 0x98, 0x1c, 0xdc, 0x36, 0x02, + 0x3e, 0x0d, 0x86, 0x3d, 0xeb, 0x70, 0x1d, 0xfb, 0xb5, 0x68, 0xcf, 0x1c, 0x9b, 0x33, 0xe6, 0xfb, + 0xca, 0x63, 0xcd, 0x46, 0x61, 0x78, 0x23, 0x21, 0xa2, 0x94, 0xcf, 0x85, 0x1d, 0x5f, 0x0a, 0x9f, + 0xd7, 0x84, 0x13, 0x22, 0x4a, 0xf9, 0xac, 0x32, 0x09, 0xad, 0x88, 0xed, 0x2b, 0x73, 0xbc, 0xf5, + 0xe2, 0xbc, 0x25, 0xc8, 0x28, 0xe1, 0xc3, 0x79, 0x90, 0xf7, 0xac, 0x43, 0x7e, 0xa7, 0x34, 0x27, + 0xb8, 0x5a, 0xde, 0x50, 0xdc, 0x90, 0x34, 0xa4, 0xb8, 0x5c, 0xd2, 0xf1, 0x85, 0xe4, 0xa4, 0x26, + 0x29, 0x69, 0x48, 0x71, 0x59, 0xfc, 0xc6, 0xbe, 0x73, 0x3f, 0xc6, 0x42, 0x18, 0x72, 0xcf, 0xa8, + 0xf8, 0xbd, 0x9b, 0xb2, 0x90, 0x2e, 0xc7, 0xee, 0x74, 0x5e, 0xec, 0x46, 0x4e, 0xe8, 0xe2, 0xcd, + 0x5d, 0xf3, 0x02, 0xf7, 0x3f, 0x2f, 0xe5, 0x37, 0x14, 0x15, 0x69, 0x12, 0xf0, 0x6d, 0xd0, 0x8f, + 0xfd, 0xd8, 0x33, 0x2f, 0xf2, 0xe3, 0xfb, 0xb4, 0xd1, 0xa7, 0xf6, 0xcb, 0xaa, 0x1f, 0x7b, 0x88, + 0x6b, 0x86, 0x2f, 0x82, 0x31, 0xcf, 0x3a, 0x64, 0x49, 0x00, 0x93, 0x88, 0x5d, 0x34, 0xa7, 0xf8, + 0xbc, 0x27, 0x59, 0x11, 0xbb, 0xa1, 0x33, 0x50, 0xab, 0x1c, 0x1f, 0xe8, 0xf8, 0xda, 0xc0, 0x69, + 0x6d, 0xa0, 0xce, 0x40, 0xad, 0x72, 0xcc, 0xc9, 0x04, 0xdf, 0x8f, 0x1d, 0x82, 0x6d, 0xf3, 0xff, + 0x78, 0xdd, 0x2b, 0xfb, 0xbb, 0x82, 0x86, 0x14, 0x17, 0xde, 0x4f, 0x5a, 0x0e, 0x26, 0xdf, 0x7c, + 0x5b, 0x3d, 0x4b, 0xdd, 0x9b, 0x64, 0x89, 0x10, 0xeb, 0x48, 0x9c, 0x2a, 0x7a, 0xb3, 0x01, 0xfa, + 0x60, 0xc0, 0x72, 0xdd, 0xcd, 0x5d, 0xf3, 0x12, 0xf7, 0x78, 0x0f, 0x4f, 0x0b, 0x95, 0x61, 0x96, + 0x98, 0x7e, 0x24, 0x60, 0x18, 0x5e, 0xe0, 0xb3, 0x58, 0x98, 0x39, 0x33, 0xbc, 0x4d, 0xa6, 0x1f, + 0x09, 0x18, 0x3e, 0x3f, 0xff, 0x68, 0x73, 0xd7, 0x7c, 0xec, 0xec, 0xe6, 0xc7, 0xf4, 0x23, 0x01, + 0x03, 0x6d, 0xd0, 0xe7, 0x07, 0x91, 0x79, 0xb9, 0xd7, 0x67, 0x2f, 0x3f, 0x4d, 0x6e, 0x07, 0x11, + 0x62, 0xea, 0xe1, 0x8f, 0x0c, 0x00, 0xc2, 0x34, 0x12, 0xaf, 0x9c, 0xb6, 0x05, 0x90, 0x41, 0x2b, + 0xa5, 0xd1, 0xbb, 0xea, 0x47, 0xe4, 0x28, 0xbd, 0xd7, 0x68, 0x51, 0xae, 0x19, 0x00, 0x7f, 0x6e, + 0x80, 0x8b, 0x7a, 0xb9, 0xab, 0x2c, 0x9b, 0xe5, 0x7e, 0xd8, 0xec, 0x61, 0x20, 0x97, 0x83, 0xc0, + 0x2d, 0x9b, 0xcd, 0x46, 0xe1, 0xe2, 0x52, 0x07, 0x40, 0xd4, 0xd1, 0x0c, 0xf8, 0x1b, 0x03, 0x4c, + 0xca, 0xec, 0xa8, 0x19, 0x57, 0xe0, 0x6e, 0x7b, 0xbb, 0x87, 0x6e, 0xcb, 0x42, 0x08, 0xef, 0xa9, + 0x57, 0xc6, 0x36, 0x3e, 0x6a, 0xb7, 0x0a, 0xfe, 0xde, 0x00, 0xa3, 0x36, 0x0e, 0xb1, 0x6f, 0x63, + 0xbf, 0xca, 0xcc, 0x9c, 0x3b, 0x6d, 0x5f, 0x21, 0x6b, 0xe6, 0x8a, 0xa6, 0x5d, 0x58, 0x58, 0x92, + 0x16, 0x8e, 0xea, 0xac, 0xe3, 0x46, 0x61, 0x3a, 0x1d, 0xaa, 0x73, 0x50, 0x8b, 0x81, 0xf0, 0xc7, + 0x06, 0x18, 0x4f, 0xdd, 0x2e, 0x0e, 0x88, 0xab, 0x67, 0xb3, 0xf0, 0xbc, 0x04, 0x5d, 0x6a, 0xc5, + 0x42, 0x59, 0x70, 0xf8, 0x5b, 0x83, 0x55, 0x5b, 0xc9, 0x5d, 0x8d, 0x9a, 0x45, 0xee, 0xc1, 0x37, + 0x7a, 0xe9, 0x41, 0xa5, 0x5c, 0x38, 0xf0, 0x7a, 0x5a, 0xc9, 0x29, 0xce, 0x71, 0xa3, 0x30, 0xa5, + 0xfb, 0x4f, 0x31, 0x90, 0x6e, 0x1c, 0x7c, 0xcf, 0x00, 0xa3, 0x38, 0x2d, 0x98, 0xa9, 0xf9, 0xf8, + 0x69, 0x5d, 0xd7, 0xb1, 0xfc, 0x16, 0xd7, 0x69, 0x8d, 0x45, 0x51, 0x0b, 0x2c, 0xab, 0xfd, 0xf0, + 0xa1, 0xe5, 0x85, 0x2e, 0x36, 0xff, 0xbf, 0x77, 0xb5, 0xdf, 0xaa, 0x50, 0x89, 0x12, 0xdd, 0xf0, + 0x3a, 0xc8, 0xfb, 0xb1, 0xeb, 0x5a, 0x3b, 0x2e, 0x36, 0x9f, 0xe0, 0x55, 0x84, 0xea, 0x2f, 0xde, + 0x96, 0x74, 0xa4, 0x24, 0xe0, 0x2e, 0x98, 0x3b, 0xbc, 0xa5, 0x3e, 0xbe, 0xe8, 0xd8, 0xc0, 0x33, + 0xaf, 0x71, 0x2d, 0x33, 0xcd, 0x46, 0x61, 0x7a, 0xbb, 0x73, 0x8b, 0xef, 0xa1, 0x3a, 0xe0, 0x9b, + 0xe0, 0x31, 0x4d, 0x66, 0xd5, 0xdb, 0xc1, 0xb6, 0x8d, 0xed, 0xe4, 0xa2, 0x65, 0x7e, 0x89, 0x43, + 0xa8, 0x7d, 0xbc, 0x9d, 0x15, 0x40, 0x0f, 0x1a, 0x0d, 0xd7, 0xc1, 0xb4, 0xc6, 0x5e, 0xf3, 0xa3, + 0x4d, 0x52, 0x89, 0x88, 0xe3, 0xd7, 0xcc, 0x79, 0xae, 0xf7, 0x62, 0xb2, 0xfb, 0xb6, 0x35, 0x1e, + 0xea, 0x32, 0x06, 0xbe, 0xd2, 0xa2, 0x8d, 0x3f, 0x5c, 0x58, 0xe1, 0x2d, 0x7c, 0x44, 0xcd, 0x27, + 0x79, 0x71, 0xc1, 0xd7, 0x79, 0x5b, 0xa3, 0xa3, 0x2e, 0xf2, 0xf0, 0x1b, 0xe0, 0x42, 0x86, 0xc3, + 0xee, 0x15, 0xe6, 0x53, 0xe2, 0x82, 0xc0, 0x2a, 0xd1, 0xed, 0x84, 0x88, 0x3a, 0x49, 0xc2, 0xaf, + 0x01, 0xa8, 0x91, 0x37, 0xac, 0x90, 0x8f, 0x7f, 0x5a, 0xdc, 0x55, 0xd8, 0x8a, 0x6e, 0x4b, 0x1a, + 0xea, 0x20, 0x07, 0x3f, 0x34, 0x5a, 0x66, 0x92, 0xde, 0x66, 0xa9, 0x79, 0x9d, 0x6f, 0xd8, 0x57, + 0x4e, 0x1e, 0x80, 0xa9, 0x32, 0x14, 0xbb, 0x58, 0xf3, 0xb0, 0x86, 0x82, 0xba, 0xa0, 0xcf, 0xb0, + 0xcb, 0x74, 0x26, 0x87, 0xc3, 0x09, 0xd0, 0xb7, 0x8f, 0xe5, 0xb3, 0x31, 0x62, 0x3f, 0xe1, 0x5b, + 0x60, 0xa0, 0x6e, 0xb9, 0x71, 0xd2, 0x0a, 0xe8, 0xdd, 0x59, 0x8f, 0x84, 0xde, 0x97, 0x72, 0x37, + 0x8c, 0x99, 0x0f, 0x0c, 0x30, 0xdd, 0xf9, 0x54, 0xf9, 0xa2, 0x2c, 0xfa, 0x99, 0x01, 0x26, 0xdb, + 0x0e, 0x90, 0x0e, 0xc6, 0xb8, 0xad, 0xc6, 0xdc, 0xeb, 0xe1, 0x49, 0x20, 0x36, 0x02, 0xaf, 0x68, + 0x75, 0xcb, 0x7e, 0x68, 0x80, 0x89, 0x6c, 0x62, 0xfe, 0x82, 0xbc, 0x54, 0x7c, 0x3f, 0x07, 0xa6, + 0x3b, 0xd7, 0xe0, 0xd0, 0x53, 0xdd, 0x85, 0x9e, 0x37, 0x68, 0x3a, 0xb5, 0x6c, 0xdf, 0x35, 0xc0, + 0xc8, 0x3b, 0x4a, 0x2e, 0x79, 0xcd, 0xec, 0x65, 0x57, 0x28, 0x39, 0xfa, 0x52, 0x06, 0x45, 0x3a, + 0x64, 0xf1, 0x77, 0x06, 0x98, 0xea, 0x78, 0x9c, 0xc3, 0x6b, 0x60, 0xd0, 0x72, 0xdd, 0xe0, 0x40, + 0x74, 0xf3, 0xb4, 0xb6, 0xfc, 0x12, 0xa7, 0x22, 0xc9, 0xd5, 0x7c, 0x96, 0xfb, 0x1c, 0x7c, 0x56, + 0xfc, 0xa3, 0x01, 0x2e, 0x3f, 0x28, 0xea, 0x3e, 0xef, 0x35, 0x9c, 0x07, 0x79, 0x59, 0x6c, 0x1f, + 0xf1, 0xf5, 0x93, 0xd9, 0x55, 0x66, 0x04, 0xfe, 0xb5, 0x8c, 0xf8, 0x55, 0xfc, 0xa5, 0x01, 0x26, + 0x2a, 0x98, 0xd4, 0x9d, 0x2a, 0x46, 0x78, 0x17, 0x13, 0xec, 0x57, 0x31, 0x5c, 0x00, 0xc3, 0xfc, + 0xb5, 0x31, 0xb4, 0xaa, 0xc9, 0x1b, 0xc9, 0xa4, 0x74, 0xf4, 0xf0, 0xed, 0x84, 0x81, 0x52, 0x19, + 0xf5, 0x9e, 0x92, 0xeb, 0xfa, 0x9e, 0x72, 0x19, 0xf4, 0x87, 0x69, 0x03, 0x38, 0xcf, 0xb8, 0xbc, + 0xe7, 0xcb, 0xa9, 0x9c, 0x1b, 0x90, 0x88, 0x77, 0xb9, 0x06, 0x24, 0x37, 0x20, 0x11, 0xe2, 0xd4, + 0xe2, 0xaf, 0x0d, 0x70, 0xbe, 0x35, 0x3f, 0x33, 0x40, 0x12, 0xbb, 0x6d, 0x0f, 0x38, 0x8c, 0x87, + 0x38, 0x47, 0xff, 0x6e, 0x20, 0xf7, 0xe0, 0xef, 0x06, 0xe0, 0xcb, 0x60, 0x52, 0xfe, 0x5c, 0x3d, + 0x0c, 0x09, 0xa6, 0xfc, 0x65, 0xb2, 0xaf, 0xf5, 0x7b, 0xbf, 0x8d, 0xac, 0x00, 0x6a, 0x1f, 0x53, + 0xfc, 0x93, 0x01, 0x2e, 0x24, 0xdf, 0xe7, 0xb8, 0x0e, 0xf6, 0xa3, 0xe5, 0xc0, 0xdf, 0x75, 0x6a, + 0xf0, 0x92, 0xe8, 0x48, 0x6a, 0x6d, 0xbe, 0xa4, 0x1b, 0x09, 0xef, 0x83, 0x21, 0x2a, 0xdc, 0x2f, + 0x23, 0xe3, 0xd5, 0x93, 0x47, 0x46, 0x76, 0x1d, 0x45, 0x41, 0x95, 0x50, 0x13, 0x1c, 0x16, 0x1c, + 0x55, 0xab, 0x1c, 0xfb, 0xb6, 0xec, 0x4a, 0x8f, 0x8a, 0xe0, 0x58, 0x5e, 0x12, 0x34, 0xa4, 0xb8, + 0xc5, 0x7f, 0x18, 0x60, 0xb2, 0xed, 0x7b, 0x23, 0xf8, 0x3d, 0x03, 0x8c, 0x56, 0xb5, 0xe9, 0xc9, + 0x2d, 0xb6, 0x71, 0xfa, 0x6f, 0x9a, 0x34, 0xa5, 0xa2, 0x2a, 0xd1, 0x29, 0xa8, 0x05, 0x14, 0x6e, + 0x03, 0xb3, 0x9a, 0xf9, 0xb4, 0x2f, 0xf3, 0x58, 0x78, 0xb9, 0xd9, 0x28, 0x98, 0xcb, 0x5d, 0x64, + 0x50, 0xd7, 0xd1, 0xe5, 0x6f, 0x7d, 0xfc, 0xd9, 0xec, 0xb9, 0x4f, 0x3e, 0x9b, 0x3d, 0xf7, 0xe9, + 0x67, 0xb3, 0xe7, 0xde, 0x6d, 0xce, 0x1a, 0x1f, 0x37, 0x67, 0x8d, 0x4f, 0x9a, 0xb3, 0xc6, 0xa7, + 0xcd, 0x59, 0xe3, 0xaf, 0xcd, 0x59, 0xe3, 0x27, 0x7f, 0x9b, 0x3d, 0xf7, 0xc6, 0x8d, 0x93, 0x7e, + 0xd0, 0xfb, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x41, 0x66, 0xfd, 0x82, 0x24, 0x2c, 0x00, 0x00, } func (m *ConversionRequest) Marshal() (dAtA []byte, err error) { @@ -2629,6 +2630,11 @@ func (m *ValidationRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.MessageExpression) + copy(dAtA[i:], m.MessageExpression) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.MessageExpression))) + i-- + dAtA[i] = 0x1a i -= len(m.Message) copy(dAtA[i:], m.Message) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) @@ -3338,6 +3344,8 @@ func (m *ValidationRule) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Message) n += 1 + l + sovGenerated(uint64(l)) + l = len(m.MessageExpression) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -3813,6 +3821,7 @@ func (this *ValidationRule) String() string { s := strings.Join([]string{`&ValidationRule{`, `Rule:` + fmt.Sprintf("%v", this.Rule) + `,`, `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `MessageExpression:` + fmt.Sprintf("%v", this.MessageExpression) + `,`, `}`, }, "") return s @@ -8879,6 +8888,38 @@ func (m *ValidationRule) Unmarshal(dAtA []byte) error { } m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MessageExpression", 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.MessageExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto index d0b190fd5..4632a83e5 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/generated.proto @@ -107,12 +107,12 @@ message CustomResourceColumnDefinition { // CustomResourceConversion describes how to convert different versions of a CR. message CustomResourceConversion { // strategy specifies how custom resources are converted between versions. Allowed values are: - // - `None`: The converter only change the apiVersion and would not touch any other field in the custom resource. - // - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information + // - `"None"`: The converter only change the apiVersion and would not touch any other field in the custom resource. + // - `"Webhook"`: API Server will call to an external webhook to do the conversion. Additional information // is needed for this option. This requires spec.preserveUnknownFields to be false, and spec.conversion.webhook to be set. optional string strategy = 1; - // webhook describes how to call the conversion webhook. Required when `strategy` is set to `Webhook`. + // webhook describes how to call the conversion webhook. Required when `strategy` is set to `"Webhook"`. // +optional optional WebhookConversion webhook = 2; } @@ -665,6 +665,19 @@ message ValidationRule { // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" optional string message = 2; + + // MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a rule, then messageExpression will be used if validation + // fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the rule; the only difference is the return type. + // Example: + // "x must be less than max ("+string(self.max)+")" + // +optional + optional string messageExpression = 3; } // WebhookClientConfig contains the information to make a TLS connection with the webhook. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go index 285058d77..59ec0e372 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types.go @@ -74,12 +74,12 @@ type CustomResourceDefinitionSpec struct { // CustomResourceConversion describes how to convert different versions of a CR. type CustomResourceConversion struct { // strategy specifies how custom resources are converted between versions. Allowed values are: - // - `None`: The converter only change the apiVersion and would not touch any other field in the custom resource. - // - `Webhook`: API Server will call to an external webhook to do the conversion. Additional information + // - `"None"`: The converter only change the apiVersion and would not touch any other field in the custom resource. + // - `"Webhook"`: API Server will call to an external webhook to do the conversion. Additional information // is needed for this option. This requires spec.preserveUnknownFields to be false, and spec.conversion.webhook to be set. Strategy ConversionStrategyType `json:"strategy" protobuf:"bytes,1,name=strategy"` - // webhook describes how to call the conversion webhook. Required when `strategy` is set to `Webhook`. + // webhook describes how to call the conversion webhook. Required when `strategy` is set to `"Webhook"`. // +optional Webhook *WebhookConversion `json:"webhook,omitempty" protobuf:"bytes,2,opt,name=webhook"` } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go index 277fd7a12..b348d0d19 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/types_jsonschema.go @@ -235,12 +235,24 @@ type ValidationRule struct { // If unset, the message is "failed rule: {Rule}". // e.g. "must be a URL with the host matching spec.host" Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"` + // MessageExpression declares a CEL expression that evaluates to the validation failure message that is returned when this rule fails. + // Since messageExpression is used as a failure message, it must evaluate to a string. + // If both message and messageExpression are present on a rule, then messageExpression will be used if validation + // fails. If messageExpression results in a runtime error, the runtime error is logged, and the validation failure message is produced + // as if the messageExpression field were unset. If messageExpression evaluates to an empty string, a string with only spaces, or a string + // that contains line breaks, then the validation failure message will also be produced as if the messageExpression field were unset, and + // the fact that messageExpression produced an empty string/string with only spaces/string with line breaks will be logged. + // messageExpression has access to all the same variables as the rule; the only difference is the return type. + // Example: + // "x must be less than max ("+string(self.max)+")" + // +optional + MessageExpression string `json:"messageExpression,omitempty" protobuf:"bytes,3,opt,name=messageExpression"` } // JSON represents any valid JSON value. // These types are supported: bool, int64, float64, string, []interface{}, map[string]interface{} and nil. type JSON struct { - Raw []byte `protobuf:"bytes,1,opt,name=raw"` + Raw []byte `json:"-" protobuf:"bytes,1,opt,name=raw"` } // OpenAPISchemaType is used by the kube-openapi generator when constructing diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go index 95a58529b..cde5275ce 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1/zz_generated.conversion.go @@ -1258,6 +1258,7 @@ func Convert_apiextensions_ServiceReference_To_v1_ServiceReference(in *apiextens func autoConvert_v1_ValidationRule_To_apiextensions_ValidationRule(in *ValidationRule, out *apiextensions.ValidationRule, s conversion.Scope) error { out.Rule = in.Rule out.Message = in.Message + out.MessageExpression = in.MessageExpression return nil } @@ -1269,6 +1270,7 @@ func Convert_v1_ValidationRule_To_apiextensions_ValidationRule(in *ValidationRul func autoConvert_apiextensions_ValidationRule_To_v1_ValidationRule(in *apiextensions.ValidationRule, out *ValidationRule, s conversion.Scope) error { out.Rule = in.Rule out.Message = in.Message + out.MessageExpression = in.MessageExpression return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/help.go b/vendor/k8s.io/apimachinery/pkg/api/meta/help.go index 899d3e8a6..1bf6b06d4 100644 --- a/vendor/k8s.io/apimachinery/pkg/api/meta/help.go +++ b/vendor/k8s.io/apimachinery/pkg/api/meta/help.go @@ -40,8 +40,7 @@ var ( // IsListType returns true if the provided Object has a slice called Items. // TODO: Replace the code in this check with an interface comparison by -// -// creating and enforcing that lists implement a list accessor. +// creating and enforcing that lists implement a list accessor. func IsListType(obj runtime.Object) bool { switch t := obj.(type) { case runtime.Unstructured: diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go new file mode 100644 index 000000000..29c6a48b6 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/defaults.go @@ -0,0 +1,38 @@ +/* +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 internalversion + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// SetListOptionsDefaults sets defaults on the provided ListOptions if applicable. +// +// TODO(#115478): once the watch-list fg is always on we register this function in the scheme (via AddTypeDefaultingFunc). +// TODO(#115478): when the function is registered in the scheme remove all callers of this method. +func SetListOptionsDefaults(obj *ListOptions, isWatchListFeatureEnabled bool) { + if !isWatchListFeatureEnabled { + return + } + if obj.SendInitialEvents != nil || len(obj.ResourceVersionMatch) != 0 { + return + } + legacy := obj.ResourceVersion == "" || obj.ResourceVersion == "0" + if obj.Watch && legacy { + turnOnInitialEvents := true + obj.SendInitialEvents = &turnOnInitialEvents + obj.ResourceVersionMatch = metav1.ResourceVersionMatchNotOlderThan + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go index a49b5f2be..00d2b8c68 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/types.go @@ -66,6 +66,31 @@ type ListOptions struct { // it does not recognize and will return a 410 error if the token can no longer be used because // it has expired. Continue string + + // `sendInitialEvents=true` may be set together with `watch=true`. + // In that case, the watch stream will begin with synthetic events to + // produce the current state of objects in the collection. Once all such + // events have been sent, a synthetic "Bookmark" event will be sent. + // The bookmark will report the ResourceVersion (RV) corresponding to the + // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. + // Afterwards, the watch stream will proceed as usual, sending watch events + // corresponding to changes (subsequent to the RV) to objects watched. + // + // When `sendInitialEvents` option is set, we require `resourceVersionMatch` + // option to also be set. The semantic of the watch request is as following: + // - `resourceVersionMatch` = NotOlderThan + // is interpreted as "data at least as new as the provided `resourceVersion`" + // and the bookmark event is send when the state is synced + // to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + // If `resourceVersion` is unset, this is interpreted as "consistent read" and the + // bookmark event is send when the state is synced at least to the moment + // when request started being processed. + // - `resourceVersionMatch` set to any other value or unset + // Invalid error is returned. + // + // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward + // compatibility reasons) and to false otherwise. + SendInitialEvents *bool } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/validation/validation.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/validation/validation.go index 8403d1a86..2734a8f3b 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/validation/validation.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/validation/validation.go @@ -17,18 +17,20 @@ limitations under the License. package validation import ( + "fmt" + "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/validation/field" ) // ValidateListOptions returns all validation errors found while validating the ListOptions. -func ValidateListOptions(options *internalversion.ListOptions) field.ErrorList { +func ValidateListOptions(options *internalversion.ListOptions, isWatchListFeatureEnabled bool) field.ErrorList { + if options.Watch { + return validateWatchOptions(options, isWatchListFeatureEnabled) + } allErrs := field.ErrorList{} if match := options.ResourceVersionMatch; len(match) > 0 { - if options.Watch { - allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch is forbidden for watch")) - } if len(options.ResourceVersion) == 0 { allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch is forbidden unless resourceVersion is provided")) } @@ -42,5 +44,33 @@ func ValidateListOptions(options *internalversion.ListOptions) field.ErrorList { allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch \"exact\" is forbidden for resourceVersion \"0\"")) } } + if options.SendInitialEvents != nil { + allErrs = append(allErrs, field.Forbidden(field.NewPath("sendInitialEvents"), "sendInitialEvents is forbidden for list")) + } + return allErrs +} + +func validateWatchOptions(options *internalversion.ListOptions, isWatchListFeatureEnabled bool) field.ErrorList { + allErrs := field.ErrorList{} + match := options.ResourceVersionMatch + if options.SendInitialEvents != nil { + if match != metav1.ResourceVersionMatchNotOlderThan { + allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), fmt.Sprintf("sendInitialEvents requires setting resourceVersionMatch to %s", metav1.ResourceVersionMatchNotOlderThan))) + } + if !isWatchListFeatureEnabled { + allErrs = append(allErrs, field.Forbidden(field.NewPath("sendInitialEvents"), "sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled")) + } + } + if len(match) > 0 { + if options.SendInitialEvents == nil { + allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch is forbidden for watch unless sendInitialEvents is provided")) + } + if match != metav1.ResourceVersionMatchNotOlderThan { + allErrs = append(allErrs, field.NotSupported(field.NewPath("resourceVersionMatch"), match, []string{string(metav1.ResourceVersionMatchNotOlderThan)})) + } + if len(options.Continue) > 0 { + allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch is forbidden when continue is provided")) + } + } return allErrs } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go index 6d212b846..a6552c276 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.conversion.go @@ -115,6 +115,7 @@ func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds)) out.Limit = in.Limit out.Continue = in.Continue + out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents)) return nil } @@ -137,6 +138,7 @@ func autoConvert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOption out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds)) out.Limit = in.Limit out.Continue = in.Continue + out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents)) return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go index 6e1eac5c7..af66a2ac4 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/zz_generated.deepcopy.go @@ -75,6 +75,11 @@ func (in *ListOptions) DeepCopyInto(out *ListOptions) { *out = new(int64) **out = **in } + if in.SendInitialEvents != nil { + in, out := &in.SendInitialEvents, &out.SendInitialEvents + *out = new(bool) + **out = **in + } return } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go index 7e00eb7d9..1a641e7c1 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.pb.go @@ -1326,185 +1326,187 @@ func init() { } var fileDescriptor_cf52fa777ced5367 = []byte{ - // 2842 bytes of a gzipped FileDescriptorProto + // 2867 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x1a, 0x4b, 0x6f, 0x24, 0x47, 0xd9, 0x3d, 0x0f, 0x7b, 0xe6, 0x9b, 0x19, 0x3f, 0x6a, 0xbd, 0x30, 0x6b, 0x84, 0xc7, 0xe9, 0x44, 0xd1, 0x06, 0x92, 0x71, 0x76, 0x09, 0xd1, 0x66, 0x43, 0x02, 0x1e, 0xcf, 0x7a, 0xe3, 0x64, 0x1d, 0x5b, 0xe5, 0xdd, 0x05, 0x42, 0x84, 0xd2, 0x9e, 0x2e, 0x8f, 0x1b, 0xf7, 0x74, 0x4f, 0xaa, 0x7a, 0xbc, 0x19, 0x38, 0x90, 0x03, 0x08, 0x90, 0x50, 0x14, 0x6e, 0x9c, 0x50, 0x22, 0xf8, 0x01, 0x88, - 0x0b, 0xdc, 0x41, 0x22, 0xc7, 0x20, 0x2e, 0x91, 0x40, 0xa3, 0xc4, 0x1c, 0x38, 0x22, 0xae, 0xbe, - 0x80, 0xea, 0xd1, 0xdd, 0xd5, 0xf3, 0x58, 0xf7, 0x64, 0x97, 0x88, 0xdb, 0xf4, 0xf7, 0xae, 0xaa, - 0xaf, 0xbe, 0x47, 0x7d, 0x03, 0x3b, 0xc7, 0xd7, 0x58, 0xdd, 0xf1, 0xd7, 0x8f, 0x7b, 0x07, 0x84, - 0x7a, 0x24, 0x20, 0x6c, 0xfd, 0x84, 0x78, 0xb6, 0x4f, 0xd7, 0x15, 0xc2, 0xea, 0x3a, 0x1d, 0xab, - 0x75, 0xe4, 0x78, 0x84, 0xf6, 0xd7, 0xbb, 0xc7, 0x6d, 0x0e, 0x60, 0xeb, 0x1d, 0x12, 0x58, 0xeb, - 0x27, 0x57, 0xd6, 0xdb, 0xc4, 0x23, 0xd4, 0x0a, 0x88, 0x5d, 0xef, 0x52, 0x3f, 0xf0, 0xd1, 0x63, - 0x92, 0xab, 0xae, 0x73, 0xd5, 0xbb, 0xc7, 0x6d, 0x0e, 0x60, 0x75, 0xce, 0x55, 0x3f, 0xb9, 0xb2, - 0xf2, 0x54, 0xdb, 0x09, 0x8e, 0x7a, 0x07, 0xf5, 0x96, 0xdf, 0x59, 0x6f, 0xfb, 0x6d, 0x7f, 0x5d, - 0x30, 0x1f, 0xf4, 0x0e, 0xc5, 0x97, 0xf8, 0x10, 0xbf, 0xa4, 0xd0, 0x95, 0x89, 0xa6, 0xd0, 0x9e, - 0x17, 0x38, 0x1d, 0x32, 0x6c, 0xc5, 0xca, 0xb3, 0xe7, 0x31, 0xb0, 0xd6, 0x11, 0xe9, 0x58, 0xc3, - 0x7c, 0xe6, 0x9f, 0xb3, 0x50, 0xd8, 0xd8, 0xdb, 0xbe, 0x49, 0xfd, 0x5e, 0x17, 0xad, 0x41, 0xce, - 0xb3, 0x3a, 0xa4, 0x6a, 0xac, 0x19, 0x97, 0x8b, 0x8d, 0xf2, 0x07, 0x83, 0xda, 0xcc, 0xe9, 0xa0, - 0x96, 0x7b, 0xd5, 0xea, 0x10, 0x2c, 0x30, 0xc8, 0x85, 0xc2, 0x09, 0xa1, 0xcc, 0xf1, 0x3d, 0x56, - 0xcd, 0xac, 0x65, 0x2f, 0x97, 0xae, 0xbe, 0x58, 0x4f, 0xb3, 0xfe, 0xba, 0x50, 0x70, 0x57, 0xb2, - 0x6e, 0xf9, 0xb4, 0xe9, 0xb0, 0x96, 0x7f, 0x42, 0x68, 0xbf, 0xb1, 0xa8, 0xb4, 0x14, 0x14, 0x92, - 0xe1, 0x48, 0x03, 0xfa, 0x91, 0x01, 0x8b, 0x5d, 0x4a, 0x0e, 0x09, 0xa5, 0xc4, 0x56, 0xf8, 0x6a, - 0x76, 0xcd, 0x78, 0x08, 0x6a, 0xab, 0x4a, 0xed, 0xe2, 0xde, 0x90, 0x7c, 0x3c, 0xa2, 0x11, 0xfd, - 0xda, 0x80, 0x15, 0x46, 0xe8, 0x09, 0xa1, 0x1b, 0xb6, 0x4d, 0x09, 0x63, 0x8d, 0xfe, 0xa6, 0xeb, - 0x10, 0x2f, 0xd8, 0xdc, 0x6e, 0x62, 0x56, 0xcd, 0x89, 0x7d, 0xf8, 0x7a, 0x3a, 0x83, 0xf6, 0x27, - 0xc9, 0x69, 0x98, 0xca, 0xa2, 0x95, 0x89, 0x24, 0x0c, 0xdf, 0xc7, 0x0c, 0xf3, 0x10, 0xca, 0xe1, - 0x41, 0xde, 0x72, 0x58, 0x80, 0xee, 0xc2, 0x6c, 0x9b, 0x7f, 0xb0, 0xaa, 0x21, 0x0c, 0xac, 0xa7, - 0x33, 0x30, 0x94, 0xd1, 0x98, 0x57, 0xf6, 0xcc, 0x8a, 0x4f, 0x86, 0x95, 0x34, 0xf3, 0x67, 0x39, - 0x28, 0x6d, 0xec, 0x6d, 0x63, 0xc2, 0xfc, 0x1e, 0x6d, 0x91, 0x14, 0x4e, 0x73, 0x0d, 0xca, 0xcc, - 0xf1, 0xda, 0x3d, 0xd7, 0xa2, 0x1c, 0x5a, 0x9d, 0x15, 0x94, 0xcb, 0x8a, 0xb2, 0xbc, 0xaf, 0xe1, - 0x70, 0x82, 0x12, 0x5d, 0x05, 0xe0, 0x12, 0x58, 0xd7, 0x6a, 0x11, 0xbb, 0x9a, 0x59, 0x33, 0x2e, - 0x17, 0x1a, 0x48, 0xf1, 0xc1, 0xab, 0x11, 0x06, 0x6b, 0x54, 0xe8, 0x51, 0xc8, 0x0b, 0x4b, 0xab, - 0x05, 0xa1, 0xa6, 0xa2, 0xc8, 0xf3, 0x62, 0x19, 0x58, 0xe2, 0xd0, 0x13, 0x30, 0xa7, 0xbc, 0xac, - 0x5a, 0x14, 0x64, 0x0b, 0x8a, 0x6c, 0x2e, 0x74, 0x83, 0x10, 0xcf, 0xd7, 0x77, 0xec, 0x78, 0xb6, - 0xf0, 0x3b, 0x6d, 0x7d, 0xaf, 0x38, 0x9e, 0x8d, 0x05, 0x06, 0xdd, 0x82, 0xfc, 0x09, 0xa1, 0x07, - 0xdc, 0x13, 0xb8, 0x6b, 0x7e, 0x39, 0xdd, 0x46, 0xdf, 0xe5, 0x2c, 0x8d, 0x22, 0x37, 0x4d, 0xfc, - 0xc4, 0x52, 0x08, 0xaa, 0x03, 0xb0, 0x23, 0x9f, 0x06, 0x62, 0x79, 0xd5, 0xfc, 0x5a, 0xf6, 0x72, - 0xb1, 0x31, 0xcf, 0xd7, 0xbb, 0x1f, 0x41, 0xb1, 0x46, 0xc1, 0xe9, 0x5b, 0x56, 0x40, 0xda, 0x3e, - 0x75, 0x08, 0xab, 0xce, 0xc5, 0xf4, 0x9b, 0x11, 0x14, 0x6b, 0x14, 0xe8, 0x65, 0x40, 0x2c, 0xf0, - 0xa9, 0xd5, 0x26, 0x6a, 0xa9, 0x2f, 0x59, 0xec, 0xa8, 0x0a, 0x62, 0x75, 0x2b, 0x6a, 0x75, 0x68, - 0x7f, 0x84, 0x02, 0x8f, 0xe1, 0x32, 0x7f, 0x67, 0xc0, 0x82, 0xe6, 0x0b, 0xc2, 0xef, 0xae, 0x41, - 0xb9, 0xad, 0xdd, 0x3a, 0xe5, 0x17, 0xd1, 0x69, 0xeb, 0x37, 0x12, 0x27, 0x28, 0x11, 0x81, 0x22, - 0x55, 0x92, 0xc2, 0xe8, 0x72, 0x25, 0xb5, 0xd3, 0x86, 0x36, 0xc4, 0x9a, 0x34, 0x20, 0xc3, 0xb1, - 0x64, 0xf3, 0x9f, 0x86, 0x70, 0xe0, 0x30, 0xde, 0xa0, 0xcb, 0x5a, 0x4c, 0x33, 0xc4, 0xf6, 0x95, - 0x27, 0xc4, 0xa3, 0x73, 0x02, 0x41, 0xe6, 0xff, 0x22, 0x10, 0x5c, 0x2f, 0xfc, 0xf2, 0xbd, 0xda, - 0xcc, 0xdb, 0x7f, 0x5f, 0x9b, 0x31, 0x7f, 0x61, 0x40, 0x79, 0xa3, 0xdb, 0x75, 0xfb, 0xbb, 0xdd, - 0x40, 0x2c, 0xc0, 0x84, 0x59, 0x9b, 0xf6, 0x71, 0xcf, 0x53, 0x0b, 0x05, 0x7e, 0xbf, 0x9b, 0x02, - 0x82, 0x15, 0x86, 0xdf, 0x9f, 0x43, 0x9f, 0xb6, 0x88, 0xba, 0x6e, 0xd1, 0xfd, 0xd9, 0xe2, 0x40, - 0x2c, 0x71, 0xfc, 0x90, 0x0f, 0x1d, 0xe2, 0xda, 0x3b, 0x96, 0x67, 0xb5, 0x09, 0x55, 0x97, 0x23, - 0xda, 0xfa, 0x2d, 0x0d, 0x87, 0x13, 0x94, 0xe6, 0x7f, 0x32, 0x50, 0xdc, 0xf4, 0x3d, 0xdb, 0x09, - 0xd4, 0xe5, 0x0a, 0xfa, 0xdd, 0x91, 0xe0, 0x71, 0xbb, 0xdf, 0x25, 0x58, 0x60, 0xd0, 0x73, 0x30, - 0xcb, 0x02, 0x2b, 0xe8, 0x31, 0x61, 0x4f, 0xb1, 0xf1, 0x48, 0x18, 0x96, 0xf6, 0x05, 0xf4, 0x6c, - 0x50, 0x5b, 0x88, 0xc4, 0x49, 0x10, 0x56, 0x0c, 0xdc, 0xd3, 0xfd, 0x03, 0xb1, 0x51, 0xf6, 0x4d, - 0x99, 0xf6, 0xc2, 0xfc, 0x91, 0x8d, 0x3d, 0x7d, 0x77, 0x84, 0x02, 0x8f, 0xe1, 0x42, 0x27, 0x80, - 0x5c, 0x8b, 0x05, 0xb7, 0xa9, 0xe5, 0x31, 0xa1, 0xeb, 0xb6, 0xd3, 0x21, 0xea, 0xc2, 0x7f, 0x29, - 0xdd, 0x89, 0x73, 0x8e, 0x58, 0xef, 0xad, 0x11, 0x69, 0x78, 0x8c, 0x06, 0xf4, 0x38, 0xcc, 0x52, - 0x62, 0x31, 0xdf, 0xab, 0xe6, 0xc5, 0xf2, 0xa3, 0xa8, 0x8c, 0x05, 0x14, 0x2b, 0x2c, 0x0f, 0x68, - 0x1d, 0xc2, 0x98, 0xd5, 0x0e, 0xc3, 0x6b, 0x14, 0xd0, 0x76, 0x24, 0x18, 0x87, 0x78, 0xf3, 0xb7, - 0x06, 0x54, 0x36, 0x29, 0xb1, 0x02, 0x32, 0x8d, 0x5b, 0x7c, 0xea, 0x13, 0x47, 0x1b, 0xb0, 0x20, - 0xbe, 0xef, 0x5a, 0xae, 0x63, 0xcb, 0x33, 0xc8, 0x09, 0xe6, 0xcf, 0x2b, 0xe6, 0x85, 0xad, 0x24, - 0x1a, 0x0f, 0xd3, 0x9b, 0x3f, 0xc9, 0x42, 0xa5, 0x49, 0x5c, 0x12, 0x9b, 0xbc, 0x05, 0xa8, 0x4d, - 0xad, 0x16, 0xd9, 0x23, 0xd4, 0xf1, 0xed, 0x7d, 0xd2, 0xf2, 0x3d, 0x9b, 0x09, 0x37, 0xca, 0x36, - 0x3e, 0xc7, 0xf7, 0xf7, 0xe6, 0x08, 0x16, 0x8f, 0xe1, 0x40, 0x2e, 0x54, 0xba, 0x54, 0xfc, 0x16, - 0x7b, 0x2e, 0xbd, 0xac, 0x74, 0xf5, 0x2b, 0xe9, 0x8e, 0x74, 0x4f, 0x67, 0x6d, 0x2c, 0x9d, 0x0e, - 0x6a, 0x95, 0x04, 0x08, 0x27, 0x85, 0xa3, 0x6f, 0xc0, 0xa2, 0x4f, 0xbb, 0x47, 0x96, 0xd7, 0x24, - 0x5d, 0xe2, 0xd9, 0xc4, 0x0b, 0x98, 0xd8, 0xc8, 0x42, 0x63, 0x99, 0xd7, 0x22, 0xbb, 0x43, 0x38, - 0x3c, 0x42, 0x8d, 0x5e, 0x83, 0xa5, 0x2e, 0xf5, 0xbb, 0x56, 0x5b, 0x6c, 0xcc, 0x9e, 0xef, 0x3a, - 0xad, 0xbe, 0xda, 0xce, 0x27, 0x4f, 0x07, 0xb5, 0xa5, 0xbd, 0x61, 0xe4, 0xd9, 0xa0, 0x76, 0x41, - 0x6c, 0x1d, 0x87, 0xc4, 0x48, 0x3c, 0x2a, 0x46, 0x73, 0x83, 0xfc, 0x24, 0x37, 0x30, 0xb7, 0xa1, - 0xd0, 0xec, 0xa9, 0x3b, 0xf1, 0x02, 0x14, 0x6c, 0xf5, 0x5b, 0xed, 0x7c, 0x78, 0x39, 0x23, 0x9a, - 0xb3, 0x41, 0xad, 0xc2, 0xcb, 0xcf, 0x7a, 0x08, 0xc0, 0x11, 0x8b, 0xf9, 0x38, 0x14, 0xc4, 0xc1, - 0xb3, 0xbb, 0x57, 0xd0, 0x22, 0x64, 0xb1, 0x75, 0x4f, 0x48, 0x29, 0x63, 0xfe, 0x53, 0x8b, 0x62, - 0xbb, 0x00, 0x37, 0x49, 0x10, 0x1e, 0xfc, 0x06, 0x2c, 0x84, 0xa1, 0x3c, 0x99, 0x61, 0x22, 0x6f, - 0xc2, 0x49, 0x34, 0x1e, 0xa6, 0x37, 0x5f, 0x87, 0xa2, 0xc8, 0x42, 0x3c, 0x85, 0xc7, 0xe5, 0x82, - 0x71, 0x9f, 0x72, 0x21, 0xac, 0x01, 0x32, 0x93, 0x6a, 0x00, 0xcd, 0x5c, 0x17, 0x2a, 0x92, 0x37, - 0x2c, 0x90, 0x52, 0x69, 0x78, 0x12, 0x0a, 0xa1, 0x99, 0x4a, 0x4b, 0x54, 0x18, 0x87, 0x82, 0x70, - 0x44, 0xa1, 0x69, 0x3b, 0x82, 0x44, 0x46, 0x4d, 0xa7, 0x4c, 0xab, 0x7e, 0x32, 0xf7, 0xaf, 0x7e, - 0x34, 0x4d, 0x3f, 0x84, 0xea, 0xa4, 0x6a, 0xfa, 0x01, 0x72, 0x7e, 0x7a, 0x53, 0xcc, 0x77, 0x0c, - 0x58, 0xd4, 0x25, 0xa5, 0x3f, 0xbe, 0xf4, 0x4a, 0xce, 0xaf, 0xf6, 0xb4, 0x1d, 0xf9, 0x95, 0x01, - 0xcb, 0x89, 0xa5, 0x4d, 0x75, 0xe2, 0x53, 0x18, 0xa5, 0x3b, 0x47, 0x76, 0x0a, 0xe7, 0xf8, 0x6b, - 0x06, 0x2a, 0xb7, 0xac, 0x03, 0xe2, 0xee, 0x13, 0x97, 0xb4, 0x02, 0x9f, 0xa2, 0x1f, 0x40, 0xa9, - 0x63, 0x05, 0xad, 0x23, 0x01, 0x0d, 0x3b, 0x83, 0x66, 0xba, 0x60, 0x97, 0x90, 0x54, 0xdf, 0x89, - 0xc5, 0xdc, 0xf0, 0x02, 0xda, 0x6f, 0x5c, 0x50, 0x26, 0x95, 0x34, 0x0c, 0xd6, 0xb5, 0x89, 0x76, - 0x4e, 0x7c, 0xdf, 0x78, 0xab, 0xcb, 0xcb, 0x96, 0xe9, 0xbb, 0xc8, 0x84, 0x09, 0x98, 0xbc, 0xd9, - 0x73, 0x28, 0xe9, 0x10, 0x2f, 0x88, 0xdb, 0xb9, 0x9d, 0x21, 0xf9, 0x78, 0x44, 0xe3, 0xca, 0x8b, - 0xb0, 0x38, 0x6c, 0x3c, 0x8f, 0x3f, 0xc7, 0xa4, 0x2f, 0xcf, 0x0b, 0xf3, 0x9f, 0x68, 0x19, 0xf2, - 0x27, 0x96, 0xdb, 0x53, 0xb7, 0x11, 0xcb, 0x8f, 0xeb, 0x99, 0x6b, 0x86, 0xf9, 0x1b, 0x03, 0xaa, - 0x93, 0x0c, 0x41, 0x5f, 0xd4, 0x04, 0x35, 0x4a, 0xca, 0xaa, 0xec, 0x2b, 0xa4, 0x2f, 0xa5, 0xde, - 0x80, 0x82, 0xdf, 0xe5, 0x35, 0x85, 0x4f, 0xd5, 0xa9, 0x3f, 0x11, 0x9e, 0xe4, 0xae, 0x82, 0x9f, - 0x0d, 0x6a, 0x17, 0x13, 0xe2, 0x43, 0x04, 0x8e, 0x58, 0x79, 0xa4, 0x16, 0xf6, 0xf0, 0xec, 0x11, - 0x45, 0xea, 0xbb, 0x02, 0x82, 0x15, 0xc6, 0xfc, 0x83, 0x01, 0x39, 0x51, 0x90, 0xbf, 0x0e, 0x05, - 0xbe, 0x7f, 0xb6, 0x15, 0x58, 0xc2, 0xae, 0xd4, 0xad, 0x20, 0xe7, 0xde, 0x21, 0x81, 0x15, 0x7b, - 0x5b, 0x08, 0xc1, 0x91, 0x44, 0x84, 0x21, 0xef, 0x04, 0xa4, 0x13, 0x1e, 0xe4, 0x53, 0x13, 0x45, - 0xab, 0x87, 0x88, 0x3a, 0xb6, 0xee, 0xdd, 0x78, 0x2b, 0x20, 0x1e, 0x3f, 0x8c, 0xf8, 0x6a, 0x6c, - 0x73, 0x19, 0x58, 0x8a, 0x32, 0xff, 0x6d, 0x40, 0xa4, 0x8a, 0x3b, 0x3f, 0x23, 0xee, 0xe1, 0x2d, - 0xc7, 0x3b, 0x56, 0xdb, 0x1a, 0x99, 0xb3, 0xaf, 0xe0, 0x38, 0xa2, 0x18, 0x97, 0x1e, 0x32, 0xd3, - 0xa5, 0x07, 0xae, 0xb0, 0xe5, 0x7b, 0x81, 0xe3, 0xf5, 0x46, 0x6e, 0xdb, 0xa6, 0x82, 0xe3, 0x88, - 0x82, 0x17, 0x22, 0x94, 0x74, 0x2c, 0xc7, 0x73, 0xbc, 0x36, 0x5f, 0xc4, 0xa6, 0xdf, 0xf3, 0x02, - 0x91, 0x91, 0x55, 0x21, 0x82, 0x47, 0xb0, 0x78, 0x0c, 0x87, 0xf9, 0xfb, 0x1c, 0x94, 0xf8, 0x9a, - 0xc3, 0x3c, 0xf7, 0x3c, 0x54, 0x5c, 0xdd, 0x0b, 0xd4, 0xda, 0x2f, 0x2a, 0x53, 0x92, 0xf7, 0x1a, - 0x27, 0x69, 0x39, 0xb3, 0x28, 0xa1, 0x22, 0xe6, 0x4c, 0x92, 0x79, 0x4b, 0x47, 0xe2, 0x24, 0x2d, - 0x8f, 0x5e, 0xf7, 0xf8, 0xfd, 0x50, 0x95, 0x49, 0x74, 0x44, 0xdf, 0xe4, 0x40, 0x2c, 0x71, 0x68, - 0x07, 0x2e, 0x58, 0xae, 0xeb, 0xdf, 0x13, 0xc0, 0x86, 0xef, 0x1f, 0x77, 0x2c, 0x7a, 0xcc, 0x44, - 0x33, 0x5d, 0x68, 0x7c, 0x41, 0xb1, 0x5c, 0xd8, 0x18, 0x25, 0xc1, 0xe3, 0xf8, 0xc6, 0x1d, 0x5b, - 0x6e, 0xca, 0x63, 0x3b, 0x82, 0xe5, 0x21, 0x90, 0xb8, 0xe5, 0xaa, 0xb3, 0x7d, 0x46, 0xc9, 0x59, - 0xc6, 0x63, 0x68, 0xce, 0x26, 0xc0, 0xf1, 0x58, 0x89, 0xe8, 0x3a, 0xcc, 0x73, 0x4f, 0xf6, 0x7b, - 0x41, 0x58, 0x77, 0xe6, 0xc5, 0x71, 0xa3, 0xd3, 0x41, 0x6d, 0xfe, 0x76, 0x02, 0x83, 0x87, 0x28, - 0xf9, 0xe6, 0xba, 0x4e, 0xc7, 0x09, 0xaa, 0x73, 0x82, 0x25, 0xda, 0xdc, 0x5b, 0x1c, 0x88, 0x25, - 0x2e, 0xe1, 0x81, 0x85, 0xf3, 0x3c, 0xd0, 0xfc, 0x4b, 0x16, 0x90, 0xac, 0xb5, 0x6d, 0x59, 0x4f, - 0xc9, 0x90, 0xc6, 0x3b, 0x02, 0x55, 0xab, 0x1b, 0x43, 0x1d, 0x81, 0x2a, 0xd3, 0x43, 0x3c, 0xda, - 0x81, 0xa2, 0x0c, 0x2d, 0xf1, 0x75, 0x59, 0x57, 0xc4, 0xc5, 0xdd, 0x10, 0x71, 0x36, 0xa8, 0xad, - 0x24, 0xd4, 0x44, 0x18, 0xd1, 0xad, 0xc5, 0x12, 0xd0, 0x55, 0x00, 0xab, 0xeb, 0xe8, 0xef, 0x75, - 0xc5, 0xf8, 0xd5, 0x26, 0xee, 0xbc, 0xb1, 0x46, 0x85, 0x5e, 0x82, 0x5c, 0xf0, 0xe9, 0x3a, 0xaa, - 0x82, 0x68, 0x18, 0x79, 0xff, 0x24, 0x24, 0x70, 0xed, 0xc2, 0x9f, 0x19, 0x37, 0x4b, 0x35, 0x43, - 0x91, 0xf6, 0xad, 0x08, 0x83, 0x35, 0x2a, 0xf4, 0x2d, 0x28, 0x1c, 0xaa, 0x52, 0x54, 0x1c, 0x4c, - 0xea, 0x10, 0x19, 0x16, 0xb0, 0xf2, 0xc9, 0x20, 0xfc, 0xc2, 0x91, 0x34, 0xf4, 0x55, 0x28, 0xb1, - 0xde, 0x41, 0x94, 0xbd, 0xe5, 0x69, 0x46, 0xa9, 0x72, 0x3f, 0x46, 0x61, 0x9d, 0xce, 0x7c, 0x13, - 0x8a, 0x3b, 0x4e, 0x8b, 0xfa, 0xa2, 0x07, 0x7c, 0x02, 0xe6, 0x58, 0xa2, 0xc1, 0x89, 0x4e, 0x32, - 0xf4, 0xb2, 0x10, 0xcf, 0xdd, 0xcb, 0xb3, 0x3c, 0x5f, 0xb6, 0x31, 0xf9, 0xd8, 0xbd, 0x5e, 0xe5, - 0x40, 0x2c, 0x71, 0xd7, 0x97, 0x79, 0x81, 0xf0, 0xd3, 0xf7, 0x6b, 0x33, 0xef, 0xbe, 0x5f, 0x9b, - 0x79, 0xef, 0x7d, 0x55, 0x2c, 0xfc, 0x11, 0x00, 0x76, 0x0f, 0xbe, 0x47, 0x5a, 0x32, 0xec, 0xa6, - 0x7a, 0xd6, 0x0b, 0x5f, 0x93, 0xc5, 0xb3, 0x5e, 0x66, 0xa8, 0xe8, 0xd3, 0x70, 0x38, 0x41, 0x89, - 0xd6, 0xa1, 0x18, 0x3d, 0xd8, 0x29, 0xff, 0x58, 0x0a, 0xfd, 0x2d, 0x7a, 0xd5, 0xc3, 0x31, 0x4d, - 0x22, 0x07, 0xe4, 0xce, 0xcd, 0x01, 0x0d, 0xc8, 0xf6, 0x1c, 0x5b, 0x35, 0xcc, 0x4f, 0x87, 0x39, - 0xf8, 0xce, 0x76, 0xf3, 0x6c, 0x50, 0x7b, 0x64, 0xd2, 0x3b, 0x79, 0xd0, 0xef, 0x12, 0x56, 0xbf, - 0xb3, 0xdd, 0xc4, 0x9c, 0x79, 0x5c, 0x40, 0x9a, 0x9d, 0x32, 0x20, 0x5d, 0x05, 0x68, 0xc7, 0xcf, - 0x0e, 0xf2, 0xbe, 0x47, 0x8e, 0xa8, 0x3d, 0x37, 0x68, 0x54, 0x88, 0xc1, 0x52, 0x8b, 0xb7, 0xe6, - 0xaa, 0xfd, 0x67, 0x81, 0xd5, 0x91, 0x0f, 0x99, 0xd3, 0xdd, 0x89, 0x4b, 0x4a, 0xcd, 0xd2, 0xe6, - 0xb0, 0x30, 0x3c, 0x2a, 0x1f, 0xf9, 0xb0, 0x64, 0xab, 0x0e, 0x31, 0x56, 0x5a, 0x9c, 0x5a, 0xe9, - 0x45, 0xae, 0xb0, 0x39, 0x2c, 0x08, 0x8f, 0xca, 0x46, 0xdf, 0x85, 0x95, 0x10, 0x38, 0xda, 0xa6, - 0x8b, 0x80, 0x9d, 0x6d, 0xac, 0x9e, 0x0e, 0x6a, 0x2b, 0xcd, 0x89, 0x54, 0xf8, 0x3e, 0x12, 0x90, - 0x0d, 0xb3, 0xae, 0x2c, 0x70, 0x4b, 0xa2, 0x28, 0xf9, 0x5a, 0xba, 0x55, 0xc4, 0xde, 0x5f, 0xd7, - 0x0b, 0xdb, 0xe8, 0xc9, 0x45, 0xd5, 0xb4, 0x4a, 0x36, 0x7a, 0x0b, 0x4a, 0x96, 0xe7, 0xf9, 0x81, - 0x25, 0x1f, 0x0e, 0xca, 0x42, 0xd5, 0xc6, 0xd4, 0xaa, 0x36, 0x62, 0x19, 0x43, 0x85, 0xb4, 0x86, - 0xc1, 0xba, 0x2a, 0x74, 0x0f, 0x16, 0xfc, 0x7b, 0x1e, 0xa1, 0x98, 0x1c, 0x12, 0x4a, 0xbc, 0x16, - 0x61, 0xd5, 0x8a, 0xd0, 0xfe, 0x4c, 0x4a, 0xed, 0x09, 0xe6, 0xd8, 0xa5, 0x93, 0x70, 0x86, 0x87, - 0xb5, 0xa0, 0x3a, 0x8f, 0xad, 0x9e, 0xe5, 0x3a, 0xdf, 0x27, 0x94, 0x55, 0xe7, 0xe3, 0xb7, 0xe6, - 0xad, 0x08, 0x8a, 0x35, 0x0a, 0xd4, 0x83, 0x4a, 0x47, 0x4f, 0x19, 0xd5, 0x25, 0x61, 0xe6, 0xb5, - 0x74, 0x66, 0x8e, 0x26, 0xb5, 0xb8, 0x82, 0x49, 0xe0, 0x70, 0x52, 0xcb, 0xca, 0x73, 0x50, 0xfa, - 0x94, 0xc5, 0x3d, 0x6f, 0x0e, 0x86, 0x0f, 0x64, 0xaa, 0xe6, 0xe0, 0x4f, 0x19, 0x98, 0x4f, 0x6e, - 0xe3, 0x50, 0x3a, 0xcc, 0xa7, 0x4a, 0x87, 0x61, 0x1b, 0x6a, 0x4c, 0x1c, 0x3a, 0x84, 0xf1, 0x39, - 0x3b, 0x31, 0x3e, 0xab, 0x30, 0x98, 0x7b, 0x90, 0x30, 0x58, 0x07, 0xe0, 0x75, 0x06, 0xf5, 0x5d, - 0x97, 0x50, 0x11, 0x01, 0x0b, 0x6a, 0xb8, 0x10, 0x41, 0xb1, 0x46, 0xc1, 0xab, 0xe1, 0x03, 0xd7, - 0x6f, 0x1d, 0x8b, 0x2d, 0x08, 0x6f, 0xaf, 0x88, 0x7d, 0x05, 0x59, 0x0d, 0x37, 0x46, 0xb0, 0x78, - 0x0c, 0x87, 0xd9, 0x87, 0x8b, 0x7b, 0x16, 0x0d, 0x1c, 0xcb, 0x8d, 0x6f, 0x8a, 0x68, 0x37, 0xde, - 0x18, 0x69, 0x66, 0x9e, 0x9e, 0xf6, 0xc6, 0xc5, 0x9b, 0x1f, 0xc3, 0xe2, 0x86, 0xc6, 0xfc, 0x9b, - 0x01, 0x97, 0xc6, 0xea, 0xfe, 0x0c, 0x9a, 0xa9, 0x37, 0x92, 0xcd, 0xd4, 0xf3, 0x29, 0x5f, 0x21, - 0xc7, 0x59, 0x3b, 0xa1, 0xb5, 0x9a, 0x83, 0xfc, 0x1e, 0x2f, 0x62, 0xcd, 0x0f, 0x0d, 0x28, 0x8b, - 0x5f, 0xd3, 0x3c, 0x02, 0xd7, 0x92, 0xb3, 0x81, 0xe2, 0xc3, 0x9b, 0x0b, 0x3c, 0x8c, 0x57, 0xe2, - 0x77, 0x0c, 0x48, 0x3e, 0xbf, 0xa2, 0x17, 0xe5, 0x15, 0x30, 0xa2, 0xf7, 0xd1, 0x29, 0xdd, 0xff, - 0x85, 0x49, 0xdd, 0xe4, 0x85, 0x54, 0x0f, 0x8d, 0x4f, 0x42, 0x11, 0xfb, 0x7e, 0xb0, 0x67, 0x05, - 0x47, 0x8c, 0xef, 0x5d, 0x97, 0xff, 0x50, 0xdb, 0x2b, 0xf6, 0x4e, 0x60, 0xb0, 0x84, 0x9b, 0x3f, - 0x37, 0xe0, 0xd2, 0xc4, 0x91, 0x0f, 0x8f, 0x22, 0xad, 0xe8, 0x4b, 0xad, 0x28, 0x72, 0xe4, 0x98, - 0x0e, 0x6b, 0x54, 0xbc, 0x0d, 0x4c, 0xcc, 0x89, 0x86, 0xdb, 0xc0, 0x84, 0x36, 0x9c, 0xa4, 0x35, - 0xff, 0x95, 0x01, 0x35, 0x63, 0xf9, 0x1f, 0x3b, 0xfd, 0xe3, 0x43, 0x13, 0x9e, 0xf9, 0xe4, 0x84, - 0x27, 0x1a, 0xe7, 0x68, 0x23, 0x8e, 0xec, 0xfd, 0x47, 0x1c, 0xe8, 0xd9, 0x68, 0x6a, 0x22, 0x7d, - 0x68, 0x35, 0x39, 0x35, 0x39, 0x1b, 0xd4, 0xca, 0x4a, 0x78, 0x72, 0x8a, 0xf2, 0x1a, 0xcc, 0xd9, - 0x24, 0xb0, 0x1c, 0x57, 0xb6, 0x74, 0xa9, 0xe7, 0x00, 0x52, 0x58, 0x53, 0xb2, 0x36, 0x4a, 0xdc, - 0x26, 0xf5, 0x81, 0x43, 0x81, 0x3c, 0x60, 0xb7, 0x7c, 0x5b, 0x76, 0x24, 0xf9, 0x38, 0x60, 0x6f, - 0xfa, 0x36, 0xc1, 0x02, 0x63, 0xbe, 0x6b, 0x40, 0x49, 0x4a, 0xda, 0xb4, 0x7a, 0x8c, 0xa0, 0x2b, - 0xd1, 0x2a, 0xe4, 0x71, 0x5f, 0xd2, 0xc7, 0x63, 0x67, 0x83, 0x5a, 0x51, 0x90, 0x89, 0x66, 0x66, - 0xcc, 0x18, 0x28, 0x73, 0xce, 0x1e, 0x3d, 0x0a, 0x79, 0x71, 0x81, 0xd4, 0x66, 0xc6, 0x73, 0x3e, - 0x0e, 0xc4, 0x12, 0x67, 0x7e, 0x9c, 0x81, 0x4a, 0x62, 0x71, 0x29, 0xfa, 0x82, 0xe8, 0xf5, 0x33, - 0x93, 0xe2, 0x45, 0x7d, 0xf2, 0x54, 0x5d, 0xa5, 0xaf, 0xd9, 0x07, 0x49, 0x5f, 0xdf, 0x86, 0xd9, - 0x16, 0xdf, 0xa3, 0xf0, 0x4f, 0x1a, 0x57, 0xa6, 0x39, 0x4e, 0xb1, 0xbb, 0xb1, 0x37, 0x8a, 0x4f, - 0x86, 0x95, 0x40, 0x74, 0x13, 0x96, 0x28, 0x09, 0x68, 0x7f, 0xe3, 0x30, 0x20, 0x54, 0x7f, 0x07, - 0xc8, 0xc7, 0xd5, 0x37, 0x1e, 0x26, 0xc0, 0xa3, 0x3c, 0xe6, 0x01, 0x94, 0x6f, 0x5b, 0x07, 0x6e, - 0x34, 0xd9, 0xc2, 0x50, 0x71, 0xbc, 0x96, 0xdb, 0xb3, 0x89, 0x0c, 0xe8, 0x61, 0xf4, 0x0a, 0x2f, - 0xed, 0xb6, 0x8e, 0x3c, 0x1b, 0xd4, 0x2e, 0x24, 0x00, 0x72, 0x94, 0x83, 0x93, 0x22, 0x4c, 0x17, - 0x72, 0x9f, 0x61, 0x27, 0xf9, 0x1d, 0x28, 0xc6, 0xb5, 0xfe, 0x43, 0x56, 0x69, 0xbe, 0x01, 0x05, - 0xee, 0xf1, 0x61, 0x8f, 0x7a, 0x4e, 0x95, 0x94, 0xac, 0xbd, 0x32, 0x69, 0x6a, 0x2f, 0x31, 0x1f, - 0xbd, 0xd3, 0xb5, 0x1f, 0x70, 0x3e, 0x9a, 0x79, 0x90, 0xcc, 0x97, 0x9d, 0x32, 0xf3, 0x5d, 0x05, - 0xf9, 0x1f, 0x12, 0x9e, 0x64, 0x64, 0x01, 0xa1, 0x25, 0x19, 0x3d, 0xff, 0x6b, 0xc3, 0x81, 0x1f, - 0x1b, 0x00, 0xe2, 0x15, 0xee, 0xc6, 0x09, 0xf1, 0x82, 0x14, 0x93, 0xf8, 0x3b, 0x30, 0xeb, 0x4b, - 0x8f, 0x94, 0x33, 0xd2, 0x29, 0x9f, 0x7a, 0xa3, 0x8b, 0x24, 0x7d, 0x12, 0x2b, 0x61, 0x8d, 0x97, - 0x3f, 0xf8, 0x64, 0x75, 0xe6, 0xc3, 0x4f, 0x56, 0x67, 0x3e, 0xfa, 0x64, 0x75, 0xe6, 0xed, 0xd3, - 0x55, 0xe3, 0x83, 0xd3, 0x55, 0xe3, 0xc3, 0xd3, 0x55, 0xe3, 0xa3, 0xd3, 0x55, 0xe3, 0xe3, 0xd3, - 0x55, 0xe3, 0xdd, 0x7f, 0xac, 0xce, 0xbc, 0xf6, 0x58, 0x9a, 0xff, 0xe6, 0xfd, 0x37, 0x00, 0x00, - 0xff, 0xff, 0x0b, 0x4d, 0x51, 0xc5, 0xdb, 0x27, 0x00, 0x00, + 0x13, 0x77, 0x90, 0xc8, 0x31, 0x88, 0x4b, 0x24, 0xd0, 0x28, 0x31, 0x07, 0x8e, 0x88, 0xab, 0x85, + 0x04, 0xaa, 0x47, 0x77, 0x57, 0xcf, 0x63, 0xdd, 0x93, 0x5d, 0x22, 0x6e, 0xd3, 0xdf, 0xbb, 0xaa, + 0xbe, 0xfa, 0xea, 0x7b, 0x0c, 0xec, 0x1c, 0x5f, 0x63, 0x75, 0xc7, 0x5f, 0x3f, 0xee, 0x1d, 0x10, + 0xea, 0x91, 0x80, 0xb0, 0xf5, 0x13, 0xe2, 0xd9, 0x3e, 0x5d, 0x57, 0x08, 0xab, 0xeb, 0x74, 0xac, + 0xd6, 0x91, 0xe3, 0x11, 0xda, 0x5f, 0xef, 0x1e, 0xb7, 0x39, 0x80, 0xad, 0x77, 0x48, 0x60, 0xad, + 0x9f, 0x5c, 0x59, 0x6f, 0x13, 0x8f, 0x50, 0x2b, 0x20, 0x76, 0xbd, 0x4b, 0xfd, 0xc0, 0x47, 0x8f, + 0x49, 0xae, 0xba, 0xce, 0x55, 0xef, 0x1e, 0xb7, 0x39, 0x80, 0xd5, 0x39, 0x57, 0xfd, 0xe4, 0xca, + 0xca, 0x53, 0x6d, 0x27, 0x38, 0xea, 0x1d, 0xd4, 0x5b, 0x7e, 0x67, 0xbd, 0xed, 0xb7, 0xfd, 0x75, + 0xc1, 0x7c, 0xd0, 0x3b, 0x14, 0x5f, 0xe2, 0x43, 0xfc, 0x92, 0x42, 0x57, 0x26, 0x9a, 0x42, 0x7b, + 0x5e, 0xe0, 0x74, 0xc8, 0xb0, 0x15, 0x2b, 0xcf, 0x9e, 0xc7, 0xc0, 0x5a, 0x47, 0xa4, 0x63, 0x0d, + 0xf3, 0x99, 0x7f, 0xca, 0x42, 0x61, 0x63, 0x6f, 0xfb, 0x26, 0xf5, 0x7b, 0x5d, 0xb4, 0x06, 0x39, + 0xcf, 0xea, 0x90, 0xaa, 0xb1, 0x66, 0x5c, 0x2e, 0x36, 0xca, 0x1f, 0x0c, 0x6a, 0x33, 0xa7, 0x83, + 0x5a, 0xee, 0x55, 0xab, 0x43, 0xb0, 0xc0, 0x20, 0x17, 0x0a, 0x27, 0x84, 0x32, 0xc7, 0xf7, 0x58, + 0x35, 0xb3, 0x96, 0xbd, 0x5c, 0xba, 0xfa, 0x62, 0x3d, 0xcd, 0xfa, 0xeb, 0x42, 0xc1, 0x5d, 0xc9, + 0xba, 0xe5, 0xd3, 0xa6, 0xc3, 0x5a, 0xfe, 0x09, 0xa1, 0xfd, 0xc6, 0xa2, 0xd2, 0x52, 0x50, 0x48, + 0x86, 0x23, 0x0d, 0xe8, 0x47, 0x06, 0x2c, 0x76, 0x29, 0x39, 0x24, 0x94, 0x12, 0x5b, 0xe1, 0xab, + 0xd9, 0x35, 0xe3, 0x21, 0xa8, 0xad, 0x2a, 0xb5, 0x8b, 0x7b, 0x43, 0xf2, 0xf1, 0x88, 0x46, 0xf4, + 0x6b, 0x03, 0x56, 0x18, 0xa1, 0x27, 0x84, 0x6e, 0xd8, 0x36, 0x25, 0x8c, 0x35, 0xfa, 0x9b, 0xae, + 0x43, 0xbc, 0x60, 0x73, 0xbb, 0x89, 0x59, 0x35, 0x27, 0xf6, 0xe1, 0xeb, 0xe9, 0x0c, 0xda, 0x9f, + 0x24, 0xa7, 0x61, 0x2a, 0x8b, 0x56, 0x26, 0x92, 0x30, 0x7c, 0x1f, 0x33, 0xcc, 0x43, 0x28, 0x87, + 0x07, 0x79, 0xcb, 0x61, 0x01, 0xba, 0x0b, 0xb3, 0x6d, 0xfe, 0xc1, 0xaa, 0x86, 0x30, 0xb0, 0x9e, + 0xce, 0xc0, 0x50, 0x46, 0x63, 0x5e, 0xd9, 0x33, 0x2b, 0x3e, 0x19, 0x56, 0xd2, 0xcc, 0x9f, 0xe5, + 0xa0, 0xb4, 0xb1, 0xb7, 0x8d, 0x09, 0xf3, 0x7b, 0xb4, 0x45, 0x52, 0x38, 0xcd, 0x35, 0x28, 0x33, + 0xc7, 0x6b, 0xf7, 0x5c, 0x8b, 0x72, 0x68, 0x75, 0x56, 0x50, 0x2e, 0x2b, 0xca, 0xf2, 0xbe, 0x86, + 0xc3, 0x09, 0x4a, 0x74, 0x15, 0x80, 0x4b, 0x60, 0x5d, 0xab, 0x45, 0xec, 0x6a, 0x66, 0xcd, 0xb8, + 0x5c, 0x68, 0x20, 0xc5, 0x07, 0xaf, 0x46, 0x18, 0xac, 0x51, 0xa1, 0x47, 0x21, 0x2f, 0x2c, 0xad, + 0x16, 0x84, 0x9a, 0x8a, 0x22, 0xcf, 0x8b, 0x65, 0x60, 0x89, 0x43, 0x4f, 0xc0, 0x9c, 0xf2, 0xb2, + 0x6a, 0x51, 0x90, 0x2d, 0x28, 0xb2, 0xb9, 0xd0, 0x0d, 0x42, 0x3c, 0x5f, 0xdf, 0xb1, 0xe3, 0xd9, + 0xc2, 0xef, 0xb4, 0xf5, 0xbd, 0xe2, 0x78, 0x36, 0x16, 0x18, 0x74, 0x0b, 0xf2, 0x27, 0x84, 0x1e, + 0x70, 0x4f, 0xe0, 0xae, 0xf9, 0xe5, 0x74, 0x1b, 0x7d, 0x97, 0xb3, 0x34, 0x8a, 0xdc, 0x34, 0xf1, + 0x13, 0x4b, 0x21, 0xa8, 0x0e, 0xc0, 0x8e, 0x7c, 0x1a, 0x88, 0xe5, 0x55, 0xf3, 0x6b, 0xd9, 0xcb, + 0xc5, 0xc6, 0x3c, 0x5f, 0xef, 0x7e, 0x04, 0xc5, 0x1a, 0x05, 0xa7, 0x6f, 0x59, 0x01, 0x69, 0xfb, + 0xd4, 0x21, 0xac, 0x3a, 0x17, 0xd3, 0x6f, 0x46, 0x50, 0xac, 0x51, 0xa0, 0x97, 0x01, 0xb1, 0xc0, + 0xa7, 0x56, 0x9b, 0xa8, 0xa5, 0xbe, 0x64, 0xb1, 0xa3, 0x2a, 0x88, 0xd5, 0xad, 0xa8, 0xd5, 0xa1, + 0xfd, 0x11, 0x0a, 0x3c, 0x86, 0xcb, 0xfc, 0x9d, 0x01, 0x0b, 0x9a, 0x2f, 0x08, 0xbf, 0xbb, 0x06, + 0xe5, 0xb6, 0x76, 0xeb, 0x94, 0x5f, 0x44, 0xa7, 0xad, 0xdf, 0x48, 0x9c, 0xa0, 0x44, 0x04, 0x8a, + 0x54, 0x49, 0x0a, 0xa3, 0xcb, 0x95, 0xd4, 0x4e, 0x1b, 0xda, 0x10, 0x6b, 0xd2, 0x80, 0x0c, 0xc7, + 0x92, 0xcd, 0x7f, 0x18, 0xc2, 0x81, 0xc3, 0x78, 0x83, 0x2e, 0x6b, 0x31, 0xcd, 0x10, 0xdb, 0x57, + 0x9e, 0x10, 0x8f, 0xce, 0x09, 0x04, 0x99, 0xff, 0x8b, 0x40, 0x70, 0xbd, 0xf0, 0xcb, 0xf7, 0x6a, + 0x33, 0x6f, 0xff, 0x6d, 0x6d, 0xc6, 0xfc, 0x85, 0x01, 0xe5, 0x8d, 0x6e, 0xd7, 0xed, 0xef, 0x76, + 0x03, 0xb1, 0x00, 0x13, 0x66, 0x6d, 0xda, 0xc7, 0x3d, 0x4f, 0x2d, 0x14, 0xf8, 0xfd, 0x6e, 0x0a, + 0x08, 0x56, 0x18, 0x7e, 0x7f, 0x0e, 0x7d, 0xda, 0x22, 0xea, 0xba, 0x45, 0xf7, 0x67, 0x8b, 0x03, + 0xb1, 0xc4, 0xf1, 0x43, 0x3e, 0x74, 0x88, 0x6b, 0xef, 0x58, 0x9e, 0xd5, 0x26, 0x54, 0x5d, 0x8e, + 0x68, 0xeb, 0xb7, 0x34, 0x1c, 0x4e, 0x50, 0x9a, 0xff, 0xc9, 0x40, 0x71, 0xd3, 0xf7, 0x6c, 0x27, + 0x50, 0x97, 0x2b, 0xe8, 0x77, 0x47, 0x82, 0xc7, 0xed, 0x7e, 0x97, 0x60, 0x81, 0x41, 0xcf, 0xc1, + 0x2c, 0x0b, 0xac, 0xa0, 0xc7, 0x84, 0x3d, 0xc5, 0xc6, 0x23, 0x61, 0x58, 0xda, 0x17, 0xd0, 0xb3, + 0x41, 0x6d, 0x21, 0x12, 0x27, 0x41, 0x58, 0x31, 0x70, 0x4f, 0xf7, 0x0f, 0xc4, 0x46, 0xd9, 0x37, + 0xe5, 0xb3, 0x17, 0xbe, 0x1f, 0xd9, 0xd8, 0xd3, 0x77, 0x47, 0x28, 0xf0, 0x18, 0x2e, 0x74, 0x02, + 0xc8, 0xb5, 0x58, 0x70, 0x9b, 0x5a, 0x1e, 0x13, 0xba, 0x6e, 0x3b, 0x1d, 0xa2, 0x2e, 0xfc, 0x97, + 0xd2, 0x9d, 0x38, 0xe7, 0x88, 0xf5, 0xde, 0x1a, 0x91, 0x86, 0xc7, 0x68, 0x40, 0x8f, 0xc3, 0x2c, + 0x25, 0x16, 0xf3, 0xbd, 0x6a, 0x5e, 0x2c, 0x3f, 0x8a, 0xca, 0x58, 0x40, 0xb1, 0xc2, 0xf2, 0x80, + 0xd6, 0x21, 0x8c, 0x59, 0xed, 0x30, 0xbc, 0x46, 0x01, 0x6d, 0x47, 0x82, 0x71, 0x88, 0x37, 0x7f, + 0x6b, 0x40, 0x65, 0x93, 0x12, 0x2b, 0x20, 0xd3, 0xb8, 0xc5, 0xa7, 0x3e, 0x71, 0xb4, 0x01, 0x0b, + 0xe2, 0xfb, 0xae, 0xe5, 0x3a, 0xb6, 0x3c, 0x83, 0x9c, 0x60, 0xfe, 0xbc, 0x62, 0x5e, 0xd8, 0x4a, + 0xa2, 0xf1, 0x30, 0xbd, 0xf9, 0x93, 0x2c, 0x54, 0x9a, 0xc4, 0x25, 0xb1, 0xc9, 0x5b, 0x80, 0xda, + 0xd4, 0x6a, 0x91, 0x3d, 0x42, 0x1d, 0xdf, 0xde, 0x27, 0x2d, 0xdf, 0xb3, 0x99, 0x70, 0xa3, 0x6c, + 0xe3, 0x73, 0x7c, 0x7f, 0x6f, 0x8e, 0x60, 0xf1, 0x18, 0x0e, 0xe4, 0x42, 0xa5, 0x4b, 0xc5, 0x6f, + 0xb1, 0xe7, 0xd2, 0xcb, 0x4a, 0x57, 0xbf, 0x92, 0xee, 0x48, 0xf7, 0x74, 0xd6, 0xc6, 0xd2, 0xe9, + 0xa0, 0x56, 0x49, 0x80, 0x70, 0x52, 0x38, 0xfa, 0x06, 0x2c, 0xfa, 0xb4, 0x7b, 0x64, 0x79, 0x4d, + 0xd2, 0x25, 0x9e, 0x4d, 0xbc, 0x80, 0x89, 0x8d, 0x2c, 0x34, 0x96, 0x79, 0x2e, 0xb2, 0x3b, 0x84, + 0xc3, 0x23, 0xd4, 0xe8, 0x35, 0x58, 0xea, 0x52, 0xbf, 0x6b, 0xb5, 0xc5, 0xc6, 0xec, 0xf9, 0xae, + 0xd3, 0xea, 0xab, 0xed, 0x7c, 0xf2, 0x74, 0x50, 0x5b, 0xda, 0x1b, 0x46, 0x9e, 0x0d, 0x6a, 0x17, + 0xc4, 0xd6, 0x71, 0x48, 0x8c, 0xc4, 0xa3, 0x62, 0x34, 0x37, 0xc8, 0x4f, 0x72, 0x03, 0x73, 0x1b, + 0x0a, 0xcd, 0x9e, 0xba, 0x13, 0x2f, 0x40, 0xc1, 0x56, 0xbf, 0xd5, 0xce, 0x87, 0x97, 0x33, 0xa2, + 0x39, 0x1b, 0xd4, 0x2a, 0x3c, 0xfd, 0xac, 0x87, 0x00, 0x1c, 0xb1, 0x98, 0x8f, 0x43, 0x41, 0x1c, + 0x3c, 0xbb, 0x7b, 0x05, 0x2d, 0x42, 0x16, 0x5b, 0xf7, 0x84, 0x94, 0x32, 0xe6, 0x3f, 0xb5, 0x28, + 0xb6, 0x0b, 0x70, 0x93, 0x04, 0xe1, 0xc1, 0x6f, 0xc0, 0x42, 0x18, 0xca, 0x93, 0x2f, 0x4c, 0xe4, + 0x4d, 0x38, 0x89, 0xc6, 0xc3, 0xf4, 0xe6, 0xeb, 0x50, 0x14, 0xaf, 0x10, 0x7f, 0xc2, 0xe3, 0x74, + 0xc1, 0xb8, 0x4f, 0xba, 0x10, 0xe6, 0x00, 0x99, 0x49, 0x39, 0x80, 0x66, 0xae, 0x0b, 0x15, 0xc9, + 0x1b, 0x26, 0x48, 0xa9, 0x34, 0x3c, 0x09, 0x85, 0xd0, 0x4c, 0xa5, 0x25, 0x4a, 0x8c, 0x43, 0x41, + 0x38, 0xa2, 0xd0, 0xb4, 0x1d, 0x41, 0xe2, 0x45, 0x4d, 0xa7, 0x4c, 0xcb, 0x7e, 0x32, 0xf7, 0xcf, + 0x7e, 0x34, 0x4d, 0x3f, 0x84, 0xea, 0xa4, 0x6c, 0xfa, 0x01, 0xde, 0xfc, 0xf4, 0xa6, 0x98, 0xef, + 0x18, 0xb0, 0xa8, 0x4b, 0x4a, 0x7f, 0x7c, 0xe9, 0x95, 0x9c, 0x9f, 0xed, 0x69, 0x3b, 0xf2, 0x2b, + 0x03, 0x96, 0x13, 0x4b, 0x9b, 0xea, 0xc4, 0xa7, 0x30, 0x4a, 0x77, 0x8e, 0xec, 0x14, 0xce, 0xf1, + 0x97, 0x0c, 0x54, 0x6e, 0x59, 0x07, 0xc4, 0xdd, 0x27, 0x2e, 0x69, 0x05, 0x3e, 0x45, 0x3f, 0x80, + 0x52, 0xc7, 0x0a, 0x5a, 0x47, 0x02, 0x1a, 0x56, 0x06, 0xcd, 0x74, 0xc1, 0x2e, 0x21, 0xa9, 0xbe, + 0x13, 0x8b, 0xb9, 0xe1, 0x05, 0xb4, 0xdf, 0xb8, 0xa0, 0x4c, 0x2a, 0x69, 0x18, 0xac, 0x6b, 0x13, + 0xe5, 0x9c, 0xf8, 0xbe, 0xf1, 0x56, 0x97, 0xa7, 0x2d, 0xd3, 0x57, 0x91, 0x09, 0x13, 0x30, 0x79, + 0xb3, 0xe7, 0x50, 0xd2, 0x21, 0x5e, 0x10, 0x97, 0x73, 0x3b, 0x43, 0xf2, 0xf1, 0x88, 0xc6, 0x95, + 0x17, 0x61, 0x71, 0xd8, 0x78, 0x1e, 0x7f, 0x8e, 0x49, 0x5f, 0x9e, 0x17, 0xe6, 0x3f, 0xd1, 0x32, + 0xe4, 0x4f, 0x2c, 0xb7, 0xa7, 0x6e, 0x23, 0x96, 0x1f, 0xd7, 0x33, 0xd7, 0x0c, 0xf3, 0x37, 0x06, + 0x54, 0x27, 0x19, 0x82, 0xbe, 0xa8, 0x09, 0x6a, 0x94, 0x94, 0x55, 0xd9, 0x57, 0x48, 0x5f, 0x4a, + 0xbd, 0x01, 0x05, 0xbf, 0xcb, 0x73, 0x0a, 0x9f, 0xaa, 0x53, 0x7f, 0x22, 0x3c, 0xc9, 0x5d, 0x05, + 0x3f, 0x1b, 0xd4, 0x2e, 0x26, 0xc4, 0x87, 0x08, 0x1c, 0xb1, 0xf2, 0x48, 0x2d, 0xec, 0xe1, 0xaf, + 0x47, 0x14, 0xa9, 0xef, 0x0a, 0x08, 0x56, 0x18, 0xf3, 0xf7, 0x06, 0xe4, 0x44, 0x42, 0xfe, 0x3a, + 0x14, 0xf8, 0xfe, 0xd9, 0x56, 0x60, 0x09, 0xbb, 0x52, 0x97, 0x82, 0x9c, 0x7b, 0x87, 0x04, 0x56, + 0xec, 0x6d, 0x21, 0x04, 0x47, 0x12, 0x11, 0x86, 0xbc, 0x13, 0x90, 0x4e, 0x78, 0x90, 0x4f, 0x4d, + 0x14, 0xad, 0x1a, 0x11, 0x75, 0x6c, 0xdd, 0xbb, 0xf1, 0x56, 0x40, 0x3c, 0x7e, 0x18, 0xf1, 0xd5, + 0xd8, 0xe6, 0x32, 0xb0, 0x14, 0x65, 0xfe, 0xcb, 0x80, 0x48, 0x15, 0x77, 0x7e, 0x46, 0xdc, 0xc3, + 0x5b, 0x8e, 0x77, 0xac, 0xb6, 0x35, 0x32, 0x67, 0x5f, 0xc1, 0x71, 0x44, 0x31, 0xee, 0x79, 0xc8, + 0x4c, 0xf7, 0x3c, 0x70, 0x85, 0x2d, 0xdf, 0x0b, 0x1c, 0xaf, 0x37, 0x72, 0xdb, 0x36, 0x15, 0x1c, + 0x47, 0x14, 0x3c, 0x11, 0xa1, 0xa4, 0x63, 0x39, 0x9e, 0xe3, 0xb5, 0xf9, 0x22, 0x36, 0xfd, 0x9e, + 0x17, 0x88, 0x17, 0x59, 0x25, 0x22, 0x78, 0x04, 0x8b, 0xc7, 0x70, 0x98, 0xff, 0xce, 0x41, 0x89, + 0xaf, 0x39, 0x7c, 0xe7, 0x9e, 0x87, 0x8a, 0xab, 0x7b, 0x81, 0x5a, 0xfb, 0x45, 0x65, 0x4a, 0xf2, + 0x5e, 0xe3, 0x24, 0x2d, 0x67, 0x16, 0x29, 0x54, 0xc4, 0x9c, 0x49, 0x32, 0x6f, 0xe9, 0x48, 0x9c, + 0xa4, 0xe5, 0xd1, 0xeb, 0x1e, 0xbf, 0x1f, 0x2a, 0x33, 0x89, 0x8e, 0xe8, 0x9b, 0x1c, 0x88, 0x25, + 0x0e, 0xed, 0xc0, 0x05, 0xcb, 0x75, 0xfd, 0x7b, 0x02, 0xd8, 0xf0, 0xfd, 0xe3, 0x8e, 0x45, 0x8f, + 0x99, 0x28, 0xa6, 0x0b, 0x8d, 0x2f, 0x28, 0x96, 0x0b, 0x1b, 0xa3, 0x24, 0x78, 0x1c, 0xdf, 0xb8, + 0x63, 0xcb, 0x4d, 0x79, 0x6c, 0x47, 0xb0, 0x3c, 0x04, 0x12, 0xb7, 0x5c, 0x55, 0xb6, 0xcf, 0x28, + 0x39, 0xcb, 0x78, 0x0c, 0xcd, 0xd9, 0x04, 0x38, 0x1e, 0x2b, 0x11, 0x5d, 0x87, 0x79, 0xee, 0xc9, + 0x7e, 0x2f, 0x08, 0xf3, 0xce, 0xbc, 0x38, 0x6e, 0x74, 0x3a, 0xa8, 0xcd, 0xdf, 0x4e, 0x60, 0xf0, + 0x10, 0x25, 0xdf, 0x5c, 0xd7, 0xe9, 0x38, 0x41, 0x75, 0x4e, 0xb0, 0x44, 0x9b, 0x7b, 0x8b, 0x03, + 0xb1, 0xc4, 0x25, 0x3c, 0xb0, 0x70, 0xae, 0x07, 0x6e, 0xc2, 0x12, 0x23, 0x9e, 0xbd, 0xed, 0x39, + 0x81, 0x63, 0xb9, 0x37, 0x4e, 0x44, 0x56, 0x59, 0x12, 0x07, 0x71, 0x91, 0xa7, 0x84, 0xfb, 0xc3, + 0x48, 0x3c, 0x4a, 0x6f, 0xfe, 0x39, 0x0b, 0x48, 0x26, 0xec, 0xb6, 0x4c, 0xca, 0x64, 0x5c, 0xe4, + 0x65, 0x85, 0x4a, 0xf8, 0x8d, 0xa1, 0xb2, 0x42, 0xe5, 0xfa, 0x21, 0x1e, 0xed, 0x40, 0x51, 0xc6, + 0xa7, 0xf8, 0xce, 0xad, 0x2b, 0xe2, 0xe2, 0x6e, 0x88, 0x38, 0x1b, 0xd4, 0x56, 0x12, 0x6a, 0x22, + 0x8c, 0x28, 0xf9, 0x62, 0x09, 0xe8, 0x2a, 0x80, 0xd5, 0x75, 0xf4, 0xa6, 0x5f, 0x31, 0x6e, 0xfd, + 0xc4, 0xe5, 0x3b, 0xd6, 0xa8, 0xd0, 0x4b, 0x90, 0x0b, 0x3e, 0x5d, 0x59, 0x56, 0x10, 0x55, 0x27, + 0x2f, 0xc2, 0x84, 0x04, 0xae, 0x5d, 0x5c, 0x0a, 0xc6, 0xcd, 0x52, 0x15, 0x55, 0xa4, 0x7d, 0x2b, + 0xc2, 0x60, 0x8d, 0x0a, 0x7d, 0x0b, 0x0a, 0x87, 0x2a, 0x9f, 0x15, 0xa7, 0x9b, 0x3a, 0xce, 0x86, + 0x59, 0xb0, 0xec, 0x3b, 0x84, 0x5f, 0x38, 0x92, 0x86, 0xbe, 0x0a, 0x25, 0xd6, 0x3b, 0x88, 0x52, + 0x00, 0xe9, 0x12, 0xd1, 0x7b, 0xbb, 0x1f, 0xa3, 0xb0, 0x4e, 0x67, 0xbe, 0x09, 0xc5, 0x1d, 0xa7, + 0x45, 0x7d, 0x51, 0x48, 0x3e, 0x01, 0x73, 0x2c, 0x51, 0x25, 0x45, 0x27, 0x19, 0xba, 0x6a, 0x88, + 0xe7, 0x3e, 0xea, 0x59, 0x9e, 0x2f, 0x6b, 0xa1, 0x7c, 0xec, 0xa3, 0xaf, 0x72, 0x20, 0x96, 0xb8, + 0xeb, 0xcb, 0x3c, 0xcb, 0xf8, 0xe9, 0xfb, 0xb5, 0x99, 0x77, 0xdf, 0xaf, 0xcd, 0xbc, 0xf7, 0xbe, + 0xca, 0x38, 0xfe, 0x00, 0x00, 0xbb, 0x07, 0xdf, 0x23, 0x2d, 0x19, 0xbb, 0x53, 0xf5, 0x06, 0xc3, + 0x96, 0xb4, 0xe8, 0x0d, 0x66, 0x86, 0x32, 0x47, 0x0d, 0x87, 0x13, 0x94, 0x68, 0x1d, 0x8a, 0x51, + 0xd7, 0x4f, 0xf9, 0xc7, 0x52, 0xe8, 0x6f, 0x51, 0x6b, 0x10, 0xc7, 0x34, 0x89, 0x87, 0x24, 0x77, + 0xee, 0x43, 0xd2, 0x80, 0x6c, 0xcf, 0xb1, 0x55, 0xd5, 0xfd, 0x74, 0xf8, 0x90, 0xdf, 0xd9, 0x6e, + 0x9e, 0x0d, 0x6a, 0x8f, 0x4c, 0x6a, 0xb6, 0x07, 0xfd, 0x2e, 0x61, 0xf5, 0x3b, 0xdb, 0x4d, 0xcc, + 0x99, 0xc7, 0x45, 0xb5, 0xd9, 0x29, 0xa3, 0xda, 0x55, 0x80, 0x76, 0xdc, 0xbb, 0x90, 0x41, 0x23, + 0x72, 0x44, 0xad, 0x67, 0xa1, 0x51, 0x21, 0x06, 0x4b, 0x2d, 0x5e, 0xdf, 0xab, 0x1e, 0x02, 0x0b, + 0xac, 0x8e, 0xec, 0x86, 0x4e, 0x77, 0x27, 0x2e, 0x29, 0x35, 0x4b, 0x9b, 0xc3, 0xc2, 0xf0, 0xa8, + 0x7c, 0xe4, 0xc3, 0x92, 0xad, 0xca, 0xcc, 0x58, 0x69, 0x71, 0x6a, 0xa5, 0x22, 0x62, 0x35, 0x87, + 0x05, 0xe1, 0x51, 0xd9, 0xe8, 0xbb, 0xb0, 0x12, 0x02, 0x47, 0x6b, 0x7d, 0x11, 0xf5, 0xb3, 0x8d, + 0xd5, 0xd3, 0x41, 0x6d, 0xa5, 0x39, 0x91, 0x0a, 0xdf, 0x47, 0x02, 0xb2, 0x61, 0xd6, 0x95, 0x59, + 0x72, 0x49, 0x64, 0x36, 0x5f, 0x4b, 0xb7, 0x8a, 0xd8, 0xfb, 0xeb, 0x7a, 0x76, 0x1c, 0xf5, 0x6d, + 0x54, 0x62, 0xac, 0x64, 0xa3, 0xb7, 0xa0, 0x64, 0x79, 0x9e, 0x1f, 0x58, 0xb2, 0xfb, 0x50, 0x16, + 0xaa, 0x36, 0xa6, 0x56, 0xb5, 0x11, 0xcb, 0x18, 0xca, 0xc6, 0x35, 0x0c, 0xd6, 0x55, 0xa1, 0x7b, + 0xb0, 0xe0, 0xdf, 0xf3, 0x08, 0xc5, 0xe4, 0x90, 0x50, 0xe2, 0xb5, 0x08, 0xab, 0x56, 0x84, 0xf6, + 0x67, 0x52, 0x6a, 0x4f, 0x30, 0xc7, 0x2e, 0x9d, 0x84, 0x33, 0x3c, 0xac, 0x05, 0xd5, 0x79, 0x6c, + 0xf5, 0x2c, 0xd7, 0xf9, 0x3e, 0xa1, 0xac, 0x3a, 0x1f, 0x37, 0xac, 0xb7, 0x22, 0x28, 0xd6, 0x28, + 0x50, 0x0f, 0x2a, 0x1d, 0xfd, 0xc9, 0xa8, 0x2e, 0x09, 0x33, 0xaf, 0xa5, 0x33, 0x73, 0xf4, 0x51, + 0x8b, 0xd3, 0xa0, 0x04, 0x0e, 0x27, 0xb5, 0xac, 0x3c, 0x07, 0xa5, 0x4f, 0x59, 0x21, 0xf0, 0x0a, + 0x63, 0xf8, 0x40, 0xa6, 0xaa, 0x30, 0xfe, 0x98, 0x81, 0xf9, 0xe4, 0x36, 0x0e, 0x3d, 0x87, 0xf9, + 0x54, 0xcf, 0x61, 0x58, 0xcb, 0x1a, 0x13, 0x27, 0x17, 0x61, 0x7c, 0xce, 0x4e, 0x8c, 0xcf, 0x2a, + 0x0c, 0xe6, 0x1e, 0x24, 0x0c, 0xd6, 0x01, 0x78, 0xb2, 0x42, 0x7d, 0xd7, 0x25, 0x54, 0x44, 0xc0, + 0x82, 0x9a, 0x50, 0x44, 0x50, 0xac, 0x51, 0xf0, 0x94, 0xfa, 0xc0, 0xf5, 0x5b, 0xc7, 0x62, 0x0b, + 0xc2, 0xdb, 0x2b, 0x62, 0x5f, 0x41, 0xa6, 0xd4, 0x8d, 0x11, 0x2c, 0x1e, 0xc3, 0x61, 0xf6, 0xe1, + 0xe2, 0x9e, 0x45, 0x79, 0x92, 0x13, 0xdf, 0x14, 0x51, 0xb3, 0xbc, 0x31, 0x52, 0x11, 0x3d, 0x3d, + 0xed, 0x8d, 0x8b, 0x37, 0x3f, 0x86, 0xc5, 0x55, 0x91, 0xf9, 0x57, 0x03, 0x2e, 0x8d, 0xd5, 0xfd, + 0x19, 0x54, 0x64, 0x6f, 0x24, 0x2b, 0xb2, 0xe7, 0x53, 0xb6, 0x32, 0xc7, 0x59, 0x3b, 0xa1, 0x3e, + 0x9b, 0x83, 0xfc, 0x1e, 0xcf, 0x84, 0xcd, 0x0f, 0x0d, 0x28, 0x8b, 0x5f, 0xd3, 0x74, 0x92, 0x6b, + 0xc9, 0x01, 0x43, 0xf1, 0xe1, 0x0d, 0x17, 0x1e, 0x46, 0xab, 0xf9, 0x1d, 0x03, 0x92, 0x3d, 0x5c, + 0xf4, 0xa2, 0xbc, 0x02, 0x46, 0xd4, 0x64, 0x9d, 0xd2, 0xfd, 0x5f, 0x98, 0x54, 0x92, 0x5e, 0x48, + 0xd5, 0xad, 0x7c, 0x12, 0x8a, 0xd8, 0xf7, 0x83, 0x3d, 0x2b, 0x38, 0x62, 0x7c, 0xef, 0xba, 0xfc, + 0x87, 0xda, 0x5e, 0xb1, 0x77, 0x02, 0x83, 0x25, 0xdc, 0xfc, 0xb9, 0x01, 0x97, 0x26, 0xce, 0x8d, + 0x78, 0x14, 0x69, 0x45, 0x5f, 0x6a, 0x45, 0x91, 0x23, 0xc7, 0x74, 0x58, 0xa3, 0xe2, 0xb5, 0x64, + 0x62, 0xd8, 0x34, 0x5c, 0x4b, 0x26, 0xb4, 0xe1, 0x24, 0xad, 0xf9, 0xcf, 0x0c, 0xa8, 0x41, 0xcd, + 0xff, 0xd8, 0xe9, 0x1f, 0x1f, 0x1a, 0x13, 0xcd, 0x27, 0xc7, 0x44, 0xd1, 0x4c, 0x48, 0x9b, 0x93, + 0x64, 0xef, 0x3f, 0x27, 0x41, 0xcf, 0x46, 0xa3, 0x17, 0xe9, 0x43, 0xab, 0xc9, 0xd1, 0xcb, 0xd9, + 0xa0, 0x56, 0x56, 0xc2, 0x93, 0xa3, 0x98, 0xd7, 0x60, 0xce, 0x26, 0x81, 0xe5, 0xb8, 0xb2, 0x2e, + 0x4c, 0x3d, 0x4c, 0x90, 0xc2, 0x9a, 0x92, 0xb5, 0x51, 0xe2, 0x36, 0xa9, 0x0f, 0x1c, 0x0a, 0xe4, + 0x01, 0xbb, 0xe5, 0xdb, 0xb2, 0x22, 0xc9, 0xc7, 0x01, 0x7b, 0xd3, 0xb7, 0x09, 0x16, 0x18, 0xf3, + 0x5d, 0x03, 0x4a, 0x52, 0xd2, 0xa6, 0xd5, 0x63, 0x04, 0x5d, 0x89, 0x56, 0x21, 0x8f, 0xfb, 0x92, + 0x3e, 0x63, 0x3b, 0x1b, 0xd4, 0x8a, 0x82, 0x4c, 0x14, 0x33, 0x63, 0x66, 0x49, 0x99, 0x73, 0xf6, + 0xe8, 0x51, 0xc8, 0x8b, 0x0b, 0xa4, 0x36, 0x33, 0x1e, 0x16, 0x72, 0x20, 0x96, 0x38, 0xf3, 0xe3, + 0x0c, 0x54, 0x12, 0x8b, 0x4b, 0x51, 0x17, 0x44, 0x2d, 0xd4, 0x4c, 0x8a, 0xb6, 0xfc, 0xe4, 0xd1, + 0xbc, 0x7a, 0xbe, 0x66, 0x1f, 0xe4, 0xf9, 0xfa, 0x36, 0xcc, 0xb6, 0xf8, 0x1e, 0x85, 0xff, 0xf4, + 0xb8, 0x32, 0xcd, 0x71, 0x8a, 0xdd, 0x8d, 0xbd, 0x51, 0x7c, 0x32, 0xac, 0x04, 0xa2, 0x9b, 0xb0, + 0x44, 0x49, 0x40, 0xfb, 0x1b, 0x87, 0x01, 0xa1, 0x7a, 0x33, 0x21, 0x1f, 0x67, 0xdf, 0x78, 0x98, + 0x00, 0x8f, 0xf2, 0x98, 0x07, 0x50, 0xbe, 0x6d, 0x1d, 0xb8, 0xd1, 0x78, 0x0c, 0x43, 0xc5, 0xf1, + 0x5a, 0x6e, 0xcf, 0x26, 0x32, 0xa0, 0x87, 0xd1, 0x2b, 0xbc, 0xb4, 0xdb, 0x3a, 0xf2, 0x6c, 0x50, + 0xbb, 0x90, 0x00, 0xc8, 0x79, 0x10, 0x4e, 0x8a, 0x30, 0x5d, 0xc8, 0x7d, 0x86, 0x95, 0xe4, 0x77, + 0xa0, 0x18, 0xe7, 0xfa, 0x0f, 0x59, 0xa5, 0xf9, 0x06, 0x14, 0xb8, 0xc7, 0x87, 0x35, 0xea, 0x39, + 0x59, 0x52, 0x32, 0xf7, 0xca, 0xa4, 0xc9, 0xbd, 0xc4, 0x90, 0xf5, 0x4e, 0xd7, 0x7e, 0xc0, 0x21, + 0x6b, 0xe6, 0x41, 0x5e, 0xbe, 0xec, 0x94, 0x2f, 0xdf, 0x55, 0x90, 0x7f, 0x44, 0xe1, 0x8f, 0x8c, + 0x4c, 0x20, 0xb4, 0x47, 0x46, 0x7f, 0xff, 0xb5, 0x09, 0xc3, 0x8f, 0x0d, 0x00, 0xd1, 0xca, 0x13, + 0x6d, 0xa4, 0x14, 0xe3, 0xfc, 0x3b, 0x30, 0xeb, 0x4b, 0x8f, 0x94, 0x83, 0xd6, 0x29, 0xfb, 0xc5, + 0xd1, 0x45, 0x92, 0x3e, 0x89, 0x95, 0xb0, 0xc6, 0xcb, 0x1f, 0x7c, 0xb2, 0x3a, 0xf3, 0xe1, 0x27, + 0xab, 0x33, 0x1f, 0x7d, 0xb2, 0x3a, 0xf3, 0xf6, 0xe9, 0xaa, 0xf1, 0xc1, 0xe9, 0xaa, 0xf1, 0xe1, + 0xe9, 0xaa, 0xf1, 0xd1, 0xe9, 0xaa, 0xf1, 0xf1, 0xe9, 0xaa, 0xf1, 0xee, 0xdf, 0x57, 0x67, 0x5e, + 0x7b, 0x2c, 0xcd, 0x1f, 0xfc, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x28, 0x27, 0x65, 0xab, 0x20, + 0x28, 0x00, 0x00, } func (m *APIGroup) Marshal() (dAtA []byte, err error) { @@ -2503,6 +2505,16 @@ func (m *ListOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SendInitialEvents != nil { + i-- + if *m.SendInitialEvents { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 + } i -= len(m.ResourceVersionMatch) copy(dAtA[i:], m.ResourceVersionMatch) i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceVersionMatch))) @@ -3908,6 +3920,9 @@ func (m *ListOptions) Size() (n int) { n += 2 l = len(m.ResourceVersionMatch) n += 1 + l + sovGenerated(uint64(l)) + if m.SendInitialEvents != nil { + n += 2 + } return n } @@ -4517,6 +4532,7 @@ func (this *ListOptions) String() string { `Continue:` + fmt.Sprintf("%v", this.Continue) + `,`, `AllowWatchBookmarks:` + fmt.Sprintf("%v", this.AllowWatchBookmarks) + `,`, `ResourceVersionMatch:` + fmt.Sprintf("%v", this.ResourceVersionMatch) + `,`, + `SendInitialEvents:` + valueToStringGenerated(this.SendInitialEvents) + `,`, `}`, }, "") return s @@ -8250,6 +8266,27 @@ func (m *ListOptions) Unmarshal(dAtA []byte) error { } m.ResourceVersionMatch = ResourceVersionMatch(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SendInitialEvents", 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.SendInitialEvents = &b default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto index 2be188a6a..48955dca8 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto @@ -246,19 +246,16 @@ message CreateOptions { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -575,6 +572,32 @@ message ListOptions { // This field is not supported when watch is true. Clients may start a watch from the last // resourceVersion value returned by the server and not miss any modifications. optional string continue = 8; + + // `sendInitialEvents=true` may be set together with `watch=true`. + // In that case, the watch stream will begin with synthetic events to + // produce the current state of objects in the collection. Once all such + // events have been sent, a synthetic "Bookmark" event will be sent. + // The bookmark will report the ResourceVersion (RV) corresponding to the + // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. + // Afterwards, the watch stream will proceed as usual, sending watch events + // corresponding to changes (subsequent to the RV) to objects watched. + // + // When `sendInitialEvents` option is set, we require `resourceVersionMatch` + // option to also be set. The semantic of the watch request is as following: + // - `resourceVersionMatch` = NotOlderThan + // is interpreted as "data at least as new as the provided `resourceVersion`" + // and the bookmark event is send when the state is synced + // to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + // If `resourceVersion` is unset, this is interpreted as "consistent read" and the + // bookmark event is send when the state is synced at least to the moment + // when request started being processed. + // - `resourceVersionMatch` set to any other value or unset + // Invalid error is returned. + // + // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward + // compatibility reasons) and to false otherwise. + // +optional + optional bool sendInitialEvents = 11; } // ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource @@ -645,7 +668,7 @@ message ObjectMeta { // automatically. Name is primarily intended for creation idempotence and configuration // definition. // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names // +optional optional string name = 1; @@ -671,7 +694,7 @@ message ObjectMeta { // // Must be a DNS_LABEL. // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/namespaces + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces // +optional optional string namespace = 3; @@ -685,7 +708,7 @@ message ObjectMeta { // // Populated by the system. // Read-only. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional optional string uid = 5; @@ -749,14 +772,14 @@ message ObjectMeta { // Map of string keys and values that can be used to organize and categorize // (scope and select) objects. May match selectors of replication controllers // and services. - // More info: http://kubernetes.io/docs/user-guide/labels + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels // +optional map labels = 11; // Annotations is an unstructured key value map stored with a resource that may be // set by external tools to store and retrieve arbitrary metadata. They are not // queryable and should be preserved when modifying objects. - // More info: http://kubernetes.io/docs/user-guide/annotations + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations // +optional map annotations = 12; @@ -811,11 +834,11 @@ message OwnerReference { optional string kind = 1; // Name of the referent. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names optional string name = 3; // UID of the referent. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids optional string uid = 4; // If true, this reference points to the managing controller. @@ -889,19 +912,16 @@ message PatchOptions { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -1024,7 +1044,7 @@ message StatusDetails { // UID of the resource. // (when there is a single resource which can be described). - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional optional string uid = 6; @@ -1128,19 +1148,16 @@ message UpdateOptions { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go index 152f99296..352d58ebc 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types.go @@ -114,7 +114,7 @@ type ObjectMeta struct { // automatically. Name is primarily intended for creation idempotence and configuration // definition. // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names // +optional Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` @@ -140,7 +140,7 @@ type ObjectMeta struct { // // Must be a DNS_LABEL. // Cannot be updated. - // More info: http://kubernetes.io/docs/user-guide/namespaces + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces // +optional Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` @@ -154,7 +154,7 @@ type ObjectMeta struct { // // Populated by the system. // Read-only. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"` @@ -218,14 +218,14 @@ type ObjectMeta struct { // Map of string keys and values that can be used to organize and categorize // (scope and select) objects. May match selectors of replication controllers // and services. - // More info: http://kubernetes.io/docs/user-guide/labels + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels // +optional Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"` // Annotations is an unstructured key value map stored with a resource that may be // set by external tools to store and retrieve arbitrary metadata. They are not // queryable and should be preserved when modifying objects. - // More info: http://kubernetes.io/docs/user-guide/annotations + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations // +optional Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"` @@ -295,10 +295,10 @@ type OwnerReference struct { // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"` // Name of the referent. - // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names Name string `json:"name" protobuf:"bytes,3,opt,name=name"` // UID of the referent. - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids UID types.UID `json:"uid" protobuf:"bytes,4,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"` // If true, this reference points to the managing controller. // +optional @@ -400,6 +400,32 @@ type ListOptions struct { // This field is not supported when watch is true. Clients may start a watch from the last // resourceVersion value returned by the server and not miss any modifications. Continue string `json:"continue,omitempty" protobuf:"bytes,8,opt,name=continue"` + + // `sendInitialEvents=true` may be set together with `watch=true`. + // In that case, the watch stream will begin with synthetic events to + // produce the current state of objects in the collection. Once all such + // events have been sent, a synthetic "Bookmark" event will be sent. + // The bookmark will report the ResourceVersion (RV) corresponding to the + // set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. + // Afterwards, the watch stream will proceed as usual, sending watch events + // corresponding to changes (subsequent to the RV) to objects watched. + // + // When `sendInitialEvents` option is set, we require `resourceVersionMatch` + // option to also be set. The semantic of the watch request is as following: + // - `resourceVersionMatch` = NotOlderThan + // is interpreted as "data at least as new as the provided `resourceVersion`" + // and the bookmark event is send when the state is synced + // to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + // If `resourceVersion` is unset, this is interpreted as "consistent read" and the + // bookmark event is send when the state is synced at least to the moment + // when request started being processed. + // - `resourceVersionMatch` set to any other value or unset + // Invalid error is returned. + // + // Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward + // compatibility reasons) and to false otherwise. + // +optional + SendInitialEvents *bool `json:"sendInitialEvents,omitempty" protobuf:"varint,11,opt,name=sendInitialEvents"` } // resourceVersionMatch specifies how the resourceVersion parameter is applied. resourceVersionMatch @@ -542,19 +568,16 @@ type CreateOptions struct { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -597,19 +620,16 @@ type PatchOptions struct { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -674,19 +694,16 @@ type UpdateOptions struct { // fieldValidation instructs the server on how to handle // objects in the request (POST/PUT/PATCH) containing unknown - // or duplicate fields, provided that the `ServerSideFieldValidation` - // feature gate is also enabled. Valid values are: + // or duplicate fields. Valid values are: // - Ignore: This will ignore any unknown fields that are silently // dropped from the object, and will ignore all but the last duplicate // field that the decoder encounters. This is the default behavior - // prior to v1.23 and is the default behavior when the - // `ServerSideFieldValidation` feature gate is disabled. + // prior to v1.23. // - Warn: This will send a warning via the standard warning response // header for each unknown field that is dropped from the object, and // for each duplicate field that is encountered. The request will // still succeed if there are no other errors, and will only persist - // the last of any duplicate fields. This is the default when the - // `ServerSideFieldValidation` feature gate is enabled. + // the last of any duplicate fields. This is the default in v1.23+ // - Strict: This will fail the request with a BadRequest error if // any unknown fields would be dropped from the object, or if any // duplicate fields are present. The error returned from the server @@ -761,7 +778,7 @@ type StatusDetails struct { Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"` // UID of the resource. // (when there is a single resource which can be described). - // More info: http://kubernetes.io/docs/user-guide/identifiers#uids + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional UID types.UID `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"` // The Causes array includes more details associated with the StatusReason diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go index 9570726a0..b736e8371 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_APIGroup = map[string]string{ @@ -115,7 +115,7 @@ var map_CreateOptions = map[string]string{ "": "CreateOptions may be provided when creating an API object.", "dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", "fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", } func (CreateOptions) SwaggerDoc() map[string]string { @@ -216,6 +216,7 @@ var map_ListOptions = map[string]string{ "timeoutSeconds": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", "limit": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", "continue": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "sendInitialEvents": "`sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic \"Bookmark\" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `\"k8s.io/initial-events-end\": \"true\"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched.\n\nWhen `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan\n is interpreted as \"data at least as new as the provided `resourceVersion`\"\n and the bookmark event is send when the state is synced\n to a `resourceVersion` at least as fresh as the one provided by the ListOptions.\n If `resourceVersion` is unset, this is interpreted as \"consistent read\" and the\n bookmark event is send when the state is synced at least to the moment\n when request started being processed.\n- `resourceVersionMatch` set to any other value or unset\n Invalid error is returned.\n\nDefaults to true if `resourceVersion=\"\"` or `resourceVersion=\"0\"` (for backward compatibility reasons) and to false otherwise.", } func (ListOptions) SwaggerDoc() map[string]string { @@ -239,18 +240,18 @@ func (ManagedFieldsEntry) SwaggerDoc() map[string]string { var map_ObjectMeta = map[string]string{ "": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", - "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names", "generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will return a 409.\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency", - "namespace": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces", + "namespace": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces", "selfLink": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", - "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", "resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", "generation": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", "creationTimestamp": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "deletionTimestamp": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "deletionGracePeriodSeconds": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", - "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels", - "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations", + "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels", + "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations", "ownerReferences": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.", "finalizers": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.", "managedFields": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.", @@ -264,8 +265,8 @@ var map_OwnerReference = map[string]string{ "": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", "apiVersion": "API version of the referent.", "kind": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "name": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names", - "uid": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "name": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names", + "uid": "UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", "controller": "If true, this reference points to the managing controller.", "blockOwnerDeletion": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.", } @@ -306,7 +307,7 @@ var map_PatchOptions = map[string]string{ "dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", "force": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.", "fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).", - "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", } func (PatchOptions) SwaggerDoc() map[string]string { @@ -372,7 +373,7 @@ var map_StatusDetails = map[string]string{ "name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", "group": "The group attribute of the resource associated with the status StatusReason.", "kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "uid": "UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "uid": "UID of the resource. (when there is a single resource which can be described). More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids", "causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", "retryAfterSeconds": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.", } @@ -451,7 +452,7 @@ var map_UpdateOptions = map[string]string{ "": "UpdateOptions may be provided when updating an API object. All fields in UpdateOptions should also be present in PatchOptions.", "dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", "fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", - "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "fieldValidation": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", } func (UpdateOptions) SwaggerDoc() map[string]string { diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go index b7590f0b3..afe01ed5a 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.conversion.go @@ -426,6 +426,13 @@ func autoConvert_url_Values_To_v1_ListOptions(in *url.Values, out *ListOptions, } else { out.Continue = "" } + if values, ok := map[string][]string(*in)["sendInitialEvents"]; ok && len(values) > 0 { + if err := runtime.Convert_Slice_string_To_Pointer_bool(&values, &out.SendInitialEvents, s); err != nil { + return err + } + } else { + out.SendInitialEvents = nil + } return nil } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go index 418e6099f..7d29c504a 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/zz_generated.deepcopy.go @@ -602,6 +602,11 @@ func (in *ListOptions) DeepCopyInto(out *ListOptions) { *out = new(int64) **out = **in } + if in.SendInitialEvents != nil { + in, out := &in.SendInitialEvents, &out.SendInitialEvents + *out = new(bool) + **out = **in + } return } diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go index ef7e7c1e9..dff735dcf 100644 --- a/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/types_swagger_doc_generated.go @@ -24,7 +24,7 @@ package v1beta1 // they are on one line! For multiple line or blocks that you want to ignore use ---. // Any context after a --- is ignored. // -// Those methods can be generated by using hack/update-generated-swagger-docs.sh +// Those methods can be generated by using hack/update-codegen.sh // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_PartialObjectMetadataList = map[string]string{ diff --git a/vendor/k8s.io/apimachinery/pkg/labels/labels.go b/vendor/k8s.io/apimachinery/pkg/labels/labels.go index 8360d842b..19d823cef 100644 --- a/vendor/k8s.io/apimachinery/pkg/labels/labels.go +++ b/vendor/k8s.io/apimachinery/pkg/labels/labels.go @@ -77,6 +77,8 @@ func (ls Set) AsValidatedSelector() (Selector, error) { // perform any validation. // According to our measurements this is significantly faster // in codepaths that matter at high scale. +// Note: this method copies the Set; if the Set is immutable, consider wrapping it with ValidatedSetSelector +// instead, which does not copy. func (ls Set) AsSelectorPreValidated() Selector { return SelectorFromValidatedSet(ls) } diff --git a/vendor/k8s.io/apimachinery/pkg/labels/selector.go b/vendor/k8s.io/apimachinery/pkg/labels/selector.go index 891004389..5e6014240 100644 --- a/vendor/k8s.io/apimachinery/pkg/labels/selector.go +++ b/vendor/k8s.io/apimachinery/pkg/labels/selector.go @@ -149,14 +149,12 @@ type Requirement struct { // NewRequirement is the constructor for a Requirement. // If any of these rules is violated, an error is returned: -// (1) The operator can only be In, NotIn, Equals, DoubleEquals, Gt, Lt, NotEquals, Exists, or DoesNotExist. -// (2) If the operator is In or NotIn, the values set must be non-empty. -// (3) If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value. -// (4) If the operator is Exists or DoesNotExist, the value set must be empty. -// (5) If the operator is Gt or Lt, the values set must contain only one value, which will be interpreted as an integer. -// (6) The key is invalid due to its length, or sequence -// -// of characters. See validateLabelKey for more details. +// 1. The operator can only be In, NotIn, Equals, DoubleEquals, Gt, Lt, NotEquals, Exists, or DoesNotExist. +// 2. If the operator is In or NotIn, the values set must be non-empty. +// 3. If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value. +// 4. If the operator is Exists or DoesNotExist, the value set must be empty. +// 5. If the operator is Gt or Lt, the values set must contain only one value, which will be interpreted as an integer. +// 6. The key is invalid due to its length, or sequence of characters. See validateLabelKey for more details. // // The empty string is a valid value in the input values set. // Returned error, if not nil, is guaranteed to be an aggregated field.ErrorList @@ -213,22 +211,15 @@ func (r *Requirement) hasValue(value string) bool { // Matches returns true if the Requirement matches the input Labels. // There is a match in the following cases: -// (1) The operator is Exists and Labels has the Requirement's key. -// (2) The operator is In, Labels has the Requirement's key and Labels' -// -// value for that key is in Requirement's value set. -// -// (3) The operator is NotIn, Labels has the Requirement's key and -// -// Labels' value for that key is not in Requirement's value set. -// -// (4) The operator is DoesNotExist or NotIn and Labels does not have the -// -// Requirement's key. -// -// (5) The operator is GreaterThanOperator or LessThanOperator, and Labels has -// -// the Requirement's key and the corresponding value satisfies mathematical inequality. +// 1. The operator is Exists and Labels has the Requirement's key. +// 2. The operator is In, Labels has the Requirement's key and Labels' +// value for that key is in Requirement's value set. +// 3. The operator is NotIn, Labels has the Requirement's key and +// Labels' value for that key is not in Requirement's value set. +// 4. The operator is DoesNotExist or NotIn and Labels does not have the +// Requirement's key. +// 5. The operator is GreaterThanOperator or LessThanOperator, and Labels has +// the Requirement's key and the corresponding value satisfies mathematical inequality. func (r *Requirement) Matches(ls Labels) bool { switch r.operator { case selection.In, selection.Equals, selection.DoubleEquals: @@ -872,15 +863,14 @@ func (p *Parser) parseExactValue() (sets.String, error) { // "x in (foo,,baz),y,z notin ()" // // Note: -// -// (1) Inclusion - " in " - denotes that the KEY exists and is equal to any of the -// VALUEs in its requirement -// (2) Exclusion - " notin " - denotes that the KEY is not equal to any -// of the VALUEs in its requirement or does not exist -// (3) The empty string is a valid VALUE -// (4) A requirement with just a KEY - as in "y" above - denotes that -// the KEY exists and can be any VALUE. -// (5) A requirement with just !KEY requires that the KEY not exist. +// 1. Inclusion - " in " - denotes that the KEY exists and is equal to any of the +// VALUEs in its requirement +// 2. Exclusion - " notin " - denotes that the KEY is not equal to any +// of the VALUEs in its requirement or does not exist +// 3. The empty string is a valid VALUE +// 4. A requirement with just a KEY - as in "y" above - denotes that +// the KEY exists and can be any VALUE. +// 5. A requirement with just !KEY requires that the KEY not exist. func Parse(selector string, opts ...field.PathOption) (Selector, error) { parsedSelector, err := parse(selector, field.ToPath(opts...)) if err == nil { @@ -948,6 +938,8 @@ func ValidatedSelectorFromSet(ls Set) (Selector, error) { // SelectorFromValidatedSet returns a Selector which will match exactly the given Set. // A nil and empty Sets are considered equivalent to Everything(). // It assumes that Set is already validated and doesn't do any validation. +// Note: this method copies the Set; if the Set is immutable, consider wrapping it with ValidatedSetSelector +// instead, which does not copy. func SelectorFromValidatedSet(ls Set) Selector { if ls == nil || len(ls) == 0 { return internalSelector{} @@ -969,3 +961,76 @@ func SelectorFromValidatedSet(ls Set) Selector { func ParseToRequirements(selector string, opts ...field.PathOption) ([]Requirement, error) { return parse(selector, field.ToPath(opts...)) } + +// ValidatedSetSelector wraps a Set, allowing it to implement the Selector interface. Unlike +// Set.AsSelectorPreValidated (which copies the input Set), this type simply wraps the underlying +// Set. As a result, it is substantially more efficient. A nil and empty Sets are considered +// equivalent to Everything(). +// +// Callers MUST ensure the underlying Set is not mutated, and that it is already validated. If these +// constraints are not met, Set.AsValidatedSelector should be preferred +// +// None of the Selector methods mutate the underlying Set, but Add() and Requirements() convert to +// the less optimized version. +type ValidatedSetSelector Set + +func (s ValidatedSetSelector) Matches(labels Labels) bool { + for k, v := range s { + if !labels.Has(k) || v != labels.Get(k) { + return false + } + } + return true +} + +func (s ValidatedSetSelector) Empty() bool { + return len(s) == 0 +} + +func (s ValidatedSetSelector) String() string { + keys := make([]string, 0, len(s)) + for k := range s { + keys = append(keys, k) + } + // Ensure deterministic output + sort.Strings(keys) + b := strings.Builder{} + for i, key := range keys { + v := s[key] + b.Grow(len(key) + 2 + len(v)) + if i != 0 { + b.WriteString(",") + } + b.WriteString(key) + b.WriteString("=") + b.WriteString(v) + } + return b.String() +} + +func (s ValidatedSetSelector) Add(r ...Requirement) Selector { + return s.toFullSelector().Add(r...) +} + +func (s ValidatedSetSelector) Requirements() (requirements Requirements, selectable bool) { + return s.toFullSelector().Requirements() +} + +func (s ValidatedSetSelector) DeepCopySelector() Selector { + res := make(ValidatedSetSelector, len(s)) + for k, v := range s { + res[k] = v + } + return res +} + +func (s ValidatedSetSelector) RequiresExactMatch(label string) (value string, found bool) { + v, f := s[label] + return v, f +} + +func (s ValidatedSetSelector) toFullSelector() Selector { + return SelectorFromValidatedSet(Set(s)) +} + +var _ Selector = ValidatedSetSelector{} diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go b/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go index b21eb664e..54ccb7a74 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version.go @@ -191,8 +191,7 @@ func (gv GroupVersion) Identifier() string { // if none of the options match the group. It prefers a match to group and version over just group. // TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme. // TODO: Introduce an adapter type between GroupVersion and runtime.GroupVersioner, and use LegacyCodec(GroupVersion) -// -// in fewer places. +// in fewer places. func (gv GroupVersion) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) { for _, gvk := range kinds { if gvk.Group == gv.Group && gvk.Version == gv.Version { @@ -240,8 +239,7 @@ func (gv GroupVersion) WithResource(resource string) GroupVersionResource { // GroupVersions can be used to represent a set of desired group versions. // TODO: Move GroupVersions to a package under pkg/runtime, since it's used by scheme. // TODO: Introduce an adapter type between GroupVersions and runtime.GroupVersioner, and use LegacyCodec(GroupVersion) -// -// in fewer places. +// in fewer places. type GroupVersions []GroupVersion // Identifier implements runtime.GroupVersioner interface. diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go b/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go index 18b25a994..a5b116718 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/scheme.go @@ -118,8 +118,7 @@ func (s *Scheme) Converter() *conversion.Converter { // API group and version that would never be updated. // // TODO: there is discussion about removing unversioned and replacing it with objects that are manifest into -// -// every version with particular schemas. Resolve this method at that point. +// every version with particular schemas. Resolve this method at that point. func (s *Scheme) AddUnversionedTypes(version schema.GroupVersion, types ...Object) { s.addObservedVersion(version) s.AddKnownTypes(version, types...) diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go index 21944f2d8..ff9820842 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go @@ -259,8 +259,7 @@ func (f CodecFactory) SupportedMediaTypes() []runtime.SerializerInfo { // invoke CodecForVersions. Callers that need only to read data should use UniversalDecoder(). // // TODO: make this call exist only in pkg/api, and initialize it with the set of default versions. -// -// All other callers will be forced to request a Codec directly. +// All other callers will be forced to request a Codec directly. func (f CodecFactory) LegacyCodec(version ...schema.GroupVersion) runtime.Codec { return versioning.NewDefaultingCodecForScheme(f.scheme, f.legacySerializer, f.universal, schema.GroupVersions(version), runtime.InternalGroupVersioner) } diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go index 446633182..25f955ed7 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go @@ -147,7 +147,7 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru } if d, ok := obj.(runtime.NestedObjectDecoder); ok { - if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{c.decoder}); err != nil { + if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{Decoder: c.decoder}); err != nil { if strictErr, ok := runtime.AsStrictDecodingError(err); ok { // save the strictDecodingError let and the caller decide what to do with it strictDecodingErrs = append(strictDecodingErrs, strictErr.Errors()...) diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/types.go b/vendor/k8s.io/apimachinery/pkg/runtime/types.go index 3dc9a5a2f..ce77c7910 100644 --- a/vendor/k8s.io/apimachinery/pkg/runtime/types.go +++ b/vendor/k8s.io/apimachinery/pkg/runtime/types.go @@ -123,7 +123,7 @@ type Unknown struct { // Raw will hold the complete serialized object which couldn't be matched // with a registered type. Most likely, nothing should be done with this // except for passing it through the system. - Raw []byte `protobuf:"bytes,2,opt,name=raw"` + Raw []byte `json:"-" protobuf:"bytes,2,opt,name=raw"` // ContentEncoding is encoding used to encode 'Raw' data. // Unspecified means no encoding. ContentEncoding string `protobuf:"bytes,3,opt,name=contentEncoding"` diff --git a/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go b/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go index b19750f3a..db18ce1ce 100644 --- a/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go +++ b/vendor/k8s.io/apimachinery/pkg/types/namespacedname.go @@ -37,3 +37,14 @@ const ( func (n NamespacedName) String() string { return n.Namespace + string(Separator) + n.Name } + +// MarshalLog emits a struct containing required key/value pair +func (n NamespacedName) MarshalLog() interface{} { + return struct { + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` + }{ + Name: n.Name, + Namespace: n.Namespace, + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go b/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go index 1f5a04fd4..1b60d145c 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go +++ b/vendor/k8s.io/apimachinery/pkg/util/errors/errors.go @@ -214,7 +214,7 @@ func CreateAggregateFromMessageCountMap(m MessageCountMap) Aggregate { return NewAggregate(result) } -// Reduce will return err or, if err is an Aggregate and only has one item, +// Reduce will return err or nil, if err is an Aggregate and only has one item, // the first item in the aggregate. func Reduce(err error) error { if agg, ok := err.(Aggregate); ok && err != nil { diff --git a/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go b/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go index ca08f8561..9b3c9c8d5 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go +++ b/vendor/k8s.io/apimachinery/pkg/util/framer/framer.go @@ -32,7 +32,7 @@ func NewLengthDelimitedFrameWriter(w io.Writer) io.Writer { return &lengthDelimitedFrameWriter{w: w} } -// Write writes a single frame to the nested writer, prepending it with the length in +// Write writes a single frame to the nested writer, prepending it with the length // in bytes of data (as a 4 byte, bigendian uint32). func (w *lengthDelimitedFrameWriter) Write(data []byte) (int, error) { binary.BigEndian.PutUint32(w.h[:], uint32(len(data))) diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml new file mode 100644 index 000000000..a667e9834 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/endpoints.yaml @@ -0,0 +1,7018 @@ +apiVersion: v1 +kind: Endpoints +metadata: + creationTimestamp: '2016-10-04T17:45:58Z' + labels: + app: my-app + name: app-server + namespace: default + resourceVersion: '184597135' + selfLink: /self/link + uid: 6826f086-8a5a-11e6-8d09-42010a800005 +subsets: +- addresses: + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0000 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0001 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0002 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0003 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0004 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0005 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0006 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0007 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0008 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0009 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0010 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0011 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0012 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0013 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0014 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0015 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0016 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0017 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0018 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0019 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0020 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0021 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0022 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0023 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0024 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0025 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0026 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0027 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0028 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0029 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0030 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0031 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0032 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0033 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0034 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0035 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0036 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0037 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0038 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0039 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0040 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0041 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0042 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0043 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0044 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0045 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0046 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0047 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0048 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0049 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0050 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0051 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0052 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0053 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0054 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0055 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0056 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0057 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0058 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0059 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0060 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0061 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0062 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0063 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0064 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0065 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0066 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0067 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0068 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0069 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0070 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0071 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0072 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0073 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0074 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0075 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0076 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0077 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0078 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0079 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0080 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0081 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0082 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0083 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0084 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0085 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0086 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0087 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0088 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0089 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0090 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0091 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0092 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0093 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0094 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0095 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0096 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0097 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0098 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0099 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0100 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0101 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0102 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0103 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0104 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0105 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0106 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0107 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0108 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0109 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0110 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0111 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0112 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0113 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0114 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0115 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0116 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0117 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0118 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0119 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0120 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0121 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0122 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0123 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0124 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0125 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0126 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0127 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0128 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0129 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0130 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0131 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0132 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0133 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0134 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0135 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0136 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0137 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0138 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0139 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0140 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0141 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0142 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0143 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0144 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0145 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0146 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0147 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0148 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0149 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0150 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0151 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0152 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0153 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0154 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0155 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0156 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0157 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0158 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0159 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0160 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0161 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0162 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0163 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0164 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0165 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0166 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0167 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0168 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0169 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0170 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0171 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0172 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0173 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0174 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0175 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0176 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0177 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0178 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0179 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0180 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0181 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0182 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0183 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0184 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0185 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0186 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0187 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0188 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0189 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0190 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0191 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0192 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0193 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0194 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0195 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0196 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0197 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0198 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0199 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0200 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0201 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0202 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0203 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0204 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0205 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0206 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0207 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0208 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0209 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0210 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0211 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0212 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0213 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0214 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0215 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0216 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0217 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0218 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0219 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0220 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0221 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0222 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0223 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0224 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0225 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0226 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0227 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0228 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0229 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0230 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0231 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0232 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0233 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0234 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0235 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0236 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0237 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0238 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0239 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0240 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0241 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0242 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0243 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0244 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0245 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0246 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0247 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0248 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0249 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0250 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0251 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0252 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0253 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0254 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0255 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0256 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0257 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0258 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0259 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0260 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0261 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0262 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0263 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0264 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0265 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0266 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0267 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0268 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0269 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0270 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0271 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0272 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0273 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0274 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0275 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0276 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0277 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0278 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0279 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0280 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0281 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0282 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0283 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0284 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0285 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0286 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0287 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0288 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0289 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0290 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0291 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0292 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0293 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0294 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0295 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0296 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0297 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0298 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0299 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0300 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0301 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0302 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0303 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0304 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0305 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0306 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0307 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0308 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0309 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0310 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0311 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0312 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0313 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0314 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0315 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0316 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0317 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0318 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0319 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0320 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0321 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0322 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0323 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0324 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0325 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0326 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0327 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0328 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0329 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0330 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0331 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0332 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0333 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0334 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0335 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0336 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0337 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0338 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0339 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0340 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0341 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0342 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0343 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0344 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0345 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0346 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0347 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0348 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0349 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0350 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0351 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0352 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0353 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0354 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0355 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0356 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0357 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0358 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0359 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0360 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0361 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0362 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0363 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0364 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0365 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0366 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0367 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0368 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0369 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0370 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0371 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0372 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0373 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0374 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0375 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0376 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0377 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0378 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0379 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0380 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0381 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0382 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0383 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0384 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0385 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0386 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0387 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0388 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0389 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0390 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0391 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0392 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0393 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0394 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0395 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0396 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0397 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0398 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0399 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0400 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0401 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0402 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0403 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0404 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0405 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0406 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0407 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0408 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0409 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0410 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0411 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0412 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0413 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0414 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0415 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0416 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0417 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0418 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0419 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0420 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0421 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0422 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0423 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0424 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0425 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0426 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0427 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0428 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0429 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0430 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0431 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0432 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0433 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0434 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0435 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0436 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0437 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0438 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0439 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0440 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0441 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0442 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0443 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0444 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0445 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0446 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0447 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0448 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0449 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0450 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0451 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0452 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0453 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0454 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0455 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0456 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0457 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0458 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0459 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0460 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0461 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0462 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0463 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0464 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0465 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0466 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0467 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0468 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0469 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0470 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0471 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0472 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0473 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0474 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0475 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0476 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0477 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0478 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0479 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0480 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0481 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0482 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0483 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0484 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0485 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0486 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0487 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0488 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0489 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0490 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0491 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0492 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0493 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0494 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0495 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0496 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0497 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0498 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0499 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0500 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0501 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0502 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0503 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0504 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0505 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0506 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0507 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0508 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0509 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0510 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0511 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0512 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0513 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0514 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0515 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0516 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0517 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0518 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0519 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0520 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0521 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0522 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0523 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0524 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0525 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0526 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0527 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0528 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0529 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0530 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0531 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0532 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0533 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0534 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0535 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0536 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0537 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0538 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0539 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0540 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0541 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0542 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0543 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0544 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0545 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0546 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0547 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0548 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0549 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0550 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0551 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0552 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0553 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0554 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0555 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0556 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0557 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0558 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0559 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0560 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0561 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0562 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0563 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0564 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0565 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0566 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0567 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0568 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0569 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0570 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0571 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0572 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0573 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0574 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0575 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0576 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0577 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0578 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0579 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0580 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0581 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0582 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0583 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0584 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0585 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0586 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0587 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0588 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0589 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0590 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0591 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0592 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0593 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0594 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0595 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0596 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0597 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0598 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0599 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0600 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0601 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0602 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0603 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0604 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0605 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0606 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0607 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0608 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0609 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0610 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0611 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0612 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0613 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0614 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0615 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0616 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0617 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0618 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0619 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0620 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0621 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0622 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0623 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0624 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0625 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0626 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0627 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0628 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0629 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0630 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0631 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0632 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0633 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0634 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0635 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0636 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0637 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0638 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0639 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0640 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0641 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0642 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0643 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0644 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0645 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0646 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0647 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0648 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0649 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0650 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0651 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0652 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0653 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0654 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0655 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0656 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0657 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0658 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0659 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0660 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0661 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0662 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0663 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0664 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0665 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0666 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0667 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0668 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0669 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0670 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0671 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0672 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0673 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0674 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0675 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0676 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0677 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0678 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0679 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0680 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0681 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0682 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0683 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0684 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0685 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0686 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0687 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0688 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0689 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0690 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0691 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0692 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0693 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0694 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0695 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0696 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0697 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0698 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0699 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0700 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0701 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0702 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0703 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0704 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0705 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0706 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0707 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0708 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0709 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0710 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0711 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0712 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0713 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0714 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0715 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0716 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0717 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0718 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0719 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0720 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0721 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0722 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0723 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0724 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0725 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0726 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0727 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0728 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0729 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0730 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0731 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0732 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0733 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0734 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0735 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0736 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0737 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0738 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0739 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0740 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0741 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0742 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0743 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0744 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0745 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0746 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0747 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0748 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0749 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0750 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0751 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0752 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0753 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0754 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0755 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0756 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0757 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0758 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0759 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0760 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0761 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0762 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0763 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0764 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0765 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0766 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0767 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0768 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0769 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0770 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0771 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0772 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0773 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0774 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0775 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0776 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0777 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0778 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0779 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0780 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0781 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0782 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0783 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0784 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0785 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0786 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0787 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0788 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0789 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0790 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0791 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0792 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0793 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0794 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0795 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0796 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0797 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0798 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0799 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0800 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0801 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0802 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0803 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0804 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0805 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0806 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0807 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0808 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0809 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0810 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0811 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0812 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0813 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0814 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0815 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0816 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0817 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0818 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0819 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0820 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0821 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0822 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0823 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0824 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0825 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0826 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0827 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0828 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0829 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0830 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0831 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0832 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0833 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0834 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0835 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0836 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0837 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0838 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0839 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0840 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0841 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0842 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0843 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0844 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0845 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0846 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0847 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0848 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0849 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0850 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0851 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0852 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0853 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0854 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0855 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0856 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0857 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0858 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0859 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0860 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0861 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0862 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0863 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0864 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0865 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0866 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0867 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0868 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0869 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0870 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0871 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0872 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0873 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0874 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0875 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0876 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0877 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0878 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0879 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0880 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0881 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0882 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0883 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0884 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0885 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0886 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0887 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0888 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0889 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0890 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0891 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0892 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0893 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0894 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0895 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0896 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0897 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0898 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0899 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0900 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0901 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0902 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0903 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0904 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0905 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0906 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0907 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0908 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0909 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0910 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0911 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0912 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0913 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0914 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0915 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0916 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0917 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0918 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0919 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0920 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0921 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0922 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0923 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0924 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0925 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0926 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0927 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0928 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0929 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0930 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0931 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0932 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0933 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0934 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0935 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0936 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0937 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0938 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0939 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0940 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0941 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0942 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0943 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0944 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0945 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0946 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0947 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0948 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0949 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0950 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0951 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0952 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0953 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0954 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0955 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0956 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0957 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0958 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0959 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0960 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0961 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0962 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0963 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0964 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0965 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0966 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0967 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0968 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0969 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0970 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0971 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0972 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0973 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0974 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0975 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0976 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0977 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0978 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0979 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0980 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0981 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0982 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0983 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0984 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0985 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0986 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0987 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0988 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0989 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0990 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0991 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0992 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0993 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0994 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0995 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0996 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0997 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0998 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + - ip: 10.0.0.1 + targetRef: + kind: Pod + name: pod-name-1234-0999 + namespace: default + resourceVersion: '1234567890' + uid: 11111111-2222-3333-4444-555555555555 + ports: + - name: port-name + port: 8080 + protocol: TCP + diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go new file mode 100644 index 000000000..978ffb3c3 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/fieldmanager.go @@ -0,0 +1,57 @@ +/* +Copyright 2018 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 managedfields + +import ( + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/managedfields/internal" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +// FieldManager updates the managed fields and merges applied +// configurations. +type FieldManager = internal.FieldManager + +// NewDefaultFieldManager creates a new FieldManager that merges apply requests +// and update managed fields for other types of requests. +func NewDefaultFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (*FieldManager, error) { + f, err := internal.NewStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields) + if err != nil { + return nil, fmt.Errorf("failed to create field manager: %v", err) + } + return internal.NewDefaultFieldManager(f, typeConverter, objectConverter, objectCreater, kind, subresource), nil +} + +// NewDefaultCRDFieldManager creates a new FieldManager specifically for +// CRDs. This allows for the possibility of fields which are not defined +// in models, as well as having no models defined at all. +func NewDefaultCRDFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (_ *FieldManager, err error) { + f, err := internal.NewCRDStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields) + if err != nil { + return nil, fmt.Errorf("failed to create field manager: %v", err) + } + return internal.NewDefaultFieldManager(f, typeConverter, objectConverter, objectCreater, kind, subresource), nil +} + +func ValidateManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) error { + _, err := internal.DecodeManagedFields(encodedManagedFields) + return err +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/atmostevery.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/atmostevery.go similarity index 100% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/atmostevery.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/atmostevery.go diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/buildmanagerinfo.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go similarity index 94% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/buildmanagerinfo.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go index 58b87eb38..fa342ca13 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/buildmanagerinfo.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/buildmanagerinfo.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "fmt" @@ -22,7 +22,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" ) type buildManagerInfoManager struct { @@ -71,5 +70,5 @@ func (f *buildManagerInfoManager) buildManagerInfo(prefix string, operation meta if managerInfo.Manager == "" { managerInfo.Manager = "unknown" } - return internal.BuildManagerIdentifier(&managerInfo) + return BuildManagerIdentifier(&managerInfo) } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go similarity index 96% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go index c3184e241..8951932ba 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/capmanagers.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/capmanagers.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "fmt" @@ -22,7 +22,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) @@ -100,7 +99,7 @@ func (f *capManagersManager) capUpdateManagers(managed Managed) (newManaged Mana // Create a new manager identifier for the versioned bucket entry. // The version for this manager comes from the version of the update being merged into the bucket. - bucket, err := internal.BuildManagerIdentifier(&metav1.ManagedFieldsEntry{ + bucket, err := BuildManagerIdentifier(&metav1.ManagedFieldsEntry{ Manager: f.oldUpdatesManagerName, Operation: metav1.ManagedFieldsOperationUpdate, APIVersion: version, diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/conflict.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/conflict.go similarity index 100% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/conflict.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/conflict.go diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go similarity index 62% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go index 6c3d2ce83..f3111d4bc 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fieldmanager.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2022 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. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "fmt" @@ -25,9 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "k8s.io/klog/v2" - "sigs.k8s.io/structured-merge-diff/v4/fieldpath" "sigs.k8s.io/structured-merge-diff/v4/merge" ) @@ -40,38 +38,9 @@ const DefaultMaxUpdateManagers int = 10 // starts being tracked from the object's creation, instead of from the first time the object is applied to. const DefaultTrackOnCreateProbability float32 = 1 -var atMostEverySecond = internal.NewAtMostEvery(time.Second) +var atMostEverySecond = NewAtMostEvery(time.Second) -// Managed groups a fieldpath.ManagedFields together with the timestamps associated with each operation. -type Managed interface { - // Fields gets the fieldpath.ManagedFields. - Fields() fieldpath.ManagedFields - - // Times gets the timestamps associated with each operation. - Times() map[string]*metav1.Time -} - -// Manager updates the managed fields and merges applied configurations. -type Manager interface { - // Update is used when the object has already been merged (non-apply - // use-case), and simply updates the managed fields in the output - // object. - // * `liveObj` is not mutated by this function - // * `newObj` may be mutated by this function - // Returns the new object with managedFields removed, and the object's new - // proposed managedFields separately. - Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) - - // Apply is used when server-side apply is called, as it merges the - // object and updates the managed fields. - // * `liveObj` is not mutated by this function - // * `newObj` may be mutated by this function - // Returns the new object with managedFields removed, and the object's new - // proposed managedFields separately. - Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) -} - -// FieldManager updates the managed fields and merge applied +// FieldManager updates the managed fields and merges applied // configurations. type FieldManager struct { fieldManager Manager @@ -84,29 +53,8 @@ func NewFieldManager(f Manager, subresource string) *FieldManager { return &FieldManager{fieldManager: f, subresource: subresource} } -// NewDefaultFieldManager creates a new FieldManager that merges apply requests -// and update managed fields for other types of requests. -func NewDefaultFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (*FieldManager, error) { - f, err := NewStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields) - if err != nil { - return nil, fmt.Errorf("failed to create field manager: %v", err) - } - return newDefaultFieldManager(f, typeConverter, objectConverter, objectCreater, kind, subresource), nil -} - -// NewDefaultCRDFieldManager creates a new FieldManager specifically for -// CRDs. This allows for the possibility of fields which are not defined -// in models, as well as having no models defined at all. -func NewDefaultCRDFieldManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, hub schema.GroupVersion, subresource string, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (_ *FieldManager, err error) { - f, err := NewCRDStructuredMergeManager(typeConverter, objectConverter, objectDefaulter, kind.GroupVersion(), hub, resetFields) - if err != nil { - return nil, fmt.Errorf("failed to create field manager: %v", err) - } - return newDefaultFieldManager(f, typeConverter, objectConverter, objectCreater, kind, subresource), nil -} - // newDefaultFieldManager is a helper function which wraps a Manager with certain default logic. -func newDefaultFieldManager(f Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, subresource string) *FieldManager { +func NewDefaultFieldManager(f Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, subresource string) *FieldManager { return NewFieldManager( NewLastAppliedUpdater( NewLastAppliedManager( @@ -123,12 +71,6 @@ func newDefaultFieldManager(f Manager, typeConverter TypeConverter, objectConver ) } -// DecodeManagedFields converts ManagedFields from the wire format (api format) -// to the format used by sigs.k8s.io/structured-merge-diff -func DecodeManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (Managed, error) { - return internal.DecodeManagedFields(encodedManagedFields) -} - func decodeLiveOrNew(liveObj, newObj runtime.Object, ignoreManagedFieldsFromRequestObject bool) (Managed, error) { liveAccessor, err := meta.Accessor(liveObj) if err != nil { @@ -149,7 +91,7 @@ func decodeLiveOrNew(liveObj, newObj runtime.Object, ignoreManagedFieldsFromRequ } if isResetManagedFields(newAccessor.GetManagedFields()) { - return internal.NewEmptyManaged(), nil + return NewEmptyManaged(), nil } // If the managed field is empty or we failed to decode it, @@ -164,7 +106,7 @@ func decodeLiveOrNew(liveObj, newObj runtime.Object, ignoreManagedFieldsFromRequ func emptyManagedFieldsOnErr(managed Managed, err error) (Managed, error) { if err != nil { - return internal.NewEmptyManaged(), nil + return NewEmptyManaged(), nil } return managed, nil } @@ -181,13 +123,13 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (o return newObj, nil } - internal.RemoveObjectManagedFields(newObj) + RemoveObjectManagedFields(newObj) if object, managed, err = f.fieldManager.Update(liveObj, newObj, managed, manager); err != nil { return nil, err } - if err = internal.EncodeObjectManagedFields(object, managed); err != nil { + if err = EncodeObjectManagedFields(object, managed); err != nil { return nil, fmt.Errorf("failed to encode managed fields: %v", err) } @@ -207,12 +149,12 @@ func (f *FieldManager) UpdateNoErrors(liveObj, newObj runtime.Object, manager st name = accessor.GetName() } - klog.ErrorS(err, "[SHOULD NOT HAPPEN] failed to update managedFields", "VersionKind", + klog.ErrorS(err, "[SHOULD NOT HAPPEN] failed to update managedFields", "versionKind", newObj.GetObjectKind().GroupVersionKind(), "namespace", ns, "name", name) }) // Explicitly remove managedFields on failure, so that // we can't have garbage in it. - internal.RemoveObjectManagedFields(newObj) + RemoveObjectManagedFields(newObj) return newObj } return obj @@ -251,12 +193,12 @@ func (f *FieldManager) Apply(liveObj, appliedObj runtime.Object, manager string, object, managed, err = f.fieldManager.Apply(liveObj, appliedObj, managed, manager, force) if err != nil { if conflicts, ok := err.(merge.Conflicts); ok { - return nil, internal.NewConflictError(conflicts) + return nil, NewConflictError(conflicts) } return nil, err } - if err = internal.EncodeObjectManagedFields(object, managed); err != nil { + if err = EncodeObjectManagedFields(object, managed); err != nil { return nil, fmt.Errorf("failed to encode managed fields: %v", err) } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/fields.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go similarity index 100% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/fields.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/fields.go diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go new file mode 100644 index 000000000..b00b6b829 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastapplied.go @@ -0,0 +1,50 @@ +/* +Copyright 2022 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 internal + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/api/meta" + apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" + "k8s.io/apimachinery/pkg/runtime" +) + +// LastAppliedConfigAnnotation is the annotation used to store the previous +// configuration of a resource for use in a three way diff by UpdateApplyAnnotation. +// +// This is a copy of the corev1 annotation since we don't want to depend on the whole package. +const LastAppliedConfigAnnotation = "kubectl.kubernetes.io/last-applied-configuration" + +// SetLastApplied sets the last-applied annotation the given value in +// the object. +func SetLastApplied(obj runtime.Object, value string) error { + accessor, err := meta.Accessor(obj) + if err != nil { + panic(fmt.Sprintf("couldn't get accessor: %v", err)) + } + var annotations = accessor.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + annotations[LastAppliedConfigAnnotation] = value + if err := apimachineryvalidation.ValidateAnnotationsSize(annotations); err != nil { + delete(annotations, LastAppliedConfigAnnotation) + } + accessor.SetAnnotations(annotations) + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go similarity index 97% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go index 4b07d462a..3f6cf8821 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedmanager.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedmanager.go @@ -14,13 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "encoding/json" "fmt" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -100,7 +99,7 @@ func (f *lastAppliedManager) allowedConflictsFromLastApplied(liveObj runtime.Obj if annotations == nil { return nil, fmt.Errorf("no last applied annotation") } - var lastApplied, ok = annotations[corev1.LastAppliedConfigAnnotation] + var lastApplied, ok = annotations[LastAppliedConfigAnnotation] if !ok || lastApplied == "" { return nil, fmt.Errorf("no last applied annotation") } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedupdater.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go similarity index 78% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedupdater.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go index 7cd4eb128..06e6c5d8c 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/lastappliedupdater.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/lastappliedupdater.go @@ -14,14 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "fmt" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" - apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" ) @@ -62,7 +60,7 @@ func (f *lastAppliedUpdater) Apply(liveObj, newObj runtime.Object, managed Manag if err != nil { return nil, nil, fmt.Errorf("failed to build last-applied annotation: %v", err) } - err = setLastApplied(liveObj, lastAppliedValue) + err = SetLastApplied(liveObj, lastAppliedValue) if err != nil { return nil, nil, fmt.Errorf("failed to set last-applied annotation: %v", err) } @@ -79,27 +77,10 @@ func hasLastApplied(obj runtime.Object) bool { if annotations == nil { return false } - lastApplied, ok := annotations[corev1.LastAppliedConfigAnnotation] + lastApplied, ok := annotations[LastAppliedConfigAnnotation] return ok && len(lastApplied) > 0 } -func setLastApplied(obj runtime.Object, value string) error { - accessor, err := meta.Accessor(obj) - if err != nil { - panic(fmt.Sprintf("couldn't get accessor: %v", err)) - } - var annotations = accessor.GetAnnotations() - if annotations == nil { - annotations = map[string]string{} - } - annotations[corev1.LastAppliedConfigAnnotation] = value - if err := apimachineryvalidation.ValidateAnnotationsSize(annotations); err != nil { - delete(annotations, corev1.LastAppliedConfigAnnotation) - } - accessor.SetAnnotations(annotations) - return nil -} - func buildLastApplied(obj runtime.Object) (string, error) { obj = obj.DeepCopyObject() @@ -110,7 +91,7 @@ func buildLastApplied(obj runtime.Object) (string, error) { // Remove the annotation from the object before encoding the object var annotations = accessor.GetAnnotations() - delete(annotations, corev1.LastAppliedConfigAnnotation) + delete(annotations, LastAppliedConfigAnnotation) accessor.SetAnnotations(annotations) lastApplied, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfields.go similarity index 100% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfields.go diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go similarity index 95% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go index 412443a6c..376eed6b2 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/managedfieldsupdater.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/managedfieldsupdater.go @@ -14,14 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) @@ -77,7 +76,7 @@ func (f *managedFieldsUpdater) Apply(liveObj, appliedObj runtime.Object, managed managed.Times()[fieldManager] = &metav1.Time{Time: time.Now().UTC()} } else { object = liveObj.DeepCopyObject() - internal.RemoveObjectManagedFields(object) + RemoveObjectManagedFields(object) } return object, managed, nil } diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go new file mode 100644 index 000000000..053936103 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/manager.go @@ -0,0 +1,52 @@ +/* +Copyright 2022 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 internal + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" +) + +// Managed groups a fieldpath.ManagedFields together with the timestamps associated with each operation. +type Managed interface { + // Fields gets the fieldpath.ManagedFields. + Fields() fieldpath.ManagedFields + + // Times gets the timestamps associated with each operation. + Times() map[string]*metav1.Time +} + +// Manager updates the managed fields and merges applied configurations. +type Manager interface { + // Update is used when the object has already been merged (non-apply + // use-case), and simply updates the managed fields in the output + // object. + // * `liveObj` is not mutated by this function + // * `newObj` may be mutated by this function + // Returns the new object with managedFields removed, and the object's new + // proposed managedFields separately. + Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) + + // Apply is used when server-side apply is called, as it merges the + // object and updates the managed fields. + // * `liveObj` is not mutated by this function + // * `newObj` may be mutated by this function + // Returns the new object with managedFields removed, and the object's new + // proposed managedFields separately. + Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/pathelement.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go similarity index 100% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/pathelement.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/pathelement.go diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go similarity index 99% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go index a8c34ad65..6b281ec1e 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/skipnonapplied.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/skipnonapplied.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "fmt" diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/stripmeta.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go similarity index 99% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/stripmeta.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go index 1460d9c80..9b61f3a6f 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/stripmeta.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/stripmeta.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "fmt" diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go similarity index 97% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go index 213988e23..eb5598ac3 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/structuredmerge.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/structuredmerge.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( "fmt" @@ -23,7 +23,6 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" "sigs.k8s.io/structured-merge-diff/v4/merge" ) @@ -108,7 +107,7 @@ func (f *structuredMergeManager) Update(liveObj, newObj runtime.Object, managed if err != nil { return nil, nil, fmt.Errorf("failed to update ManagedFields (%v): %v", objectGVKNN(newObjVersioned), err) } - managed = internal.NewManaged(managedFields, managed.Times()) + managed = NewManaged(managedFields, managed.Times()) return newObj, managed, nil } @@ -151,7 +150,7 @@ func (f *structuredMergeManager) Apply(liveObj, patchObj runtime.Object, managed if err != nil { return nil, nil, err } - managed = internal.NewManaged(managedFields, managed.Times()) + managed = NewManaged(managedFields, managed.Times()) if newObjTyped == nil { return nil, managed, nil diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go new file mode 100644 index 000000000..1ac96d7f7 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/typeconverter.go @@ -0,0 +1,193 @@ +/* +Copyright 2022 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 internal + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kube-openapi/pkg/schemaconv" + "k8s.io/kube-openapi/pkg/validation/spec" + smdschema "sigs.k8s.io/structured-merge-diff/v4/schema" + "sigs.k8s.io/structured-merge-diff/v4/typed" + "sigs.k8s.io/structured-merge-diff/v4/value" +) + +// TypeConverter allows you to convert from runtime.Object to +// typed.TypedValue and the other way around. +type TypeConverter interface { + ObjectToTyped(runtime.Object) (*typed.TypedValue, error) + TypedToObject(*typed.TypedValue) (runtime.Object, error) +} + +type typeConverter struct { + parser map[schema.GroupVersionKind]*typed.ParseableType +} + +var _ TypeConverter = &typeConverter{} + +func NewTypeConverter(openapiSpec map[string]*spec.Schema, preserveUnknownFields bool) (TypeConverter, error) { + typeSchema, err := schemaconv.ToSchemaFromOpenAPI(openapiSpec, preserveUnknownFields) + if err != nil { + return nil, fmt.Errorf("failed to convert models to schema: %v", err) + } + + typeParser := typed.Parser{Schema: smdschema.Schema{Types: typeSchema.Types}} + tr := indexModels(&typeParser, openapiSpec) + + return &typeConverter{parser: tr}, nil +} + +func (c *typeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { + gvk := obj.GetObjectKind().GroupVersionKind() + t := c.parser[gvk] + if t == nil { + return nil, NewNoCorrespondingTypeError(gvk) + } + switch o := obj.(type) { + case *unstructured.Unstructured: + return t.FromUnstructured(o.UnstructuredContent()) + default: + return t.FromStructured(obj) + } +} + +func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { + return valueToObject(value.AsValue()) +} + +type deducedTypeConverter struct{} + +// DeducedTypeConverter is a TypeConverter for CRDs that don't have a +// schema. It does implement the same interface though (and create the +// same types of objects), so that everything can still work the same. +// CRDs are merged with all their fields being "atomic" (lists +// included). +func NewDeducedTypeConverter() TypeConverter { + return deducedTypeConverter{} +} + +// ObjectToTyped converts an object into a TypedValue with a "deduced type". +func (deducedTypeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { + switch o := obj.(type) { + case *unstructured.Unstructured: + return typed.DeducedParseableType.FromUnstructured(o.UnstructuredContent()) + default: + return typed.DeducedParseableType.FromStructured(obj) + } +} + +// TypedToObject transforms the typed value into a runtime.Object. That +// is not specific to deduced type. +func (deducedTypeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { + return valueToObject(value.AsValue()) +} + +func valueToObject(val value.Value) (runtime.Object, error) { + vu := val.Unstructured() + switch o := vu.(type) { + case map[string]interface{}: + return &unstructured.Unstructured{Object: o}, nil + default: + return nil, fmt.Errorf("failed to convert value to unstructured for type %T", vu) + } +} + +func indexModels( + typeParser *typed.Parser, + openAPISchemas map[string]*spec.Schema, +) map[schema.GroupVersionKind]*typed.ParseableType { + tr := map[schema.GroupVersionKind]*typed.ParseableType{} + for modelName, model := range openAPISchemas { + gvkList := parseGroupVersionKind(model.Extensions) + if len(gvkList) == 0 { + continue + } + + parsedType := typeParser.Type(modelName) + for _, gvk := range gvkList { + if len(gvk.Kind) > 0 { + tr[schema.GroupVersionKind(gvk)] = &parsedType + } + } + } + return tr +} + +// Get and parse GroupVersionKind from the extension. Returns empty if it doesn't have one. +func parseGroupVersionKind(extensions map[string]interface{}) []schema.GroupVersionKind { + gvkListResult := []schema.GroupVersionKind{} + + // Get the extensions + gvkExtension, ok := extensions["x-kubernetes-group-version-kind"] + if !ok { + return []schema.GroupVersionKind{} + } + + // gvk extension must be a list of at least 1 element. + gvkList, ok := gvkExtension.([]interface{}) + if !ok { + return []schema.GroupVersionKind{} + } + + for _, gvk := range gvkList { + var group, version, kind string + + // gvk extension list must be a map with group, version, and + // kind fields + if gvkMap, ok := gvk.(map[interface{}]interface{}); ok { + group, ok = gvkMap["group"].(string) + if !ok { + continue + } + version, ok = gvkMap["version"].(string) + if !ok { + continue + } + kind, ok = gvkMap["kind"].(string) + if !ok { + continue + } + + } else if gvkMap, ok := gvk.(map[string]interface{}); ok { + group, ok = gvkMap["group"].(string) + if !ok { + continue + } + version, ok = gvkMap["version"].(string) + if !ok { + continue + } + kind, ok = gvkMap["kind"].(string) + if !ok { + continue + } + } else { + continue + } + + gvkListResult = append(gvkListResult, schema.GroupVersionKind{ + Group: group, + Version: version, + Kind: kind, + }) + } + + return gvkListResult +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go similarity index 87% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go index 477e92f79..45855fa4c 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/versionconverter.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/internal/versionconverter.go @@ -14,9 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package internal import ( + "fmt" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" @@ -99,3 +101,23 @@ func (v *versionConverter) Convert(object *typed.TypedValue, version fieldpath.A func (v *versionConverter) IsMissingVersionError(err error) bool { return runtime.IsNotRegisteredError(err) || isNoCorrespondingTypeError(err) } + +type noCorrespondingTypeErr struct { + gvk schema.GroupVersionKind +} + +func NewNoCorrespondingTypeError(gvk schema.GroupVersionKind) error { + return &noCorrespondingTypeErr{gvk: gvk} +} + +func (k *noCorrespondingTypeErr) Error() string { + return fmt.Sprintf("no corresponding type for %v", k.gvk) +} + +func isNoCorrespondingTypeError(err error) bool { + if err == nil { + return false + } + _, ok := err.(*noCorrespondingTypeErr) + return ok +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml new file mode 100644 index 000000000..66e849f23 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/node.yaml @@ -0,0 +1,261 @@ +apiVersion: v1 +kind: Node +metadata: + annotations: + container.googleapis.com/instance_id: "123456789321654789" + node.alpha.kubernetes.io/ttl: "0" + volumes.kubernetes.io/controller-managed-attach-detach: "true" + creationTimestamp: "2019-07-09T16:17:29Z" + labels: + kubernetes.io/arch: amd64 + beta.kubernetes.io/fluentd-ds-ready: "true" + beta.kubernetes.io/instance-type: n1-standard-4 + kubernetes.io/os: linux + cloud.google.com/gke-nodepool: default-pool + cloud.google.com/gke-os-distribution: cos + failure-domain.beta.kubernetes.io/region: us-central1 + failure-domain.beta.kubernetes.io/zone: us-central1-b + topology.kubernetes.io/region: us-central1 + topology.kubernetes.io/zone: us-central1-b + kubernetes.io/hostname: node-default-pool-something + name: node-default-pool-something + resourceVersion: "211582541" + selfLink: /api/v1/nodes/node-default-pool-something + uid: 0c24d0e1-a265-11e9-abe4-42010a80026b +spec: + podCIDR: 10.0.0.1/24 + providerID: some-provider-id-of-some-sort +status: + addresses: + - address: 10.0.0.1 + type: InternalIP + - address: 192.168.0.1 + type: ExternalIP + - address: node-default-pool-something + type: Hostname + allocatable: + cpu: 3920m + ephemeral-storage: "104638878617" + hugepages-2Mi: "0" + memory: 12700100Ki + pods: "110" + capacity: + cpu: "4" + ephemeral-storage: 202086868Ki + hugepages-2Mi: "0" + memory: 15399364Ki + pods: "110" + conditions: + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:08Z" + message: containerd is functioning properly + reason: FrequentContainerdRestart + status: "False" + type: FrequentContainerdRestart + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:06Z" + message: docker overlay2 is functioning properly + reason: CorruptDockerOverlay2 + status: "False" + type: CorruptDockerOverlay2 + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:06Z" + message: node is functioning properly + reason: UnregisterNetDevice + status: "False" + type: FrequentUnregisterNetDevice + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:17:04Z" + message: kernel has no deadlock + reason: KernelHasNoDeadlock + status: "False" + type: KernelDeadlock + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:17:04Z" + message: Filesystem is not read-only + reason: FilesystemIsNotReadOnly + status: "False" + type: ReadonlyFilesystem + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:05Z" + message: kubelet is functioning properly + reason: FrequentKubeletRestart + status: "False" + type: FrequentKubeletRestart + - lastHeartbeatTime: "2019-09-20T19:32:08Z" + lastTransitionTime: "2019-07-09T16:22:06Z" + message: docker is functioning properly + reason: FrequentDockerRestart + status: "False" + type: FrequentDockerRestart + - lastHeartbeatTime: "2019-07-09T16:17:47Z" + lastTransitionTime: "2019-07-09T16:17:47Z" + message: RouteController created a route + reason: RouteCreated + status: "False" + type: NetworkUnavailable + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:29Z" + message: kubelet has sufficient disk space available + reason: KubeletHasSufficientDisk + status: "False" + type: OutOfDisk + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:29Z" + message: kubelet has sufficient memory available + reason: KubeletHasSufficientMemory + status: "False" + type: MemoryPressure + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:29Z" + message: kubelet has no disk pressure + reason: KubeletHasNoDiskPressure + status: "False" + type: DiskPressure + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:29Z" + message: kubelet has sufficient PID available + reason: KubeletHasSufficientPID + status: "False" + type: PIDPressure + - lastHeartbeatTime: "2019-09-20T19:32:50Z" + lastTransitionTime: "2019-07-09T16:17:49Z" + message: kubelet is posting ready status. AppArmor enabled + reason: KubeletReady + status: "True" + type: Ready + daemonEndpoints: + kubeletEndpoint: + Port: 10250 + images: + - names: + - grafana/grafana@sha256:80e5e113a984d74836aa16f5b4524012099436b1a50df293f00ac6377fb512c8 + - grafana/grafana:4.4.2 + sizeBytes: 287008013 + - names: + - registry.k8s.io/node-problem-detector@sha256:f95cab985c26b2f46e9bd43283e0bfa88860c14e0fb0649266babe8b65e9eb2b + - registry.k8s.io/node-problem-detector:v0.4.1 + sizeBytes: 286572743 + - names: + - grafana/grafana@sha256:7ff7f9b2501a5d55b55ce3f58d21771b1c5af1f2a4ab7dbf11bef7142aae7033 + - grafana/grafana:4.2.0 + sizeBytes: 277940263 + - names: + - influxdb@sha256:7dddf03376348876ed4bdf33d6dfa3326f45a2bae0930dbd80781a374eb519bc + - influxdb:1.2.2 + sizeBytes: 223948571 + - names: + - gcr.io/stackdriver-agents/stackdriver-logging-agent@sha256:f8d5231b67b9c53f60068b535a11811d29d1b3efd53d2b79f2a2591ea338e4f2 + - gcr.io/stackdriver-agents/stackdriver-logging-agent:0.6-1.6.0-1 + sizeBytes: 223242132 + - names: + - nginx@sha256:35779791c05d119df4fe476db8f47c0bee5943c83eba5656a15fc046db48178b + - nginx:1.10.1 + sizeBytes: 180708613 + - names: + - registry.k8s.io/fluentd-elasticsearch@sha256:b8c94527b489fb61d3d81ce5ad7f3ddbb7be71e9620a3a36e2bede2f2e487d73 + - registry.k8s.io/fluentd-elasticsearch:v2.0.4 + sizeBytes: 135716379 + - names: + - nginx@sha256:00be67d6ba53d5318cd91c57771530f5251cfbe028b7be2c4b70526f988cfc9f + - nginx:latest + sizeBytes: 109357355 + - names: + - registry.k8s.io/kubernetes-dashboard-amd64@sha256:dc4026c1b595435ef5527ca598e1e9c4343076926d7d62b365c44831395adbd0 + - registry.k8s.io/kubernetes-dashboard-amd64:v1.8.3 + sizeBytes: 102319441 + - names: + - gcr.io/google_containers/kube-proxy:v1.11.10-gke.5 + - registry.k8s.io/kube-proxy:v1.11.10-gke.5 + sizeBytes: 102279340 + - names: + - registry.k8s.io/event-exporter@sha256:7f9cd7cb04d6959b0aa960727d04fa86759008048c785397b7b0d9dff0007516 + - registry.k8s.io/event-exporter:v0.2.3 + sizeBytes: 94171943 + - names: + - registry.k8s.io/prometheus-to-sd@sha256:6c0c742475363d537ff059136e5d5e4ab1f512ee0fd9b7ca42ea48bc309d1662 + - registry.k8s.io/prometheus-to-sd:v0.3.1 + sizeBytes: 88077694 + - names: + - registry.k8s.io/fluentd-gcp-scaler@sha256:a5ace7506d393c4ed65eb2cbb6312c64ab357fcea16dff76b9055bc6e498e5ff + - registry.k8s.io/fluentd-gcp-scaler:0.5.1 + sizeBytes: 86637208 + - names: + - registry.k8s.io/heapster-amd64@sha256:9fae0af136ce0cf4f88393b3670f7139ffc464692060c374d2ae748e13144521 + - registry.k8s.io/heapster-amd64:v1.6.0-beta.1 + sizeBytes: 76016169 + - names: + - registry.k8s.io/ingress-glbc-amd64@sha256:31d36bbd9c44caffa135fc78cf0737266fcf25e3cf0cd1c2fcbfbc4f7309cc52 + - registry.k8s.io/ingress-glbc-amd64:v1.1.1 + sizeBytes: 67801919 + - names: + - registry.k8s.io/kube-addon-manager@sha256:d53486c3a0b49ebee019932878dc44232735d5622a51dbbdcec7124199020d09 + - registry.k8s.io/kube-addon-manager:v8.7 + sizeBytes: 63322109 + - names: + - nginx@sha256:4aacdcf186934dcb02f642579314075910f1855590fd3039d8fa4c9f96e48315 + - nginx:1.10-alpine + sizeBytes: 54042627 + - names: + - registry.k8s.io/cpvpa-amd64@sha256:cfe7b0a11c9c8e18c87b1eb34fef9a7cbb8480a8da11fc2657f78dbf4739f869 + - registry.k8s.io/cpvpa-amd64:v0.6.0 + sizeBytes: 51785854 + - names: + - registry.k8s.io/cluster-proportional-autoscaler-amd64@sha256:003f98d9f411ddfa6ff6d539196355e03ddd69fa4ed38c7ffb8fec6f729afe2d + - registry.k8s.io/cluster-proportional-autoscaler-amd64:1.1.2-r2 + sizeBytes: 49648481 + - names: + - registry.k8s.io/ip-masq-agent-amd64@sha256:1ffda57d87901bc01324c82ceb2145fe6a0448d3f0dd9cb65aa76a867cd62103 + - registry.k8s.io/ip-masq-agent-amd64:v2.1.1 + sizeBytes: 49612505 + - names: + - registry.k8s.io/k8s-dns-kube-dns-amd64@sha256:b99fc3eee2a9f052f7eb4cc00f15eb12fc405fa41019baa2d6b79847ae7284a8 + - registry.k8s.io/k8s-dns-kube-dns-amd64:1.14.10 + sizeBytes: 49549457 + - names: + - registry.k8s.io/rescheduler@sha256:156cfbfd05a5a815206fd2eeb6cbdaf1596d71ea4b415d3a6c43071dd7b99450 + - registry.k8s.io/rescheduler:v0.4.0 + sizeBytes: 48973149 + - names: + - registry.k8s.io/event-exporter@sha256:16ca66e2b5dc7a1ce6a5aafcb21d0885828b75cdfc08135430480f7ad2364adc + - registry.k8s.io/event-exporter:v0.2.4 + sizeBytes: 47261019 + - names: + - registry.k8s.io/coredns@sha256:db2bf53126ed1c761d5a41f24a1b82a461c85f736ff6e90542e9522be4757848 + - registry.k8s.io/coredns:1.1.3 + sizeBytes: 45587362 + - names: + - prom/prometheus@sha256:483f4c9d7733699ba79facca9f8bcce1cef1af43dfc3e7c5a1882aa85f53cb74 + - prom/prometheus:v1.1.3 + sizeBytes: 45493941 + nodeInfo: + architecture: amd64 + bootID: a32eca78-4ad4-4b76-9252-f143d6c2ae61 + containerRuntimeVersion: docker://17.3.2 + kernelVersion: 4.14.127+ + kubeProxyVersion: v1.11.10-gke.5 + kubeletVersion: v1.11.10-gke.5 + machineID: 1739555e5b231057f0f9a0b5fa29511b + operatingSystem: linux + osImage: Container-Optimized OS from Google + systemUUID: 1739555E-5B23-1057-F0F9-A0B5FA29511B + volumesAttached: + - devicePath: /dev/disk/by-id/b9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049 + - devicePath: /dev/disk/by-id/b9772-pvc-8895a852-fd42-11e6-94d4-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-8895a852-fd42-11e6-94d4-42010a800049 + - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049 + - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049 + - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049 + - devicePath: /dev/disk/by-id/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283 + name: kubernetes.io/pd/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283 + volumesInUse: + - kubernetes.io/pd/some-random-clusterb9772-pvc-72e1c7f1-fd41-11e6-94d4-42010a800049 + - kubernetes.io/pd/some-random-clusterb9772-pvc-8895a852-fd42-11e6-94d4-42010a800049 + - kubernetes.io/pd/some-random-clusterb9772-pvc-8bf50554-fd42-11e6-94d4-42010a800049 + - kubernetes.io/pd/some-random-clusterb9772-pvc-8fb5e386-4641-11e7-a490-42010a800283 + - kubernetes.io/pd/some-random-clusterb9772-pvc-c2435a06-14d7-11e7-9baf-42010a800049 + - kubernetes.io/pd/some-random-clusterb9772-pvc-c787c67d-14d7-11e7-9baf-42010a800049 diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml b/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml new file mode 100644 index 000000000..3fb0877d6 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/pod.yaml @@ -0,0 +1,121 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + app: some-app + plugin1: some-value + plugin2: some-value + plugin3: some-value + plugin4: some-value + name: some-name + namespace: default + ownerReferences: + - apiVersion: apps/v1 + blockOwnerDeletion: true + controller: true + kind: ReplicaSet + name: some-name + uid: 0a9d2b9e-779e-11e7-b422-42010a8001be +spec: + containers: + - args: + - one + - two + - three + - four + - five + - six + - seven + - eight + - nine + env: + - name: VAR_3 + valueFrom: + secretKeyRef: + key: some-other-key + name: some-oher-name + - name: VAR_2 + valueFrom: + secretKeyRef: + key: other-key + name: other-name + - name: VAR_1 + valueFrom: + secretKeyRef: + key: some-key + name: some-name + image: some-image-name + imagePullPolicy: IfNotPresent + name: some-name + resources: + requests: + cpu: '0' + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: default-token-hu5jz + readOnly: true + dnsPolicy: ClusterFirst + nodeName: node-name + priority: 0 + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: default + serviceAccountName: default + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + volumes: + - name: default-token-hu5jz + secret: + defaultMode: 420 + secretName: default-token-hu5jz +status: + conditions: + - lastProbeTime: null + lastTransitionTime: '2019-07-08T09:31:18Z' + status: 'True' + type: Initialized + - lastProbeTime: null + lastTransitionTime: '2019-07-08T09:41:59Z' + status: 'True' + type: Ready + - lastProbeTime: null + lastTransitionTime: null + status: 'True' + type: ContainersReady + - lastProbeTime: null + lastTransitionTime: '2019-07-08T09:31:18Z' + status: 'True' + type: PodScheduled + containerStatuses: + - containerID: docker://885e82a1ed0b7356541bb410a0126921ac42439607c09875cd8097dd5d7b5376 + image: some-image-name + imageID: docker-pullable://some-image-id + lastState: + terminated: + containerID: docker://d57290f9e00fad626b20d2dd87a3cf69bbc22edae07985374f86a8b2b4e39565 + exitCode: 255 + finishedAt: '2019-07-08T09:39:09Z' + reason: Error + startedAt: '2019-07-08T09:38:54Z' + name: name + ready: true + restartCount: 6 + state: + running: + startedAt: '2019-07-08T09:41:59Z' + hostIP: 10.0.0.1 + phase: Running + podIP: 10.0.0.1 + qosClass: BestEffort + startTime: '2019-07-08T09:31:18Z' diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/scalehandler.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go similarity index 94% rename from vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/scalehandler.go rename to vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go index d9844990c..48b774cec 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/scalehandler.go +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/scalehandler.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package fieldmanager +package managedfields import ( "fmt" @@ -23,7 +23,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" + "k8s.io/apimachinery/pkg/util/managedfields/internal" "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) @@ -60,7 +60,7 @@ func NewScaleHandler(parentEntries []metav1.ManagedFieldsEntry, groupVersion sch // 2. Replicas path of the main resource is transformed to the replicas path of // the scale subresource func (h *ScaleHandler) ToSubresource() ([]metav1.ManagedFieldsEntry, error) { - managed, err := DecodeManagedFields(h.parentEntries) + managed, err := internal.DecodeManagedFields(h.parentEntries) if err != nil { return nil, err } @@ -92,13 +92,13 @@ func (h *ScaleHandler) ToSubresource() ([]metav1.ManagedFieldsEntry, error) { // ToParent merges `scaleEntries` with the entries of the main resource and // transforms them accordingly func (h *ScaleHandler) ToParent(scaleEntries []metav1.ManagedFieldsEntry) ([]metav1.ManagedFieldsEntry, error) { - decodedParentEntries, err := DecodeManagedFields(h.parentEntries) + decodedParentEntries, err := internal.DecodeManagedFields(h.parentEntries) if err != nil { return nil, err } parentFields := decodedParentEntries.Fields() - decodedScaleEntries, err := DecodeManagedFields(scaleEntries) + decodedScaleEntries, err := internal.DecodeManagedFields(scaleEntries) if err != nil { return nil, err } diff --git a/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go b/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go new file mode 100644 index 000000000..d031eefaa --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/managedfields/typeconverter.go @@ -0,0 +1,47 @@ +/* +Copyright 2018 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 managedfields + +import ( + "k8s.io/apimachinery/pkg/util/managedfields/internal" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// TypeConverter allows you to convert from runtime.Object to +// typed.TypedValue and the other way around. +type TypeConverter = internal.TypeConverter + +// NewDeducedTypeConverter creates a TypeConverter for CRDs that don't +// have a schema. It does implement the same interface though (and +// create the same types of objects), so that everything can still work +// the same. CRDs are merged with all their fields being "atomic" (lists +// included). +func NewDeducedTypeConverter() TypeConverter { + return internal.NewDeducedTypeConverter() +} + +// NewTypeConverter builds a TypeConverter from a map of OpenAPIV3 schemas. +// This will automatically find the proper version of the object, and the +// corresponding schema information. +// The keys to the map must be consistent with the names +// used by Refs within the schemas. +// The schemas should conform to the Kubernetes Structural Schema OpenAPI +// restrictions found in docs: +// https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema +func NewTypeConverter(openapiSpec map[string]*spec.Schema, preserveUnknownFields bool) (TypeConverter, error) { + return internal.NewTypeConverter(openapiSpec, preserveUnknownFields) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go b/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go index e39627568..a20efd187 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go +++ b/vendor/k8s.io/apimachinery/pkg/util/mergepatch/util.go @@ -88,8 +88,7 @@ func toYAML(v interface{}) (string, error) { // supports JSON merge patch semantics. // // NOTE: Numbers with different types (e.g. int(0) vs int64(0)) will be detected as conflicts. -// -// Make sure the unmarshaling of left and right are consistent (e.g. use the same library). +// Make sure the unmarshaling of left and right are consistent (e.g. use the same library). func HasConflicts(left, right interface{}) (bool, error) { switch typedLeft := left.(type) { case map[string]interface{}: diff --git a/vendor/k8s.io/apimachinery/pkg/util/sets/set.go b/vendor/k8s.io/apimachinery/pkg/util/sets/set.go index 99c292fed..d50526f42 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/sets/set.go +++ b/vendor/k8s.io/apimachinery/pkg/util/sets/set.go @@ -64,6 +64,20 @@ func (s Set[T]) Delete(items ...T) Set[T] { return s } +// Clear empties the set. +// It is preferable to replace the set with a newly constructed set, +// but not all callers can do that (when there are other references to the map). +// In some cases the set *won't* be fully cleared, e.g. a Set[float32] containing NaN +// can't be cleared because NaN can't be removed. +// For sets containing items of a type that is reflexive for ==, +// this is optimized to a single call to runtime.mapclear(). +func (s Set[T]) Clear() Set[T] { + for key := range s { + delete(s, key) + } + return s +} + // Has returns true if and only if item is contained in the set. func (s Set[T]) Has(item T) bool { _, contained := s[item] diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS index 4443bafd1..73244449f 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS +++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/OWNERS @@ -1,6 +1,7 @@ # See the OWNERS docs at https://go.k8s.io/owners approvers: + - apelisse - pwittrock reviewers: - apelisse diff --git a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go index 6fb369732..3ee683b99 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go +++ b/vendor/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go @@ -1106,7 +1106,7 @@ func applyRetainKeysDirective(original, patch map[string]interface{}, options Me // Then, sort them by the relative order in setElementOrder, patch list and live list. // The precedence is $setElementOrder > order in patch list > order in live list. // This function will delete the item after merging it to prevent process it again in the future. -// Ref: https://git.k8s.io/community/contributors/design-proposals/cli/preserve-order-in-strategic-merge-patch.md +// Ref: https://git.k8s.io/design-proposals-archive/cli/preserve-order-in-strategic-merge-patch.md func mergePatchIntoOriginal(original, patch map[string]interface{}, schema LookupPatchMeta, mergeOptions MergeOptions) error { for key, patchV := range patch { // Do nothing if there is no ordering directive diff --git a/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go b/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go index e767092dd..0b8a6cb35 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go +++ b/vendor/k8s.io/apimachinery/pkg/util/validation/validation.go @@ -191,7 +191,13 @@ func IsDNS1123Label(value string) []string { errs = append(errs, MaxLenError(DNS1123LabelMaxLength)) } if !dns1123LabelRegexp.MatchString(value) { - errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc")) + if dns1123SubdomainRegexp.MatchString(value) { + // It was a valid subdomain and not a valid label. Since we + // already checked length, it must be dots. + errs = append(errs, "must not contain dots") + } else { + errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc")) + } } return errs } diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go b/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go new file mode 100644 index 000000000..418761925 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/backoff.go @@ -0,0 +1,502 @@ +/* +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 wait + +import ( + "context" + "math" + "sync" + "time" + + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/utils/clock" +) + +// Backoff holds parameters applied to a Backoff function. +type Backoff struct { + // The initial duration. + Duration time.Duration + // Duration is multiplied by factor each iteration, if factor is not zero + // and the limits imposed by Steps and Cap have not been reached. + // Should not be negative. + // The jitter does not contribute to the updates to the duration parameter. + Factor float64 + // The sleep at each iteration is the duration plus an additional + // amount chosen uniformly at random from the interval between + // zero and `jitter*duration`. + Jitter float64 + // The remaining number of iterations in which the duration + // parameter may change (but progress can be stopped earlier by + // hitting the cap). If not positive, the duration is not + // changed. Used for exponential backoff in combination with + // Factor and Cap. + Steps int + // A limit on revised values of the duration parameter. If a + // multiplication by the factor parameter would make the duration + // exceed the cap then the duration is set to the cap and the + // steps parameter is set to zero. + Cap time.Duration +} + +// Step returns an amount of time to sleep determined by the original +// Duration and Jitter. The backoff is mutated to update its Steps and +// Duration. A nil Backoff always has a zero-duration step. +func (b *Backoff) Step() time.Duration { + if b == nil { + return 0 + } + var nextDuration time.Duration + nextDuration, b.Duration, b.Steps = delay(b.Steps, b.Duration, b.Cap, b.Factor, b.Jitter) + return nextDuration +} + +// DelayFunc returns a function that will compute the next interval to +// wait given the arguments in b. It does not mutate the original backoff +// but the function is safe to use only from a single goroutine. +func (b Backoff) DelayFunc() DelayFunc { + steps := b.Steps + duration := b.Duration + cap := b.Cap + factor := b.Factor + jitter := b.Jitter + + return func() time.Duration { + var nextDuration time.Duration + // jitter is applied per step and is not cumulative over multiple steps + nextDuration, duration, steps = delay(steps, duration, cap, factor, jitter) + return nextDuration + } +} + +// Timer returns a timer implementation appropriate to this backoff's parameters +// for use with wait functions. +func (b Backoff) Timer() Timer { + if b.Steps > 1 || b.Jitter != 0 { + return &variableTimer{new: internalClock.NewTimer, fn: b.DelayFunc()} + } + if b.Duration > 0 { + return &fixedTimer{new: internalClock.NewTicker, interval: b.Duration} + } + return newNoopTimer() +} + +// delay implements the core delay algorithm used in this package. +func delay(steps int, duration, cap time.Duration, factor, jitter float64) (_ time.Duration, next time.Duration, nextSteps int) { + // when steps is non-positive, do not alter the base duration + if steps < 1 { + if jitter > 0 { + return Jitter(duration, jitter), duration, 0 + } + return duration, duration, 0 + } + steps-- + + // calculate the next step's interval + if factor != 0 { + next = time.Duration(float64(duration) * factor) + if cap > 0 && next > cap { + next = cap + steps = 0 + } + } else { + next = duration + } + + // add jitter for this step + if jitter > 0 { + duration = Jitter(duration, jitter) + } + + return duration, next, steps + +} + +// DelayWithReset returns a DelayFunc that will return the appropriate next interval to +// wait. Every resetInterval the backoff parameters are reset to their initial state. +// This method is safe to invoke from multiple goroutines, but all calls will advance +// the backoff state when Factor is set. If Factor is zero, this method is the same as +// invoking b.DelayFunc() since Steps has no impact without Factor. If resetInterval is +// zero no backoff will be performed as the same calling DelayFunc with a zero factor +// and steps. +func (b Backoff) DelayWithReset(c clock.Clock, resetInterval time.Duration) DelayFunc { + if b.Factor <= 0 { + return b.DelayFunc() + } + if resetInterval <= 0 { + b.Steps = 0 + b.Factor = 0 + return b.DelayFunc() + } + return (&backoffManager{ + backoff: b, + initialBackoff: b, + resetInterval: resetInterval, + + clock: c, + lastStart: c.Now(), + timer: nil, + }).Step +} + +// Until loops until stop channel is closed, running f every period. +// +// Until is syntactic sugar on top of JitterUntil with zero jitter factor and +// with sliding = true (which means the timer for period starts after the f +// completes). +func Until(f func(), period time.Duration, stopCh <-chan struct{}) { + JitterUntil(f, period, 0.0, true, stopCh) +} + +// UntilWithContext loops until context is done, running f every period. +// +// UntilWithContext is syntactic sugar on top of JitterUntilWithContext +// with zero jitter factor and with sliding = true (which means the timer +// for period starts after the f completes). +func UntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { + JitterUntilWithContext(ctx, f, period, 0.0, true) +} + +// NonSlidingUntil loops until stop channel is closed, running f every +// period. +// +// NonSlidingUntil is syntactic sugar on top of JitterUntil with zero jitter +// factor, with sliding = false (meaning the timer for period starts at the same +// time as the function starts). +func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) { + JitterUntil(f, period, 0.0, false, stopCh) +} + +// NonSlidingUntilWithContext loops until context is done, running f every +// period. +// +// NonSlidingUntilWithContext is syntactic sugar on top of JitterUntilWithContext +// with zero jitter factor, with sliding = false (meaning the timer for period +// starts at the same time as the function starts). +func NonSlidingUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { + JitterUntilWithContext(ctx, f, period, 0.0, false) +} + +// JitterUntil loops until stop channel is closed, running f every period. +// +// If jitterFactor is positive, the period is jittered before every run of f. +// If jitterFactor is not positive, the period is unchanged and not jittered. +// +// If sliding is true, the period is computed after f runs. If it is false then +// period includes the runtime for f. +// +// Close stopCh to stop. f may not be invoked if stop channel is already +// closed. Pass NeverStop to if you don't want it stop. +func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) { + BackoffUntil(f, NewJitteredBackoffManager(period, jitterFactor, &clock.RealClock{}), sliding, stopCh) +} + +// BackoffUntil loops until stop channel is closed, run f every duration given by BackoffManager. +// +// If sliding is true, the period is computed after f runs. If it is false then +// period includes the runtime for f. +func BackoffUntil(f func(), backoff BackoffManager, sliding bool, stopCh <-chan struct{}) { + var t clock.Timer + for { + select { + case <-stopCh: + return + default: + } + + if !sliding { + t = backoff.Backoff() + } + + func() { + defer runtime.HandleCrash() + f() + }() + + if sliding { + t = backoff.Backoff() + } + + // NOTE: b/c there is no priority selection in golang + // it is possible for this to race, meaning we could + // trigger t.C and stopCh, and t.C select falls through. + // In order to mitigate we re-check stopCh at the beginning + // of every loop to prevent extra executions of f(). + select { + case <-stopCh: + if !t.Stop() { + <-t.C() + } + return + case <-t.C(): + } + } +} + +// JitterUntilWithContext loops until context is done, running f every period. +// +// If jitterFactor is positive, the period is jittered before every run of f. +// If jitterFactor is not positive, the period is unchanged and not jittered. +// +// If sliding is true, the period is computed after f runs. If it is false then +// period includes the runtime for f. +// +// Cancel context to stop. f may not be invoked if context is already expired. +func JitterUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) { + JitterUntil(func() { f(ctx) }, period, jitterFactor, sliding, ctx.Done()) +} + +// backoffManager provides simple backoff behavior in a threadsafe manner to a caller. +type backoffManager struct { + backoff Backoff + initialBackoff Backoff + resetInterval time.Duration + + clock clock.Clock + + lock sync.Mutex + lastStart time.Time + timer clock.Timer +} + +// Step returns the expected next duration to wait. +func (b *backoffManager) Step() time.Duration { + b.lock.Lock() + defer b.lock.Unlock() + + switch { + case b.resetInterval == 0: + b.backoff = b.initialBackoff + case b.clock.Now().Sub(b.lastStart) > b.resetInterval: + b.backoff = b.initialBackoff + b.lastStart = b.clock.Now() + } + return b.backoff.Step() +} + +// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer +// for exponential backoff. The returned timer must be drained before calling Backoff() the second +// time. +func (b *backoffManager) Backoff() clock.Timer { + b.lock.Lock() + defer b.lock.Unlock() + if b.timer == nil { + b.timer = b.clock.NewTimer(b.Step()) + } else { + b.timer.Reset(b.Step()) + } + return b.timer +} + +// Timer returns a new Timer instance that shares the clock and the reset behavior with all other +// timers. +func (b *backoffManager) Timer() Timer { + return DelayFunc(b.Step).Timer(b.clock) +} + +// BackoffManager manages backoff with a particular scheme based on its underlying implementation. +type BackoffManager interface { + // Backoff returns a shared clock.Timer that is Reset on every invocation. This method is not + // safe for use from multiple threads. It returns a timer for backoff, and caller shall backoff + // until Timer.C() drains. If the second Backoff() is called before the timer from the first + // Backoff() call finishes, the first timer will NOT be drained and result in undetermined + // behavior. + Backoff() clock.Timer +} + +// Deprecated: Will be removed when the legacy polling functions are removed. +type exponentialBackoffManagerImpl struct { + backoff *Backoff + backoffTimer clock.Timer + lastBackoffStart time.Time + initialBackoff time.Duration + backoffResetDuration time.Duration + clock clock.Clock +} + +// NewExponentialBackoffManager returns a manager for managing exponential backoff. Each backoff is jittered and +// backoff will not exceed the given max. If the backoff is not called within resetDuration, the backoff is reset. +// This backoff manager is used to reduce load during upstream unhealthiness. +// +// Deprecated: Will be removed when the legacy Poll methods are removed. Callers should construct a +// Backoff struct, use DelayWithReset() to get a DelayFunc that periodically resets itself, and then +// invoke Timer() when calling wait.BackoffUntil. +// +// Instead of: +// +// bm := wait.NewExponentialBackoffManager(init, max, reset, factor, jitter, clock) +// ... +// wait.BackoffUntil(..., bm.Backoff, ...) +// +// Use: +// +// delayFn := wait.Backoff{ +// Duration: init, +// Cap: max, +// Steps: int(math.Ceil(float64(max) / float64(init))), // now a required argument +// Factor: factor, +// Jitter: jitter, +// }.DelayWithReset(reset, clock) +// wait.BackoffUntil(..., delayFn.Timer(), ...) +func NewExponentialBackoffManager(initBackoff, maxBackoff, resetDuration time.Duration, backoffFactor, jitter float64, c clock.Clock) BackoffManager { + return &exponentialBackoffManagerImpl{ + backoff: &Backoff{ + Duration: initBackoff, + Factor: backoffFactor, + Jitter: jitter, + + // the current impl of wait.Backoff returns Backoff.Duration once steps are used up, which is not + // what we ideally need here, we set it to max int and assume we will never use up the steps + Steps: math.MaxInt32, + Cap: maxBackoff, + }, + backoffTimer: nil, + initialBackoff: initBackoff, + lastBackoffStart: c.Now(), + backoffResetDuration: resetDuration, + clock: c, + } +} + +func (b *exponentialBackoffManagerImpl) getNextBackoff() time.Duration { + if b.clock.Now().Sub(b.lastBackoffStart) > b.backoffResetDuration { + b.backoff.Steps = math.MaxInt32 + b.backoff.Duration = b.initialBackoff + } + b.lastBackoffStart = b.clock.Now() + return b.backoff.Step() +} + +// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for exponential backoff. +// The returned timer must be drained before calling Backoff() the second time +func (b *exponentialBackoffManagerImpl) Backoff() clock.Timer { + if b.backoffTimer == nil { + b.backoffTimer = b.clock.NewTimer(b.getNextBackoff()) + } else { + b.backoffTimer.Reset(b.getNextBackoff()) + } + return b.backoffTimer +} + +// Deprecated: Will be removed when the legacy polling functions are removed. +type jitteredBackoffManagerImpl struct { + clock clock.Clock + duration time.Duration + jitter float64 + backoffTimer clock.Timer +} + +// NewJitteredBackoffManager returns a BackoffManager that backoffs with given duration plus given jitter. If the jitter +// is negative, backoff will not be jittered. +// +// Deprecated: Will be removed when the legacy Poll methods are removed. Callers should construct a +// Backoff struct and invoke Timer() when calling wait.BackoffUntil. +// +// Instead of: +// +// bm := wait.NewJitteredBackoffManager(duration, jitter, clock) +// ... +// wait.BackoffUntil(..., bm.Backoff, ...) +// +// Use: +// +// wait.BackoffUntil(..., wait.Backoff{Duration: duration, Jitter: jitter}.Timer(), ...) +func NewJitteredBackoffManager(duration time.Duration, jitter float64, c clock.Clock) BackoffManager { + return &jitteredBackoffManagerImpl{ + clock: c, + duration: duration, + jitter: jitter, + backoffTimer: nil, + } +} + +func (j *jitteredBackoffManagerImpl) getNextBackoff() time.Duration { + jitteredPeriod := j.duration + if j.jitter > 0.0 { + jitteredPeriod = Jitter(j.duration, j.jitter) + } + return jitteredPeriod +} + +// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for jittered backoff. +// The returned timer must be drained before calling Backoff() the second time +func (j *jitteredBackoffManagerImpl) Backoff() clock.Timer { + backoff := j.getNextBackoff() + if j.backoffTimer == nil { + j.backoffTimer = j.clock.NewTimer(backoff) + } else { + j.backoffTimer.Reset(backoff) + } + return j.backoffTimer +} + +// ExponentialBackoff repeats a condition check with exponential backoff. +// +// It repeatedly checks the condition and then sleeps, using `backoff.Step()` +// to determine the length of the sleep and adjust Duration and Steps. +// Stops and returns as soon as: +// 1. the condition check returns true or an error, +// 2. `backoff.Steps` checks of the condition have been done, or +// 3. a sleep truncated by the cap on duration has been completed. +// In case (1) the returned error is what the condition function returned. +// In all other cases, ErrWaitTimeout is returned. +// +// Since backoffs are often subject to cancellation, we recommend using +// ExponentialBackoffWithContext and passing a context to the method. +func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error { + for backoff.Steps > 0 { + if ok, err := runConditionWithCrashProtection(condition); err != nil || ok { + return err + } + if backoff.Steps == 1 { + break + } + time.Sleep(backoff.Step()) + } + return ErrWaitTimeout +} + +// ExponentialBackoffWithContext repeats a condition check with exponential backoff. +// It immediately returns an error if the condition returns an error, the context is cancelled +// or hits the deadline, or if the maximum attempts defined in backoff is exceeded (ErrWaitTimeout). +// If an error is returned by the condition the backoff stops immediately. The condition will +// never be invoked more than backoff.Steps times. +func ExponentialBackoffWithContext(ctx context.Context, backoff Backoff, condition ConditionWithContextFunc) error { + for backoff.Steps > 0 { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + if ok, err := runConditionWithCrashProtectionWithContext(ctx, condition); err != nil || ok { + return err + } + + if backoff.Steps == 1 { + break + } + + waitBeforeRetry := backoff.Step() + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(waitBeforeRetry): + } + } + + return ErrWaitTimeout +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go b/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go new file mode 100644 index 000000000..1d3dcaa74 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/delay.go @@ -0,0 +1,51 @@ +/* +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 wait + +import ( + "context" + "sync" + "time" + + "k8s.io/utils/clock" +) + +// DelayFunc returns the next time interval to wait. +type DelayFunc func() time.Duration + +// Timer takes an arbitrary delay function and returns a timer that can handle arbitrary interval changes. +// Use Backoff{...}.Timer() for simple delays and more efficient timers. +func (fn DelayFunc) Timer(c clock.Clock) Timer { + return &variableTimer{fn: fn, new: c.NewTimer} +} + +// Until takes an arbitrary delay function and runs until cancelled or the condition indicates exit. This +// offers all of the functionality of the methods in this package. +func (fn DelayFunc) Until(ctx context.Context, immediate, sliding bool, condition ConditionWithContextFunc) error { + return loopConditionUntilContext(ctx, &variableTimer{fn: fn, new: internalClock.NewTimer}, immediate, sliding, condition) +} + +// Concurrent returns a version of this DelayFunc that is safe for use by multiple goroutines that +// wish to share a single delay timer. +func (fn DelayFunc) Concurrent() DelayFunc { + var lock sync.Mutex + return func() time.Duration { + lock.Lock() + defer lock.Unlock() + return fn() + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/error.go b/vendor/k8s.io/apimachinery/pkg/util/wait/error.go new file mode 100644 index 000000000..dd75801d8 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/error.go @@ -0,0 +1,96 @@ +/* +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 wait + +import ( + "context" + "errors" +) + +// ErrWaitTimeout is returned when the condition was not satisfied in time. +// +// Deprecated: This type will be made private in favor of Interrupted() +// for checking errors or ErrorInterrupted(err) for returning a wrapped error. +var ErrWaitTimeout = ErrorInterrupted(errors.New("timed out waiting for the condition")) + +// Interrupted returns true if the error indicates a Poll, ExponentialBackoff, or +// Until loop exited for any reason besides the condition returning true or an +// error. A loop is considered interrupted if the calling context is cancelled, +// the context reaches its deadline, or a backoff reaches its maximum allowed +// steps. +// +// Callers should use this method instead of comparing the error value directly to +// ErrWaitTimeout, as methods that cancel a context may not return that error. +// +// Instead of: +// +// err := wait.Poll(...) +// if err == wait.ErrWaitTimeout { +// log.Infof("Wait for operation exceeded") +// } else ... +// +// Use: +// +// err := wait.Poll(...) +// if wait.Interrupted(err) { +// log.Infof("Wait for operation exceeded") +// } else ... +func Interrupted(err error) bool { + switch { + case errors.Is(err, errWaitTimeout), + errors.Is(err, context.Canceled), + errors.Is(err, context.DeadlineExceeded): + return true + default: + return false + } +} + +// errInterrupted +type errInterrupted struct { + cause error +} + +// ErrorInterrupted returns an error that indicates the wait was ended +// early for a given reason. If no cause is provided a generic error +// will be used but callers are encouraged to provide a real cause for +// clarity in debugging. +func ErrorInterrupted(cause error) error { + switch cause.(type) { + case errInterrupted: + // no need to wrap twice since errInterrupted is only needed + // once in a chain + return cause + default: + return errInterrupted{cause} + } +} + +// errWaitTimeout is the private version of the previous ErrWaitTimeout +// and is private to prevent direct comparison. Use ErrorInterrupted(err) +// to get an error that will return true for Interrupted(err). +var errWaitTimeout = errInterrupted{} + +func (e errInterrupted) Unwrap() error { return e.cause } +func (e errInterrupted) Is(target error) bool { return target == errWaitTimeout } +func (e errInterrupted) Error() string { + if e.cause == nil { + // returns the same error message as historical behavior + return "timed out waiting for the condition" + } + return e.cause.Error() +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go b/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go new file mode 100644 index 000000000..51864d70f --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/loop.go @@ -0,0 +1,86 @@ +/* +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 wait + +import ( + "context" + "time" + + "k8s.io/apimachinery/pkg/util/runtime" +) + +// loopConditionUntilContext executes the provided condition at intervals defined by +// the provided timer until the provided context is cancelled, the condition returns +// true, or the condition returns an error. If sliding is true, the period is computed +// after condition runs. If it is false then period includes the runtime for condition. +// If immediate is false the first delay happens before any call to condition. The +// returned error is the error returned by the last condition or the context error if +// the context was terminated. +// +// This is the common loop construct for all polling in the wait package. +func loopConditionUntilContext(ctx context.Context, t Timer, immediate, sliding bool, condition ConditionWithContextFunc) error { + defer t.Stop() + + var timeCh <-chan time.Time + doneCh := ctx.Done() + + // if we haven't requested immediate execution, delay once + if !immediate { + timeCh = t.C() + select { + case <-doneCh: + return ctx.Err() + case <-timeCh: + } + } + + for { + // checking ctx.Err() is slightly faster than checking a select + if err := ctx.Err(); err != nil { + return err + } + + if !sliding { + t.Next() + } + if ok, err := func() (bool, error) { + defer runtime.HandleCrash() + return condition(ctx) + }(); err != nil || ok { + return err + } + if sliding { + t.Next() + } + + if timeCh == nil { + timeCh = t.C() + } + + // NOTE: b/c there is no priority selection in golang + // it is possible for this to race, meaning we could + // trigger t.C and doneCh, and t.C select falls through. + // In order to mitigate we re-check doneCh at the beginning + // of every loop to guarantee at-most one extra execution + // of condition. + select { + case <-doneCh: + return ctx.Err() + case <-timeCh: + } + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go b/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go new file mode 100644 index 000000000..32e8688ca --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/poll.go @@ -0,0 +1,315 @@ +/* +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 wait + +import ( + "context" + "time" +) + +// PollUntilContextCancel tries a condition func until it returns true, an error, or the context +// is cancelled or hits a deadline. condition will be invoked after the first interval if the +// context is not cancelled first. The returned error will be from ctx.Err(), the condition's +// err return value, or nil. If invoking condition takes longer than interval the next condition +// will be invoked immediately. When using very short intervals, condition may be invoked multiple +// times before a context cancellation is detected. If immediate is true, condition will be +// invoked before waiting and guarantees that condition is invoked at least once, regardless of +// whether the context has been cancelled. +func PollUntilContextCancel(ctx context.Context, interval time.Duration, immediate bool, condition ConditionWithContextFunc) error { + return loopConditionUntilContext(ctx, Backoff{Duration: interval}.Timer(), immediate, false, condition) +} + +// PollUntilContextTimeout will terminate polling after timeout duration by setting a context +// timeout. This is provided as a convenience function for callers not currently executing under +// a deadline and is equivalent to: +// +// deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout) +// err := PollUntilContextCancel(ctx, interval, immediate, condition) +// +// The deadline context will be cancelled if the Poll succeeds before the timeout, simplifying +// inline usage. All other behavior is identical to PollWithContextTimeout. +func PollUntilContextTimeout(ctx context.Context, interval, timeout time.Duration, immediate bool, condition ConditionWithContextFunc) error { + deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout) + defer deadlineCancel() + return loopConditionUntilContext(deadlineCtx, Backoff{Duration: interval}.Timer(), immediate, false, condition) +} + +// Poll tries a condition func until it returns true, an error, or the timeout +// is reached. +// +// Poll always waits the interval before the run of 'condition'. +// 'condition' will always be invoked at least once. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// If you want to Poll something forever, see PollInfinite. +// +// Deprecated: This method does not return errors from context, use PollWithContextTimeout. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func Poll(interval, timeout time.Duration, condition ConditionFunc) error { + return PollWithContext(context.Background(), interval, timeout, condition.WithContext()) +} + +// PollWithContext tries a condition func until it returns true, an error, +// or when the context expires or the timeout is reached, whichever +// happens first. +// +// PollWithContext always waits the interval before the run of 'condition'. +// 'condition' will always be invoked at least once. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// If you want to Poll something forever, see PollInfinite. +// +// Deprecated: This method does not return errors from context, use PollWithContextTimeout. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, false, poller(interval, timeout), condition) +} + +// PollUntil tries a condition func until it returns true, an error or stopCh is +// closed. +// +// PollUntil always waits interval before the first run of 'condition'. +// 'condition' will always be invoked at least once. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error { + return PollUntilWithContext(ContextForChannel(stopCh), interval, condition.WithContext()) +} + +// PollUntilWithContext tries a condition func until it returns true, +// an error or the specified context is cancelled or expired. +// +// PollUntilWithContext always waits interval before the first run of 'condition'. +// 'condition' will always be invoked at least once. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, false, poller(interval, 0), condition) +} + +// PollInfinite tries a condition func until it returns true or an error +// +// PollInfinite always waits the interval before the run of 'condition'. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollInfinite(interval time.Duration, condition ConditionFunc) error { + return PollInfiniteWithContext(context.Background(), interval, condition.WithContext()) +} + +// PollInfiniteWithContext tries a condition func until it returns true or an error +// +// PollInfiniteWithContext always waits the interval before the run of 'condition'. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, false, poller(interval, 0), condition) +} + +// PollImmediate tries a condition func until it returns true, an error, or the timeout +// is reached. +// +// PollImmediate always checks 'condition' before waiting for the interval. 'condition' +// will always be invoked at least once. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// If you want to immediately Poll something forever, see PollImmediateInfinite. +// +// Deprecated: This method does not return errors from context, use PollWithContextTimeout. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error { + return PollImmediateWithContext(context.Background(), interval, timeout, condition.WithContext()) +} + +// PollImmediateWithContext tries a condition func until it returns true, an error, +// or the timeout is reached or the specified context expires, whichever happens first. +// +// PollImmediateWithContext always checks 'condition' before waiting for the interval. +// 'condition' will always be invoked at least once. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// If you want to immediately Poll something forever, see PollImmediateInfinite. +// +// Deprecated: This method does not return errors from context, use PollWithContextTimeout. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, true, poller(interval, timeout), condition) +} + +// PollImmediateUntil tries a condition func until it returns true, an error or stopCh is closed. +// +// PollImmediateUntil runs the 'condition' before waiting for the interval. +// 'condition' will always be invoked at least once. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error { + return PollImmediateUntilWithContext(ContextForChannel(stopCh), interval, condition.WithContext()) +} + +// PollImmediateUntilWithContext tries a condition func until it returns true, +// an error or the specified context is cancelled or expired. +// +// PollImmediateUntilWithContext runs the 'condition' before waiting for the interval. +// 'condition' will always be invoked at least once. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, true, poller(interval, 0), condition) +} + +// PollImmediateInfinite tries a condition func until it returns true or an error +// +// PollImmediateInfinite runs the 'condition' before waiting for the interval. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) error { + return PollImmediateInfiniteWithContext(context.Background(), interval, condition.WithContext()) +} + +// PollImmediateInfiniteWithContext tries a condition func until it returns true +// or an error or the specified context gets cancelled or expired. +// +// PollImmediateInfiniteWithContext runs the 'condition' before waiting for the interval. +// +// Some intervals may be missed if the condition takes too long or the time +// window is too short. +// +// Deprecated: This method does not return errors from context, use PollWithContextCancel. +// Note that the new method will no longer return ErrWaitTimeout and instead return errors +// defined by the context package. Will be removed in a future release. +func PollImmediateInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { + return poll(ctx, true, poller(interval, 0), condition) +} + +// Internally used, each of the public 'Poll*' function defined in this +// package should invoke this internal function with appropriate parameters. +// ctx: the context specified by the caller, for infinite polling pass +// a context that never gets cancelled or expired. +// immediate: if true, the 'condition' will be invoked before waiting for the interval, +// in this case 'condition' will always be invoked at least once. +// wait: user specified WaitFunc function that controls at what interval the condition +// function should be invoked periodically and whether it is bound by a timeout. +// condition: user specified ConditionWithContextFunc function. +// +// Deprecated: will be removed in favor of loopConditionUntilContext. +func poll(ctx context.Context, immediate bool, wait waitWithContextFunc, condition ConditionWithContextFunc) error { + if immediate { + done, err := runConditionWithCrashProtectionWithContext(ctx, condition) + if err != nil { + return err + } + if done { + return nil + } + } + + select { + case <-ctx.Done(): + // returning ctx.Err() will break backward compatibility, use new PollUntilContext* + // methods instead + return ErrWaitTimeout + default: + return waitForWithContext(ctx, wait, condition) + } +} + +// poller returns a WaitFunc that will send to the channel every interval until +// timeout has elapsed and then closes the channel. +// +// Over very short intervals you may receive no ticks before the channel is +// closed. A timeout of 0 is interpreted as an infinity, and in such a case +// it would be the caller's responsibility to close the done channel. +// Failure to do so would result in a leaked goroutine. +// +// Output ticks are not buffered. If the channel is not ready to receive an +// item, the tick is skipped. +// +// Deprecated: Will be removed in a future release. +func poller(interval, timeout time.Duration) waitWithContextFunc { + return waitWithContextFunc(func(ctx context.Context) <-chan struct{} { + ch := make(chan struct{}) + + go func() { + defer close(ch) + + tick := time.NewTicker(interval) + defer tick.Stop() + + var after <-chan time.Time + if timeout != 0 { + // time.After is more convenient, but it + // potentially leaves timers around much longer + // than necessary if we exit early. + timer := time.NewTimer(timeout) + after = timer.C + defer timer.Stop() + } + + for { + select { + case <-tick.C: + // If the consumer isn't ready for this signal drop it and + // check the other channels. + select { + case ch <- struct{}{}: + default: + } + case <-after: + return + case <-ctx.Done(): + return + } + } + }() + + return ch + }) +} diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go b/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go new file mode 100644 index 000000000..3efba3213 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/timer.go @@ -0,0 +1,121 @@ +/* +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 wait + +import ( + "time" + + "k8s.io/utils/clock" +) + +// Timer abstracts how wait functions interact with time runtime efficiently. Test +// code may implement this interface directly but package consumers are encouraged +// to use the Backoff type as the primary mechanism for acquiring a Timer. The +// interface is a simplification of clock.Timer to prevent misuse. Timers are not +// expected to be safe for calls from multiple goroutines. +type Timer interface { + // C returns a channel that will receive a struct{} each time the timer fires. + // The channel should not be waited on after Stop() is invoked. It is allowed + // to cache the returned value of C() for the lifetime of the Timer. + C() <-chan time.Time + // Next is invoked by wait functions to signal timers that the next interval + // should begin. You may only use Next() if you have drained the channel C(). + // You should not call Next() after Stop() is invoked. + Next() + // Stop releases the timer. It is safe to invoke if no other methods have been + // called. + Stop() +} + +type noopTimer struct { + closedCh <-chan time.Time +} + +// newNoopTimer creates a timer with a unique channel to avoid contention +// for the channel's lock across multiple unrelated timers. +func newNoopTimer() noopTimer { + ch := make(chan time.Time) + close(ch) + return noopTimer{closedCh: ch} +} + +func (t noopTimer) C() <-chan time.Time { + return t.closedCh +} +func (noopTimer) Next() {} +func (noopTimer) Stop() {} + +type variableTimer struct { + fn DelayFunc + t clock.Timer + new func(time.Duration) clock.Timer +} + +func (t *variableTimer) C() <-chan time.Time { + if t.t == nil { + d := t.fn() + t.t = t.new(d) + } + return t.t.C() +} +func (t *variableTimer) Next() { + if t.t == nil { + return + } + d := t.fn() + t.t.Reset(d) +} +func (t *variableTimer) Stop() { + if t.t == nil { + return + } + t.t.Stop() + t.t = nil +} + +type fixedTimer struct { + interval time.Duration + t clock.Ticker + new func(time.Duration) clock.Ticker +} + +func (t *fixedTimer) C() <-chan time.Time { + if t.t == nil { + t.t = t.new(t.interval) + } + return t.t.C() +} +func (t *fixedTimer) Next() { + // no-op for fixed timers +} +func (t *fixedTimer) Stop() { + if t.t == nil { + return + } + t.t.Stop() + t.t = nil +} + +var ( + // RealTimer can be passed to methods that need a clock.Timer. + RealTimer = clock.RealClock{}.NewTimer +) + +var ( + // internalClock is used for test injection of clocks + internalClock = clock.RealClock{} +) diff --git a/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go b/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go index 137627b40..6805e8cf9 100644 --- a/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go +++ b/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go @@ -18,14 +18,11 @@ package wait import ( "context" - "errors" - "math" "math/rand" "sync" "time" "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/utils/clock" ) // For any test of the style: @@ -83,113 +80,6 @@ func Forever(f func(), period time.Duration) { Until(f, period, NeverStop) } -// Until loops until stop channel is closed, running f every period. -// -// Until is syntactic sugar on top of JitterUntil with zero jitter factor and -// with sliding = true (which means the timer for period starts after the f -// completes). -func Until(f func(), period time.Duration, stopCh <-chan struct{}) { - JitterUntil(f, period, 0.0, true, stopCh) -} - -// UntilWithContext loops until context is done, running f every period. -// -// UntilWithContext is syntactic sugar on top of JitterUntilWithContext -// with zero jitter factor and with sliding = true (which means the timer -// for period starts after the f completes). -func UntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { - JitterUntilWithContext(ctx, f, period, 0.0, true) -} - -// NonSlidingUntil loops until stop channel is closed, running f every -// period. -// -// NonSlidingUntil is syntactic sugar on top of JitterUntil with zero jitter -// factor, with sliding = false (meaning the timer for period starts at the same -// time as the function starts). -func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) { - JitterUntil(f, period, 0.0, false, stopCh) -} - -// NonSlidingUntilWithContext loops until context is done, running f every -// period. -// -// NonSlidingUntilWithContext is syntactic sugar on top of JitterUntilWithContext -// with zero jitter factor, with sliding = false (meaning the timer for period -// starts at the same time as the function starts). -func NonSlidingUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) { - JitterUntilWithContext(ctx, f, period, 0.0, false) -} - -// JitterUntil loops until stop channel is closed, running f every period. -// -// If jitterFactor is positive, the period is jittered before every run of f. -// If jitterFactor is not positive, the period is unchanged and not jittered. -// -// If sliding is true, the period is computed after f runs. If it is false then -// period includes the runtime for f. -// -// Close stopCh to stop. f may not be invoked if stop channel is already -// closed. Pass NeverStop to if you don't want it stop. -func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) { - BackoffUntil(f, NewJitteredBackoffManager(period, jitterFactor, &clock.RealClock{}), sliding, stopCh) -} - -// BackoffUntil loops until stop channel is closed, run f every duration given by BackoffManager. -// -// If sliding is true, the period is computed after f runs. If it is false then -// period includes the runtime for f. -func BackoffUntil(f func(), backoff BackoffManager, sliding bool, stopCh <-chan struct{}) { - var t clock.Timer - for { - select { - case <-stopCh: - return - default: - } - - if !sliding { - t = backoff.Backoff() - } - - func() { - defer runtime.HandleCrash() - f() - }() - - if sliding { - t = backoff.Backoff() - } - - // NOTE: b/c there is no priority selection in golang - // it is possible for this to race, meaning we could - // trigger t.C and stopCh, and t.C select falls through. - // In order to mitigate we re-check stopCh at the beginning - // of every loop to prevent extra executions of f(). - select { - case <-stopCh: - if !t.Stop() { - <-t.C() - } - return - case <-t.C(): - } - } -} - -// JitterUntilWithContext loops until context is done, running f every period. -// -// If jitterFactor is positive, the period is jittered before every run of f. -// If jitterFactor is not positive, the period is unchanged and not jittered. -// -// If sliding is true, the period is computed after f runs. If it is false then -// period includes the runtime for f. -// -// Cancel context to stop. f may not be invoked if context is already expired. -func JitterUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) { - JitterUntil(func() { f(ctx) }, period, jitterFactor, sliding, ctx.Done()) -} - // Jitter returns a time.Duration between duration and duration + maxFactor * // duration. // @@ -203,9 +93,6 @@ func Jitter(duration time.Duration, maxFactor float64) time.Duration { return wait } -// ErrWaitTimeout is returned when the condition exited without success. -var ErrWaitTimeout = errors.New("timed out waiting for the condition") - // ConditionFunc returns true if the condition is satisfied, or an error // if the loop should be aborted. type ConditionFunc func() (done bool, err error) @@ -223,425 +110,80 @@ func (cf ConditionFunc) WithContext() ConditionWithContextFunc { } } -// runConditionWithCrashProtection runs a ConditionFunc with crash protection -func runConditionWithCrashProtection(condition ConditionFunc) (bool, error) { - return runConditionWithCrashProtectionWithContext(context.TODO(), condition.WithContext()) +// ContextForChannel provides a context that will be treated as cancelled +// when the provided parentCh is closed. The implementation returns +// context.Canceled for Err() if and only if the parentCh is closed. +func ContextForChannel(parentCh <-chan struct{}) context.Context { + return channelContext{stopCh: parentCh} } -// runConditionWithCrashProtectionWithContext runs a -// ConditionWithContextFunc with crash protection. +var _ context.Context = channelContext{} + +// channelContext will behave as if the context were cancelled when stopCh is +// closed. +type channelContext struct { + stopCh <-chan struct{} +} + +func (c channelContext) Done() <-chan struct{} { return c.stopCh } +func (c channelContext) Err() error { + select { + case <-c.stopCh: + return context.Canceled + default: + return nil + } +} +func (c channelContext) Deadline() (time.Time, bool) { return time.Time{}, false } +func (c channelContext) Value(key any) any { return nil } + +// runConditionWithCrashProtection runs a ConditionFunc with crash protection. +// +// Deprecated: Will be removed when the legacy polling methods are removed. +func runConditionWithCrashProtection(condition ConditionFunc) (bool, error) { + defer runtime.HandleCrash() + return condition() +} + +// runConditionWithCrashProtectionWithContext runs a ConditionWithContextFunc +// with crash protection. +// +// Deprecated: Will be removed when the legacy polling methods are removed. func runConditionWithCrashProtectionWithContext(ctx context.Context, condition ConditionWithContextFunc) (bool, error) { defer runtime.HandleCrash() return condition(ctx) } -// Backoff holds parameters applied to a Backoff function. -type Backoff struct { - // The initial duration. - Duration time.Duration - // Duration is multiplied by factor each iteration, if factor is not zero - // and the limits imposed by Steps and Cap have not been reached. - // Should not be negative. - // The jitter does not contribute to the updates to the duration parameter. - Factor float64 - // The sleep at each iteration is the duration plus an additional - // amount chosen uniformly at random from the interval between - // zero and `jitter*duration`. - Jitter float64 - // The remaining number of iterations in which the duration - // parameter may change (but progress can be stopped earlier by - // hitting the cap). If not positive, the duration is not - // changed. Used for exponential backoff in combination with - // Factor and Cap. - Steps int - // A limit on revised values of the duration parameter. If a - // multiplication by the factor parameter would make the duration - // exceed the cap then the duration is set to the cap and the - // steps parameter is set to zero. - Cap time.Duration -} - -// Step (1) returns an amount of time to sleep determined by the -// original Duration and Jitter and (2) mutates the provided Backoff -// to update its Steps and Duration. -func (b *Backoff) Step() time.Duration { - if b.Steps < 1 { - if b.Jitter > 0 { - return Jitter(b.Duration, b.Jitter) - } - return b.Duration - } - b.Steps-- - - duration := b.Duration - - // calculate the next step - if b.Factor != 0 { - b.Duration = time.Duration(float64(b.Duration) * b.Factor) - if b.Cap > 0 && b.Duration > b.Cap { - b.Duration = b.Cap - b.Steps = 0 - } - } - - if b.Jitter > 0 { - duration = Jitter(duration, b.Jitter) - } - return duration -} - -// ContextForChannel derives a child context from a parent channel. -// -// The derived context's Done channel is closed when the returned cancel function -// is called or when the parent channel is closed, whichever happens first. -// -// Note the caller must *always* call the CancelFunc, otherwise resources may be leaked. -func ContextForChannel(parentCh <-chan struct{}) (context.Context, context.CancelFunc) { - ctx, cancel := context.WithCancel(context.Background()) - - go func() { - select { - case <-parentCh: - cancel() - case <-ctx.Done(): - } - }() - return ctx, cancel -} - -// BackoffManager manages backoff with a particular scheme based on its underlying implementation. It provides -// an interface to return a timer for backoff, and caller shall backoff until Timer.C() drains. If the second Backoff() -// is called before the timer from the first Backoff() call finishes, the first timer will NOT be drained and result in -// undetermined behavior. -// The BackoffManager is supposed to be called in a single-threaded environment. -type BackoffManager interface { - Backoff() clock.Timer -} - -type exponentialBackoffManagerImpl struct { - backoff *Backoff - backoffTimer clock.Timer - lastBackoffStart time.Time - initialBackoff time.Duration - backoffResetDuration time.Duration - clock clock.Clock -} - -// NewExponentialBackoffManager returns a manager for managing exponential backoff. Each backoff is jittered and -// backoff will not exceed the given max. If the backoff is not called within resetDuration, the backoff is reset. -// This backoff manager is used to reduce load during upstream unhealthiness. -func NewExponentialBackoffManager(initBackoff, maxBackoff, resetDuration time.Duration, backoffFactor, jitter float64, c clock.Clock) BackoffManager { - return &exponentialBackoffManagerImpl{ - backoff: &Backoff{ - Duration: initBackoff, - Factor: backoffFactor, - Jitter: jitter, - - // the current impl of wait.Backoff returns Backoff.Duration once steps are used up, which is not - // what we ideally need here, we set it to max int and assume we will never use up the steps - Steps: math.MaxInt32, - Cap: maxBackoff, - }, - backoffTimer: nil, - initialBackoff: initBackoff, - lastBackoffStart: c.Now(), - backoffResetDuration: resetDuration, - clock: c, - } -} - -func (b *exponentialBackoffManagerImpl) getNextBackoff() time.Duration { - if b.clock.Now().Sub(b.lastBackoffStart) > b.backoffResetDuration { - b.backoff.Steps = math.MaxInt32 - b.backoff.Duration = b.initialBackoff - } - b.lastBackoffStart = b.clock.Now() - return b.backoff.Step() -} - -// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for exponential backoff. -// The returned timer must be drained before calling Backoff() the second time -func (b *exponentialBackoffManagerImpl) Backoff() clock.Timer { - if b.backoffTimer == nil { - b.backoffTimer = b.clock.NewTimer(b.getNextBackoff()) - } else { - b.backoffTimer.Reset(b.getNextBackoff()) - } - return b.backoffTimer -} - -type jitteredBackoffManagerImpl struct { - clock clock.Clock - duration time.Duration - jitter float64 - backoffTimer clock.Timer -} - -// NewJitteredBackoffManager returns a BackoffManager that backoffs with given duration plus given jitter. If the jitter -// is negative, backoff will not be jittered. -func NewJitteredBackoffManager(duration time.Duration, jitter float64, c clock.Clock) BackoffManager { - return &jitteredBackoffManagerImpl{ - clock: c, - duration: duration, - jitter: jitter, - backoffTimer: nil, - } -} - -func (j *jitteredBackoffManagerImpl) getNextBackoff() time.Duration { - jitteredPeriod := j.duration - if j.jitter > 0.0 { - jitteredPeriod = Jitter(j.duration, j.jitter) - } - return jitteredPeriod -} - -// Backoff implements BackoffManager.Backoff, it returns a timer so caller can block on the timer for jittered backoff. -// The returned timer must be drained before calling Backoff() the second time -func (j *jitteredBackoffManagerImpl) Backoff() clock.Timer { - backoff := j.getNextBackoff() - if j.backoffTimer == nil { - j.backoffTimer = j.clock.NewTimer(backoff) - } else { - j.backoffTimer.Reset(backoff) - } - return j.backoffTimer -} - -// ExponentialBackoff repeats a condition check with exponential backoff. -// -// It repeatedly checks the condition and then sleeps, using `backoff.Step()` -// to determine the length of the sleep and adjust Duration and Steps. -// Stops and returns as soon as: -// 1. the condition check returns true or an error, -// 2. `backoff.Steps` checks of the condition have been done, or -// 3. a sleep truncated by the cap on duration has been completed. -// In case (1) the returned error is what the condition function returned. -// In all other cases, ErrWaitTimeout is returned. -func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error { - for backoff.Steps > 0 { - if ok, err := runConditionWithCrashProtection(condition); err != nil || ok { - return err - } - if backoff.Steps == 1 { - break - } - time.Sleep(backoff.Step()) - } - return ErrWaitTimeout -} - -// Poll tries a condition func until it returns true, an error, or the timeout -// is reached. -// -// Poll always waits the interval before the run of 'condition'. -// 'condition' will always be invoked at least once. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -// -// If you want to Poll something forever, see PollInfinite. -func Poll(interval, timeout time.Duration, condition ConditionFunc) error { - return PollWithContext(context.Background(), interval, timeout, condition.WithContext()) -} - -// PollWithContext tries a condition func until it returns true, an error, -// or when the context expires or the timeout is reached, whichever -// happens first. -// -// PollWithContext always waits the interval before the run of 'condition'. -// 'condition' will always be invoked at least once. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -// -// If you want to Poll something forever, see PollInfinite. -func PollWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, false, poller(interval, timeout), condition) -} - -// PollUntil tries a condition func until it returns true, an error or stopCh is -// closed. -// -// PollUntil always waits interval before the first run of 'condition'. -// 'condition' will always be invoked at least once. -func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error { - ctx, cancel := ContextForChannel(stopCh) - defer cancel() - return PollUntilWithContext(ctx, interval, condition.WithContext()) -} - -// PollUntilWithContext tries a condition func until it returns true, -// an error or the specified context is cancelled or expired. -// -// PollUntilWithContext always waits interval before the first run of 'condition'. -// 'condition' will always be invoked at least once. -func PollUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, false, poller(interval, 0), condition) -} - -// PollInfinite tries a condition func until it returns true or an error -// -// PollInfinite always waits the interval before the run of 'condition'. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -func PollInfinite(interval time.Duration, condition ConditionFunc) error { - return PollInfiniteWithContext(context.Background(), interval, condition.WithContext()) -} - -// PollInfiniteWithContext tries a condition func until it returns true or an error -// -// PollInfiniteWithContext always waits the interval before the run of 'condition'. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -func PollInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, false, poller(interval, 0), condition) -} - -// PollImmediate tries a condition func until it returns true, an error, or the timeout -// is reached. -// -// PollImmediate always checks 'condition' before waiting for the interval. 'condition' -// will always be invoked at least once. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -// -// If you want to immediately Poll something forever, see PollImmediateInfinite. -func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error { - return PollImmediateWithContext(context.Background(), interval, timeout, condition.WithContext()) -} - -// PollImmediateWithContext tries a condition func until it returns true, an error, -// or the timeout is reached or the specified context expires, whichever happens first. -// -// PollImmediateWithContext always checks 'condition' before waiting for the interval. -// 'condition' will always be invoked at least once. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -// -// If you want to immediately Poll something forever, see PollImmediateInfinite. -func PollImmediateWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, true, poller(interval, timeout), condition) -} - -// PollImmediateUntil tries a condition func until it returns true, an error or stopCh is closed. -// -// PollImmediateUntil runs the 'condition' before waiting for the interval. -// 'condition' will always be invoked at least once. -func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error { - ctx, cancel := ContextForChannel(stopCh) - defer cancel() - return PollImmediateUntilWithContext(ctx, interval, condition.WithContext()) -} - -// PollImmediateUntilWithContext tries a condition func until it returns true, -// an error or the specified context is cancelled or expired. -// -// PollImmediateUntilWithContext runs the 'condition' before waiting for the interval. -// 'condition' will always be invoked at least once. -func PollImmediateUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, true, poller(interval, 0), condition) -} - -// PollImmediateInfinite tries a condition func until it returns true or an error -// -// PollImmediateInfinite runs the 'condition' before waiting for the interval. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) error { - return PollImmediateInfiniteWithContext(context.Background(), interval, condition.WithContext()) -} - -// PollImmediateInfiniteWithContext tries a condition func until it returns true -// or an error or the specified context gets cancelled or expired. -// -// PollImmediateInfiniteWithContext runs the 'condition' before waiting for the interval. -// -// Some intervals may be missed if the condition takes too long or the time -// window is too short. -func PollImmediateInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error { - return poll(ctx, true, poller(interval, 0), condition) -} - -// Internally used, each of the public 'Poll*' function defined in this -// package should invoke this internal function with appropriate parameters. -// ctx: the context specified by the caller, for infinite polling pass -// a context that never gets cancelled or expired. -// immediate: if true, the 'condition' will be invoked before waiting for the interval, -// in this case 'condition' will always be invoked at least once. -// wait: user specified WaitFunc function that controls at what interval the condition -// function should be invoked periodically and whether it is bound by a timeout. -// condition: user specified ConditionWithContextFunc function. -func poll(ctx context.Context, immediate bool, wait WaitWithContextFunc, condition ConditionWithContextFunc) error { - if immediate { - done, err := runConditionWithCrashProtectionWithContext(ctx, condition) - if err != nil { - return err - } - if done { - return nil - } - } - - select { - case <-ctx.Done(): - // returning ctx.Err() will break backward compatibility - return ErrWaitTimeout - default: - return WaitForWithContext(ctx, wait, condition) - } -} - -// WaitFunc creates a channel that receives an item every time a test +// waitFunc creates a channel that receives an item every time a test // should be executed and is closed when the last test should be invoked. -type WaitFunc func(done <-chan struct{}) <-chan struct{} +// +// Deprecated: Will be removed in a future release in favor of +// loopConditionUntilContext. +type waitFunc func(done <-chan struct{}) <-chan struct{} // WithContext converts the WaitFunc to an equivalent WaitWithContextFunc -func (w WaitFunc) WithContext() WaitWithContextFunc { +func (w waitFunc) WithContext() waitWithContextFunc { return func(ctx context.Context) <-chan struct{} { return w(ctx.Done()) } } -// WaitWithContextFunc creates a channel that receives an item every time a test +// waitWithContextFunc creates a channel that receives an item every time a test // should be executed and is closed when the last test should be invoked. // // When the specified context gets cancelled or expires the function // stops sending item and returns immediately. -type WaitWithContextFunc func(ctx context.Context) <-chan struct{} +// +// Deprecated: Will be removed in a future release in favor of +// loopConditionUntilContext. +type waitWithContextFunc func(ctx context.Context) <-chan struct{} -// WaitFor continually checks 'fn' as driven by 'wait'. +// waitForWithContext continually checks 'fn' as driven by 'wait'. // -// WaitFor gets a channel from 'wait()”, and then invokes 'fn' once for every value -// placed on the channel and once more when the channel is closed. If the channel is closed -// and 'fn' returns false without error, WaitFor returns ErrWaitTimeout. -// -// If 'fn' returns an error the loop ends and that error is returned. If -// 'fn' returns true the loop ends and nil is returned. -// -// ErrWaitTimeout will be returned if the 'done' channel is closed without fn ever -// returning true. -// -// When the done channel is closed, because the golang `select` statement is -// "uniform pseudo-random", the `fn` might still run one or multiple time, -// though eventually `WaitFor` will return. -func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error { - ctx, cancel := ContextForChannel(done) - defer cancel() - return WaitForWithContext(ctx, wait.WithContext(), fn.WithContext()) -} - -// WaitForWithContext continually checks 'fn' as driven by 'wait'. -// -// WaitForWithContext gets a channel from 'wait()”, and then invokes 'fn' +// waitForWithContext gets a channel from 'wait()”, and then invokes 'fn' // once for every value placed on the channel and once more when the // channel is closed. If the channel is closed and 'fn' -// returns false without error, WaitForWithContext returns ErrWaitTimeout. +// returns false without error, waitForWithContext returns ErrWaitTimeout. // // If 'fn' returns an error the loop ends and that error is returned. If // 'fn' returns true the loop ends and nil is returned. @@ -651,8 +193,11 @@ func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error { // // When the ctx.Done() channel is closed, because the golang `select` statement is // "uniform pseudo-random", the `fn` might still run one or multiple times, -// though eventually `WaitForWithContext` will return. -func WaitForWithContext(ctx context.Context, wait WaitWithContextFunc, fn ConditionWithContextFunc) error { +// though eventually `waitForWithContext` will return. +// +// Deprecated: Will be removed in a future release in favor of +// loopConditionUntilContext. +func waitForWithContext(ctx context.Context, wait waitWithContextFunc, fn ConditionWithContextFunc) error { waitCtx, cancel := context.WithCancel(context.Background()) defer cancel() c := wait(waitCtx) @@ -670,88 +215,9 @@ func WaitForWithContext(ctx context.Context, wait WaitWithContextFunc, fn Condit return ErrWaitTimeout } case <-ctx.Done(): - // returning ctx.Err() will break backward compatibility + // returning ctx.Err() will break backward compatibility, use new PollUntilContext* + // methods instead return ErrWaitTimeout } } } - -// poller returns a WaitFunc that will send to the channel every interval until -// timeout has elapsed and then closes the channel. -// -// Over very short intervals you may receive no ticks before the channel is -// closed. A timeout of 0 is interpreted as an infinity, and in such a case -// it would be the caller's responsibility to close the done channel. -// Failure to do so would result in a leaked goroutine. -// -// Output ticks are not buffered. If the channel is not ready to receive an -// item, the tick is skipped. -func poller(interval, timeout time.Duration) WaitWithContextFunc { - return WaitWithContextFunc(func(ctx context.Context) <-chan struct{} { - ch := make(chan struct{}) - - go func() { - defer close(ch) - - tick := time.NewTicker(interval) - defer tick.Stop() - - var after <-chan time.Time - if timeout != 0 { - // time.After is more convenient, but it - // potentially leaves timers around much longer - // than necessary if we exit early. - timer := time.NewTimer(timeout) - after = timer.C - defer timer.Stop() - } - - for { - select { - case <-tick.C: - // If the consumer isn't ready for this signal drop it and - // check the other channels. - select { - case ch <- struct{}{}: - default: - } - case <-after: - return - case <-ctx.Done(): - return - } - } - }() - - return ch - }) -} - -// ExponentialBackoffWithContext works with a request context and a Backoff. It ensures that the retry wait never -// exceeds the deadline specified by the request context. -func ExponentialBackoffWithContext(ctx context.Context, backoff Backoff, condition ConditionFunc) error { - for backoff.Steps > 0 { - select { - case <-ctx.Done(): - return ctx.Err() - default: - } - - if ok, err := runConditionWithCrashProtection(condition); err != nil || ok { - return err - } - - if backoff.Steps == 1 { - break - } - - waitBeforeRetry := backoff.Step() - select { - case <-ctx.Done(): - return ctx.Err() - case <-time.After(waitBeforeRetry): - } - } - - return ErrWaitTimeout -} diff --git a/vendor/k8s.io/apimachinery/pkg/util/waitgroup/ratelimited_waitgroup.go b/vendor/k8s.io/apimachinery/pkg/util/waitgroup/ratelimited_waitgroup.go new file mode 100644 index 000000000..8766390fc --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/waitgroup/ratelimited_waitgroup.go @@ -0,0 +1,134 @@ +/* +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 waitgroup + +import ( + "context" + "fmt" + "sync" +) + +// RateLimiter abstracts the rate limiter used by RateLimitedSafeWaitGroup. +// The implementation must be thread-safe. +type RateLimiter interface { + Wait(ctx context.Context) error +} + +// RateLimiterFactoryFunc is used by the RateLimitedSafeWaitGroup to create a new +// instance of a RateLimiter that will be used to rate limit the return rate +// of the active number of request(s). 'count' is the number of requests in +// flight that are expected to invoke 'Done' on this wait group. +type RateLimiterFactoryFunc func(count int) (RateLimiter, context.Context, context.CancelFunc) + +// RateLimitedSafeWaitGroup must not be copied after first use. +type RateLimitedSafeWaitGroup struct { + wg sync.WaitGroup + // Once Wait is initiated, all consecutive Done invocation will be + // rate limited using this rate limiter. + limiter RateLimiter + stopCtx context.Context + + mu sync.Mutex + // wait indicate whether Wait is called, if true, + // then any Add with positive delta will return error. + wait bool + // number of request(s) currently using the wait group + count int +} + +// Add adds delta, which may be negative, similar to sync.WaitGroup. +// If Add with a positive delta happens after Wait, it will return error, +// which prevent unsafe Add. +func (wg *RateLimitedSafeWaitGroup) Add(delta int) error { + wg.mu.Lock() + defer wg.mu.Unlock() + + if wg.wait && delta > 0 { + return fmt.Errorf("add with positive delta after Wait is forbidden") + } + wg.wg.Add(delta) + wg.count += delta + return nil +} + +// Done decrements the WaitGroup counter, rate limiting is applied only +// when the wait group is in waiting mode. +func (wg *RateLimitedSafeWaitGroup) Done() { + var limiter RateLimiter + func() { + wg.mu.Lock() + defer wg.mu.Unlock() + + wg.count -= 1 + if wg.wait { + // we are using the limiter outside the scope of the lock + limiter = wg.limiter + } + }() + + defer wg.wg.Done() + if limiter != nil { + limiter.Wait(wg.stopCtx) + } +} + +// Wait blocks until the WaitGroup counter is zero or a hard limit has elapsed. +// It returns the number of active request(s) accounted for at the time Wait +// has been invoked, number of request(s) that have drianed (done using the +// wait group immediately before Wait returns). +// Ideally, the both numbers returned should be equal, to indicate that all +// request(s) using the wait group have released their lock. +func (wg *RateLimitedSafeWaitGroup) Wait(limiterFactory RateLimiterFactoryFunc) (int, int, error) { + if limiterFactory == nil { + return 0, 0, fmt.Errorf("rate limiter factory must be specified") + } + + var cancel context.CancelFunc + var countNow, countAfter int + func() { + wg.mu.Lock() + defer wg.mu.Unlock() + + wg.limiter, wg.stopCtx, cancel = limiterFactory(wg.count) + countNow = wg.count + wg.wait = true + }() + + defer cancel() + // there should be a hard stop, in case request(s) are not responsive + // enough to invoke Done before the grace period is over. + waitDoneCh := make(chan struct{}) + go func() { + defer close(waitDoneCh) + wg.wg.Wait() + }() + + var err error + select { + case <-wg.stopCtx.Done(): + err = wg.stopCtx.Err() + case <-waitDoneCh: + } + + func() { + wg.mu.Lock() + defer wg.mu.Unlock() + + countAfter = wg.count + }() + return countNow, countAfter, err +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/cel/metrics.go b/vendor/k8s.io/apiserver/pkg/admission/cel/metrics.go index 77d2210c2..9f8a94110 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/cel/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/admission/cel/metrics.go @@ -109,3 +109,15 @@ func (m *ValidatingAdmissionPolicyMetrics) ObserveRejection(ctx context.Context, m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "deny", state).Inc() m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "deny", state).Observe(elapsed.Seconds()) } + +// ObserveAudit observes a policy validation audit annotation was published for a validation failure. +func (m *ValidatingAdmissionPolicyMetrics) ObserveAudit(ctx context.Context, elapsed time.Duration, policy, binding, state string) { + m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "audit", state).Inc() + m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "audit", state).Observe(elapsed.Seconds()) +} + +// ObserveWarn observes a policy validation warning was published for a validation failure. +func (m *ValidatingAdmissionPolicyMetrics) ObserveWarn(ctx context.Context, elapsed time.Duration, policy, binding, state string) { + m.policyCheck.WithContext(ctx).WithLabelValues(policy, binding, "warn", state).Inc() + m.policyLatency.WithContext(ctx).WithLabelValues(policy, binding, "warn", state).Observe(elapsed.Seconds()) +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/configuration/mutating_webhook_manager.go b/vendor/k8s.io/apiserver/pkg/admission/configuration/mutating_webhook_manager.go index ea58e6c32..daee67859 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/configuration/mutating_webhook_manager.go +++ b/vendor/k8s.io/apiserver/pkg/admission/configuration/mutating_webhook_manager.go @@ -19,7 +19,6 @@ package configuration import ( "fmt" "sort" - "sync/atomic" "k8s.io/api/admissionregistration/v1" "k8s.io/apimachinery/pkg/labels" @@ -29,18 +28,14 @@ import ( "k8s.io/client-go/informers" admissionregistrationlisters "k8s.io/client-go/listers/admissionregistration/v1" "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/cache/synctrack" ) // mutatingWebhookConfigurationManager collects the mutating webhook objects so that they can be called. type mutatingWebhookConfigurationManager struct { - configuration *atomic.Value - lister admissionregistrationlisters.MutatingWebhookConfigurationLister - hasSynced func() bool - // initialConfigurationSynced tracks if - // the existing webhook configs have been synced (honored) by the - // manager at startup-- the informer has synced and either has no items - // or has finished executing updateConfiguration() once. - initialConfigurationSynced *atomic.Bool + lister admissionregistrationlisters.MutatingWebhookConfigurationLister + hasSynced func() bool + lazy synctrack.Lazy[[]webhook.WebhookAccessor] } var _ generic.Source = &mutatingWebhookConfigurationManager{} @@ -48,62 +43,39 @@ var _ generic.Source = &mutatingWebhookConfigurationManager{} func NewMutatingWebhookConfigurationManager(f informers.SharedInformerFactory) generic.Source { informer := f.Admissionregistration().V1().MutatingWebhookConfigurations() manager := &mutatingWebhookConfigurationManager{ - configuration: &atomic.Value{}, - lister: informer.Lister(), - hasSynced: informer.Informer().HasSynced, - initialConfigurationSynced: &atomic.Bool{}, + lister: informer.Lister(), } + manager.lazy.Evaluate = manager.getConfiguration - // Start with an empty list - manager.configuration.Store([]webhook.WebhookAccessor{}) - manager.initialConfigurationSynced.Store(false) - - // On any change, rebuild the config - informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(_ interface{}) { manager.updateConfiguration() }, - UpdateFunc: func(_, _ interface{}) { manager.updateConfiguration() }, - DeleteFunc: func(_ interface{}) { manager.updateConfiguration() }, + handle, _ := informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(_ interface{}) { manager.lazy.Notify() }, + UpdateFunc: func(_, _ interface{}) { manager.lazy.Notify() }, + DeleteFunc: func(_ interface{}) { manager.lazy.Notify() }, }) + manager.hasSynced = handle.HasSynced return manager } // Webhooks returns the merged MutatingWebhookConfiguration. func (m *mutatingWebhookConfigurationManager) Webhooks() []webhook.WebhookAccessor { - return m.configuration.Load().([]webhook.WebhookAccessor) + out, err := m.lazy.Get() + if err != nil { + utilruntime.HandleError(fmt.Errorf("error getting webhook configuration: %v", err)) + } + return out } -// HasSynced returns true when the manager is synced with existing webhookconfig -// objects at startup-- which means the informer is synced and either has no items -// or updateConfiguration() has completed. -func (m *mutatingWebhookConfigurationManager) HasSynced() bool { - if !m.hasSynced() { - return false - } - if m.initialConfigurationSynced.Load() { - // the informer has synced and configuration has been updated - return true - } - if configurations, err := m.lister.List(labels.Everything()); err == nil && len(configurations) == 0 { - // the empty list we initially stored is valid to use. - // Setting initialConfigurationSynced to true, so subsequent checks - // would be able to take the fast path on the atomic boolean in a - // cluster without any admission webhooks configured. - m.initialConfigurationSynced.Store(true) - // the informer has synced and we don't have any items - return true - } - return false -} +// HasSynced returns true if the initial set of mutating webhook configurations +// has been loaded. +func (m *mutatingWebhookConfigurationManager) HasSynced() bool { return m.hasSynced() } -func (m *mutatingWebhookConfigurationManager) updateConfiguration() { +func (m *mutatingWebhookConfigurationManager) getConfiguration() ([]webhook.WebhookAccessor, error) { configurations, err := m.lister.List(labels.Everything()) if err != nil { - utilruntime.HandleError(fmt.Errorf("error updating configuration: %v", err)) - return + return []webhook.WebhookAccessor{}, err } - m.configuration.Store(mergeMutatingWebhookConfigurations(configurations)) - m.initialConfigurationSynced.Store(true) + return mergeMutatingWebhookConfigurations(configurations), nil } func mergeMutatingWebhookConfigurations(configurations []*v1.MutatingWebhookConfiguration) []webhook.WebhookAccessor { diff --git a/vendor/k8s.io/apiserver/pkg/admission/configuration/validating_webhook_manager.go b/vendor/k8s.io/apiserver/pkg/admission/configuration/validating_webhook_manager.go index 00f954251..f318b5012 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/configuration/validating_webhook_manager.go +++ b/vendor/k8s.io/apiserver/pkg/admission/configuration/validating_webhook_manager.go @@ -19,7 +19,6 @@ package configuration import ( "fmt" "sort" - "sync/atomic" "k8s.io/api/admissionregistration/v1" "k8s.io/apimachinery/pkg/labels" @@ -29,18 +28,14 @@ import ( "k8s.io/client-go/informers" admissionregistrationlisters "k8s.io/client-go/listers/admissionregistration/v1" "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/cache/synctrack" ) // validatingWebhookConfigurationManager collects the validating webhook objects so that they can be called. type validatingWebhookConfigurationManager struct { - configuration *atomic.Value - lister admissionregistrationlisters.ValidatingWebhookConfigurationLister - hasSynced func() bool - // initialConfigurationSynced tracks if - // the existing webhook configs have been synced (honored) by the - // manager at startup-- the informer has synced and either has no items - // or has finished executing updateConfiguration() once. - initialConfigurationSynced *atomic.Bool + lister admissionregistrationlisters.ValidatingWebhookConfigurationLister + hasSynced func() bool + lazy synctrack.Lazy[[]webhook.WebhookAccessor] } var _ generic.Source = &validatingWebhookConfigurationManager{} @@ -48,63 +43,39 @@ var _ generic.Source = &validatingWebhookConfigurationManager{} func NewValidatingWebhookConfigurationManager(f informers.SharedInformerFactory) generic.Source { informer := f.Admissionregistration().V1().ValidatingWebhookConfigurations() manager := &validatingWebhookConfigurationManager{ - configuration: &atomic.Value{}, - lister: informer.Lister(), - hasSynced: informer.Informer().HasSynced, - initialConfigurationSynced: &atomic.Bool{}, + lister: informer.Lister(), } + manager.lazy.Evaluate = manager.getConfiguration - // Start with an empty list - manager.configuration.Store([]webhook.WebhookAccessor{}) - manager.initialConfigurationSynced.Store(false) - - // On any change, rebuild the config - informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(_ interface{}) { manager.updateConfiguration() }, - UpdateFunc: func(_, _ interface{}) { manager.updateConfiguration() }, - DeleteFunc: func(_ interface{}) { manager.updateConfiguration() }, + handle, _ := informer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(_ interface{}) { manager.lazy.Notify() }, + UpdateFunc: func(_, _ interface{}) { manager.lazy.Notify() }, + DeleteFunc: func(_ interface{}) { manager.lazy.Notify() }, }) + manager.hasSynced = handle.HasSynced return manager } // Webhooks returns the merged ValidatingWebhookConfiguration. func (v *validatingWebhookConfigurationManager) Webhooks() []webhook.WebhookAccessor { - return v.configuration.Load().([]webhook.WebhookAccessor) + out, err := v.lazy.Get() + if err != nil { + utilruntime.HandleError(fmt.Errorf("error getting webhook configuration: %v", err)) + } + return out } -// HasSynced returns true when the manager is synced with existing webhookconfig -// objects at startup-- which means the informer is synced and either has no items -// or updateConfiguration() has completed. -func (v *validatingWebhookConfigurationManager) HasSynced() bool { - if !v.hasSynced() { - return false - } - if v.initialConfigurationSynced.Load() { - // the informer has synced and configuration has been updated - return true - } - if configurations, err := v.lister.List(labels.Everything()); err == nil && len(configurations) == 0 { - // the empty list we initially stored is valid to use. - // Setting initialConfigurationSynced to true, so subsequent checks - // would be able to take the fast path on the atomic boolean in a - // cluster without any admission webhooks configured. - v.initialConfigurationSynced.Store(true) - // the informer has synced and we don't have any items - return true - } - return false +// HasSynced returns true if the initial set of mutating webhook configurations +// has been loaded. +func (v *validatingWebhookConfigurationManager) HasSynced() bool { return v.hasSynced() } -} - -func (v *validatingWebhookConfigurationManager) updateConfiguration() { +func (v *validatingWebhookConfigurationManager) getConfiguration() ([]webhook.WebhookAccessor, error) { configurations, err := v.lister.List(labels.Everything()) if err != nil { - utilruntime.HandleError(fmt.Errorf("error updating configuration: %v", err)) - return + return []webhook.WebhookAccessor{}, err } - v.configuration.Store(mergeValidatingWebhookConfigurations(configurations)) - v.initialConfigurationSynced.Store(true) + return mergeValidatingWebhookConfigurations(configurations), nil } func mergeValidatingWebhookConfigurations(configurations []*v1.ValidatingWebhookConfiguration) []webhook.WebhookAccessor { diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion.go b/vendor/k8s.io/apiserver/pkg/admission/conversion.go similarity index 73% rename from vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion.go rename to vendor/k8s.io/apiserver/pkg/admission/conversion.go index f0e0ed79c..a2b313a98 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/conversion.go +++ b/vendor/k8s.io/apiserver/pkg/admission/conversion.go @@ -14,16 +14,40 @@ See the License for the specific language governing permissions and limitations under the License. */ -package generic +package admission import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/admission" ) +// VersionedAttributes is a wrapper around the original admission attributes, adding versioned +// variants of the object and old object. +type VersionedAttributes struct { + // Attributes holds the original admission attributes + Attributes + // VersionedOldObject holds Attributes.OldObject (if non-nil), converted to VersionedKind. + // It must never be mutated. + VersionedOldObject runtime.Object + // VersionedObject holds Attributes.Object (if non-nil), converted to VersionedKind. + // If mutated, Dirty must be set to true by the mutator. + VersionedObject runtime.Object + // VersionedKind holds the fully qualified kind + VersionedKind schema.GroupVersionKind + // Dirty indicates VersionedObject has been modified since being converted from Attributes.Object + Dirty bool +} + +// GetObject overrides the Attributes.GetObject() +func (v *VersionedAttributes) GetObject() runtime.Object { + if v.VersionedObject != nil { + return v.VersionedObject + } + return v.Attributes.GetObject() +} + // ConvertToGVK converts object to the desired gvk. -func ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind, o admission.ObjectInterfaces) (runtime.Object, error) { +func ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind, o ObjectInterfaces) (runtime.Object, error) { // Unlike other resources, custom resources do not have internal version, so // if obj is a custom resource, it should not need conversion. if obj.GetObjectKind().GroupVersionKind() == gvk { @@ -43,7 +67,7 @@ func ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind, o admission.O } // NewVersionedAttributes returns versioned attributes with the old and new object (if non-nil) converted to the requested kind -func NewVersionedAttributes(attr admission.Attributes, gvk schema.GroupVersionKind, o admission.ObjectInterfaces) (*VersionedAttributes, error) { +func NewVersionedAttributes(attr Attributes, gvk schema.GroupVersionKind, o ObjectInterfaces) (*VersionedAttributes, error) { // convert the old and new objects to the requested version versionedAttr := &VersionedAttributes{ Attributes: attr, @@ -72,7 +96,7 @@ func NewVersionedAttributes(attr admission.Attributes, gvk schema.GroupVersionKi // * attr.VersionedObject is used as the source for the new object if Dirty=true (and is round-tripped through attr.Attributes.Object, clearing Dirty in the process) // * attr.Attributes.Object is used as the source for the new object if Dirty=false // * attr.Attributes.OldObject is used as the source for the old object -func ConvertVersionedAttributes(attr *VersionedAttributes, gvk schema.GroupVersionKind, o admission.ObjectInterfaces) error { +func ConvertVersionedAttributes(attr *VersionedAttributes, gvk schema.GroupVersionKind, o ObjectInterfaces) error { // we already have the desired kind, we're done if attr.VersionedKind == gvk { return nil diff --git a/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go b/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go index 2a6632c3e..6077c89de 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go +++ b/vendor/k8s.io/apiserver/pkg/admission/initializer/interfaces.go @@ -20,6 +20,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/cel/openapi/resolver" quota "k8s.io/apiserver/pkg/quota/v1" "k8s.io/client-go/dynamic" "k8s.io/client-go/informers" @@ -81,3 +82,10 @@ type WantsRESTMapper interface { SetRESTMapper(meta.RESTMapper) admission.InitializationValidator } + +// WantsSchemaResolver defines a function which sets the SchemaResolver for +// an admission plugin that needs it. +type WantsSchemaResolver interface { + SetSchemaResolver(resolver resolver.SchemaResolver) + admission.InitializationValidator +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/admission/metrics/metrics.go index 8482aea88..26b82c37e 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/admission/metrics/metrics.go @@ -112,12 +112,13 @@ func (p pluginHandlerWithMetrics) Validate(ctx context.Context, a admission.Attr // AdmissionMetrics instruments admission with prometheus metrics. type AdmissionMetrics struct { - step *metricSet - controller *metricSet - webhook *metricSet - webhookRejection *metrics.CounterVec - webhookFailOpen *metrics.CounterVec - webhookRequest *metrics.CounterVec + step *metricSet + controller *metricSet + webhook *metricSet + webhookRejection *metrics.CounterVec + webhookFailOpen *metrics.CounterVec + webhookRequest *metrics.CounterVec + matchConditionEvalErrors *metrics.CounterVec } // newAdmissionMetrics create a new AdmissionMetrics, configured with default metric names. @@ -178,7 +179,7 @@ func newAdmissionMetrics() *AdmissionMetrics { Subsystem: subsystem, Name: "webhook_admission_duration_seconds", Help: "Admission webhook latency histogram in seconds, identified by name and broken out for each operation and API resource and type (validate or admit).", - Buckets: []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5}, + Buckets: []float64{0.005, 0.025, 0.1, 0.5, 1.0, 2.5, 10, 25}, StabilityLevel: metrics.STABLE, }, []string{"name", "type", "operation", "rejected"}, @@ -217,13 +218,24 @@ func newAdmissionMetrics() *AdmissionMetrics { }, []string{"name", "type", "operation", "code", "rejected"}) + matchConditionEvalError := metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "admission_match_condition_evaluation_errors_total", + Help: "Admission match condition evaluation errors count, identified by name of resource containing the match condition and broken out for each admission type (validating or mutating).", + StabilityLevel: metrics.ALPHA, + }, + []string{"name", "type"}) + step.mustRegister() controller.mustRegister() webhook.mustRegister() legacyregistry.MustRegister(webhookRejection) legacyregistry.MustRegister(webhookFailOpen) legacyregistry.MustRegister(webhookRequest) - return &AdmissionMetrics{step: step, controller: controller, webhook: webhook, webhookRejection: webhookRejection, webhookFailOpen: webhookFailOpen, webhookRequest: webhookRequest} + legacyregistry.MustRegister(matchConditionEvalError) + return &AdmissionMetrics{step: step, controller: controller, webhook: webhook, webhookRejection: webhookRejection, webhookFailOpen: webhookFailOpen, webhookRequest: webhookRequest, matchConditionEvalErrors: matchConditionEvalError} } func (m *AdmissionMetrics) reset() { @@ -267,6 +279,11 @@ func (m *AdmissionMetrics) ObserveWebhookFailOpen(ctx context.Context, name, ste m.webhookFailOpen.WithContext(ctx).WithLabelValues(name, stepType).Inc() } +// ObserveMatchConditionEvalError records validating or mutating webhook that are not called due to match conditions +func (m *AdmissionMetrics) ObserveMatchConditionEvalError(ctx context.Context, name, stepType string) { + m.matchConditionEvalErrors.WithContext(ctx).WithLabelValues(name, stepType).Inc() +} + type metricSet struct { latencies *metrics.HistogramVec latenciesSummary *metrics.SummaryVec diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/OWNERS b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/OWNERS new file mode 100644 index 000000000..6a637d28d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - jpbetz + - cici37 + - alexzielenski +reviewers: + - jpbetz + - cici37 + - alexzielenski diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/compiler.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/compile.go similarity index 61% rename from vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/compiler.go rename to vendor/k8s.io/apiserver/pkg/admission/plugin/cel/compile.go index 3767c0d9d..bb122de5f 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/compiler.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/compile.go @@ -14,9 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -package validatingadmissionpolicy +package cel import ( + "fmt" + celconfig "k8s.io/apiserver/pkg/apis/cel" "sync" "github.com/google/cel-go/cel" @@ -26,43 +28,33 @@ import ( ) const ( - ObjectVarName = "object" - OldObjectVarName = "oldObject" - ParamsVarName = "params" - RequestVarName = "request" - - checkFrequency = 100 + ObjectVarName = "object" + OldObjectVarName = "oldObject" + ParamsVarName = "params" + RequestVarName = "request" + AuthorizerVarName = "authorizer" + RequestResourceAuthorizerVarName = "authorizer.requestResource" ) -type envs struct { - noParams *cel.Env - withParams *cel.Env -} - var ( initEnvsOnce sync.Once - initEnvs *envs + initEnvs envs initEnvsErr error ) -func getEnvs() (*envs, error) { +func getEnvs() (envs, error) { initEnvsOnce.Do(func() { - base, err := buildBaseEnv() + requiredVarsEnv, err := buildRequiredVarsEnv() if err != nil { initEnvsErr = err return } - noParams, err := buildNoParamsEnv(base) + + initEnvs, err = buildWithOptionalVarsEnvs(requiredVarsEnv) if err != nil { initEnvsErr = err return } - withParams, err := buildWithParamsEnv(noParams) - if err != nil { - initEnvsErr = err - return - } - initEnvs = &envs{noParams: noParams, withParams: withParams} }) return initEnvs, initEnvsErr } @@ -81,11 +73,15 @@ func buildBaseEnv() (*cel.Env, error) { return cel.NewEnv(opts...) } -func buildNoParamsEnv(baseEnv *cel.Env) (*cel.Env, error) { +func buildRequiredVarsEnv() (*cel.Env, error) { + baseEnv, err := buildBaseEnv() + if err != nil { + return nil, err + } var propDecls []cel.EnvOption reg := apiservercel.NewRegistry(baseEnv) - requestType := buildRequestType() + requestType := BuildRequestType() rt, err := apiservercel.NewRuleTypes(requestType.TypeName(), requestType, reg) if err != nil { return nil, err @@ -109,15 +105,40 @@ func buildNoParamsEnv(baseEnv *cel.Env) (*cel.Env, error) { return env, nil } -func buildWithParamsEnv(noParams *cel.Env) (*cel.Env, error) { - return noParams.Extend(cel.Variable(ParamsVarName, cel.DynType)) +type envs map[OptionalVariableDeclarations]*cel.Env + +func buildEnvWithVars(baseVarsEnv *cel.Env, options OptionalVariableDeclarations) (*cel.Env, error) { + var opts []cel.EnvOption + if options.HasParams { + opts = append(opts, cel.Variable(ParamsVarName, cel.DynType)) + } + if options.HasAuthorizer { + opts = append(opts, cel.Variable(AuthorizerVarName, library.AuthorizerType)) + opts = append(opts, cel.Variable(RequestResourceAuthorizerVarName, library.ResourceCheckType)) + } + return baseVarsEnv.Extend(opts...) } -// buildRequestType generates a DeclType for AdmissionRequest. This may be replaced with a utility that +func buildWithOptionalVarsEnvs(requiredVarsEnv *cel.Env) (envs, error) { + envs := make(envs, 4) // since the number of variable combinations is small, pre-build a environment for each + for _, hasParams := range []bool{false, true} { + for _, hasAuthorizer := range []bool{false, true} { + opts := OptionalVariableDeclarations{HasParams: hasParams, HasAuthorizer: hasAuthorizer} + env, err := buildEnvWithVars(requiredVarsEnv, opts) + if err != nil { + return nil, err + } + envs[opts] = env + } + } + return envs, nil +} + +// BuildRequestType generates a DeclType for AdmissionRequest. This may be replaced with a utility that // converts the native type definition to apiservercel.DeclType once such a utility becomes available. // The 'uid' field is omitted since it is not needed for in-process admission review. // The 'object' and 'oldObject' fields are omitted since they are exposed as root level CEL variables. -func buildRequestType() *apiservercel.DeclType { +func BuildRequestType() *apiservercel.DeclType { field := func(name string, declType *apiservercel.DeclType, required bool) *apiservercel.DeclField { return apiservercel.NewDeclField(name, declType, required, nil, nil) } @@ -160,14 +181,16 @@ func buildRequestType() *apiservercel.DeclType { )) } -// CompilationResult represents a compiled ValidatingAdmissionPolicy validation expression. +// CompilationResult represents a compiled validations expression. type CompilationResult struct { - Program cel.Program - Error *apiservercel.Error + Program cel.Program + Error *apiservercel.Error + ExpressionAccessor ExpressionAccessor } -// CompileValidatingPolicyExpression returns a compiled vaalidating policy CEL expression. -func CompileValidatingPolicyExpression(validationExpression string, hasParams bool) CompilationResult { +// CompileCELExpression returns a compiled CEL expression. +// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func CompileCELExpression(expressionAccessor ExpressionAccessor, optionalVars OptionalVariableDeclarations, perCallLimit uint64) CompilationResult { var env *cel.Env envs, err := getEnvs() if err != nil { @@ -176,29 +199,52 @@ func CompileValidatingPolicyExpression(validationExpression string, hasParams bo Type: apiservercel.ErrorTypeInternal, Detail: "compiler initialization failed: " + err.Error(), }, + ExpressionAccessor: expressionAccessor, } } - if hasParams { - env = envs.withParams - } else { - env = envs.noParams + env, ok := envs[optionalVars] + if !ok { + return CompilationResult{ + Error: &apiservercel.Error{ + Type: apiservercel.ErrorTypeInvalid, + Detail: fmt.Sprintf("compiler initialization failed: failed to load environment for %v", optionalVars), + }, + ExpressionAccessor: expressionAccessor, + } } - ast, issues := env.Compile(validationExpression) + ast, issues := env.Compile(expressionAccessor.GetExpression()) if issues != nil { return CompilationResult{ Error: &apiservercel.Error{ Type: apiservercel.ErrorTypeInvalid, Detail: "compilation failed: " + issues.String(), }, + ExpressionAccessor: expressionAccessor, } } - if ast.OutputType() != cel.BoolType { + found := false + returnTypes := expressionAccessor.ReturnTypes() + for _, returnType := range returnTypes { + if ast.OutputType() == returnType { + found = true + break + } + } + if !found { + var reason string + if len(returnTypes) == 1 { + reason = fmt.Sprintf("must evaluate to %v", returnTypes[0].String()) + } else { + reason = fmt.Sprintf("must evaluate to one of %v", returnTypes) + } + return CompilationResult{ Error: &apiservercel.Error{ Type: apiservercel.ErrorTypeInvalid, - Detail: "cel expression must evaluate to a bool", + Detail: reason, }, + ExpressionAccessor: expressionAccessor, } } @@ -210,12 +256,14 @@ func CompileValidatingPolicyExpression(validationExpression string, hasParams bo Type: apiservercel.ErrorTypeInternal, Detail: "unexpected compilation error: " + err.Error(), }, + ExpressionAccessor: expressionAccessor, } } prog, err := env.Program(ast, - cel.EvalOptions(cel.OptOptimize), + cel.EvalOptions(cel.OptOptimize, cel.OptTrackCost), cel.OptimizeRegex(library.ExtensionLibRegexOptimizations...), - cel.InterruptCheckFrequency(checkFrequency), + cel.InterruptCheckFrequency(celconfig.CheckFrequency), + cel.CostLimit(perCallLimit), ) if err != nil { return CompilationResult{ @@ -223,9 +271,11 @@ func CompileValidatingPolicyExpression(validationExpression string, hasParams bo Type: apiservercel.ErrorTypeInvalid, Detail: "program instantiation failed: " + err.Error(), }, + ExpressionAccessor: expressionAccessor, } } return CompilationResult{ - Program: prog, + Program: prog, + ExpressionAccessor: expressionAccessor, } } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go new file mode 100644 index 000000000..6e504897c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/filter.go @@ -0,0 +1,296 @@ +/* +Copyright 2022 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 cel + +import ( + "context" + "fmt" + "math" + "reflect" + "time" + + "github.com/google/cel-go/interpreter" + + admissionv1 "k8s.io/api/admission/v1" + authenticationv1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/library" +) + +// filterCompiler implement the interface FilterCompiler. +type filterCompiler struct { +} + +func NewFilterCompiler() FilterCompiler { + return &filterCompiler{} +} + +type evaluationActivation struct { + object, oldObject, params, request, authorizer, requestResourceAuthorizer interface{} +} + +// ResolveName returns a value from the activation by qualified name, or false if the name +// could not be found. +func (a *evaluationActivation) ResolveName(name string) (interface{}, bool) { + switch name { + case ObjectVarName: + return a.object, true + case OldObjectVarName: + return a.oldObject, true + case ParamsVarName: + return a.params, true // params may be null + case RequestVarName: + return a.request, true + case AuthorizerVarName: + return a.authorizer, a.authorizer != nil + case RequestResourceAuthorizerVarName: + return a.requestResourceAuthorizer, a.requestResourceAuthorizer != nil + default: + return nil, false + } +} + +// Parent returns the parent of the current activation, may be nil. +// If non-nil, the parent will be searched during resolve calls. +func (a *evaluationActivation) Parent() interpreter.Activation { + return nil +} + +// Compile compiles the cel expressions defined in the ExpressionAccessors into a Filter +func (c *filterCompiler) Compile(expressionAccessors []ExpressionAccessor, options OptionalVariableDeclarations, perCallLimit uint64) Filter { + compilationResults := make([]CompilationResult, len(expressionAccessors)) + for i, expressionAccessor := range expressionAccessors { + if expressionAccessor == nil { + continue + } + compilationResults[i] = CompileCELExpression(expressionAccessor, options, perCallLimit) + } + return NewFilter(compilationResults) +} + +// filter implements the Filter interface +type filter struct { + compilationResults []CompilationResult +} + +func NewFilter(compilationResults []CompilationResult) Filter { + return &filter{ + compilationResults, + } +} + +func convertObjectToUnstructured(obj interface{}) (*unstructured.Unstructured, error) { + if obj == nil || reflect.ValueOf(obj).IsNil() { + return &unstructured.Unstructured{Object: nil}, nil + } + ret, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return nil, err + } + return &unstructured.Unstructured{Object: ret}, nil +} + +func objectToResolveVal(r runtime.Object) (interface{}, error) { + if r == nil || reflect.ValueOf(r).IsNil() { + return nil, nil + } + v, err := convertObjectToUnstructured(r) + if err != nil { + return nil, err + } + return v.Object, nil +} + +// ForInput evaluates the compiled CEL expressions converting them into CELEvaluations +// errors per evaluation are returned on the Evaluation object +// runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func (f *filter) ForInput(ctx context.Context, versionedAttr *admission.VersionedAttributes, request *admissionv1.AdmissionRequest, inputs OptionalVariableBindings, runtimeCELCostBudget int64) ([]EvaluationResult, int64, error) { + // TODO: replace unstructured with ref.Val for CEL variables when native type support is available + evaluations := make([]EvaluationResult, len(f.compilationResults)) + var err error + + oldObjectVal, err := objectToResolveVal(versionedAttr.VersionedOldObject) + if err != nil { + return nil, -1, err + } + objectVal, err := objectToResolveVal(versionedAttr.VersionedObject) + if err != nil { + return nil, -1, err + } + var paramsVal, authorizerVal, requestResourceAuthorizerVal any + if inputs.VersionedParams != nil { + paramsVal, err = objectToResolveVal(inputs.VersionedParams) + if err != nil { + return nil, -1, err + } + } + + if inputs.Authorizer != nil { + authorizerVal = library.NewAuthorizerVal(versionedAttr.GetUserInfo(), inputs.Authorizer) + requestResourceAuthorizerVal = library.NewResourceAuthorizerVal(versionedAttr.GetUserInfo(), inputs.Authorizer, versionedAttr) + } + + requestVal, err := convertObjectToUnstructured(request) + if err != nil { + return nil, -1, err + } + va := &evaluationActivation{ + object: objectVal, + oldObject: oldObjectVal, + params: paramsVal, + request: requestVal.Object, + authorizer: authorizerVal, + requestResourceAuthorizer: requestResourceAuthorizerVal, + } + + remainingBudget := runtimeCELCostBudget + for i, compilationResult := range f.compilationResults { + var evaluation = &evaluations[i] + if compilationResult.ExpressionAccessor == nil { // in case of placeholder + continue + } + evaluation.ExpressionAccessor = compilationResult.ExpressionAccessor + if compilationResult.Error != nil { + evaluation.Error = &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("compilation error: %v", compilationResult.Error), + } + continue + } + if compilationResult.Program == nil { + evaluation.Error = &cel.Error{ + Type: cel.ErrorTypeInternal, + Detail: fmt.Sprintf("unexpected internal error compiling expression"), + } + continue + } + t1 := time.Now() + evalResult, evalDetails, err := compilationResult.Program.ContextEval(ctx, va) + elapsed := time.Since(t1) + evaluation.Elapsed = elapsed + if evalDetails == nil { + return nil, -1, &cel.Error{ + Type: cel.ErrorTypeInternal, + Detail: fmt.Sprintf("runtime cost could not be calculated for expression: %v, no further expression will be run", compilationResult.ExpressionAccessor.GetExpression()), + } + } else { + rtCost := evalDetails.ActualCost() + if rtCost == nil { + return nil, -1, &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("runtime cost could not be calculated for expression: %v, no further expression will be run", compilationResult.ExpressionAccessor.GetExpression()), + } + } else { + if *rtCost > math.MaxInt64 || int64(*rtCost) > remainingBudget { + return nil, -1, &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("validation failed due to running out of cost budget, no further validation rules will be run"), + } + } + remainingBudget -= int64(*rtCost) + } + } + if err != nil { + evaluation.Error = &cel.Error{ + Type: cel.ErrorTypeInvalid, + Detail: fmt.Sprintf("expression '%v' resulted in error: %v", compilationResult.ExpressionAccessor.GetExpression(), err), + } + } else { + evaluation.EvalResult = evalResult + } + } + + return evaluations, remainingBudget, nil +} + +// TODO: to reuse https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go#L154 +func CreateAdmissionRequest(attr admission.Attributes) *admissionv1.AdmissionRequest { + // FIXME: how to get resource GVK, GVR and subresource? + gvk := attr.GetKind() + gvr := attr.GetResource() + subresource := attr.GetSubresource() + + requestGVK := attr.GetKind() + requestGVR := attr.GetResource() + requestSubResource := attr.GetSubresource() + + aUserInfo := attr.GetUserInfo() + var userInfo authenticationv1.UserInfo + if aUserInfo != nil { + userInfo = authenticationv1.UserInfo{ + Extra: make(map[string]authenticationv1.ExtraValue), + Groups: aUserInfo.GetGroups(), + UID: aUserInfo.GetUID(), + Username: aUserInfo.GetName(), + } + // Convert the extra information in the user object + for key, val := range aUserInfo.GetExtra() { + userInfo.Extra[key] = authenticationv1.ExtraValue(val) + } + } + + dryRun := attr.IsDryRun() + + return &admissionv1.AdmissionRequest{ + Kind: metav1.GroupVersionKind{ + Group: gvk.Group, + Kind: gvk.Kind, + Version: gvk.Version, + }, + Resource: metav1.GroupVersionResource{ + Group: gvr.Group, + Resource: gvr.Resource, + Version: gvr.Version, + }, + SubResource: subresource, + RequestKind: &metav1.GroupVersionKind{ + Group: requestGVK.Group, + Kind: requestGVK.Kind, + Version: requestGVK.Version, + }, + RequestResource: &metav1.GroupVersionResource{ + Group: requestGVR.Group, + Resource: requestGVR.Resource, + Version: requestGVR.Version, + }, + RequestSubResource: requestSubResource, + Name: attr.GetName(), + Namespace: attr.GetNamespace(), + Operation: admissionv1.Operation(attr.GetOperation()), + UserInfo: userInfo, + // Leave Object and OldObject unset since we don't provide access to them via request + DryRun: &dryRun, + Options: runtime.RawExtension{ + Object: attr.GetOperationOptions(), + }, + } +} + +// CompilationErrors returns a list of all the errors from the compilation of the evaluator +func (e *filter) CompilationErrors() []error { + compilationErrors := []error{} + for _, result := range e.compilationResults { + if result.Error != nil { + compilationErrors = append(compilationErrors, result.Error) + } + } + return compilationErrors +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go new file mode 100644 index 000000000..d3c4a0217 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/cel/interface.go @@ -0,0 +1,87 @@ +/* +Copyright 2022 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 cel + +import ( + "context" + "time" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types/ref" + + v1 "k8s.io/api/admission/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/authorization/authorizer" +) + +type ExpressionAccessor interface { + GetExpression() string + ReturnTypes() []*cel.Type +} + +// EvaluationResult contains the minimal required fields and metadata of a cel evaluation +type EvaluationResult struct { + EvalResult ref.Val + ExpressionAccessor ExpressionAccessor + Elapsed time.Duration + Error error +} + +// OptionalVariableDeclarations declares which optional CEL variables +// are declared for an expression. +type OptionalVariableDeclarations struct { + // HasParams specifies if the "params" variable is declared. + // The "params" variable may still be bound to "null" when declared. + HasParams bool + // HasAuthorizer specifies if the"authorizer" and "authorizer.requestResource" + // variables are declared. When declared, the authorizer variables are + // expected to be non-null. + HasAuthorizer bool +} + +// FilterCompiler contains a function to assist with converting types and values to/from CEL-typed values. +type FilterCompiler interface { + // Compile is used for the cel expression compilation + // perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input. + Compile(expressions []ExpressionAccessor, optionalDecls OptionalVariableDeclarations, perCallLimit uint64) Filter +} + +// OptionalVariableBindings provides expression bindings for optional CEL variables. +type OptionalVariableBindings struct { + // VersionedParams provides the "params" variable binding. This variable binding may + // be set to nil even when OptionalVariableDeclarations.HashParams is set to true. + VersionedParams runtime.Object + // Authorizer provides the authorizer used for the "authorizer" and + // "authorizer.requestResource" variable bindings. If the expression was compiled with + // OptionalVariableDeclarations.HasAuthorizer set to true this must be non-nil. + Authorizer authorizer.Authorizer +} + +// Filter contains a function to evaluate compiled CEL-typed values +// It expects the inbound object to already have been converted to the version expected +// by the underlying CEL code (which is indicated by the match criteria of a policy definition). +// versionedParams may be nil. +type Filter interface { + // ForInput converts compiled CEL-typed values into evaluated CEL-typed value. + // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. + // If cost budget is calculated, the filter should return the remaining budget. + ForInput(ctx context.Context, versionedAttr *admission.VersionedAttributes, request *v1.AdmissionRequest, optionalVars OptionalVariableBindings, runtimeCELCostBudget int64) ([]EvaluationResult, int64, error) + + // CompilationErrors returns a list of errors from the compilation of the evaluator + CompilationErrors() []error +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission.go index acc307630..9a514b463 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/admission.go @@ -23,6 +23,8 @@ import ( "io" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/cel/openapi/resolver" "k8s.io/apiserver/pkg/features" "k8s.io/client-go/dynamic" "k8s.io/component-base/featuregate" @@ -71,6 +73,8 @@ type celAdmissionPlugin struct { restMapper meta.RESTMapper dynamicClient dynamic.Interface stopCh <-chan struct{} + authorizer authorizer.Authorizer + schemaResolver resolver.SchemaResolver } var _ initializer.WantsExternalKubeInformerFactory = &celAdmissionPlugin{} @@ -78,7 +82,8 @@ var _ initializer.WantsExternalKubeClientSet = &celAdmissionPlugin{} var _ initializer.WantsRESTMapper = &celAdmissionPlugin{} var _ initializer.WantsDynamicClient = &celAdmissionPlugin{} var _ initializer.WantsDrainedNotification = &celAdmissionPlugin{} - +var _ initializer.WantsAuthorizer = &celAdmissionPlugin{} +var _ initializer.WantsSchemaResolver = &celAdmissionPlugin{} var _ admission.InitializationValidator = &celAdmissionPlugin{} var _ admission.ValidationInterface = &celAdmissionPlugin{} @@ -108,6 +113,14 @@ func (c *celAdmissionPlugin) SetDrainedNotification(stopCh <-chan struct{}) { c.stopCh = stopCh } +func (c *celAdmissionPlugin) SetAuthorizer(authorizer authorizer.Authorizer) { + c.authorizer = authorizer +} + +func (c *celAdmissionPlugin) SetSchemaResolver(resolver resolver.SchemaResolver) { + c.schemaResolver = resolver +} + func (c *celAdmissionPlugin) InspectFeatureGates(featureGates featuregate.FeatureGate) { if featureGates.Enabled(features.ValidatingAdmissionPolicy) { c.enabled = true @@ -138,7 +151,10 @@ func (c *celAdmissionPlugin) ValidateInitialization() error { if c.stopCh == nil { return errors.New("missing stop channel") } - c.evaluator = NewAdmissionController(c.informerFactory, c.client, c.restMapper, c.dynamicClient) + if c.authorizer == nil { + return errors.New("missing authorizer") + } + c.evaluator = NewAdmissionController(c.informerFactory, c.client, c.restMapper, c.schemaResolver /* (optional) */, c.dynamicClient, c.authorizer) if err := c.evaluator.ValidateInitialization(); err != nil { return err } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go index 4398aa6b1..f54f1acb3 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller.go @@ -20,25 +20,35 @@ import ( "context" "errors" "fmt" + "strings" "sync" "sync/atomic" + "time" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching" + "k8s.io/klog/v2" "k8s.io/api/admissionregistration/v1alpha1" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + utiljson "k8s.io/apimachinery/pkg/util/json" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/admission" celmetrics "k8s.io/apiserver/pkg/admission/cel" + "k8s.io/apiserver/pkg/admission/plugin/cel" "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic" + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/cel/openapi/resolver" + "k8s.io/apiserver/pkg/warning" "k8s.io/client-go/dynamic" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" ) var _ CELPolicyEvaluator = &celAdmissionController{} @@ -46,44 +56,32 @@ var _ CELPolicyEvaluator = &celAdmissionController{} // celAdmissionController is the top-level controller for admission control using CEL // it is responsible for watching policy definitions, bindings, and config param CRDs type celAdmissionController struct { - // Context under which the controller runs - runningContext context.Context + // Controller which manages book-keeping for the cluster's dynamic policy + // information. + policyController *policyController - policyDefinitionsController generic.Controller[*v1alpha1.ValidatingAdmissionPolicy] - policyBindingController generic.Controller[*v1alpha1.ValidatingAdmissionPolicyBinding] + // atomic []policyData + // list of every known policy definition, and all informatoin required to + // validate its bindings against an object. + // A snapshot of the current policy configuration is synced with this field + // asynchronously + definitions atomic.Value +} - // dynamicclient used to create informers to watch the param crd types - dynamicClient dynamic.Interface - restMapper meta.RESTMapper +// Everything someone might need to validate a single ValidatingPolicyDefinition +// against all of its registered bindings. +type policyData struct { + definitionInfo + paramController generic.Controller[runtime.Object] + bindings []bindingInfo +} - // Provided to the policy's Compile function as an injected dependency to - // assist with compiling its expressions to CEL - validatorCompiler ValidatorCompiler - - // Lock which protects: - // - definitionInfo - // - bindingInfos - // - paramCRDControllers - // - definitionsToBindings - // All other fields should be assumed constant - mutex sync.RWMutex - - // controller and metadata - paramsCRDControllers map[v1alpha1.ParamKind]*paramInfo - - // Index for each definition namespace/name, contains all binding - // namespace/names known to exist for that definition - definitionInfo map[namespacedName]*definitionInfo - - // Index for each bindings namespace/name. Contains compiled templates - // for the binding depending on the policy/param combination. - bindingInfos map[namespacedName]*bindingInfo - - // Map from namespace/name of a definition to a set of namespace/name - // of bindings which depend on it. - // All keys must have at least one dependent binding - // All binding names MUST exist as a key bindingInfos - definitionsToBindings map[namespacedName]sets.Set[namespacedName] +// contains the cel PolicyDecisions along with the ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding +// that determined the decision +type policyDecisionWithMetadata struct { + PolicyDecision + Definition *v1alpha1.ValidatingAdmissionPolicy + Binding *v1alpha1.ValidatingAdmissionPolicyBinding } // namespaceName is used as a key in definitionInfo and bindingInfos @@ -104,7 +102,7 @@ type definitionInfo struct { type bindingInfo struct { // Compiled CEL expression turned into an validator - validator atomic.Pointer[Validator] + validator Validator // Last value seen by this controller to be used in policy enforcement // May not be nil @@ -113,7 +111,7 @@ type bindingInfo struct { type paramInfo struct { // Controller which is watching this param CRD - controller generic.Controller[*unstructured.Unstructured] + controller generic.Controller[runtime.Object] // Function to call to stop the informer and clean up the controller stop func() @@ -127,67 +125,54 @@ func NewAdmissionController( informerFactory informers.SharedInformerFactory, client kubernetes.Interface, restMapper meta.RESTMapper, + schemaResolver resolver.SchemaResolver, dynamicClient dynamic.Interface, + authz authorizer.Authorizer, ) CELPolicyEvaluator { - matcher := matching.NewMatcher(informerFactory.Core().V1().Namespaces().Lister(), client) - validatorCompiler := &CELValidatorCompiler{ - Matcher: matcher, + var typeChecker *TypeChecker + if schemaResolver != nil { + typeChecker = &TypeChecker{schemaResolver: schemaResolver, restMapper: restMapper} } - c := &celAdmissionController{ - definitionInfo: make(map[namespacedName]*definitionInfo), - bindingInfos: make(map[namespacedName]*bindingInfo), - paramsCRDControllers: make(map[v1alpha1.ParamKind]*paramInfo), - definitionsToBindings: make(map[namespacedName]sets.Set[namespacedName]), - dynamicClient: dynamicClient, - validatorCompiler: validatorCompiler, - restMapper: restMapper, + return &celAdmissionController{ + definitions: atomic.Value{}, + policyController: newPolicyController( + restMapper, + client, + dynamicClient, + typeChecker, + cel.NewFilterCompiler(), + NewMatcher(matching.NewMatcher(informerFactory.Core().V1().Namespaces().Lister(), client)), + generic.NewInformer[*v1alpha1.ValidatingAdmissionPolicy]( + informerFactory.Admissionregistration().V1alpha1().ValidatingAdmissionPolicies().Informer()), + generic.NewInformer[*v1alpha1.ValidatingAdmissionPolicyBinding]( + informerFactory.Admissionregistration().V1alpha1().ValidatingAdmissionPolicyBindings().Informer()), + authz, + ), } - - c.policyDefinitionsController = generic.NewController( - generic.NewInformer[*v1alpha1.ValidatingAdmissionPolicy]( - informerFactory.Admissionregistration().V1alpha1().ValidatingAdmissionPolicies().Informer()), - c.reconcilePolicyDefinition, - generic.ControllerOptions{ - Workers: 1, - Name: "cel-policy-definitions", - }, - ) - c.policyBindingController = generic.NewController( - generic.NewInformer[*v1alpha1.ValidatingAdmissionPolicyBinding]( - informerFactory.Admissionregistration().V1alpha1().ValidatingAdmissionPolicyBindings().Informer()), - c.reconcilePolicyBinding, - generic.ControllerOptions{ - Workers: 1, - Name: "cel-policy-bindings", - }, - ) - return c } func (c *celAdmissionController) Run(stopCh <-chan struct{}) { - if c.runningContext != nil { - return - } - ctx, cancel := context.WithCancel(context.Background()) - - c.runningContext = ctx - defer func() { - c.runningContext = nil - }() - wg := sync.WaitGroup{} wg.Add(1) go func() { defer wg.Done() - c.policyDefinitionsController.Run(ctx) + c.policyController.Run(ctx) }() wg.Add(1) go func() { defer wg.Done() - c.policyBindingController.Run(ctx) + + // Wait indefinitely until policies/bindings are listed & handled before + // allowing policies to be refreshed + if !cache.WaitForNamedCacheSync("cel-admission-controller", ctx.Done(), c.policyController.HasSynced) { + return + } + + // Loop every 1 second until context is cancelled, refreshing policies + wait.Until(c.refreshPolicies, 1*time.Second, ctx.Done()) }() <-stopCh @@ -195,13 +180,16 @@ func (c *celAdmissionController) Run(stopCh <-chan struct{}) { wg.Wait() } +const maxAuditAnnotationValueLength = 10 * 1024 + func (c *celAdmissionController) Validate( ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces, ) (err error) { - c.mutex.RLock() - defer c.mutex.RUnlock() + if !c.HasSynced() { + return admission.NewForbidden(a, fmt.Errorf("not yet ready to handle request")) + } var deniedDecisions []policyDecisionWithMetadata @@ -227,27 +215,29 @@ func (c *celAdmissionController) Validate( message = fmt.Errorf("failed to configure binding: %w", err).Error() } deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ - policyDecision: policyDecision{ - action: actionDeny, - message: message, + PolicyDecision: PolicyDecision{ + Action: ActionDeny, + Message: message, }, - definition: definition, - binding: binding, + Definition: definition, + Binding: binding, }) default: deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ - policyDecision: policyDecision{ - action: actionDeny, - message: fmt.Errorf("unrecognized failure policy: '%v'", policy).Error(), + PolicyDecision: PolicyDecision{ + Action: ActionDeny, + Message: fmt.Errorf("unrecognized failure policy: '%v'", policy).Error(), }, - definition: definition, - binding: binding, + Definition: definition, + Binding: binding, }) } } - for definitionNamespacedName, definitionInfo := range c.definitionInfo { + policyDatas := c.definitions.Load().([]policyData) + + for _, definitionInfo := range policyDatas { definition := definitionInfo.lastReconciledValue - matches, matchKind, err := c.validatorCompiler.DefinitionMatches(a, o, definition) + matches, matchKind, err := c.policyController.matcher.DefinitionMatches(a, o, definition) if err != nil { // Configuration error. addConfigError(err, definition, nil) @@ -262,17 +252,12 @@ func (c *celAdmissionController) Validate( continue } - dependentBindings := c.definitionsToBindings[definitionNamespacedName] - if len(dependentBindings) == 0 { - continue - } - - for namespacedBindingName := range dependentBindings { + auditAnnotationCollector := newAuditAnnotationCollector() + for _, bindingInfo := range definitionInfo.bindings { // If the key is inside dependentBindings, there is guaranteed to // be a bindingInfo for it - bindingInfo := c.bindingInfos[namespacedBindingName] binding := bindingInfo.lastReconciledValue - matches, err := c.validatorCompiler.BindingMatches(a, o, binding) + matches, err := c.policyController.matcher.BindingMatches(a, o, binding) if err != nil { // Configuration error. addConfigError(err, definition, binding) @@ -282,18 +267,21 @@ func (c *celAdmissionController) Validate( continue } - var param *unstructured.Unstructured + var param runtime.Object + + // versionedAttributes will be set to non-nil inside of the loop, but + // is scoped outside of the param loop so we only convert once. We defer + // conversion so that it is only performed when we know a policy matches, + // saving the cost of converting non-matching requests. + var versionedAttr *admission.VersionedAttributes // If definition has paramKind, paramRef is required in binding. // If definition has no paramKind, paramRef set in binding will be ignored. paramKind := definition.Spec.ParamKind paramRef := binding.Spec.ParamRef if paramKind != nil && paramRef != nil { - - // Find the params referred by the binding by looking its name up - // in our informer for its CRD - paramInfo, ok := c.paramsCRDControllers[*paramKind] - if !ok { + paramController := definitionInfo.paramController + if paramController == nil { addConfigError(fmt.Errorf("paramKind kind `%v` not known", paramKind.String()), definition, binding) continue @@ -302,18 +290,19 @@ func (c *celAdmissionController) Validate( // If the param informer for this admission policy has not yet // had time to perform an initial listing, don't attempt to use // it. - //!TOOD(alexzielenski): add a wait for a very short amount of - // time for the cache to sync - if !paramInfo.controller.HasSynced() { + timeoutCtx, cancel := context.WithTimeout(c.policyController.context, 1*time.Second) + defer cancel() + + if !cache.WaitForCacheSync(timeoutCtx.Done(), paramController.HasSynced) { addConfigError(fmt.Errorf("paramKind kind `%v` not yet synced to use for admission", paramKind.String()), definition, binding) continue } if len(paramRef.Namespace) == 0 { - param, err = paramInfo.controller.Informer().Get(paramRef.Name) + param, err = paramController.Informer().Get(paramRef.Name) } else { - param, err = paramInfo.controller.Informer().Namespaced(paramRef.Namespace).Get(paramRef.Name) + param, err = paramController.Informer().Namespaced(paramRef.Namespace).Get(paramRef.Name) } if err != nil { @@ -336,16 +325,17 @@ func (c *celAdmissionController) Validate( } } - validator := bindingInfo.validator.Load() - if validator == nil { - // Compile policy definition using binding - newValidator := c.validatorCompiler.Compile(definition) - validator = &newValidator - - bindingInfo.validator.Store(validator) + if versionedAttr == nil { + va, err := admission.NewVersionedAttributes(a, matchKind, o) + if err != nil { + wrappedErr := fmt.Errorf("failed to convert object version: %w", err) + addConfigError(wrappedErr, definition, binding) + continue + } + versionedAttr = va } - decisions, err := (*validator).Validate(a, o, param, matchKind) + validationResult := bindingInfo.validator.Validate(ctx, versionedAttr, param, celconfig.RuntimeCELCostBudget) if err != nil { // runtime error. Apply failure policy wrappedError := fmt.Errorf("failed to evaluate CEL expression: %w", err) @@ -353,38 +343,77 @@ func (c *celAdmissionController) Validate( continue } - for _, decision := range decisions { - switch decision.action { - case actionAdmit: - if decision.evaluation == evalError { - celmetrics.Metrics.ObserveAdmissionWithError(ctx, decision.elapsed, definition.Name, binding.Name, "active") + for i, decision := range validationResult.Decisions { + switch decision.Action { + case ActionAdmit: + if decision.Evaluation == EvalError { + celmetrics.Metrics.ObserveAdmissionWithError(ctx, decision.Elapsed, definition.Name, binding.Name, "active") + } + case ActionDeny: + for _, action := range binding.Spec.ValidationActions { + switch action { + case v1alpha1.Deny: + deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ + Definition: definition, + Binding: binding, + PolicyDecision: decision, + }) + celmetrics.Metrics.ObserveRejection(ctx, decision.Elapsed, definition.Name, binding.Name, "active") + case v1alpha1.Audit: + c.publishValidationFailureAnnotation(binding, i, decision, versionedAttr) + celmetrics.Metrics.ObserveAudit(ctx, decision.Elapsed, definition.Name, binding.Name, "active") + case v1alpha1.Warn: + warning.AddWarning(ctx, "", fmt.Sprintf("Validation failed for ValidatingAdmissionPolicy '%s' with binding '%s': %s", definition.Name, binding.Name, decision.Message)) + celmetrics.Metrics.ObserveWarn(ctx, decision.Elapsed, definition.Name, binding.Name, "active") + } } - case actionDeny: - deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ - definition: definition, - binding: binding, - policyDecision: decision, - }) - celmetrics.Metrics.ObserveRejection(ctx, decision.elapsed, definition.Name, binding.Name, "active") default: return fmt.Errorf("unrecognized evaluation decision '%s' for ValidatingAdmissionPolicyBinding '%s' with ValidatingAdmissionPolicy '%s'", - decision.action, binding.Name, definition.Name) + decision.Action, binding.Name, definition.Name) + } + } + + for _, auditAnnotation := range validationResult.AuditAnnotations { + switch auditAnnotation.Action { + case AuditAnnotationActionPublish: + value := auditAnnotation.Value + if len(auditAnnotation.Value) > maxAuditAnnotationValueLength { + value = value[:maxAuditAnnotationValueLength] + } + auditAnnotationCollector.add(auditAnnotation.Key, value) + case AuditAnnotationActionError: + // When failurePolicy=fail, audit annotation errors result in deny + deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{ + Definition: definition, + Binding: binding, + PolicyDecision: PolicyDecision{ + Action: ActionDeny, + Evaluation: EvalError, + Message: auditAnnotation.Error, + Elapsed: auditAnnotation.Elapsed, + }, + }) + celmetrics.Metrics.ObserveRejection(ctx, auditAnnotation.Elapsed, definition.Name, binding.Name, "active") + case AuditAnnotationActionExclude: // skip it + default: + return fmt.Errorf("unsupported AuditAnnotation Action: %s", auditAnnotation.Action) } } } + auditAnnotationCollector.publish(definition.Name, a) } if len(deniedDecisions) > 0 { // TODO: refactor admission.NewForbidden so the name extraction is reusable but the code/reason is customizable var message string deniedDecision := deniedDecisions[0] - if deniedDecision.binding != nil { - message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' with binding '%s' denied request: %s", deniedDecision.definition.Name, deniedDecision.binding.Name, deniedDecision.message) + if deniedDecision.Binding != nil { + message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' with binding '%s' denied request: %s", deniedDecision.Definition.Name, deniedDecision.Binding.Name, deniedDecision.Message) } else { - message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' denied request: %s", deniedDecision.definition.Name, deniedDecision.message) + message = fmt.Sprintf("ValidatingAdmissionPolicy '%s' denied request: %s", deniedDecision.Definition.Name, deniedDecision.Message) } err := admission.NewForbidden(a, errors.New(message)).(*k8serrors.StatusError) - reason := deniedDecision.reason + reason := deniedDecision.Reason if len(reason) == 0 { reason = metav1.StatusReasonInvalid } @@ -396,11 +425,78 @@ func (c *celAdmissionController) Validate( return nil } +func (c *celAdmissionController) publishValidationFailureAnnotation(binding *v1alpha1.ValidatingAdmissionPolicyBinding, expressionIndex int, decision PolicyDecision, attributes admission.Attributes) { + key := "validation.policy.admission.k8s.io/validation_failure" + // Marshal to a list of failures since, in the future, we may need to support multiple failures + valueJson, err := utiljson.Marshal([]validationFailureValue{{ + ExpressionIndex: expressionIndex, + Message: decision.Message, + ValidationActions: binding.Spec.ValidationActions, + Binding: binding.Name, + Policy: binding.Spec.PolicyName, + }}) + if err != nil { + klog.Warningf("Failed to set admission audit annotation %s for ValidatingAdmissionPolicy %s and ValidatingAdmissionPolicyBinding %s: %v", key, binding.Spec.PolicyName, binding.Name, err) + } + value := string(valueJson) + if err := attributes.AddAnnotation(key, value); err != nil { + klog.Warningf("Failed to set admission audit annotation %s to %s for ValidatingAdmissionPolicy %s and ValidatingAdmissionPolicyBinding %s: %v", key, value, binding.Spec.PolicyName, binding.Name, err) + } +} + func (c *celAdmissionController) HasSynced() bool { - return c.policyBindingController.HasSynced() && - c.policyDefinitionsController.HasSynced() + return c.policyController.HasSynced() && c.definitions.Load() != nil } func (c *celAdmissionController) ValidateInitialization() error { - return c.validatorCompiler.ValidateInitialization() + return c.policyController.matcher.ValidateInitialization() +} + +func (c *celAdmissionController) refreshPolicies() { + c.definitions.Store(c.policyController.latestPolicyData()) +} + +// validationFailureValue defines the JSON format of a "validation.policy.admission.k8s.io/validation_failure" audit +// annotation value. +type validationFailureValue struct { + Message string `json:"message"` + Policy string `json:"policy"` + Binding string `json:"binding"` + ExpressionIndex int `json:"expressionIndex"` + ValidationActions []v1alpha1.ValidationAction `json:"validationActions"` +} + +type auditAnnotationCollector struct { + annotations map[string][]string +} + +func newAuditAnnotationCollector() auditAnnotationCollector { + return auditAnnotationCollector{annotations: map[string][]string{}} +} + +func (a auditAnnotationCollector) add(key, value string) { + // If multiple bindings produces the exact same key and value for an audit annotation, + // ignore the duplicates. + for _, v := range a.annotations[key] { + if v == value { + return + } + } + a.annotations[key] = append(a.annotations[key], value) +} + +func (a auditAnnotationCollector) publish(policyName string, attributes admission.Attributes) { + for key, bindingAnnotations := range a.annotations { + var value string + if len(bindingAnnotations) == 1 { + value = bindingAnnotations[0] + } else { + // Multiple distinct values can exist when binding params are used in the valueExpression of an auditAnnotation. + // When this happens, the values are concatenated into a comma-separated list. + value = strings.Join(bindingAnnotations, ", ") + } + if err := attributes.AddAnnotation(policyName+"/"+key, value); err != nil { + klog.Warningf("Failed to set admission audit annotation %s to %s for ValidatingAdmissionPolicy %s: %v", key, value, policyName, err) + } + } } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller_reconcile.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller_reconcile.go index eaf37b471..296ac416a 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller_reconcile.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/controller_reconcile.go @@ -19,22 +19,177 @@ package validatingadmissionpolicy import ( "context" "fmt" + "sync" "time" + v1 "k8s.io/api/admissionregistration/v1" "k8s.io/api/admissionregistration/v1alpha1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" celmetrics "k8s.io/apiserver/pkg/admission/cel" + "k8s.io/apiserver/pkg/admission/plugin/cel" "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic" + "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic/dynamicinformer" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + k8sscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/cache" ) -func (c *celAdmissionController) reconcilePolicyDefinition(namespace, name string, definition *v1alpha1.ValidatingAdmissionPolicy) error { +type policyController struct { + once sync.Once + context context.Context + dynamicClient dynamic.Interface + restMapper meta.RESTMapper + policyDefinitionsController generic.Controller[*v1alpha1.ValidatingAdmissionPolicy] + policyBindingController generic.Controller[*v1alpha1.ValidatingAdmissionPolicyBinding] + + // Provided to the policy's Compile function as an injected dependency to + // assist with compiling its expressions to CEL + filterCompiler cel.FilterCompiler + + matcher Matcher + + newValidator + + // The TypeCheck checks the policy's expressions for type errors. + // Type of params is defined in policy.Spec.ParamsKind + // Types of object are calculated from policy.Spec.MatchingConstraints + typeChecker *TypeChecker + + // Lock which protects: + // - cachedPolicies + // - paramCRDControllers + // - definitionInfo + // - bindingInfos + // - definitionsToBindings + // All other fields should be assumed constant + mutex sync.RWMutex + + cachedPolicies []policyData + + // controller and metadata + paramsCRDControllers map[v1alpha1.ParamKind]*paramInfo + + // Index for each definition namespace/name, contains all binding + // namespace/names known to exist for that definition + definitionInfo map[namespacedName]*definitionInfo + + // Index for each bindings namespace/name. Contains compiled templates + // for the binding depending on the policy/param combination. + bindingInfos map[namespacedName]*bindingInfo + + // Map from namespace/name of a definition to a set of namespace/name + // of bindings which depend on it. + // All keys must have at least one dependent binding + // All binding names MUST exist as a key bindingInfos + definitionsToBindings map[namespacedName]sets.Set[namespacedName] + + client kubernetes.Interface + + authz authorizer.Authorizer +} + +type newValidator func(validationFilter cel.Filter, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.Filter, failurePolicy *v1.FailurePolicyType, authorizer authorizer.Authorizer) Validator + +func newPolicyController( + restMapper meta.RESTMapper, + client kubernetes.Interface, + dynamicClient dynamic.Interface, + typeChecker *TypeChecker, + filterCompiler cel.FilterCompiler, + matcher Matcher, + policiesInformer generic.Informer[*v1alpha1.ValidatingAdmissionPolicy], + bindingsInformer generic.Informer[*v1alpha1.ValidatingAdmissionPolicyBinding], + authz authorizer.Authorizer, +) *policyController { + res := &policyController{} + *res = policyController{ + filterCompiler: filterCompiler, + typeChecker: typeChecker, + definitionInfo: make(map[namespacedName]*definitionInfo), + bindingInfos: make(map[namespacedName]*bindingInfo), + paramsCRDControllers: make(map[v1alpha1.ParamKind]*paramInfo), + definitionsToBindings: make(map[namespacedName]sets.Set[namespacedName]), + matcher: matcher, + newValidator: NewValidator, + policyDefinitionsController: generic.NewController( + policiesInformer, + res.reconcilePolicyDefinition, + generic.ControllerOptions{ + Workers: 1, + Name: "cel-policy-definitions", + }, + ), + policyBindingController: generic.NewController( + bindingsInformer, + res.reconcilePolicyBinding, + generic.ControllerOptions{ + Workers: 1, + Name: "cel-policy-bindings", + }, + ), + restMapper: restMapper, + dynamicClient: dynamicClient, + client: client, + authz: authz, + } + return res +} + +func (c *policyController) Run(ctx context.Context) { + // Only support being run once + c.once.Do(func() { + c.context = ctx + + wg := sync.WaitGroup{} + + wg.Add(1) + go func() { + defer wg.Done() + c.policyDefinitionsController.Run(ctx) + }() + + wg.Add(1) + go func() { + defer wg.Done() + c.policyBindingController.Run(ctx) + }() + + <-ctx.Done() + wg.Wait() + }) +} + +func (c *policyController) HasSynced() bool { + return c.policyDefinitionsController.HasSynced() && c.policyBindingController.HasSynced() +} + +func (c *policyController) reconcilePolicyDefinition(namespace, name string, definition *v1alpha1.ValidatingAdmissionPolicy) error { c.mutex.Lock() defer c.mutex.Unlock() + err := c.reconcilePolicyDefinitionSpec(namespace, name, definition) + if err != nil { + return err + } + if c.typeChecker != nil { + err = c.reconcilePolicyStatus(namespace, name, definition) + } + return err +} + +func (c *policyController) reconcilePolicyDefinitionSpec(namespace, name string, definition *v1alpha1.ValidatingAdmissionPolicy) error { + c.cachedPolicies = nil // invalidate cachedPolicies // Namespace for policydefinition is empty. nn := getNamespaceName(namespace, name) @@ -46,6 +201,12 @@ func (c *celAdmissionController) reconcilePolicyDefinition(namespace, name strin celmetrics.Metrics.ObserveDefinition(context.TODO(), "active", "deny") } + // Skip reconcile if the spec of the definition is unchanged + if info.lastReconciledValue != nil && definition != nil && + apiequality.Semantic.DeepEqual(info.lastReconciledValue.Spec, definition.Spec) { + return nil + } + var paramSource *v1alpha1.ParamKind if definition != nil { paramSource = definition.Spec.ParamKind @@ -75,7 +236,7 @@ func (c *celAdmissionController) reconcilePolicyDefinition(namespace, name strin // definition has changed. for key := range c.definitionsToBindings[nn] { bindingInfo := c.bindingInfos[key] - bindingInfo.validator.Store(nil) + bindingInfo.validator = nil c.bindingInfos[key] = bindingInfo } @@ -125,20 +286,77 @@ func (c *celAdmissionController) reconcilePolicyDefinition(namespace, name strin info.dependentDefinitions.Insert(nn) } else { - instanceContext, instanceCancel := context.WithCancel(c.runningContext) + instanceContext, instanceCancel := context.WithCancel(c.context) - // Watch for new instances of this policy - informer := dynamicinformer.NewFilteredDynamicInformer( - c.dynamicClient, - paramsGVR.Resource, - corev1.NamespaceAll, - 30*time.Second, - cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, - nil, - ) + var informer cache.SharedIndexInformer + + // Informer Factory is optional + if c.client != nil { + // Create temporary informer factory + // Cannot use the k8s shared informer factory for dynamic params informer. + // Would leak unnecessary informers when we are done since we would have to + // call informerFactory.Start() with a longer-lived stopCh than necessary. + // SharedInformerFactory does not support temporary usage. + dynamicFactory := informers.NewSharedInformerFactory(c.client, 10*time.Minute) + + // Look for a typed informer. If it does not exist + genericInformer, err := dynamicFactory.ForResource(paramsGVR.Resource) + + // Ignore error. We fallback to dynamic informer if there is no + // typed informer + if err != nil { + informer = nil + } else { + informer = genericInformer.Informer() + + // Set transformer on the informer to workaround inconsistency + // where typed objects have TypeMeta wiped out but dynamic + // objects keep kind/apiVersion fields + informer.SetTransform(func(i interface{}) (interface{}, error) { + // Ensure param is populated with its GVK for consistency + // (CRD dynamic informer always returns objects with kind/apiversion, + // but native types do not include populated TypeMeta. + if param := i.(runtime.Object); param != nil { + if param.GetObjectKind().GroupVersionKind().Empty() { + // https://github.com/kubernetes/client-go/issues/413#issue-324586398 + gvks, _, _ := k8sscheme.Scheme.ObjectKinds(param) + for _, gvk := range gvks { + if len(gvk.Kind) == 0 { + continue + } + if len(gvk.Version) == 0 || gvk.Version == runtime.APIVersionInternal { + continue + } + param.GetObjectKind().SetGroupVersionKind(gvk) + break + } + } + } + + return i, nil + }) + } + } + + if informer == nil { + // Dynamic JSON informer fallback. + // Cannot use shared dynamic informer since it would be impossible + // to clean CRD informers properly with multiple dependents + // (cannot start ahead of time, and cannot track dependencies via stopCh) + informer = dynamicinformer.NewFilteredDynamicInformer( + c.dynamicClient, + paramsGVR.Resource, + corev1.NamespaceAll, + // Use same interval as is used for k8s typed sharedInformerFactory + // https://github.com/kubernetes/kubernetes/blob/7e0923899fed622efbc8679cca6b000d43633e38/cmd/kube-apiserver/app/server.go#L430 + 10*time.Minute, + cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, + nil, + ).Informer() + } controller := generic.NewController( - generic.NewInformer[*unstructured.Unstructured](informer.Informer()), + generic.NewInformer[runtime.Object](informer), c.reconcileParams, generic.ControllerOptions{ Workers: 1, @@ -152,17 +370,19 @@ func (c *celAdmissionController) reconcilePolicyDefinition(namespace, name strin dependentDefinitions: sets.New(nn), } - go informer.Informer().Run(instanceContext.Done()) go controller.Run(instanceContext) + go informer.Run(instanceContext.Done()) } return nil } -func (c *celAdmissionController) reconcilePolicyBinding(namespace, name string, binding *v1alpha1.ValidatingAdmissionPolicyBinding) error { +func (c *policyController) reconcilePolicyBinding(namespace, name string, binding *v1alpha1.ValidatingAdmissionPolicyBinding) error { c.mutex.Lock() defer c.mutex.Unlock() + c.cachedPolicies = nil // invalidate cachedPolicies + // Namespace for PolicyBinding is empty. In the future a namespaced binding // may be added // https://github.com/kubernetes/enhancements/blob/bf5c3c81ea2081d60c1dc7c832faa98479e06209/keps/sig-api-machinery/3488-cel-admission-control/README.md?plain=1#L1042 @@ -173,6 +393,12 @@ func (c *celAdmissionController) reconcilePolicyBinding(namespace, name string, c.bindingInfos[nn] = info } + // Skip if the spec of the binding is unchanged. + if info.lastReconciledValue != nil && binding != nil && + apiequality.Semantic.DeepEqual(info.lastReconciledValue.Spec, binding.Spec) { + return nil + } + var oldNamespacedDefinitionName namespacedName if info.lastReconciledValue != nil { // All validating policies are cluster-scoped so have empty namespace @@ -212,12 +438,36 @@ func (c *celAdmissionController) reconcilePolicyBinding(namespace, name string, } // Remove compiled template for old binding - info.validator.Store(nil) + info.validator = nil info.lastReconciledValue = binding return nil } -func (c *celAdmissionController) reconcileParams(namespace, name string, params *unstructured.Unstructured) error { +func (c *policyController) reconcilePolicyStatus(namespace, name string, definition *v1alpha1.ValidatingAdmissionPolicy) error { + if definition != nil && definition.Status.ObservedGeneration < definition.Generation { + st := c.calculatePolicyStatus(definition) + newDefinition := definition.DeepCopy() + newDefinition.Status = *st + _, err := c.client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().UpdateStatus(c.context, newDefinition, metav1.UpdateOptions{}) + if err != nil { + // ignore error when the controller is not able to + // mutate the definition, and to avoid infinite requeue. + utilruntime.HandleError(err) + } + } + return nil +} + +func (c *policyController) calculatePolicyStatus(definition *v1alpha1.ValidatingAdmissionPolicy) *v1alpha1.ValidatingAdmissionPolicyStatus { + expressionWarnings := c.typeChecker.Check(definition) + // modifying a deepcopy of the original status, preserving unrelated existing data + status := definition.Status.DeepCopy() + status.ObservedGeneration = definition.Generation + status.TypeChecking = &v1alpha1.TypeChecking{ExpressionWarnings: expressionWarnings} + return status +} + +func (c *policyController) reconcileParams(namespace, name string, params runtime.Object) error { // Do nothing. // When we add informational type checking we will need to compile in the // reconcile loops instead of lazily so we can add compiler errors / type @@ -225,6 +475,127 @@ func (c *celAdmissionController) reconcileParams(namespace, name string, params return nil } +// Fetches the latest set of policy data or recalculates it if it has changed +// since it was last fetched +func (c *policyController) latestPolicyData() []policyData { + existing := func() []policyData { + c.mutex.RLock() + defer c.mutex.RUnlock() + + return c.cachedPolicies + }() + + if existing != nil { + return existing + } + + c.mutex.Lock() + defer c.mutex.Unlock() + + var res []policyData + for definitionNN, definitionInfo := range c.definitionInfo { + var bindingInfos []bindingInfo + for bindingNN := range c.definitionsToBindings[definitionNN] { + bindingInfo := c.bindingInfos[bindingNN] + if bindingInfo.validator == nil && definitionInfo.configurationError == nil { + hasParam := false + if definitionInfo.lastReconciledValue.Spec.ParamKind != nil { + hasParam = true + } + optionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: true} + expressionOptionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: false} + failurePolicy := convertv1alpha1FailurePolicyTypeTov1FailurePolicyType(definitionInfo.lastReconciledValue.Spec.FailurePolicy) + var matcher matchconditions.Matcher = nil + matchConditions := definitionInfo.lastReconciledValue.Spec.MatchConditions + if len(matchConditions) > 0 { + matchExpressionAccessors := make([]cel.ExpressionAccessor, len(matchConditions)) + for i := range matchConditions { + matchExpressionAccessors[i] = (*matchconditions.MatchCondition)(&matchConditions[i]) + } + matcher = matchconditions.NewMatcher(c.filterCompiler.Compile(matchExpressionAccessors, optionalVars, celconfig.PerCallLimit), c.authz, failurePolicy, "validatingadmissionpolicy", definitionInfo.lastReconciledValue.Name) + } + bindingInfo.validator = c.newValidator( + c.filterCompiler.Compile(convertv1alpha1Validations(definitionInfo.lastReconciledValue.Spec.Validations), optionalVars, celconfig.PerCallLimit), + matcher, + c.filterCompiler.Compile(convertv1alpha1AuditAnnotations(definitionInfo.lastReconciledValue.Spec.AuditAnnotations), optionalVars, celconfig.PerCallLimit), + c.filterCompiler.Compile(convertV1Alpha1MessageExpressions(definitionInfo.lastReconciledValue.Spec.Validations), expressionOptionalVars, celconfig.PerCallLimit), + failurePolicy, + c.authz, + ) + } + bindingInfos = append(bindingInfos, *bindingInfo) + } + + var paramController generic.Controller[runtime.Object] + if paramKind := definitionInfo.lastReconciledValue.Spec.ParamKind; paramKind != nil { + if info, ok := c.paramsCRDControllers[*paramKind]; ok { + paramController = info.controller + } + } + + res = append(res, policyData{ + definitionInfo: *definitionInfo, + paramController: paramController, + bindings: bindingInfos, + }) + } + + c.cachedPolicies = res + return res +} + +func convertv1alpha1FailurePolicyTypeTov1FailurePolicyType(policyType *v1alpha1.FailurePolicyType) *v1.FailurePolicyType { + if policyType == nil { + return nil + } + + var v1FailPolicy v1.FailurePolicyType + if *policyType == v1alpha1.Fail { + v1FailPolicy = v1.Fail + } else if *policyType == v1alpha1.Ignore { + v1FailPolicy = v1.Ignore + } + return &v1FailPolicy +} + +func convertv1alpha1Validations(inputValidations []v1alpha1.Validation) []cel.ExpressionAccessor { + celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations)) + for i, validation := range inputValidations { + validation := ValidationCondition{ + Expression: validation.Expression, + Message: validation.Message, + Reason: validation.Reason, + } + celExpressionAccessor[i] = &validation + } + return celExpressionAccessor +} + +func convertV1Alpha1MessageExpressions(inputValidations []v1alpha1.Validation) []cel.ExpressionAccessor { + celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations)) + for i, validation := range inputValidations { + if validation.MessageExpression != "" { + condition := MessageExpressionCondition{ + MessageExpression: validation.MessageExpression, + } + celExpressionAccessor[i] = &condition + } + } + return celExpressionAccessor +} + +func convertv1alpha1AuditAnnotations(inputValidations []v1alpha1.AuditAnnotation) []cel.ExpressionAccessor { + celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations)) + for i, validation := range inputValidations { + validation := AuditAnnotationCondition{ + Key: validation.Key, + ValueExpression: validation.ValueExpression, + } + celExpressionAccessor[i] = &validation + } + return celExpressionAccessor +} + func getNamespaceName(namespace, name string) namespacedName { return namespacedName{ namespace: namespace, diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/initializer.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/initializer.go index 563bb69de..15b757985 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/initializer.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/initializer.go @@ -18,6 +18,7 @@ package validatingadmissionpolicy import ( "context" + "k8s.io/apiserver/pkg/admission" ) diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go index 217d6bfc4..0f84152e8 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/interface.go @@ -17,34 +17,73 @@ limitations under the License. package validatingadmissionpolicy import ( + "context" + + celgo "github.com/google/cel-go/cel" + "k8s.io/api/admissionregistration/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/plugin/cel" ) -// Validator defines the func used to validate the cel expressions -// matchKind provides the GroupVersionKind that the object should be -// validated by CEL expressions as. -type Validator interface { - Validate(a admission.Attributes, o admission.ObjectInterfaces, versionedParams runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error) +var _ cel.ExpressionAccessor = &ValidationCondition{} + +// ValidationCondition contains the inputs needed to compile, evaluate and validate a cel expression +type ValidationCondition struct { + Expression string + Message string + Reason *metav1.StatusReason } -// ValidatorCompiler is Dependency Injected into the PolicyDefinition's `Compile` -// function to assist with converting types and values to/from CEL-typed values. -type ValidatorCompiler interface { +func (v *ValidationCondition) GetExpression() string { + return v.Expression +} + +func (v *ValidationCondition) ReturnTypes() []*celgo.Type { + return []*celgo.Type{celgo.BoolType} +} + +// AuditAnnotationCondition contains the inputs needed to compile, evaluate and publish a cel audit annotation +type AuditAnnotationCondition struct { + Key string + ValueExpression string +} + +func (v *AuditAnnotationCondition) GetExpression() string { + return v.ValueExpression +} + +func (v *AuditAnnotationCondition) ReturnTypes() []*celgo.Type { + return []*celgo.Type{celgo.StringType, celgo.NullType} +} + +// Matcher is used for matching ValidatingAdmissionPolicy and ValidatingAdmissionPolicyBinding to attributes +type Matcher interface { admission.InitializationValidator - // Matches says whether this policy definition matches the provided admission + // DefinitionMatches says whether this policy definition matches the provided admission // resource request DefinitionMatches(a admission.Attributes, o admission.ObjectInterfaces, definition *v1alpha1.ValidatingAdmissionPolicy) (bool, schema.GroupVersionKind, error) - // Matches says whether this policy definition matches the provided admission + // BindingMatches says whether this policy definition matches the provided admission // resource request BindingMatches(a admission.Attributes, o admission.ObjectInterfaces, definition *v1alpha1.ValidatingAdmissionPolicyBinding) (bool, error) - - // Compile is used for the cel expression compilation - Compile( - policy *v1alpha1.ValidatingAdmissionPolicy, - ) Validator +} + +// ValidateResult defines the result of a Validator.Validate operation. +type ValidateResult struct { + // Decisions specifies the outcome of the validation as well as the details about the decision. + Decisions []PolicyDecision + // AuditAnnotations specifies the audit annotations that should be recorded for the validation. + AuditAnnotations []PolicyAuditAnnotation +} + +// Validator is contains logic for converting ValidationEvaluation to PolicyDecisions +type Validator interface { + // Validate is used to take cel evaluations and convert into decisions + // runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. + Validate(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/controller.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/controller.go index bd5ea818d..4334c0dd8 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/controller.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/internal/generic/controller.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "sync" + "sync/atomic" "time" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -30,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/cache/synctrack" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" ) @@ -45,6 +47,11 @@ type controller[T runtime.Object] struct { reconciler func(namespace, name string, newObj T) error options ControllerOptions + + // must hold a func() bool or nil + notificationsDelivered atomic.Value + + hasProcessed synctrack.AsyncTracker[string] } type ControllerOptions struct { @@ -69,12 +76,20 @@ func NewController[T runtime.Object]( options.Name = fmt.Sprintf("%T-controller", *new(T)) } - return &controller[T]{ + c := &controller[T]{ options: options, informer: informer, reconciler: reconciler, queue: nil, } + c.hasProcessed.UpstreamHasSynced = func() bool { + f := c.notificationsDelivered.Load() + if f == nil { + return false + } + return f.(func() bool)() + } + return c } // Runs the controller and returns an error explaining why running was stopped. @@ -92,20 +107,22 @@ func (c *controller[T]) Run(ctx context.Context) error { // would never shut down the workqueue defer c.queue.ShutDown() - enqueue := func(obj interface{}) { + enqueue := func(obj interface{}, isInInitialList bool) { var key string var err error if key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj); err != nil { utilruntime.HandleError(err) return } + if isInInitialList { + c.hasProcessed.Start(key) + } + c.queue.Add(key) } - registration, err := c.informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: func(obj interface{}) { - enqueue(obj) - }, + registration, err := c.informer.AddEventHandler(cache.ResourceEventHandlerDetailedFuncs{ + AddFunc: enqueue, UpdateFunc: func(oldObj, newObj interface{}) { oldMeta, err1 := meta.Accessor(oldObj) newMeta, err2 := meta.Accessor(newObj) @@ -126,11 +143,11 @@ func (c *controller[T]) Run(ctx context.Context) error { return } - enqueue(newObj) + enqueue(newObj, false) }, DeleteFunc: func(obj interface{}) { // Enqueue - enqueue(obj) + enqueue(obj, false) }, }) @@ -139,9 +156,12 @@ func (c *controller[T]) Run(ctx context.Context) error { return err } + c.notificationsDelivered.Store(registration.HasSynced) + // Make sure event handler is removed from informer in case return early from // an error defer func() { + c.notificationsDelivered.Store(func() bool { return false }) // Remove event handler and Handle Error here. Error should only be raised // for improper usage of event handler API. if err := c.informer.RemoveEventHandler(registration); err != nil { @@ -166,8 +186,8 @@ func (c *controller[T]) Run(ctx context.Context) error { for i := uint(0); i < c.options.Workers; i++ { waitGroup.Add(1) go func() { + defer waitGroup.Done() wait.Until(c.runWorker, time.Second, ctx.Done()) - waitGroup.Done() }() } @@ -188,7 +208,7 @@ func (c *controller[T]) Run(ctx context.Context) error { } func (c *controller[T]) HasSynced() bool { - return c.informer.HasSynced() + return c.hasProcessed.HasSynced() } func (c *controller[T]) runWorker() { @@ -220,6 +240,7 @@ func (c *controller[T]) runWorker() { // but the key is invalid so there is no point in doing that) return fmt.Errorf("expected string in workqueue but got %#v", obj) } + defer c.hasProcessed.Finished(key) if err := c.reconcile(key); err != nil { // Put the item back on the workqueue to handle any transient errors. diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matcher.go new file mode 100644 index 000000000..a659a99f1 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matcher.go @@ -0,0 +1,78 @@ +/* +Copyright 2022 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 validatingadmissionpolicy + +import ( + "k8s.io/api/admissionregistration/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching" +) + +var _ matching.MatchCriteria = &matchCriteria{} + +type matchCriteria struct { + constraints *v1alpha1.MatchResources +} + +// GetParsedNamespaceSelector returns the converted LabelSelector which implements labels.Selector +func (m *matchCriteria) GetParsedNamespaceSelector() (labels.Selector, error) { + return metav1.LabelSelectorAsSelector(m.constraints.NamespaceSelector) +} + +// GetParsedObjectSelector returns the converted LabelSelector which implements labels.Selector +func (m *matchCriteria) GetParsedObjectSelector() (labels.Selector, error) { + return metav1.LabelSelectorAsSelector(m.constraints.ObjectSelector) +} + +// GetMatchResources returns the matchConstraints +func (m *matchCriteria) GetMatchResources() v1alpha1.MatchResources { + return *m.constraints +} + +type matcher struct { + Matcher *matching.Matcher +} + +func NewMatcher(m *matching.Matcher) Matcher { + return &matcher{ + Matcher: m, + } +} + +// ValidateInitialization checks if Matcher is initialized. +func (c *matcher) ValidateInitialization() error { + return c.Matcher.ValidateInitialization() +} + +// DefinitionMatches returns whether this ValidatingAdmissionPolicy matches the provided admission resource request +func (c *matcher) DefinitionMatches(a admission.Attributes, o admission.ObjectInterfaces, definition *v1alpha1.ValidatingAdmissionPolicy) (bool, schema.GroupVersionKind, error) { + criteria := matchCriteria{constraints: definition.Spec.MatchConstraints} + return c.Matcher.Matches(a, o, &criteria) +} + +// BindingMatches returns whether this ValidatingAdmissionPolicyBinding matches the provided admission resource request +func (c *matcher) BindingMatches(a admission.Attributes, o admission.ObjectInterfaces, binding *v1alpha1.ValidatingAdmissionPolicyBinding) (bool, error) { + if binding.Spec.MatchResources == nil { + return true, nil + } + criteria := matchCriteria{constraints: binding.Spec.MatchResources} + isMatch, _, err := c.Matcher.Matches(a, o, &criteria) + return isMatch, err +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/message.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/message.go new file mode 100644 index 000000000..772891e3c --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/message.go @@ -0,0 +1,36 @@ +/* +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 validatingadmissionpolicy + +import ( + celgo "github.com/google/cel-go/cel" + "k8s.io/apiserver/pkg/admission/plugin/cel" +) + +var _ cel.ExpressionAccessor = (*MessageExpressionCondition)(nil) + +type MessageExpressionCondition struct { + MessageExpression string +} + +func (m *MessageExpressionCondition) GetExpression() string { + return m.MessageExpression +} + +func (m *MessageExpressionCondition) ReturnTypes() []*celgo.Type { + return []*celgo.Type{celgo.StringType} +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go index 101874370..939cbea70 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/policy_decision.go @@ -20,37 +20,54 @@ import ( "net/http" "time" - "k8s.io/api/admissionregistration/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -type policyDecisionAction string +type PolicyDecisionAction string const ( - actionAdmit policyDecisionAction = "admit" - actionDeny policyDecisionAction = "deny" + ActionAdmit PolicyDecisionAction = "admit" + ActionDeny PolicyDecisionAction = "deny" ) -type policyDecisionEvaluation string +type PolicyDecisionEvaluation string const ( - evalAdmit policyDecisionEvaluation = "admit" - evalError policyDecisionEvaluation = "error" - evalDeny policyDecisionEvaluation = "deny" + EvalAdmit PolicyDecisionEvaluation = "admit" + EvalError PolicyDecisionEvaluation = "error" + EvalDeny PolicyDecisionEvaluation = "deny" ) -type policyDecision struct { - action policyDecisionAction - evaluation policyDecisionEvaluation - message string - reason metav1.StatusReason - elapsed time.Duration +// PolicyDecision contains the action determined from a cel evaluation along with metadata such as message, reason and duration +type PolicyDecision struct { + Action PolicyDecisionAction + Evaluation PolicyDecisionEvaluation + Message string + Reason metav1.StatusReason + Elapsed time.Duration } -type policyDecisionWithMetadata struct { - policyDecision - definition *v1alpha1.ValidatingAdmissionPolicy - binding *v1alpha1.ValidatingAdmissionPolicyBinding +type PolicyAuditAnnotationAction string + +const ( + // AuditAnnotationActionPublish indicates that the audit annotation should be + // published with the audit event. + AuditAnnotationActionPublish PolicyAuditAnnotationAction = "publish" + // AuditAnnotationActionError indicates that the valueExpression resulted + // in an error. + AuditAnnotationActionError PolicyAuditAnnotationAction = "error" + // AuditAnnotationActionExclude indicates that the audit annotation should be excluded + // because the valueExpression evaluated to null, or because FailurePolicy is Ignore + // and the expression failed with a parse error, type check error, or runtime error. + AuditAnnotationActionExclude PolicyAuditAnnotationAction = "exclude" +) + +type PolicyAuditAnnotation struct { + Key string + Value string + Elapsed time.Duration + Action PolicyAuditAnnotationAction + Error string } func reasonToCode(r metav1.StatusReason) int32 { diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/typechecking.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/typechecking.go new file mode 100644 index 000000000..7b128e381 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/typechecking.go @@ -0,0 +1,435 @@ +/* +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 validatingadmissionpolicy + +import ( + "errors" + "fmt" + "sort" + "strings" + "sync" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types/ref" + + "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/validation/field" + plugincel "k8s.io/apiserver/pkg/admission/plugin/cel" + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/common" + "k8s.io/apiserver/pkg/cel/library" + "k8s.io/apiserver/pkg/cel/openapi" + "k8s.io/apiserver/pkg/cel/openapi/resolver" + "k8s.io/klog/v2" +) + +const maxTypesToCheck = 10 + +type TypeChecker struct { + schemaResolver resolver.SchemaResolver + restMapper meta.RESTMapper +} + +type typeOverwrite struct { + object *apiservercel.DeclType + params *apiservercel.DeclType +} + +// typeCheckingResult holds the issues found during type checking, any returned +// error, and the gvk that the type checking is performed against. +type typeCheckingResult struct { + gvk schema.GroupVersionKind + + issues *cel.Issues + err error +} + +// Check preforms the type check against the given policy, and format the result +// as []ExpressionWarning that is ready to be set in policy.Status +// The result is nil if type checking returns no warning. +// The policy object is NOT mutated. The caller should update Status accordingly +func (c *TypeChecker) Check(policy *v1alpha1.ValidatingAdmissionPolicy) []v1alpha1.ExpressionWarning { + exps := make([]string, 0, len(policy.Spec.Validations)) + // check main validation expressions, located in spec.validations[*] + fieldRef := field.NewPath("spec", "validations") + for _, v := range policy.Spec.Validations { + exps = append(exps, v.Expression) + } + msgs := c.CheckExpressions(exps, policy.Spec.ParamKind != nil, policy) + var results []v1alpha1.ExpressionWarning // intentionally not setting capacity + for i, msg := range msgs { + if msg != "" { + results = append(results, v1alpha1.ExpressionWarning{ + FieldRef: fieldRef.Index(i).Child("expression").String(), + Warning: msg, + }) + } + } + return results +} + +// CheckExpressions checks a set of compiled CEL programs against the GVKs defined in +// policy.Spec.MatchConstraints +// The result is a human-readable form that describe which expressions +// violate what types at what place. The indexes of the return []string +// matches these of the input expressions. +// TODO: It is much more useful to have machine-readable output and let the +// client format it. That requires an update to the KEP, probably in coming +// releases. +func (c *TypeChecker) CheckExpressions(expressions []string, hasParams bool, policy *v1alpha1.ValidatingAdmissionPolicy) []string { + var allWarnings []string + allGvks := c.typesToCheck(policy) + gvks := make([]schema.GroupVersionKind, 0, len(allGvks)) + schemas := make([]common.Schema, 0, len(allGvks)) + for _, gvk := range allGvks { + s, err := c.schemaResolver.ResolveSchema(gvk) + if err != nil { + // type checking errors MUST NOT alter the behavior of the policy + // even if an error occurs. + if !errors.Is(err, resolver.ErrSchemaNotFound) { + // Anything except ErrSchemaNotFound is an internal error + klog.ErrorS(err, "internal error: schema resolution failure", "gvk", gvk) + } + // skip if an unrecoverable error occurs. + continue + } + gvks = append(gvks, gvk) + schemas = append(schemas, &openapi.Schema{Schema: s}) + } + + paramsType := c.paramsType(policy) + paramsDeclType, err := c.declType(paramsType) + if err != nil { + if !errors.Is(err, resolver.ErrSchemaNotFound) { + klog.V(2).ErrorS(err, "cannot resolve schema for params", "gvk", paramsType) + } + paramsDeclType = nil + } + + for _, exp := range expressions { + var results []typeCheckingResult + for i, gvk := range gvks { + s := schemas[i] + issues, err := c.checkExpression(exp, hasParams, typeOverwrite{ + object: common.SchemaDeclType(s, true), + params: paramsDeclType, + }) + // save even if no issues are found, for the sake of formatting. + results = append(results, typeCheckingResult{ + gvk: gvk, + issues: issues, + err: err, + }) + } + allWarnings = append(allWarnings, c.formatWarning(results)) + } + + return allWarnings +} + +// formatWarning converts the resulting issues and possible error during +// type checking into a human-readable string +func (c *TypeChecker) formatWarning(results []typeCheckingResult) string { + var sb strings.Builder + for _, result := range results { + if result.issues == nil && result.err == nil { + continue + } + if result.err != nil { + sb.WriteString(fmt.Sprintf("%v: type checking error: %v\n", result.gvk, result.err)) + } else { + sb.WriteString(fmt.Sprintf("%v: %s\n", result.gvk, result.issues)) + } + } + return strings.TrimSuffix(sb.String(), "\n") +} + +func (c *TypeChecker) declType(gvk schema.GroupVersionKind) (*apiservercel.DeclType, error) { + if gvk.Empty() { + return nil, nil + } + s, err := c.schemaResolver.ResolveSchema(gvk) + if err != nil { + return nil, err + } + return common.SchemaDeclType(&openapi.Schema{Schema: s}, true), nil +} + +func (c *TypeChecker) paramsType(policy *v1alpha1.ValidatingAdmissionPolicy) schema.GroupVersionKind { + if policy.Spec.ParamKind == nil { + return schema.GroupVersionKind{} + } + gv, err := schema.ParseGroupVersion(policy.Spec.ParamKind.APIVersion) + if err != nil { + return schema.GroupVersionKind{} + } + return gv.WithKind(policy.Spec.ParamKind.Kind) +} + +func (c *TypeChecker) checkExpression(expression string, hasParams bool, types typeOverwrite) (*cel.Issues, error) { + env, err := buildEnv(hasParams, types) + if err != nil { + return nil, err + } + + // We cannot reuse an AST that is parsed by another env, so reparse it here. + // Compile = Parse + Check, we especially want the results of Check. + // + // Paradoxically, we discard the type-checked result and let the admission + // controller use the dynamic typed program. + // This is a compromise that is defined in the KEP. We can revisit this + // decision and expect a change with limited size. + _, issues := env.Compile(expression) + return issues, nil +} + +// typesToCheck extracts a list of GVKs that needs type checking from the policy +// the result is sorted in the order of Group, Version, and Kind +func (c *TypeChecker) typesToCheck(p *v1alpha1.ValidatingAdmissionPolicy) []schema.GroupVersionKind { + gvks := sets.New[schema.GroupVersionKind]() + if p.Spec.MatchConstraints == nil || len(p.Spec.MatchConstraints.ResourceRules) == 0 { + return nil + } + + for _, rule := range p.Spec.MatchConstraints.ResourceRules { + groups := extractGroups(&rule.Rule) + if len(groups) == 0 { + continue + } + versions := extractVersions(&rule.Rule) + if len(versions) == 0 { + continue + } + resources := extractResources(&rule.Rule) + if len(resources) == 0 { + continue + } + // sort GVRs so that the loop below provides + // consistent results. + sort.Strings(groups) + sort.Strings(versions) + sort.Strings(resources) + count := 0 + for _, group := range groups { + for _, version := range versions { + for _, resource := range resources { + gvr := schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: resource, + } + resolved, err := c.restMapper.KindsFor(gvr) + if err != nil { + continue + } + for _, r := range resolved { + if !r.Empty() { + gvks.Insert(r) + count++ + // early return if maximum number of types are already + // collected + if count == maxTypesToCheck { + if gvks.Len() == 0 { + return nil + } + return sortGVKList(gvks.UnsortedList()) + } + } + } + } + } + } + } + if gvks.Len() == 0 { + return nil + } + return sortGVKList(gvks.UnsortedList()) +} + +func extractGroups(rule *v1alpha1.Rule) []string { + groups := make([]string, 0, len(rule.APIGroups)) + for _, group := range rule.APIGroups { + // give up if wildcard + if strings.ContainsAny(group, "*") { + return nil + } + groups = append(groups, group) + } + return groups +} + +func extractVersions(rule *v1alpha1.Rule) []string { + versions := make([]string, 0, len(rule.APIVersions)) + for _, version := range rule.APIVersions { + if strings.ContainsAny(version, "*") { + return nil + } + versions = append(versions, version) + } + return versions +} + +func extractResources(rule *v1alpha1.Rule) []string { + resources := make([]string, 0, len(rule.Resources)) + for _, resource := range rule.Resources { + // skip wildcard and subresources + if strings.ContainsAny(resource, "*/") { + continue + } + resources = append(resources, resource) + } + return resources +} + +// sortGVKList sorts the list by Group, Version, and Kind +// returns the list itself. +func sortGVKList(list []schema.GroupVersionKind) []schema.GroupVersionKind { + sort.Slice(list, func(i, j int) bool { + if g := strings.Compare(list[i].Group, list[j].Group); g != 0 { + return g < 0 + } + if v := strings.Compare(list[i].Version, list[j].Version); v != 0 { + return v < 0 + } + return strings.Compare(list[i].Kind, list[j].Kind) < 0 + }) + return list +} + +func buildEnv(hasParams bool, types typeOverwrite) (*cel.Env, error) { + baseEnv, err := getBaseEnv() + if err != nil { + return nil, err + } + reg := apiservercel.NewRegistry(baseEnv) + requestType := plugincel.BuildRequestType() + + var varOpts []cel.EnvOption + var rts []*apiservercel.RuleTypes + + // request, hand-crafted type + rt, opts, err := createRuleTypesAndOptions(reg, requestType, plugincel.RequestVarName) + if err != nil { + return nil, err + } + rts = append(rts, rt) + varOpts = append(varOpts, opts...) + + // object and oldObject, same type, type(s) resolved from constraints + rt, opts, err = createRuleTypesAndOptions(reg, types.object, plugincel.ObjectVarName, plugincel.OldObjectVarName) + if err != nil { + return nil, err + } + rts = append(rts, rt) + varOpts = append(varOpts, opts...) + + // params, defined by ParamKind + if hasParams { + rt, opts, err := createRuleTypesAndOptions(reg, types.params, plugincel.ParamsVarName) + if err != nil { + return nil, err + } + rts = append(rts, rt) + varOpts = append(varOpts, opts...) + } + + opts, err = ruleTypesOpts(rts, baseEnv.TypeProvider()) + if err != nil { + return nil, err + } + opts = append(opts, varOpts...) // add variables after ruleTypes. + env, err := baseEnv.Extend(opts...) + if err != nil { + return nil, err + } + return env, nil +} + +// createRuleTypeAndOptions creates the cel RuleTypes and a slice of EnvOption +// that can be used for creating a CEL env containing variables of declType. +// declType can be nil, in which case the variables will be of DynType. +func createRuleTypesAndOptions(registry *apiservercel.Registry, declType *apiservercel.DeclType, variables ...string) (*apiservercel.RuleTypes, []cel.EnvOption, error) { + opts := make([]cel.EnvOption, 0, len(variables)) + // untyped, use DynType + if declType == nil { + for _, v := range variables { + opts = append(opts, cel.Variable(v, cel.DynType)) + } + return nil, opts, nil + } + // create a RuleType for the given type + rt, err := apiservercel.NewRuleTypes(declType.TypeName(), declType, registry) + if err != nil { + return nil, nil, err + } + if rt == nil { + return nil, nil, nil + } + for _, v := range variables { + opts = append(opts, cel.Variable(v, declType.CelType())) + } + return rt, opts, nil +} + +func ruleTypesOpts(ruleTypes []*apiservercel.RuleTypes, underlyingTypeProvider ref.TypeProvider) ([]cel.EnvOption, error) { + var providers []ref.TypeProvider // may be unused, too small to matter + var adapters []ref.TypeAdapter + for _, rt := range ruleTypes { + if rt != nil { + withTP, err := rt.WithTypeProvider(underlyingTypeProvider) + if err != nil { + return nil, err + } + providers = append(providers, withTP) + adapters = append(adapters, withTP) + } + } + var tp ref.TypeProvider + var ta ref.TypeAdapter + switch len(providers) { + case 0: + return nil, nil + case 1: + tp = providers[0] + ta = adapters[0] + default: + tp = &apiservercel.CompositedTypeProvider{Providers: providers} + ta = &apiservercel.CompositedTypeAdapter{Adapters: adapters} + } + return []cel.EnvOption{cel.CustomTypeProvider(tp), cel.CustomTypeAdapter(ta)}, nil +} + +func getBaseEnv() (*cel.Env, error) { + typeCheckingBaseEnvInit.Do(func() { + var opts []cel.EnvOption + opts = append(opts, cel.HomogeneousAggregateLiterals()) + // Validate function declarations once during base env initialization, + // so they don't need to be evaluated each time a CEL rule is compiled. + // This is a relatively expensive operation. + opts = append(opts, cel.EagerlyValidateDeclarations(true), cel.DefaultUTCTimeZone(true)) + opts = append(opts, library.ExtensionLibs...) + typeCheckingBaseEnv, typeCheckingBaseEnvError = cel.NewEnv(opts...) + }) + return typeCheckingBaseEnv, typeCheckingBaseEnvError +} + +var typeCheckingBaseEnv *cel.Env +var typeCheckingBaseEnvError error +var typeCheckingBaseEnvInit sync.Once diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go index 033d2e48e..448750c91 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/validator.go @@ -17,302 +17,232 @@ limitations under the License. package validatingadmissionpolicy import ( + "context" "fmt" - "reflect" "strings" - "time" celtypes "github.com/google/cel-go/common/types" - "github.com/google/cel-go/interpreter" - admissionv1 "k8s.io/api/admission/v1" - "k8s.io/api/admissionregistration/v1alpha1" - authenticationv1 "k8s.io/api/authentication/v1" + v1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" - "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy/matching" - "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" + "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/klog/v2" ) -var _ ValidatorCompiler = &CELValidatorCompiler{} -var _ matching.MatchCriteria = &matchCriteria{} - -type matchCriteria struct { - constraints *v1alpha1.MatchResources +// validator implements the Validator interface +type validator struct { + celMatcher matchconditions.Matcher + validationFilter cel.Filter + auditAnnotationFilter cel.Filter + messageFilter cel.Filter + failPolicy *v1.FailurePolicyType + authorizer authorizer.Authorizer } -// GetParsedNamespaceSelector returns the converted LabelSelector which implements labels.Selector -func (m *matchCriteria) GetParsedNamespaceSelector() (labels.Selector, error) { - return metav1.LabelSelectorAsSelector(m.constraints.NamespaceSelector) -} - -// GetParsedObjectSelector returns the converted LabelSelector which implements labels.Selector -func (m *matchCriteria) GetParsedObjectSelector() (labels.Selector, error) { - return metav1.LabelSelectorAsSelector(m.constraints.ObjectSelector) -} - -// GetMatchResources returns the matchConstraints -func (m *matchCriteria) GetMatchResources() v1alpha1.MatchResources { - return *m.constraints -} - -// CELValidatorCompiler implement the interface ValidatorCompiler. -type CELValidatorCompiler struct { - Matcher *matching.Matcher -} - -// DefinitionMatches returns whether this ValidatingAdmissionPolicy matches the provided admission resource request -func (c *CELValidatorCompiler) DefinitionMatches(a admission.Attributes, o admission.ObjectInterfaces, definition *v1alpha1.ValidatingAdmissionPolicy) (bool, schema.GroupVersionKind, error) { - criteria := matchCriteria{constraints: definition.Spec.MatchConstraints} - return c.Matcher.Matches(a, o, &criteria) -} - -// BindingMatches returns whether this ValidatingAdmissionPolicyBinding matches the provided admission resource request -func (c *CELValidatorCompiler) BindingMatches(a admission.Attributes, o admission.ObjectInterfaces, binding *v1alpha1.ValidatingAdmissionPolicyBinding) (bool, error) { - if binding.Spec.MatchResources == nil { - return true, nil - } - criteria := matchCriteria{constraints: binding.Spec.MatchResources} - isMatch, _, err := c.Matcher.Matches(a, o, &criteria) - return isMatch, err -} - -// ValidateInitialization checks if Matcher is initialized. -func (c *CELValidatorCompiler) ValidateInitialization() error { - return c.Matcher.ValidateInitialization() -} - -type validationActivation struct { - object, oldObject, params, request interface{} -} - -// ResolveName returns a value from the activation by qualified name, or false if the name -// could not be found. -func (a *validationActivation) ResolveName(name string) (interface{}, bool) { - switch name { - case ObjectVarName: - return a.object, true - case OldObjectVarName: - return a.oldObject, true - case ParamsVarName: - return a.params, true - case RequestVarName: - return a.request, true - default: - return nil, false +func NewValidator(validationFilter cel.Filter, celMatcher matchconditions.Matcher, auditAnnotationFilter, messageFilter cel.Filter, failPolicy *v1.FailurePolicyType, authorizer authorizer.Authorizer) Validator { + return &validator{ + celMatcher: celMatcher, + validationFilter: validationFilter, + auditAnnotationFilter: auditAnnotationFilter, + messageFilter: messageFilter, + failPolicy: failPolicy, + authorizer: authorizer, } } -// Parent returns the parent of the current activation, may be nil. -// If non-nil, the parent will be searched during resolve calls. -func (a *validationActivation) Parent() interpreter.Activation { - return nil +func policyDecisionActionForError(f v1.FailurePolicyType) PolicyDecisionAction { + if f == v1.Ignore { + return ActionAdmit + } + return ActionDeny } -// Compile compiles the cel expression defined in ValidatingAdmissionPolicy -func (c *CELValidatorCompiler) Compile(p *v1alpha1.ValidatingAdmissionPolicy) Validator { - if len(p.Spec.Validations) == 0 { - return nil +func auditAnnotationEvaluationForError(f v1.FailurePolicyType) PolicyAuditAnnotationAction { + if f == v1.Ignore { + return AuditAnnotationActionExclude } - hasParam := false - if p.Spec.ParamKind != nil { - hasParam = true - } - compilationResults := make([]CompilationResult, len(p.Spec.Validations)) - for i, validation := range p.Spec.Validations { - compilationResults[i] = CompileValidatingPolicyExpression(validation.Expression, hasParam) - } - return &CELValidator{policy: p, compilationResults: compilationResults} + return AuditAnnotationActionError } -// CELValidator implements the Validator interface -type CELValidator struct { - policy *v1alpha1.ValidatingAdmissionPolicy - compilationResults []CompilationResult -} - -func convertObjectToUnstructured(obj interface{}) (*unstructured.Unstructured, error) { - if obj == nil || reflect.ValueOf(obj).IsNil() { - return &unstructured.Unstructured{Object: nil}, nil - } - ret, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) - if err != nil { - return nil, err - } - return &unstructured.Unstructured{Object: ret}, nil -} - -func objectToResolveVal(r runtime.Object) (interface{}, error) { - if r == nil || reflect.ValueOf(r).IsNil() { - return nil, nil - } - v, err := convertObjectToUnstructured(r) - if err != nil { - return nil, err - } - return v.Object, nil -} - -func policyDecisionActionForError(f v1alpha1.FailurePolicyType) policyDecisionAction { - if f == v1alpha1.Ignore { - return actionAdmit - } - return actionDeny -} - -// Validate validates all cel expressions in Validator and returns a PolicyDecision for each CEL expression or returns an error. -// An error will be returned if failed to convert the object/oldObject/params/request to unstructured. -// Each PolicyDecision will have a decision and a message. -// policyDecision.message will be empty if the decision is allowed and no error met. -func (v *CELValidator) Validate(a admission.Attributes, o admission.ObjectInterfaces, versionedParams runtime.Object, matchKind schema.GroupVersionKind) ([]policyDecision, error) { - // TODO: replace unstructured with ref.Val for CEL variables when native type support is available - - decisions := make([]policyDecision, len(v.compilationResults)) - var err error - versionedAttr, err := generic.NewVersionedAttributes(a, matchKind, o) - if err != nil { - return nil, err - } - oldObjectVal, err := objectToResolveVal(versionedAttr.VersionedOldObject) - if err != nil { - return nil, err - } - objectVal, err := objectToResolveVal(versionedAttr.VersionedObject) - if err != nil { - return nil, err - } - paramsVal, err := objectToResolveVal(versionedParams) - if err != nil { - return nil, err - } - request := createAdmissionRequest(versionedAttr.Attributes) - requestVal, err := convertObjectToUnstructured(request) - if err != nil { - return nil, err - } - va := &validationActivation{ - object: objectVal, - oldObject: oldObjectVal, - params: paramsVal, - request: requestVal.Object, - } - - var f v1alpha1.FailurePolicyType - if v.policy.Spec.FailurePolicy == nil { - f = v1alpha1.Fail +// Validate takes a list of Evaluation and a failure policy and converts them into actionable PolicyDecisions +// runtimeCELCostBudget was added for testing purpose only. Callers should always use const RuntimeCELCostBudget from k8s.io/apiserver/pkg/apis/cel/config.go as input. +func (v *validator) Validate(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, runtimeCELCostBudget int64) ValidateResult { + var f v1.FailurePolicyType + if v.failPolicy == nil { + f = v1.Fail } else { - f = *v.policy.Spec.FailurePolicy + f = *v.failPolicy } - for i, compilationResult := range v.compilationResults { - validation := v.policy.Spec.Validations[i] + if v.celMatcher != nil { + matchResults := v.celMatcher.Match(ctx, versionedAttr, versionedParams) + if matchResults.Error != nil { + return ValidateResult{ + Decisions: []PolicyDecision{ + { + Action: policyDecisionActionForError(f), + Evaluation: EvalError, + Message: matchResults.Error.Error(), + }, + }, + } + } - var policyDecision = &decisions[i] + // if preconditions are not met, then do not return any validations + if !matchResults.Matches { + return ValidateResult{} + } + } - if compilationResult.Error != nil { - policyDecision.action = policyDecisionActionForError(f) - policyDecision.evaluation = evalError - policyDecision.message = fmt.Sprintf("compilation error: %v", compilationResult.Error) + optionalVars := cel.OptionalVariableBindings{VersionedParams: versionedParams, Authorizer: v.authorizer} + expressionOptionalVars := cel.OptionalVariableBindings{VersionedParams: versionedParams} + admissionRequest := cel.CreateAdmissionRequest(versionedAttr.Attributes) + evalResults, remainingBudget, err := v.validationFilter.ForInput(ctx, versionedAttr, admissionRequest, optionalVars, runtimeCELCostBudget) + if err != nil { + return ValidateResult{ + Decisions: []PolicyDecision{ + { + Action: policyDecisionActionForError(f), + Evaluation: EvalError, + Message: err.Error(), + }, + }, + } + } + decisions := make([]PolicyDecision, len(evalResults)) + messageResults, _, err := v.messageFilter.ForInput(ctx, versionedAttr, admissionRequest, expressionOptionalVars, remainingBudget) + for i, evalResult := range evalResults { + var decision = &decisions[i] + // TODO: move this to generics + validation, ok := evalResult.ExpressionAccessor.(*ValidationCondition) + if !ok { + klog.Error("Invalid type conversion to ValidationCondition") + decision.Action = policyDecisionActionForError(f) + decision.Evaluation = EvalError + decision.Message = "Invalid type sent to validator, expected ValidationCondition" continue } - if compilationResult.Program == nil { - policyDecision.action = policyDecisionActionForError(f) - policyDecision.evaluation = evalError - policyDecision.message = "unexpected internal error compiling expression" - continue + + var messageResult *cel.EvaluationResult + var messageError *apiservercel.Error + if len(messageResults) > i { + messageResult = &messageResults[i] } - t1 := time.Now() - evalResult, _, err := compilationResult.Program.Eval(va) - elapsed := time.Since(t1) - policyDecision.elapsed = elapsed - if err != nil { - policyDecision.action = policyDecisionActionForError(f) - policyDecision.evaluation = evalError - policyDecision.message = fmt.Sprintf("expression '%v' resulted in error: %v", v.policy.Spec.Validations[i].Expression, err) - } else if evalResult != celtypes.True { - policyDecision.action = actionDeny + messageError, _ = err.(*apiservercel.Error) + if evalResult.Error != nil { + decision.Action = policyDecisionActionForError(f) + decision.Evaluation = EvalError + decision.Message = evalResult.Error.Error() + } else if messageError != nil && + (messageError.Type == apiservercel.ErrorTypeInternal || + (messageError.Type == apiservercel.ErrorTypeInvalid && + strings.HasPrefix(messageError.Detail, "validation failed due to running out of cost budget"))) { + decision.Action = policyDecisionActionForError(f) + decision.Evaluation = EvalError + decision.Message = fmt.Sprintf("failed messageExpression: %s", err) + } else if evalResult.EvalResult != celtypes.True { + decision.Action = ActionDeny if validation.Reason == nil { - policyDecision.reason = metav1.StatusReasonInvalid + decision.Reason = metav1.StatusReasonInvalid } else { - policyDecision.reason = *validation.Reason + decision.Reason = *validation.Reason } - if len(validation.Message) > 0 { - policyDecision.message = strings.TrimSpace(validation.Message) - } else { - policyDecision.message = fmt.Sprintf("failed expression: %v", strings.TrimSpace(validation.Expression)) + // decide the failure message + var message string + // attempt to set message with messageExpression result + if messageResult != nil && messageResult.Error == nil && messageResult.EvalResult != nil { + // also fallback if the eval result is non-string (including null) or + // whitespaces. + if message, ok = messageResult.EvalResult.Value().(string); ok { + message = strings.TrimSpace(message) + // deny excessively long message from EvalResult + if len(message) > celconfig.MaxEvaluatedMessageExpressionSizeBytes { + klog.V(2).InfoS("excessively long message denied", "message", message) + message = "" + } + // deny message that contains newlines + if strings.ContainsAny(message, "\n") { + klog.V(2).InfoS("multi-line message denied", "message", message) + message = "" + } + } } - + if messageResult != nil && messageResult.Error != nil { + // log any error with messageExpression + klog.V(2).ErrorS(messageResult.Error, "error while evaluating messageExpression") + } + // fallback to set message to the custom message + if message == "" && len(validation.Message) > 0 { + message = strings.TrimSpace(validation.Message) + } + // fallback to use the expression to compose a message + if message == "" { + message = fmt.Sprintf("failed expression: %v", strings.TrimSpace(validation.Expression)) + } + decision.Message = message } else { - policyDecision.action = actionAdmit - policyDecision.evaluation = evalAdmit + decision.Action = ActionAdmit + decision.Evaluation = EvalAdmit } } - return decisions, nil -} - -func createAdmissionRequest(attr admission.Attributes) *admissionv1.AdmissionRequest { - // FIXME: how to get resource GVK, GVR and subresource? - gvk := attr.GetKind() - gvr := attr.GetResource() - subresource := attr.GetSubresource() - - requestGVK := attr.GetKind() - requestGVR := attr.GetResource() - requestSubResource := attr.GetSubresource() - - aUserInfo := attr.GetUserInfo() - var userInfo authenticationv1.UserInfo - if aUserInfo != nil { - userInfo = authenticationv1.UserInfo{ - Extra: make(map[string]authenticationv1.ExtraValue), - Groups: aUserInfo.GetGroups(), - UID: aUserInfo.GetUID(), - Username: aUserInfo.GetName(), - } - // Convert the extra information in the user object - for key, val := range aUserInfo.GetExtra() { - userInfo.Extra[key] = authenticationv1.ExtraValue(val) - } - } - - dryRun := attr.IsDryRun() - - return &admissionv1.AdmissionRequest{ - Kind: metav1.GroupVersionKind{ - Group: gvk.Group, - Kind: gvk.Kind, - Version: gvk.Version, - }, - Resource: metav1.GroupVersionResource{ - Group: gvr.Group, - Resource: gvr.Resource, - Version: gvr.Version, - }, - SubResource: subresource, - RequestKind: &metav1.GroupVersionKind{ - Group: requestGVK.Group, - Kind: requestGVK.Kind, - Version: requestGVK.Version, - }, - RequestResource: &metav1.GroupVersionResource{ - Group: requestGVR.Group, - Resource: requestGVR.Resource, - Version: requestGVR.Version, - }, - RequestSubResource: requestSubResource, - Name: attr.GetName(), - Namespace: attr.GetNamespace(), - Operation: admissionv1.Operation(attr.GetOperation()), - UserInfo: userInfo, - // Leave Object and OldObject unset since we don't provide access to them via request - DryRun: &dryRun, - Options: runtime.RawExtension{ - Object: attr.GetOperationOptions(), - }, - } + options := cel.OptionalVariableBindings{VersionedParams: versionedParams} + auditAnnotationEvalResults, _, err := v.auditAnnotationFilter.ForInput(ctx, versionedAttr, cel.CreateAdmissionRequest(versionedAttr.Attributes), options, runtimeCELCostBudget) + if err != nil { + return ValidateResult{ + Decisions: []PolicyDecision{ + { + Action: policyDecisionActionForError(f), + Evaluation: EvalError, + Message: err.Error(), + }, + }, + } + } + + auditAnnotationResults := make([]PolicyAuditAnnotation, len(auditAnnotationEvalResults)) + for i, evalResult := range auditAnnotationEvalResults { + if evalResult.ExpressionAccessor == nil { + continue + } + var auditAnnotationResult = &auditAnnotationResults[i] + // TODO: move this to generics + validation, ok := evalResult.ExpressionAccessor.(*AuditAnnotationCondition) + if !ok { + klog.Error("Invalid type conversion to AuditAnnotationCondition") + auditAnnotationResult.Action = auditAnnotationEvaluationForError(f) + auditAnnotationResult.Error = fmt.Sprintf("Invalid type sent to validator, expected AuditAnnotationCondition but got %T", evalResult.ExpressionAccessor) + continue + } + auditAnnotationResult.Key = validation.Key + + if evalResult.Error != nil { + auditAnnotationResult.Action = auditAnnotationEvaluationForError(f) + auditAnnotationResult.Error = evalResult.Error.Error() + } else { + switch evalResult.EvalResult.Type() { + case celtypes.StringType: + value := strings.TrimSpace(evalResult.EvalResult.Value().(string)) + if len(value) == 0 { + auditAnnotationResult.Action = AuditAnnotationActionExclude + } else { + auditAnnotationResult.Action = AuditAnnotationActionPublish + auditAnnotationResult.Value = value + } + case celtypes.NullType: + auditAnnotationResult.Action = AuditAnnotationActionExclude + default: + auditAnnotationResult.Action = AuditAnnotationActionError + auditAnnotationResult.Error = fmt.Sprintf("valueExpression '%v' resulted in unsupported return type: %v. "+ + "Return type must be either string or null.", validation.ValueExpression, evalResult.EvalResult.Type()) + } + } + } + return ValidateResult{Decisions: decisions, AuditAnnotations: auditAnnotationResults} } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/accessors.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/accessors.go index bbe355f31..102597cbc 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/accessors.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/accessors.go @@ -19,11 +19,15 @@ package webhook import ( "sync" - "k8s.io/api/admissionregistration/v1" + v1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apiserver/pkg/admission/plugin/cel" + "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace" "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" webhookutil "k8s.io/apiserver/pkg/util/webhook" "k8s.io/client-go/rest" ) @@ -44,6 +48,9 @@ type WebhookAccessor interface { // GetRESTClient gets the webhook client GetRESTClient(clientManager *webhookutil.ClientManager) (*rest.RESTClient, error) + // GetCompiledMatcher gets the compiled matcher object + GetCompiledMatcher(compiler cel.FilterCompiler, authorizer authorizer.Authorizer) matchconditions.Matcher + // GetName gets the webhook Name field. Note that the name is scoped to the webhook // configuration and does not provide a globally unique identity, if a unique identity is // needed, use GetUID. @@ -67,6 +74,9 @@ type WebhookAccessor interface { // GetAdmissionReviewVersions gets the webhook AdmissionReviewVersions field. GetAdmissionReviewVersions() []string + // GetMatchConditions gets the webhook match conditions field. + GetMatchConditions() []v1.MatchCondition + // GetMutatingWebhook if the accessor contains a MutatingWebhook, returns it and true, else returns false. GetMutatingWebhook() (*v1.MutatingWebhook, bool) // GetValidatingWebhook if the accessor contains a ValidatingWebhook, returns it and true, else returns false. @@ -94,6 +104,9 @@ type mutatingWebhookAccessor struct { initClient sync.Once client *rest.RESTClient clientErr error + + compileMatcher sync.Once + compiledMatcher matchconditions.Matcher } func (m *mutatingWebhookAccessor) GetUID() string { @@ -111,6 +124,28 @@ func (m *mutatingWebhookAccessor) GetRESTClient(clientManager *webhookutil.Clien return m.client, m.clientErr } +// TODO: graduation to beta: resolve the fact that we rebuild ALL items whenever ANY config changes in NewMutatingWebhookConfigurationManager and NewValidatingWebhookConfigurationManager ... now that we're doing CEL compilation, we probably want to avoid that +func (m *mutatingWebhookAccessor) GetCompiledMatcher(compiler cel.FilterCompiler, authorizer authorizer.Authorizer) matchconditions.Matcher { + m.compileMatcher.Do(func() { + expressions := make([]cel.ExpressionAccessor, len(m.MutatingWebhook.MatchConditions)) + for i, matchCondition := range m.MutatingWebhook.MatchConditions { + expressions[i] = &matchconditions.MatchCondition{ + Name: matchCondition.Name, + Expression: matchCondition.Expression, + } + } + m.compiledMatcher = matchconditions.NewMatcher(compiler.Compile( + expressions, + cel.OptionalVariableDeclarations{ + HasParams: false, + HasAuthorizer: true, + }, + celconfig.PerCallLimit, + ), authorizer, m.FailurePolicy, "validating", m.Name) + }) + return m.compiledMatcher +} + func (m *mutatingWebhookAccessor) GetParsedNamespaceSelector() (labels.Selector, error) { m.initNamespaceSelector.Do(func() { m.namespaceSelector, m.namespaceSelectorErr = metav1.LabelSelectorAsSelector(m.NamespaceSelector) @@ -165,6 +200,10 @@ func (m *mutatingWebhookAccessor) GetAdmissionReviewVersions() []string { return m.AdmissionReviewVersions } +func (m *mutatingWebhookAccessor) GetMatchConditions() []v1.MatchCondition { + return m.MatchConditions +} + func (m *mutatingWebhookAccessor) GetMutatingWebhook() (*v1.MutatingWebhook, bool) { return m.MutatingWebhook, true } @@ -194,6 +233,9 @@ type validatingWebhookAccessor struct { initClient sync.Once client *rest.RESTClient clientErr error + + compileMatcher sync.Once + compiledMatcher matchconditions.Matcher } func (v *validatingWebhookAccessor) GetUID() string { @@ -211,6 +253,27 @@ func (v *validatingWebhookAccessor) GetRESTClient(clientManager *webhookutil.Cli return v.client, v.clientErr } +func (v *validatingWebhookAccessor) GetCompiledMatcher(compiler cel.FilterCompiler, authorizer authorizer.Authorizer) matchconditions.Matcher { + v.compileMatcher.Do(func() { + expressions := make([]cel.ExpressionAccessor, len(v.ValidatingWebhook.MatchConditions)) + for i, matchCondition := range v.ValidatingWebhook.MatchConditions { + expressions[i] = &matchconditions.MatchCondition{ + Name: matchCondition.Name, + Expression: matchCondition.Expression, + } + } + v.compiledMatcher = matchconditions.NewMatcher(compiler.Compile( + expressions, + cel.OptionalVariableDeclarations{ + HasParams: false, + HasAuthorizer: true, + }, + celconfig.PerCallLimit, + ), authorizer, v.FailurePolicy, "validating", v.Name) + }) + return v.compiledMatcher +} + func (v *validatingWebhookAccessor) GetParsedNamespaceSelector() (labels.Selector, error) { v.initNamespaceSelector.Do(func() { v.namespaceSelector, v.namespaceSelectorErr = metav1.LabelSelectorAsSelector(v.NamespaceSelector) @@ -265,6 +328,10 @@ func (v *validatingWebhookAccessor) GetAdmissionReviewVersions() []string { return v.AdmissionReviewVersions } +func (v *validatingWebhookAccessor) GetMatchConditions() []v1.MatchCondition { + return v.MatchConditions +} + func (v *validatingWebhookAccessor) GetMutatingWebhook() (*v1.MutatingWebhook, bool) { return nil, false } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/interfaces.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/interfaces.go index 4381691ef..af33a09f4 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/interfaces.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/interfaces.go @@ -19,43 +19,21 @@ package generic import ( "context" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/plugin/webhook" ) +type VersionedAttributeAccessor interface { + VersionedAttribute(gvk schema.GroupVersionKind) (*admission.VersionedAttributes, error) +} + // Source can list dynamic webhook plugins. type Source interface { Webhooks() []webhook.WebhookAccessor HasSynced() bool } -// VersionedAttributes is a wrapper around the original admission attributes, adding versioned -// variants of the object and old object. -type VersionedAttributes struct { - // Attributes holds the original admission attributes - admission.Attributes - // VersionedOldObject holds Attributes.OldObject (if non-nil), converted to VersionedKind. - // It must never be mutated. - VersionedOldObject runtime.Object - // VersionedObject holds Attributes.Object (if non-nil), converted to VersionedKind. - // If mutated, Dirty must be set to true by the mutator. - VersionedObject runtime.Object - // VersionedKind holds the fully qualified kind - VersionedKind schema.GroupVersionKind - // Dirty indicates VersionedObject has been modified since being converted from Attributes.Object - Dirty bool -} - -// GetObject overrides the Attributes.GetObject() -func (v *VersionedAttributes) GetObject() runtime.Object { - if v.VersionedObject != nil { - return v.VersionedObject - } - return v.Attributes.GetObject() -} - // WebhookInvocation describes how to call a webhook, including the resource and subresource the webhook registered for, // and the kind that should be sent to the webhook. type WebhookInvocation struct { diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go index 52df53af8..a58289831 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/generic/webhook.go @@ -23,19 +23,22 @@ import ( admissionv1 "k8s.io/api/admission/v1" admissionv1beta1 "k8s.io/api/admission/v1beta1" - "k8s.io/api/admissionregistration/v1" + v1 "k8s.io/api/admissionregistration/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer" + "k8s.io/apiserver/pkg/admission/plugin/cel" "k8s.io/apiserver/pkg/admission/plugin/webhook" "k8s.io/apiserver/pkg/admission/plugin/webhook/config" "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace" "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/object" "k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/rules" + "k8s.io/apiserver/pkg/authorization/authorizer" webhookutil "k8s.io/apiserver/pkg/util/webhook" "k8s.io/client-go/informers" clientset "k8s.io/client-go/kubernetes" + "k8s.io/klog/v2" ) // Webhook is an abstract admission plugin with all the infrastructure to define Admit or Validate on-top. @@ -49,6 +52,8 @@ type Webhook struct { namespaceMatcher *namespace.Matcher objectMatcher *object.Matcher dispatcher Dispatcher + filterCompiler cel.FilterCompiler + authorizer authorizer.Authorizer } var ( @@ -92,6 +97,7 @@ func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory namespaceMatcher: &namespace.Matcher{}, objectMatcher: &object.Matcher{}, dispatcher: dispatcherFactory(&cm), + filterCompiler: cel.NewFilterCompiler(), }, nil } @@ -124,6 +130,10 @@ func (a *Webhook) SetExternalKubeInformerFactory(f informers.SharedInformerFacto }) } +func (a *Webhook) SetAuthorizer(authorizer authorizer.Authorizer) { + a.authorizer = authorizer +} + // ValidateInitialization implements the InitializationValidator interface. func (a *Webhook) ValidateInitialization() error { if a.hookSource == nil { @@ -140,7 +150,7 @@ func (a *Webhook) ValidateInitialization() error { // ShouldCallHook returns invocation details if the webhook should be called, nil if the webhook should not be called, // or an error if an error was encountered during evaluation. -func (a *Webhook) ShouldCallHook(h webhook.WebhookAccessor, attr admission.Attributes, o admission.ObjectInterfaces) (*WebhookInvocation, *apierrors.StatusError) { +func (a *Webhook) ShouldCallHook(ctx context.Context, h webhook.WebhookAccessor, attr admission.Attributes, o admission.ObjectInterfaces, v VersionedAttributeAccessor) (*WebhookInvocation, *apierrors.StatusError) { matches, matchNsErr := a.namespaceMatcher.MatchNamespaceSelector(h, attr) // Should not return an error here for webhooks which do not apply to the request, even if err is an unexpected scenario. if !matches && matchNsErr == nil { @@ -207,6 +217,25 @@ func (a *Webhook) ShouldCallHook(h webhook.WebhookAccessor, attr admission.Attri return nil, matchObjErr } + matchConditions := h.GetMatchConditions() + if len(matchConditions) > 0 { + versionedAttr, err := v.VersionedAttribute(invocation.Kind) + if err != nil { + return nil, apierrors.NewInternalError(err) + } + + matcher := h.GetCompiledMatcher(a.filterCompiler, a.authorizer) + matchResult := matcher.Match(ctx, versionedAttr, nil) + + if matchResult.Error != nil { + klog.Warningf("Failed evaluating match conditions, failing closed %v: %v", h.GetName(), matchResult.Error) + return nil, apierrors.NewForbidden(attr.GetResource().GroupResource(), attr.GetName(), matchResult.Error) + } else if !matchResult.Matches { + // if no match, always skip webhook + return nil, nil + } + } + return invocation, nil } diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/interface.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/interface.go new file mode 100644 index 000000000..09468655b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/interface.go @@ -0,0 +1,36 @@ +/* +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 matchconditions + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/admission" +) + +type MatchResult struct { + Matches bool + Error error + FailedConditionName string +} + +// Matcher contains logic for converting Evaluations to bool of matches or does not match +type Matcher interface { + // Match is used to take cel evaluations and convert into decisions + Match(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object) MatchResult +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/matcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/matcher.go new file mode 100644 index 000000000..09a500dd3 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions/matcher.go @@ -0,0 +1,139 @@ +/* +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 matchconditions + +import ( + "context" + "errors" + "fmt" + + "github.com/google/cel-go/cel" + celtypes "github.com/google/cel-go/common/types" + + v1 "k8s.io/api/admissionregistration/v1" + "k8s.io/apimachinery/pkg/runtime" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apiserver/pkg/admission" + admissionmetrics "k8s.io/apiserver/pkg/admission/metrics" + celplugin "k8s.io/apiserver/pkg/admission/plugin/cel" + celconfig "k8s.io/apiserver/pkg/apis/cel" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/klog/v2" +) + +var _ celplugin.ExpressionAccessor = &MatchCondition{} + +// MatchCondition contains the inputs needed to compile, evaluate and match a cel expression +type MatchCondition v1.MatchCondition + +func (v *MatchCondition) GetExpression() string { + return v.Expression +} + +func (v *MatchCondition) ReturnTypes() []*cel.Type { + return []*cel.Type{cel.BoolType} +} + +var _ Matcher = &matcher{} + +// matcher evaluates compiled cel expressions and determines if they match the given request or not +type matcher struct { + filter celplugin.Filter + authorizer authorizer.Authorizer + failPolicy v1.FailurePolicyType + matcherType string + objectName string +} + +func NewMatcher(filter celplugin.Filter, authorizer authorizer.Authorizer, failPolicy *v1.FailurePolicyType, matcherType, objectName string) Matcher { + var f v1.FailurePolicyType + if failPolicy == nil { + f = v1.Fail + } else { + f = *failPolicy + } + return &matcher{ + filter: filter, + authorizer: authorizer, + failPolicy: f, + matcherType: matcherType, + objectName: objectName, + } +} + +func (m *matcher) Match(ctx context.Context, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object) MatchResult { + evalResults, _, err := m.filter.ForInput(ctx, versionedAttr, celplugin.CreateAdmissionRequest(versionedAttr.Attributes), celplugin.OptionalVariableBindings{ + VersionedParams: versionedParams, + Authorizer: m.authorizer, + }, celconfig.RuntimeCELCostBudgetMatchConditions) + + if err != nil { + // filter returning error is unexpected and not an evaluation error so not incrementing metric here + if m.failPolicy == v1.Fail { + return MatchResult{ + Error: err, + } + } else if m.failPolicy == v1.Ignore { + return MatchResult{ + Matches: false, + } + } + //TODO: add default so that if in future we add different failure types it doesn't fall through + } + + errorList := []error{} + for _, evalResult := range evalResults { + matchCondition, ok := evalResult.ExpressionAccessor.(*MatchCondition) + if !ok { + // This shouldnt happen, but if it does treat same as eval error + klog.Error("Invalid type conversion to MatchCondition") + errorList = append(errorList, errors.New(fmt.Sprintf("internal error converting ExpressionAccessor to MatchCondition"))) + continue + } + if evalResult.Error != nil { + errorList = append(errorList, evalResult.Error) + //TODO: what's the best way to handle this metric since its reused by VAP for match conditions + admissionmetrics.Metrics.ObserveMatchConditionEvalError(ctx, m.objectName, m.matcherType) + } + if evalResult.EvalResult == celtypes.False { + // If any condition false, skip calling webhook always + return MatchResult{ + Matches: false, + FailedConditionName: matchCondition.Name, + } + } + } + if len(errorList) > 0 { + // If mix of true and eval errors then resort to fail policy + if m.failPolicy == v1.Fail { + // mix of true and errors with fail policy fail should fail request without calling webhook + err = utilerrors.NewAggregate(errorList) + return MatchResult{ + Error: err, + } + } else if m.failPolicy == v1.Ignore { + // if fail policy ignore then skip call to webhook + return MatchResult{ + Matches: false, + } + } + } + // if no results eval to false, return matches true with list of any errors encountered + return MatchResult{ + Matches: true, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go index cadf753e3..c1d1ca6ff 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/dispatcher.go @@ -26,14 +26,13 @@ import ( jsonpatch "github.com/evanphx/json-patch" "go.opentelemetry.io/otel/attribute" - apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/klog/v2" - admissionv1 "k8s.io/api/admission/v1" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer/json" utiljson "k8s.io/apimachinery/pkg/util/json" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -48,6 +47,7 @@ import ( webhookutil "k8s.io/apiserver/pkg/util/webhook" "k8s.io/apiserver/pkg/warning" "k8s.io/component-base/tracing" + "k8s.io/klog/v2" ) const ( @@ -75,6 +75,30 @@ func newMutatingDispatcher(p *Plugin) func(cm *webhookutil.ClientManager) generi } } +var _ generic.VersionedAttributeAccessor = &versionedAttributeAccessor{} + +type versionedAttributeAccessor struct { + versionedAttr *admission.VersionedAttributes + attr admission.Attributes + objectInterfaces admission.ObjectInterfaces +} + +func (v *versionedAttributeAccessor) VersionedAttribute(gvk schema.GroupVersionKind) (*admission.VersionedAttributes, error) { + if v.versionedAttr == nil { + // First call, create versioned attributes + var err error + if v.versionedAttr, err = admission.NewVersionedAttributes(v.attr, gvk, v.objectInterfaces); err != nil { + return nil, apierrors.NewInternalError(err) + } + } else { + // Subsequent call, convert existing versioned attributes to the requested version + if err := admission.ConvertVersionedAttributes(v.versionedAttr, gvk, v.objectInterfaces); err != nil { + return nil, apierrors.NewInternalError(err) + } + } + return v.versionedAttr, nil +} + var _ generic.Dispatcher = &mutatingDispatcher{} func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attributes, o admission.ObjectInterfaces, hooks []webhook.WebhookAccessor) error { @@ -95,19 +119,24 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib defer func() { webhookReinvokeCtx.SetLastWebhookInvocationOutput(attr.GetObject()) }() - var versionedAttr *generic.VersionedAttributes + v := &versionedAttributeAccessor{ + attr: attr, + objectInterfaces: o, + } for i, hook := range hooks { attrForCheck := attr - if versionedAttr != nil { - attrForCheck = versionedAttr + if v.versionedAttr != nil { + attrForCheck = v.versionedAttr } - invocation, statusErr := a.plugin.ShouldCallHook(hook, attrForCheck, o) + + invocation, statusErr := a.plugin.ShouldCallHook(ctx, hook, attrForCheck, o, v) if statusErr != nil { return statusErr } if invocation == nil { continue } + hook, ok := invocation.Webhook.GetMutatingWebhook() if !ok { return fmt.Errorf("mutating webhook dispatch requires v1.MutatingWebhook, but got %T", hook) @@ -121,17 +150,9 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib continue } - if versionedAttr == nil { - // First webhook, create versioned attributes - var err error - if versionedAttr, err = generic.NewVersionedAttributes(attr, invocation.Kind, o); err != nil { - return apierrors.NewInternalError(err) - } - } else { - // Subsequent webhook, convert existing versioned attributes to this webhook's version - if err := generic.ConvertVersionedAttributes(versionedAttr, invocation.Kind, o); err != nil { - return apierrors.NewInternalError(err) - } + versionedAttr, err := v.VersionedAttribute(invocation.Kind) + if err != nil { + return apierrors.NewInternalError(err) } t := time.Now() @@ -203,8 +224,8 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib } // convert versionedAttr.VersionedObject to the internal version in the underlying admission.Attributes - if versionedAttr != nil && versionedAttr.VersionedObject != nil && versionedAttr.Dirty { - return o.GetObjectConvertor().Convert(versionedAttr.VersionedObject, versionedAttr.Attributes.GetObject(), nil) + if v.versionedAttr != nil && v.versionedAttr.VersionedObject != nil && v.versionedAttr.Dirty { + return o.GetObjectConvertor().Convert(v.versionedAttr.VersionedObject, v.versionedAttr.Attributes.GetObject(), nil) } return nil @@ -212,7 +233,7 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr admission.Attrib // note that callAttrMutatingHook updates attr -func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *admissionregistrationv1.MutatingWebhook, invocation *generic.WebhookInvocation, attr *generic.VersionedAttributes, annotator *webhookAnnotator, o admission.ObjectInterfaces, round, idx int) (bool, error) { +func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *admissionregistrationv1.MutatingWebhook, invocation *generic.WebhookInvocation, attr *admission.VersionedAttributes, annotator *webhookAnnotator, o admission.ObjectInterfaces, round, idx int) (bool, error) { configurationName := invocation.Webhook.GetConfigurationName() changed := false defer func() { annotator.addMutationAnnotation(changed) }() @@ -363,7 +384,7 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *admiss } type webhookAnnotator struct { - attr *generic.VersionedAttributes + attr *admission.VersionedAttributes failedOpenAnnotationKey string patchAnnotationKey string mutationAnnotationKey string @@ -371,7 +392,7 @@ type webhookAnnotator struct { configuration string } -func newWebhookAnnotator(attr *generic.VersionedAttributes, round, idx int, webhook, configuration string) *webhookAnnotator { +func newWebhookAnnotator(attr *admission.VersionedAttributes, round, idx int, webhook, configuration string) *webhookAnnotator { return &webhookAnnotator{ attr: attr, failedOpenAnnotationKey: fmt.Sprintf("%sround_%d_index_%d", MutationAuditAnnotationFailedOpenKeyPrefix, round, idx), diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go index bb7948973..459e3f5df 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/predicates/namespace/matcher.go @@ -116,7 +116,7 @@ func (m *Matcher) MatchNamespaceSelector(p NamespaceSelectorProvider, attr admis if !ok { return false, apierrors.NewInternalError(err) } - return false, &apierrors.StatusError{status.Status()} + return false, &apierrors.StatusError{ErrStatus: status.Status()} } if err != nil { return false, apierrors.NewInternalError(err) diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go index c60d0fb9e..91b070a3e 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/request/admissionreview.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission/plugin/webhook/generic" ) @@ -130,7 +131,7 @@ func VerifyAdmissionResponse(uid types.UID, mutating bool, review runtime.Object // CreateAdmissionObjects returns the unique request uid, the AdmissionReview object to send the webhook and to decode the response into, // or an error if the webhook does not support receiving any of the admission review versions we know to send -func CreateAdmissionObjects(versionedAttributes *generic.VersionedAttributes, invocation *generic.WebhookInvocation) (uid types.UID, request, response runtime.Object, err error) { +func CreateAdmissionObjects(versionedAttributes *admission.VersionedAttributes, invocation *generic.WebhookInvocation) (uid types.UID, request, response runtime.Object, err error) { for _, version := range invocation.Webhook.GetAdmissionReviewVersions() { switch version { case admissionv1.SchemeGroupVersion.Version: @@ -151,7 +152,7 @@ func CreateAdmissionObjects(versionedAttributes *generic.VersionedAttributes, in } // CreateV1AdmissionReview creates an AdmissionReview for the provided admission.Attributes -func CreateV1AdmissionReview(uid types.UID, versionedAttributes *generic.VersionedAttributes, invocation *generic.WebhookInvocation) *admissionv1.AdmissionReview { +func CreateV1AdmissionReview(uid types.UID, versionedAttributes *admission.VersionedAttributes, invocation *generic.WebhookInvocation) *admissionv1.AdmissionReview { attr := versionedAttributes.Attributes gvk := invocation.Kind gvr := invocation.Resource @@ -217,7 +218,7 @@ func CreateV1AdmissionReview(uid types.UID, versionedAttributes *generic.Version } // CreateV1beta1AdmissionReview creates an AdmissionReview for the provided admission.Attributes -func CreateV1beta1AdmissionReview(uid types.UID, versionedAttributes *generic.VersionedAttributes, invocation *generic.WebhookInvocation) *admissionv1beta1.AdmissionReview { +func CreateV1beta1AdmissionReview(uid types.UID, versionedAttributes *admission.VersionedAttributes, invocation *generic.WebhookInvocation) *admissionv1beta1.AdmissionReview { attr := versionedAttributes.Attributes gvk := invocation.Kind gvr := invocation.Resource diff --git a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go index 025e4fe38..14312fadd 100644 --- a/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go +++ b/vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/dispatcher.go @@ -62,30 +62,51 @@ func newValidatingDispatcher(p *Plugin) func(cm *webhookutil.ClientManager) gene } } +var _ generic.VersionedAttributeAccessor = &versionedAttributeAccessor{} + +type versionedAttributeAccessor struct { + versionedAttrs map[schema.GroupVersionKind]*admission.VersionedAttributes + attr admission.Attributes + objectInterfaces admission.ObjectInterfaces +} + +func (v *versionedAttributeAccessor) VersionedAttribute(gvk schema.GroupVersionKind) (*admission.VersionedAttributes, error) { + if val, ok := v.versionedAttrs[gvk]; ok { + return val, nil + } + versionedAttr, err := admission.NewVersionedAttributes(v.attr, gvk, v.objectInterfaces) + if err != nil { + return nil, err + } + v.versionedAttrs[gvk] = versionedAttr + return versionedAttr, nil +} + var _ generic.Dispatcher = &validatingDispatcher{} func (d *validatingDispatcher) Dispatch(ctx context.Context, attr admission.Attributes, o admission.ObjectInterfaces, hooks []webhook.WebhookAccessor) error { var relevantHooks []*generic.WebhookInvocation // Construct all the versions we need to call our webhooks - versionedAttrs := map[schema.GroupVersionKind]*generic.VersionedAttributes{} + versionedAttrAccessor := &versionedAttributeAccessor{ + versionedAttrs: map[schema.GroupVersionKind]*admission.VersionedAttributes{}, + attr: attr, + objectInterfaces: o, + } for _, hook := range hooks { - invocation, statusError := d.plugin.ShouldCallHook(hook, attr, o) + invocation, statusError := d.plugin.ShouldCallHook(ctx, hook, attr, o, versionedAttrAccessor) if statusError != nil { return statusError } if invocation == nil { continue } + relevantHooks = append(relevantHooks, invocation) - // If we already have this version, continue - if _, ok := versionedAttrs[invocation.Kind]; ok { - continue - } - versionedAttr, err := generic.NewVersionedAttributes(attr, invocation.Kind, o) + // VersionedAttr result will be cached and reused later during parallel webhook calls + _, err := versionedAttrAccessor.VersionedAttribute(invocation.Kind) if err != nil { return apierrors.NewInternalError(err) } - versionedAttrs[invocation.Kind] = versionedAttr } if len(relevantHooks) == 0 { @@ -108,7 +129,7 @@ func (d *validatingDispatcher) Dispatch(ctx context.Context, attr admission.Attr go func(invocation *generic.WebhookInvocation, idx int) { ignoreClientCallFailures := false hookName := "unknown" - versionedAttr := versionedAttrs[invocation.Kind] + versionedAttr := versionedAttrAccessor.versionedAttrs[invocation.Kind] // The ordering of these two defers is critical. The wg.Done will release the parent go func to close the errCh // that is used by the second defer to report errors. The recovery and error reporting must be done first. defer wg.Done() @@ -215,7 +236,7 @@ func (d *validatingDispatcher) Dispatch(ctx context.Context, attr admission.Attr return errs[0] } -func (d *validatingDispatcher) callHook(ctx context.Context, h *v1.ValidatingWebhook, invocation *generic.WebhookInvocation, attr *generic.VersionedAttributes) error { +func (d *validatingDispatcher) callHook(ctx context.Context, h *v1.ValidatingWebhook, invocation *generic.WebhookInvocation, attr *admission.VersionedAttributes) error { if attr.Attributes.IsDryRun() { if h.SideEffects == nil { return &webhookutil.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook SideEffects is nil"), Status: apierrors.NewBadRequest("Webhook SideEffects is nil")} diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go index 1d723d5e3..dcb082e09 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/types.go @@ -19,6 +19,7 @@ package apiserver import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + tracingapi "k8s.io/component-base/tracing/api/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -153,16 +154,6 @@ type TLSConfig struct { type TracingConfiguration struct { metav1.TypeMeta - // +optional - // Endpoint of the collector that's running on the control-plane node. - // The APIServer uses the egressType ControlPlane when sending data to the collector. - // The syntax is defined in https://github.com/grpc/grpc/blob/master/doc/naming.md. - // Defaults to the otlp grpc default, localhost:4317 - // The connection is insecure, and does not currently support TLS. - Endpoint *string - - // +optional - // SamplingRatePerMillion is the number of samples to collect per million spans. - // Defaults to 0. - SamplingRatePerMillion *int32 + // Embed the component config tracing configuration struct + tracingapi.TracingConfiguration } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go index cd937f1c7..b18d84d9d 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go @@ -19,6 +19,7 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + tracingapi "k8s.io/component-base/tracing/api/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -154,16 +155,6 @@ type TLSConfig struct { type TracingConfiguration struct { metav1.TypeMeta `json:",inline"` - // +optional - // Endpoint of the collector that's running on the control-plane node. - // The APIServer uses the egressType ControlPlane when sending data to the collector. - // The syntax is defined in https://github.com/grpc/grpc/blob/master/doc/naming.md. - // Defaults to the otlpgrpc default, localhost:4317 - // The connection is insecure, and does not support TLS. - Endpoint *string `json:"endpoint,omitempty" protobuf:"bytes,1,opt,name=endpoint"` - - // +optional - // SamplingRatePerMillion is the number of samples to collect per million spans. - // Defaults to 0. - SamplingRatePerMillion *int32 `json:"samplingRatePerMillion,omitempty" protobuf:"varint,2,opt,name=samplingRatePerMillion"` + // Embed the component config tracing configuration struct + tracingapi.TracingConfiguration `json:",inline"` } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go index e60f2f3b7..41b350c48 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.conversion.go @@ -313,8 +313,7 @@ func Convert_apiserver_TLSConfig_To_v1alpha1_TLSConfig(in *apiserver.TLSConfig, } func autoConvert_v1alpha1_TracingConfiguration_To_apiserver_TracingConfiguration(in *TracingConfiguration, out *apiserver.TracingConfiguration, s conversion.Scope) error { - out.Endpoint = (*string)(unsafe.Pointer(in.Endpoint)) - out.SamplingRatePerMillion = (*int32)(unsafe.Pointer(in.SamplingRatePerMillion)) + out.TracingConfiguration = in.TracingConfiguration return nil } @@ -324,8 +323,7 @@ func Convert_v1alpha1_TracingConfiguration_To_apiserver_TracingConfiguration(in } func autoConvert_apiserver_TracingConfiguration_To_v1alpha1_TracingConfiguration(in *apiserver.TracingConfiguration, out *TracingConfiguration, s conversion.Scope) error { - out.Endpoint = (*string)(unsafe.Pointer(in.Endpoint)) - out.SamplingRatePerMillion = (*int32)(unsafe.Pointer(in.SamplingRatePerMillion)) + out.TracingConfiguration = in.TracingConfiguration return nil } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go index 0e95103e0..f8ac34035 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/zz_generated.deepcopy.go @@ -189,16 +189,7 @@ func (in *TLSConfig) DeepCopy() *TLSConfig { func (in *TracingConfiguration) DeepCopyInto(out *TracingConfiguration) { *out = *in out.TypeMeta = in.TypeMeta - if in.Endpoint != nil { - in, out := &in.Endpoint, &out.Endpoint - *out = new(string) - **out = **in - } - if in.SamplingRatePerMillion != nil { - in, out := &in.SamplingRatePerMillion, &out.SamplingRatePerMillion - *out = new(int32) - **out = **in - } + in.TracingConfiguration.DeepCopyInto(&out.TracingConfiguration) return } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/register.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/register.go index 9ea529472..705d2e5eb 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/register.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/register.go @@ -23,10 +23,14 @@ import ( ) const GroupName = "apiserver.k8s.io" +const ConfigGroupName = "apiserver.config.k8s.io" // SchemeGroupVersion is group version used to register these objects var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} +// ConfigSchemeGroupVersion is group version used to register these objects +var ConfigSchemeGroupVersion = schema.GroupVersion{Group: ConfigGroupName, Version: "v1beta1"} + var ( // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. @@ -47,6 +51,9 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &EgressSelectorConfiguration{}, ) + scheme.AddKnownTypes(ConfigSchemeGroupVersion, + &TracingConfiguration{}, + ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go index ea22b403a..c61baea9f 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/types.go @@ -18,6 +18,7 @@ package v1beta1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + tracingapi "k8s.io/component-base/tracing/api/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -118,3 +119,13 @@ type TLSConfig struct { // +optional ClientCert string `json:"clientCert,omitempty"` } + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TracingConfiguration provides versioned configuration for tracing clients. +type TracingConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // Embed the component config tracing configuration struct + tracingapi.TracingConfiguration `json:",inline"` +} diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go index 37b0f2f7b..ebf810b05 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.conversion.go @@ -81,6 +81,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*TracingConfiguration)(nil), (*apiserver.TracingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration(a.(*TracingConfiguration), b.(*apiserver.TracingConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*apiserver.TracingConfiguration)(nil), (*TracingConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration(a.(*apiserver.TracingConfiguration), b.(*TracingConfiguration), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*Transport)(nil), (*apiserver.Transport)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_Transport_To_apiserver_Transport(a.(*Transport), b.(*apiserver.Transport), scope) }); err != nil { @@ -238,6 +248,26 @@ func Convert_apiserver_TLSConfig_To_v1beta1_TLSConfig(in *apiserver.TLSConfig, o return autoConvert_apiserver_TLSConfig_To_v1beta1_TLSConfig(in, out, s) } +func autoConvert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration(in *TracingConfiguration, out *apiserver.TracingConfiguration, s conversion.Scope) error { + out.TracingConfiguration = in.TracingConfiguration + return nil +} + +// Convert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration is an autogenerated conversion function. +func Convert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration(in *TracingConfiguration, out *apiserver.TracingConfiguration, s conversion.Scope) error { + return autoConvert_v1beta1_TracingConfiguration_To_apiserver_TracingConfiguration(in, out, s) +} + +func autoConvert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration(in *apiserver.TracingConfiguration, out *TracingConfiguration, s conversion.Scope) error { + out.TracingConfiguration = in.TracingConfiguration + return nil +} + +// Convert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration is an autogenerated conversion function. +func Convert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration(in *apiserver.TracingConfiguration, out *TracingConfiguration, s conversion.Scope) error { + return autoConvert_apiserver_TracingConfiguration_To_v1beta1_TracingConfiguration(in, out, s) +} + func autoConvert_v1beta1_Transport_To_apiserver_Transport(in *Transport, out *apiserver.Transport, s conversion.Scope) error { out.TCP = (*apiserver.TCPTransport)(unsafe.Pointer(in.TCP)) out.UDS = (*apiserver.UDSTransport)(unsafe.Pointer(in.UDS)) diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.deepcopy.go index bb1819cac..beb0b50b5 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/v1beta1/zz_generated.deepcopy.go @@ -132,6 +132,32 @@ func (in *TLSConfig) DeepCopy() *TLSConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TracingConfiguration) DeepCopyInto(out *TracingConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.TracingConfiguration.DeepCopyInto(&out.TracingConfiguration) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TracingConfiguration. +func (in *TracingConfiguration) DeepCopy() *TracingConfiguration { + if in == nil { + return nil + } + out := new(TracingConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TracingConfiguration) 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 *Transport) DeepCopyInto(out *Transport) { *out = *in diff --git a/vendor/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go b/vendor/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go index 86acce65f..40c8b4a6e 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiserver/pkg/apis/apiserver/zz_generated.deepcopy.go @@ -189,16 +189,7 @@ func (in *TLSConfig) DeepCopy() *TLSConfig { func (in *TracingConfiguration) DeepCopyInto(out *TracingConfiguration) { *out = *in out.TypeMeta = in.TypeMeta - if in.Endpoint != nil { - in, out := &in.Endpoint, &out.Endpoint - *out = new(string) - **out = **in - } - if in.SamplingRatePerMillion != nil { - in, out := &in.SamplingRatePerMillion, &out.SamplingRatePerMillion - *out = new(int32) - **out = **in - } + in.TracingConfiguration.DeepCopyInto(&out.TracingConfiguration) return } diff --git a/vendor/k8s.io/apiserver/pkg/apis/cel/config.go b/vendor/k8s.io/apiserver/pkg/apis/cel/config.go new file mode 100644 index 000000000..319548cd5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/apis/cel/config.go @@ -0,0 +1,45 @@ +/* +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 cel + +const ( + // PerCallLimit specify the actual cost limit per CEL validation call + // current PerCallLimit gives roughly 0.1 second for each expression validation call + PerCallLimit = 1000000 + + // RuntimeCELCostBudget is the overall cost budget for runtime CEL validation cost per ValidatingAdmissionPolicyBinding or CustomResource + // current RuntimeCELCostBudget gives roughly 1 seconds for the validation + RuntimeCELCostBudget = 10000000 + + // RuntimeCELCostBudgetMatchConditions is the overall cost budget for runtime CEL validation cost on matchConditions per object with matchConditions + // this is per webhook for validatingwebhookconfigurations and mutatingwebhookconfigurations or per ValidatingAdmissionPolicyBinding + // current RuntimeCELCostBudgetMatchConditions gives roughly 1/4 seconds for the validation + RuntimeCELCostBudgetMatchConditions = 2500000 + + // CheckFrequency configures the number of iterations within a comprehension to evaluate + // before checking whether the function evaluation has been interrupted + CheckFrequency = 100 + + // MaxRequestSizeBytes is the maximum size of a request to the API server + // TODO(DangerOnTheRanger): wire in MaxRequestBodyBytes from apiserver/pkg/server/options/server_run_options.go to make this configurable + // Note that even if server_run_options.go becomes configurable in the future, this cost constant should be fixed and it should be the max allowed request size for the server + MaxRequestSizeBytes = int64(3 * 1024 * 1024) + + // MaxEvaluatedMessageExpressionSizeBytes represents the largest-allowable string generated + // by a messageExpression field + MaxEvaluatedMessageExpressionSizeBytes = 5 * 1024 +) diff --git a/vendor/k8s.io/apiserver/pkg/apis/config/types.go b/vendor/k8s.io/apiserver/pkg/apis/config/types.go index 72107fe66..bae49e8ee 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/config/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/config/types.go @@ -24,7 +24,49 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// EncryptionConfiguration stores the complete configuration for encryption providers. +/* +EncryptionConfiguration stores the complete configuration for encryption providers. +It also allows the use of wildcards to specify the resources that should be encrypted. +Use '*.' to encrypt all resources within a group or '*.*' to encrypt all resources. +'*.' can be used to encrypt all resource in the core group. '*.*' will encrypt all +resources, even custom resources that are added after API server start. +Use of wildcards that overlap within the same resource list or across multiple +entries are not allowed since part of the configuration would be ineffective. +Resource lists are processed in order, with earlier lists taking precedence. + +Example: + + kind: EncryptionConfiguration + apiVersion: apiserver.config.k8s.io/v1 + resources: + - resources: + - events + providers: + - identity: {} # do not encrypt events even though *.* is specified below + - resources: + - secrets + - configmaps + - pandas.awesome.bears.example + providers: + - aescbc: + keys: + - name: key1 + secret: c2VjcmV0IGlzIHNlY3VyZQ== + - resources: + - '*.apps' + providers: + - aescbc: + keys: + - name: key2 + secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg== + - resources: + - '*.*' + providers: + - aescbc: + keys: + - name: key3 + secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw== +*/ type EncryptionConfiguration struct { metav1.TypeMeta // resources is a list containing resources, and their corresponding encryption providers. @@ -33,10 +75,14 @@ type EncryptionConfiguration struct { // ResourceConfiguration stores per resource configuration. type ResourceConfiguration struct { - // resources is a list of kubernetes resources which have to be encrypted. + // resources is a list of kubernetes resources which have to be encrypted. The resource names are derived from `resource` or `resource.group` of the group/version/resource. + // eg: pandas.awesome.bears.example is a custom resource with 'group': awesome.bears.example, 'resource': pandas. + // Use '*.*' to encrypt all resources and '*.' to encrypt all resources in a specific group. + // eg: '*.awesome.bears.example' will encrypt all resources in the group 'awesome.bears.example'. + // eg: '*.' will encrypt all resources in the core group (such as pods, configmaps, etc). Resources []string // providers is a list of transformers to be used for reading and writing the resources to disk. - // eg: aesgcm, aescbc, secretbox, identity. + // eg: aesgcm, aescbc, secretbox, identity, kms. Providers []ProviderConfiguration } @@ -92,7 +138,7 @@ type KMSConfiguration struct { // name is the name of the KMS plugin to be used. Name string // cachesize is the maximum number of secrets which are cached in memory. The default value is 1000. - // Set to a negative value to disable caching. + // Set to a negative value to disable caching. This field is only allowed for KMS v1 providers. // +optional CacheSize *int32 // endpoint is the gRPC server listening address, for example "unix:///var/run/kms-provider.sock". diff --git a/vendor/k8s.io/apiserver/pkg/apis/config/v1/defaults.go b/vendor/k8s.io/apiserver/pkg/apis/config/v1/defaults.go index 8666022a9..b71b53c65 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/config/v1/defaults.go +++ b/vendor/k8s.io/apiserver/pkg/apis/config/v1/defaults.go @@ -39,11 +39,12 @@ func SetDefaults_KMSConfiguration(obj *KMSConfiguration) { obj.Timeout = defaultTimeout } - if obj.CacheSize == nil { - obj.CacheSize = &defaultCacheSize - } - if obj.APIVersion == "" { obj.APIVersion = defaultAPIVersion } + + // cacheSize is relevant only for kms v1 + if obj.CacheSize == nil && obj.APIVersion == "v1" { + obj.CacheSize = &defaultCacheSize + } } diff --git a/vendor/k8s.io/apiserver/pkg/apis/config/v1/types.go b/vendor/k8s.io/apiserver/pkg/apis/config/v1/types.go index 23dab942e..7aced8cf6 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/config/v1/types.go +++ b/vendor/k8s.io/apiserver/pkg/apis/config/v1/types.go @@ -24,7 +24,49 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// EncryptionConfiguration stores the complete configuration for encryption providers. +/* +EncryptionConfiguration stores the complete configuration for encryption providers. +It also allows the use of wildcards to specify the resources that should be encrypted. +Use '*.' to encrypt all resources within a group or '*.*' to encrypt all resources. +'*.' can be used to encrypt all resource in the core group. '*.*' will encrypt all +resources, even custom resources that are added after API server start. +Use of wildcards that overlap within the same resource list or across multiple +entries are not allowed since part of the configuration would be ineffective. +Resource lists are processed in order, with earlier lists taking precedence. + +Example: + + kind: EncryptionConfiguration + apiVersion: apiserver.config.k8s.io/v1 + resources: + - resources: + - events + providers: + - identity: {} # do not encrypt events even though *.* is specified below + - resources: + - secrets + - configmaps + - pandas.awesome.bears.example + providers: + - aescbc: + keys: + - name: key1 + secret: c2VjcmV0IGlzIHNlY3VyZQ== + - resources: + - '*.apps' + providers: + - aescbc: + keys: + - name: key2 + secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg== + - resources: + - '*.*' + providers: + - aescbc: + keys: + - name: key3 + secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw== +*/ type EncryptionConfiguration struct { metav1.TypeMeta // resources is a list containing resources, and their corresponding encryption providers. @@ -33,10 +75,14 @@ type EncryptionConfiguration struct { // ResourceConfiguration stores per resource configuration. type ResourceConfiguration struct { - // resources is a list of kubernetes resources which have to be encrypted. + // resources is a list of kubernetes resources which have to be encrypted. The resource names are derived from `resource` or `resource.group` of the group/version/resource. + // eg: pandas.awesome.bears.example is a custom resource with 'group': awesome.bears.example, 'resource': pandas. + // Use '*.*' to encrypt all resources and '*.' to encrypt all resources in a specific group. + // eg: '*.awesome.bears.example' will encrypt all resources in the group 'awesome.bears.example'. + // eg: '*.' will encrypt all resources in the core group (such as pods, configmaps, etc). Resources []string `json:"resources"` // providers is a list of transformers to be used for reading and writing the resources to disk. - // eg: aesgcm, aescbc, secretbox, identity. + // eg: aesgcm, aescbc, secretbox, identity, kms. Providers []ProviderConfiguration `json:"providers"` } @@ -92,7 +138,7 @@ type KMSConfiguration struct { // name is the name of the KMS plugin to be used. Name string `json:"name"` // cachesize is the maximum number of secrets which are cached in memory. The default value is 1000. - // Set to a negative value to disable caching. + // Set to a negative value to disable caching. This field is only allowed for KMS v1 providers. // +optional CacheSize *int32 `json:"cachesize,omitempty"` // endpoint is the gRPC server listening address, for example "unix:///var/run/kms-provider.sock". diff --git a/vendor/k8s.io/apiserver/pkg/apis/config/validation/validation.go b/vendor/k8s.io/apiserver/pkg/apis/config/validation/validation.go index 84b2764df..90708472a 100644 --- a/vendor/k8s.io/apiserver/pkg/apis/config/validation/validation.go +++ b/vendor/k8s.io/apiserver/pkg/apis/config/validation/validation.go @@ -23,6 +23,7 @@ import ( "net/url" "strings" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/apis/config" @@ -34,7 +35,7 @@ const ( unsupportedSchemeErrFmt = "unsupported scheme %q for KMS provider, only unix is supported" unsupportedKMSAPIVersionErrFmt = "unsupported apiVersion %s for KMS provider, only v1 and v2 are supported" atLeastOneRequiredErrFmt = "at least one %s is required" - invalidURLErrFmt = "invalid endpoint for kms provider, error: parse %s: net/url: invalid control character in URL" + invalidURLErrFmt = "invalid endpoint for kms provider, error: %v" mandatoryFieldErrFmt = "%s is a mandatory field for a %s" base64EncodingErr = "secrets must be base64 encoded" zeroOrNegativeErrFmt = "%s should be a positive value" @@ -42,6 +43,14 @@ const ( encryptionConfigNilErr = "EncryptionConfiguration can't be nil" invalidKMSConfigNameErrFmt = "invalid KMS provider name %s, must not contain ':'" duplicateKMSConfigNameErrFmt = "duplicate KMS provider name %s, names must be unique" + eventsGroupErr = "'*.events.k8s.io' objects are stored using the 'events' API group in etcd. Use 'events' instead in the config file" + extensionsGroupErr = "'extensions' group has been removed and cannot be used for encryption" + starResourceErr = "use '*.' to encrypt all the resources from core API group or *.* to encrypt all resources" + overlapErr = "using overlapping resources such as 'secrets' and '*.' in the same resource list is not allowed as they will be masked" + nonRESTAPIResourceErr = "resources which do not have REST API/s cannot be encrypted" + resourceNameErr = "resource name should not contain capital letters" + resourceAcrossGroupErr = "encrypting the same resource across groups is not supported" + duplicateResourceErr = "the same resource cannot be specified multiple times" ) var ( @@ -59,7 +68,7 @@ func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration, reload b allErrs := field.ErrorList{} if c == nil { - allErrs = append(allErrs, field.Required(root, "EncryptionConfiguration can't be nil")) + allErrs = append(allErrs, field.Required(root, encryptionConfigNilErr)) return allErrs } @@ -78,6 +87,9 @@ func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration, reload b allErrs = append(allErrs, field.Required(r, fmt.Sprintf(atLeastOneRequiredErrFmt, r))) } + allErrs = append(allErrs, validateResourceOverlap(conf.Resources, r)...) + allErrs = append(allErrs, validateResourceNames(conf.Resources, r)...) + if len(conf.Providers) == 0 { allErrs = append(allErrs, field.Required(p, fmt.Sprintf(atLeastOneRequiredErrFmt, p))) } @@ -103,6 +115,175 @@ func ValidateEncryptionConfiguration(c *config.EncryptionConfiguration, reload b return allErrs } +var anyGroupAnyResource = schema.GroupResource{ + Group: "*", + Resource: "*", +} + +func validateResourceOverlap(resources []string, fieldPath *field.Path) field.ErrorList { + if len(resources) < 2 { // cannot have overlap with a single resource + return nil + } + + var allErrs field.ErrorList + + r := make([]schema.GroupResource, 0, len(resources)) + for _, resource := range resources { + r = append(r, schema.ParseGroupResource(resource)) + } + + var hasOverlap, hasDuplicate bool + + for i, r1 := range r { + for j, r2 := range r { + if i == j { + continue + } + + if r1 == r2 && !hasDuplicate { + hasDuplicate = true + continue + } + + if hasOverlap { + continue + } + + if r1 == anyGroupAnyResource { + hasOverlap = true + continue + } + + if r1.Group != r2.Group { + continue + } + + if r1.Resource == "*" || r2.Resource == "*" { + hasOverlap = true + continue + } + } + } + + if hasDuplicate { + allErrs = append( + allErrs, + field.Invalid( + fieldPath, + resources, + duplicateResourceErr, + ), + ) + } + + if hasOverlap { + allErrs = append( + allErrs, + field.Invalid( + fieldPath, + resources, + overlapErr, + ), + ) + } + + return allErrs +} + +func validateResourceNames(resources []string, fieldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + for j, res := range resources { + jj := fieldPath.Index(j) + + // check if resource name has capital letters + if hasCapital(res) { + allErrs = append( + allErrs, + field.Invalid( + jj, + resources[j], + resourceNameErr, + ), + ) + continue + } + + // check if resource is '*' + if res == "*" { + allErrs = append( + allErrs, + field.Invalid( + jj, + resources[j], + starResourceErr, + ), + ) + continue + } + + // check if resource is: + // 'apiserveripinfo' OR + // 'serviceipallocations' OR + // 'servicenodeportallocations' OR + if res == "apiserveripinfo" || + res == "serviceipallocations" || + res == "servicenodeportallocations" { + allErrs = append( + allErrs, + field.Invalid( + jj, + resources[j], + nonRESTAPIResourceErr, + ), + ) + continue + } + + // check if group is 'events.k8s.io' + gr := schema.ParseGroupResource(res) + if gr.Group == "events.k8s.io" { + allErrs = append( + allErrs, + field.Invalid( + jj, + resources[j], + eventsGroupErr, + ), + ) + continue + } + + // check if group is 'extensions' + if gr.Group == "extensions" { + allErrs = append( + allErrs, + field.Invalid( + jj, + resources[j], + extensionsGroupErr, + ), + ) + continue + } + + // disallow resource.* as encrypting the same resource across groups does not make sense + if gr.Group == "*" && gr.Resource != "*" { + allErrs = append( + allErrs, + field.Invalid( + jj, + resources[j], + resourceAcrossGroupErr, + ), + ) + continue + } + } + + return allErrs +} + func validateSingleProvider(provider config.ProviderConfiguration, fieldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} found := 0 @@ -195,7 +376,13 @@ func validateKMSConfiguration(c *config.KMSConfiguration, fieldPath *field.Path, func validateKMSCacheSize(c *config.KMSConfiguration, fieldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - if *c.CacheSize == 0 { + + // In defaulting, we set the cache size to the default value only when API version is v1. + // So, for v2 API version, we expect the cache size field to be nil. + if c.APIVersion != "v1" && c.CacheSize != nil { + allErrs = append(allErrs, field.Invalid(fieldPath, *c.CacheSize, "cachesize is not supported in v2")) + } + if c.APIVersion == "v1" && *c.CacheSize == 0 { allErrs = append(allErrs, field.Invalid(fieldPath, *c.CacheSize, fmt.Sprintf(nonZeroErrFmt, "cachesize"))) } @@ -219,7 +406,7 @@ func validateKMSEndpoint(c *config.KMSConfiguration, fieldPath *field.Path) fiel u, err := url.Parse(c.Endpoint) if err != nil { - return append(allErrs, field.Invalid(fieldPath, c.Endpoint, fmt.Sprintf("invalid endpoint for kms provider, error: %v", err))) + return append(allErrs, field.Invalid(fieldPath, c.Endpoint, fmt.Sprintf(invalidURLErrFmt, err))) } if u.Scheme != "unix" { @@ -259,3 +446,7 @@ func validateKMSConfigName(c *config.KMSConfiguration, fieldPath *field.Path, km return allErrs } + +func hasCapital(input string) bool { + return strings.ToLower(input) != input +} diff --git a/vendor/k8s.io/apiserver/pkg/audit/evaluator.go b/vendor/k8s.io/apiserver/pkg/audit/evaluator.go index 93907dc5f..f9664fef6 100644 --- a/vendor/k8s.io/apiserver/pkg/audit/evaluator.go +++ b/vendor/k8s.io/apiserver/pkg/audit/evaluator.go @@ -25,6 +25,9 @@ import ( // a given request. PolicyRuleEvaluator evaluates the audit policy against the // authorizer attributes and returns a RequestAuditConfig that applies to the request. type RequestAuditConfig struct { + // Level at which the request is being audited at + Level audit.Level + // OmitStages is the stages that need to be omitted from being audited. OmitStages []audit.Stage @@ -33,21 +36,10 @@ type RequestAuditConfig struct { OmitManagedFields bool } -// RequestAuditConfigWithLevel includes Level at which the request is being audited. -// PolicyRuleEvaluator evaluates the audit configuration for a request -// against the authorizer attributes and returns an RequestAuditConfigWithLevel -// that applies to the request. -type RequestAuditConfigWithLevel struct { - RequestAuditConfig - - // Level at which the request is being audited at - Level audit.Level -} - // PolicyRuleEvaluator exposes methods for evaluating the policy rules. type PolicyRuleEvaluator interface { // EvaluatePolicyRule evaluates the audit policy of the apiserver against // the given authorizer attributes and returns the audit configuration that // is applicable to the given equest. - EvaluatePolicyRule(authorizer.Attributes) RequestAuditConfigWithLevel + EvaluatePolicyRule(authorizer.Attributes) RequestAuditConfig } diff --git a/vendor/k8s.io/apiserver/pkg/audit/policy/checker.go b/vendor/k8s.io/apiserver/pkg/audit/policy/checker.go index 6a98ff4ac..cd6ec92bc 100644 --- a/vendor/k8s.io/apiserver/pkg/audit/policy/checker.go +++ b/vendor/k8s.io/apiserver/pkg/audit/policy/checker.go @@ -61,25 +61,21 @@ type policyRuleEvaluator struct { audit.Policy } -func (p *policyRuleEvaluator) EvaluatePolicyRule(attrs authorizer.Attributes) auditinternal.RequestAuditConfigWithLevel { +func (p *policyRuleEvaluator) EvaluatePolicyRule(attrs authorizer.Attributes) auditinternal.RequestAuditConfig { for _, rule := range p.Rules { if ruleMatches(&rule, attrs) { - return auditinternal.RequestAuditConfigWithLevel{ - Level: rule.Level, - RequestAuditConfig: auditinternal.RequestAuditConfig{ - OmitStages: rule.OmitStages, - OmitManagedFields: isOmitManagedFields(&rule, p.OmitManagedFields), - }, + return auditinternal.RequestAuditConfig{ + Level: rule.Level, + OmitStages: rule.OmitStages, + OmitManagedFields: isOmitManagedFields(&rule, p.OmitManagedFields), } } } - return auditinternal.RequestAuditConfigWithLevel{ - Level: DefaultAuditLevel, - RequestAuditConfig: auditinternal.RequestAuditConfig{ - OmitStages: p.OmitStages, - OmitManagedFields: p.OmitManagedFields, - }, + return auditinternal.RequestAuditConfig{ + Level: DefaultAuditLevel, + OmitStages: p.OmitStages, + OmitManagedFields: p.OmitManagedFields, } } @@ -235,11 +231,9 @@ type fakePolicyRuleEvaluator struct { stage []audit.Stage } -func (f *fakePolicyRuleEvaluator) EvaluatePolicyRule(_ authorizer.Attributes) auditinternal.RequestAuditConfigWithLevel { - return auditinternal.RequestAuditConfigWithLevel{ - Level: f.level, - RequestAuditConfig: auditinternal.RequestAuditConfig{ - OmitStages: f.stage, - }, +func (f *fakePolicyRuleEvaluator) EvaluatePolicyRule(_ authorizer.Attributes) auditinternal.RequestAuditConfig { + return auditinternal.RequestAuditConfig{ + Level: f.level, + OmitStages: f.stage, } } diff --git a/vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader.go b/vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader.go index abf509a97..d02732739 100644 --- a/vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader.go +++ b/vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest/requestheader.go @@ -163,17 +163,7 @@ func (a *requestHeaderAuthRequestHandler) AuthenticateRequest(req *http.Request) extra := newExtra(req.Header, a.extraHeaderPrefixes.Value()) // clear headers used for authentication - for _, headerName := range a.nameHeaders.Value() { - req.Header.Del(headerName) - } - for _, headerName := range a.groupHeaders.Value() { - req.Header.Del(headerName) - } - for k := range extra { - for _, prefix := range a.extraHeaderPrefixes.Value() { - req.Header.Del(prefix + k) - } - } + ClearAuthenticationHeaders(req.Header, a.nameHeaders, a.groupHeaders, a.extraHeaderPrefixes) return &authenticator.Response{ User: &user.DefaultInfo{ @@ -184,6 +174,26 @@ func (a *requestHeaderAuthRequestHandler) AuthenticateRequest(req *http.Request) }, true, nil } +func ClearAuthenticationHeaders(h http.Header, nameHeaders, groupHeaders, extraHeaderPrefixes StringSliceProvider) { + for _, headerName := range nameHeaders.Value() { + h.Del(headerName) + } + for _, headerName := range groupHeaders.Value() { + h.Del(headerName) + } + for _, prefix := range extraHeaderPrefixes.Value() { + for k := range h { + if hasPrefixIgnoreCase(k, prefix) { + delete(h, k) // we have the raw key so avoid relying on canonicalization + } + } + } +} + +func hasPrefixIgnoreCase(s, prefix string) bool { + return len(s) >= len(prefix) && strings.EqualFold(s[:len(prefix)], prefix) +} + func headerValue(h http.Header, headerNames []string) string { for _, headerName := range headerNames { headerValue := h.Get(headerName) @@ -226,7 +236,7 @@ func newExtra(h http.Header, headerPrefixes []string) map[string][]string { // we have to iterate over prefixes first in order to have proper ordering inside the value slices for _, prefix := range headerPrefixes { for headerName, vv := range h { - if !strings.HasPrefix(strings.ToLower(headerName), strings.ToLower(prefix)) { + if !hasPrefixIgnoreCase(headerName, prefix) { continue } diff --git a/vendor/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go b/vendor/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go index ae388b937..ec0b14768 100644 --- a/vendor/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go +++ b/vendor/k8s.io/apiserver/pkg/authentication/token/cache/cached_token_authenticator.go @@ -277,12 +277,24 @@ func writeLength(w io.Writer, b []byte, length int) { // toBytes performs unholy acts to avoid allocations func toBytes(s string) []byte { - return *(*[]byte)(unsafe.Pointer(&s)) + // unsafe.StringData is unspecified for the empty string, so we provide a strict interpretation + if len(s) == 0 { + return nil + } + // Copied from go 1.20.1 os.File.WriteString + // https://github.com/golang/go/blob/202a1a57064127c3f19d96df57b9f9586145e21c/src/os/file.go#L246 + return unsafe.Slice(unsafe.StringData(s), len(s)) } // toString performs unholy acts to avoid allocations func toString(b []byte) string { - return *(*string)(unsafe.Pointer(&b)) + // unsafe.SliceData relies on cap whereas we want to rely on len + if len(b) == 0 { + return "" + } + // Copied from go 1.20.1 strings.Builder.String + // https://github.com/golang/go/blob/202a1a57064127c3f19d96df57b9f9586145e21c/src/strings/builder.go#L48 + return unsafe.String(unsafe.SliceData(b), len(b)) } // simple recorder that only appends warning diff --git a/vendor/k8s.io/apiserver/pkg/cel/OWNERS b/vendor/k8s.io/apiserver/pkg/cel/OWNERS new file mode 100644 index 000000000..f550fc179 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/OWNERS @@ -0,0 +1,11 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +# Kubernetes CEL library authors and maintainers +approvers: + - jpbetz + - cici37 + - jiahuif +reviewers: + - jpbetz + - cici37 + - jiahuif diff --git a/vendor/k8s.io/apiserver/pkg/cel/common/adaptor.go b/vendor/k8s.io/apiserver/pkg/cel/common/adaptor.go new file mode 100644 index 000000000..c28d6ce51 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/common/adaptor.go @@ -0,0 +1,81 @@ +/* +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 common + +// Schema is the adapted type for an OpenAPI schema that CEL uses. +// This schema does not cover all OpenAPI fields but only these CEL requires +// are exposed as getters. +type Schema interface { + // Type returns the OpenAPI type. + // Multiple types are not supported. It should return + // empty string if no type is specified. + Type() string + + // Format returns the OpenAPI format. May be empty + Format() string + + // Items returns the OpenAPI items. or nil of this field does not exist or + // contains no schema. + Items() Schema + + // Properties returns the OpenAPI properties, or nil if this field does not + // exist. + // The values of the returned map are of the adapted type. + Properties() map[string]Schema + + // AdditionalProperties returns the OpenAPI additional properties field, + // or nil if this field does not exist. + AdditionalProperties() SchemaOrBool + + // Default returns the OpenAPI default field, or nil if this field does not exist. + Default() any + + Validations + KubeExtensions + + // WithTypeAndObjectMeta returns a schema that has the type and object meta set. + // the type includes "kind", "apiVersion" field + // the "metadata" field requires "name" and "generateName" to be set + // The original schema must not be mutated. Make a copy if necessary. + WithTypeAndObjectMeta() Schema +} + +// Validations contains OpenAPI validation that the CEL library uses. +type Validations interface { + MaxItems() *int64 + MaxLength() *int64 + MaxProperties() *int64 + Required() []string + Enum() []any + Nullable() bool +} + +// KubeExtensions contains Kubernetes-specific extensions to the OpenAPI schema. +type KubeExtensions interface { + IsXIntOrString() bool + IsXEmbeddedResource() bool + IsXPreserveUnknownFields() bool + XListType() string + XListMapKeys() []string +} + +// SchemaOrBool contains either a schema or a boolean indicating if the object +// can contain any fields. +type SchemaOrBool interface { + Schema() Schema + Allows() bool +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/common/maplist.go b/vendor/k8s.io/apiserver/pkg/cel/common/maplist.go new file mode 100644 index 000000000..99fda092e --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/common/maplist.go @@ -0,0 +1,177 @@ +/* +Copyright 2022 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 common + +import ( + "fmt" + "strings" +) + +// MapList provides a "lookup by key" operation for lists (arrays) with x-kubernetes-list-type=map. +type MapList interface { + // Get returns the first element having given key, for all + // x-kubernetes-list-map-keys, to the provided object. If the provided object isn't itself a valid MapList element, + // get returns nil. + Get(interface{}) interface{} +} + +type keyStrategy interface { + // CompositeKeyFor returns a composite key for the provided object, if possible, and a + // boolean that indicates whether or not a key could be generated for the provided object. + CompositeKeyFor(map[string]interface{}) (interface{}, bool) +} + +// singleKeyStrategy is a cheaper strategy for associative lists that have exactly one key. +type singleKeyStrategy struct { + key string +} + +// CompositeKeyFor directly returns the value of the single key to +// use as a composite key. +func (ks *singleKeyStrategy) CompositeKeyFor(obj map[string]interface{}) (interface{}, bool) { + v, ok := obj[ks.key] + if !ok { + return nil, false + } + + switch v.(type) { + case bool, float64, int64, string: + return v, true + default: + return nil, false // non-scalar + } +} + +// multiKeyStrategy computes a composite key of all key values. +type multiKeyStrategy struct { + sts Schema +} + +// CompositeKeyFor returns a composite key computed from the values of all +// keys. +func (ks *multiKeyStrategy) CompositeKeyFor(obj map[string]interface{}) (interface{}, bool) { + const keyDelimiter = "\x00" // 0 byte should never appear in the composite key except as delimiter + + var delimited strings.Builder + for _, key := range ks.sts.XListMapKeys() { + v, ok := obj[key] + if !ok { + return nil, false + } + + switch v.(type) { + case bool: + fmt.Fprintf(&delimited, keyDelimiter+"%t", v) + case float64: + fmt.Fprintf(&delimited, keyDelimiter+"%f", v) + case int64: + fmt.Fprintf(&delimited, keyDelimiter+"%d", v) + case string: + fmt.Fprintf(&delimited, keyDelimiter+"%q", v) + default: + return nil, false // values must be scalars + } + } + return delimited.String(), true +} + +// emptyMapList is a MapList containing no elements. +type emptyMapList struct{} + +func (emptyMapList) Get(interface{}) interface{} { + return nil +} + +type mapListImpl struct { + sts Schema + ks keyStrategy + // keyedItems contains all lazily keyed map items + keyedItems map[interface{}]interface{} + // unkeyedItems contains all map items that have not yet been keyed + unkeyedItems []interface{} +} + +func (a *mapListImpl) Get(obj interface{}) interface{} { + mobj, ok := obj.(map[string]interface{}) + if !ok { + return nil + } + + key, ok := a.ks.CompositeKeyFor(mobj) + if !ok { + return nil + } + if match, ok := a.keyedItems[key]; ok { + return match + } + // keep keying items until we either find a match or run out of unkeyed items + for len(a.unkeyedItems) > 0 { + // dequeue an unkeyed item + item := a.unkeyedItems[0] + a.unkeyedItems = a.unkeyedItems[1:] + + // key the item + mitem, ok := item.(map[string]interface{}) + if !ok { + continue + } + itemKey, ok := a.ks.CompositeKeyFor(mitem) + if !ok { + continue + } + if _, exists := a.keyedItems[itemKey]; !exists { + a.keyedItems[itemKey] = mitem + } + + // if it matches, short-circuit + if itemKey == key { + return mitem + } + } + + return nil +} + +func makeKeyStrategy(sts Schema) keyStrategy { + listMapKeys := sts.XListMapKeys() + if len(listMapKeys) == 1 { + key := listMapKeys[0] + return &singleKeyStrategy{ + key: key, + } + } + + return &multiKeyStrategy{ + sts: sts, + } +} + +// MakeMapList returns a queryable interface over the provided x-kubernetes-list-type=map +// keyedItems. If the provided schema is _not_ an array with x-kubernetes-list-type=map, returns an +// empty mapList. +func MakeMapList(sts Schema, items []interface{}) (rv MapList) { + if sts.Type() != "array" || sts.XListType() != "map" || len(sts.XListMapKeys()) == 0 || len(items) == 0 { + return emptyMapList{} + } + ks := makeKeyStrategy(sts) + return &mapListImpl{ + sts: sts, + ks: ks, + keyedItems: map[interface{}]interface{}{}, + unkeyedItems: items, + } +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/common/schemas.go b/vendor/k8s.io/apiserver/pkg/cel/common/schemas.go new file mode 100644 index 000000000..3fdd3a6c8 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/common/schemas.go @@ -0,0 +1,257 @@ +/* +Copyright 2022 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 common + +import ( + "time" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +const maxRequestSizeBytes = apiservercel.DefaultMaxRequestSizeBytes + +// SchemaDeclType converts the structural schema to a CEL declaration, or returns nil if the +// structural schema should not be exposed in CEL expressions. +// Set isResourceRoot to true for the root of a custom resource or embedded resource. +// +// Schemas with XPreserveUnknownFields not exposed unless they are objects. Array and "maps" schemas +// are not exposed if their items or additionalProperties schemas are not exposed. Object Properties are not exposed +// if their schema is not exposed. +// +// The CEL declaration for objects with XPreserveUnknownFields does not expose unknown fields. +func SchemaDeclType(s Schema, isResourceRoot bool) *apiservercel.DeclType { + if s == nil { + return nil + } + if s.IsXIntOrString() { + // schemas using XIntOrString are not required to have a type. + + // intOrStringType represents the x-kubernetes-int-or-string union type in CEL expressions. + // In CEL, the type is represented as dynamic value, which can be thought of as a union type of all types. + // All type checking for XIntOrString is deferred to runtime, so all access to values of this type must + // be guarded with a type check, e.g.: + // + // To require that the string representation be a percentage: + // `type(intOrStringField) == string && intOrStringField.matches(r'(\d+(\.\d+)?%)')` + // To validate requirements on both the int and string representation: + // `type(intOrStringField) == int ? intOrStringField < 5 : double(intOrStringField.replace('%', '')) < 0.5 + // + dyn := apiservercel.NewSimpleTypeWithMinSize("dyn", cel.DynType, nil, 1) // smallest value for a serialized x-kubernetes-int-or-string is 0 + // handle x-kubernetes-int-or-string by returning the max length/min serialized size of the largest possible string + dyn.MaxElements = maxRequestSizeBytes - 2 + return dyn + } + + // We ignore XPreserveUnknownFields since we don't support validation rules on + // data that we don't have schema information for. + + if isResourceRoot { + // 'apiVersion', 'kind', 'metadata.name' and 'metadata.generateName' are always accessible to validator rules + // at the root of resources, even if not specified in the schema. + // This includes the root of a custom resource and the root of XEmbeddedResource objects. + s = s.WithTypeAndObjectMeta() + } + + switch s.Type() { + case "array": + if s.Items() != nil { + itemsType := SchemaDeclType(s.Items(), s.Items().IsXEmbeddedResource()) + if itemsType == nil { + return nil + } + var maxItems int64 + if s.MaxItems() != nil { + maxItems = zeroIfNegative(*s.MaxItems()) + } else { + maxItems = estimateMaxArrayItemsFromMinSize(itemsType.MinSerializedSize) + } + return apiservercel.NewListType(itemsType, maxItems) + } + return nil + case "object": + if s.AdditionalProperties() != nil && s.AdditionalProperties().Schema() != nil { + propsType := SchemaDeclType(s.AdditionalProperties().Schema(), s.AdditionalProperties().Schema().IsXEmbeddedResource()) + if propsType != nil { + var maxProperties int64 + if s.MaxProperties() != nil { + maxProperties = zeroIfNegative(*s.MaxProperties()) + } else { + maxProperties = estimateMaxAdditionalPropertiesFromMinSize(propsType.MinSerializedSize) + } + return apiservercel.NewMapType(apiservercel.StringType, propsType, maxProperties) + } + return nil + } + fields := make(map[string]*apiservercel.DeclField, len(s.Properties())) + + required := map[string]bool{} + if s.Required() != nil { + for _, f := range s.Required() { + required[f] = true + } + } + // an object will always be serialized at least as {}, so account for that + minSerializedSize := int64(2) + for name, prop := range s.Properties() { + var enumValues []interface{} + if prop.Enum() != nil { + for _, e := range prop.Enum() { + enumValues = append(enumValues, e) + } + } + if fieldType := SchemaDeclType(prop, prop.IsXEmbeddedResource()); fieldType != nil { + if propName, ok := apiservercel.Escape(name); ok { + fields[propName] = apiservercel.NewDeclField(propName, fieldType, required[name], enumValues, prop.Default()) + } + // the min serialized size for an object is 2 (for {}) plus the min size of all its required + // properties + // only include required properties without a default value; default values are filled in + // server-side + if required[name] && prop.Default() == nil { + minSerializedSize += int64(len(name)) + fieldType.MinSerializedSize + 4 + } + } + } + objType := apiservercel.NewObjectType("object", fields) + objType.MinSerializedSize = minSerializedSize + return objType + case "string": + switch s.Format() { + case "byte": + byteWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("bytes", cel.BytesType, types.Bytes([]byte{}), apiservercel.MinStringSize) + if s.MaxLength() != nil { + byteWithMaxLength.MaxElements = zeroIfNegative(*s.MaxLength()) + } else { + byteWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + } + return byteWithMaxLength + case "duration": + durationWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("duration", cel.DurationType, types.Duration{Duration: time.Duration(0)}, int64(apiservercel.MinDurationSizeJSON)) + durationWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + return durationWithMaxLength + case "date": + timestampWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, int64(apiservercel.JSONDateSize)) + timestampWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + return timestampWithMaxLength + case "date-time": + timestampWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, int64(apiservercel.MinDatetimeSizeJSON)) + timestampWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + return timestampWithMaxLength + } + + strWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("string", cel.StringType, types.String(""), apiservercel.MinStringSize) + if s.MaxLength() != nil { + // multiply the user-provided max length by 4 in the case of an otherwise-untyped string + // we do this because the OpenAPIv3 spec indicates that maxLength is specified in runes/code points, + // but we need to reason about length for things like request size, so we use bytes in this code (and an individual + // unicode code point can be up to 4 bytes long) + strWithMaxLength.MaxElements = zeroIfNegative(*s.MaxLength()) * 4 + } else { + strWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s) + } + return strWithMaxLength + case "boolean": + return apiservercel.BoolType + case "number": + return apiservercel.DoubleType + case "integer": + return apiservercel.IntType + } + return nil +} + +func zeroIfNegative(v int64) int64 { + if v < 0 { + return 0 + } + return v +} + +// WithTypeAndObjectMeta ensures the kind, apiVersion and +// metadata.name and metadata.generateName properties are specified, making a shallow copy of the provided schema if needed. +func WithTypeAndObjectMeta(s *spec.Schema) *spec.Schema { + if s.Properties != nil && + s.Properties["kind"].Type.Contains("string") && + s.Properties["apiVersion"].Type.Contains("string") && + s.Properties["metadata"].Type.Contains("object") && + s.Properties["metadata"].Properties != nil && + s.Properties["metadata"].Properties["name"].Type.Contains("string") && + s.Properties["metadata"].Properties["generateName"].Type.Contains("string") { + return s + } + result := *s + props := make(map[string]spec.Schema, len(s.Properties)) + for k, prop := range s.Properties { + props[k] = prop + } + stringType := spec.StringProperty() + props["kind"] = *stringType + props["apiVersion"] = *stringType + props["metadata"] = spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": *stringType, + "generateName": *stringType, + }, + }, + } + result.Properties = props + + return &result +} + +// estimateMaxStringLengthPerRequest estimates the maximum string length (in characters) +// of a string compatible with the format requirements in the provided schema. +// must only be called on schemas of type "string" or x-kubernetes-int-or-string: true +func estimateMaxStringLengthPerRequest(s Schema) int64 { + if s.IsXIntOrString() { + return maxRequestSizeBytes - 2 + } + switch s.Format() { + case "duration": + return apiservercel.MaxDurationSizeJSON + case "date": + return apiservercel.JSONDateSize + case "date-time": + return apiservercel.MaxDatetimeSizeJSON + default: + // subtract 2 to account for "" + return maxRequestSizeBytes - 2 + } +} + +// estimateMaxArrayItemsPerRequest estimates the maximum number of array items with +// the provided minimum serialized size that can fit into a single request. +func estimateMaxArrayItemsFromMinSize(minSize int64) int64 { + // subtract 2 to account for [ and ] + return (maxRequestSizeBytes - 2) / (minSize + 1) +} + +// estimateMaxAdditionalPropertiesPerRequest estimates the maximum number of additional properties +// with the provided minimum serialized size that can fit into a single request. +func estimateMaxAdditionalPropertiesFromMinSize(minSize int64) int64 { + // 2 bytes for key + "" + colon + comma + smallest possible value, realistically the actual keys + // will all vary in length + keyValuePairSize := minSize + 6 + // subtract 2 to account for { and } + return (maxRequestSizeBytes - 2) / keyValuePairSize +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/common/values.go b/vendor/k8s.io/apiserver/pkg/cel/common/values.go new file mode 100644 index 000000000..d9034a80f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/common/values.go @@ -0,0 +1,717 @@ +/* +Copyright 2021 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 common + +import ( + "fmt" + "reflect" + "sync" + "time" + + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/google/cel-go/common/types/traits" + + "k8s.io/kube-openapi/pkg/validation/strfmt" + + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apiserver/pkg/cel" +) + +// UnstructuredToVal converts a Kubernetes unstructured data element to a CEL Val. +// The root schema of custom resource schema is expected contain type meta and object meta schemas. +// If Embedded resources do not contain type meta and object meta schemas, they will be added automatically. +func UnstructuredToVal(unstructured interface{}, schema Schema) ref.Val { + if unstructured == nil { + if schema.Nullable() { + return types.NullValue + } + return types.NewErr("invalid data, got null for schema with nullable=false") + } + if schema.IsXIntOrString() { + switch v := unstructured.(type) { + case string: + return types.String(v) + case int: + return types.Int(v) + case int32: + return types.Int(v) + case int64: + return types.Int(v) + } + return types.NewErr("invalid data, expected XIntOrString value to be either a string or integer") + } + if schema.Type() == "object" { + m, ok := unstructured.(map[string]interface{}) + if !ok { + return types.NewErr("invalid data, expected a map for the provided schema with type=object") + } + if schema.IsXEmbeddedResource() || schema.Properties() != nil { + if schema.IsXEmbeddedResource() { + schema = schema.WithTypeAndObjectMeta() + } + return &unstructuredMap{ + value: m, + schema: schema, + propSchema: func(key string) (Schema, bool) { + if schema, ok := schema.Properties()[key]; ok { + return schema, true + } + return nil, false + }, + } + } + if schema.AdditionalProperties() != nil && schema.AdditionalProperties().Schema() != nil { + return &unstructuredMap{ + value: m, + schema: schema, + propSchema: func(key string) (Schema, bool) { + return schema.AdditionalProperties().Schema(), true + }, + } + } + // A object with x-kubernetes-preserve-unknown-fields but no properties or additionalProperties is treated + // as an empty object. + if schema.IsXPreserveUnknownFields() { + return &unstructuredMap{ + value: m, + schema: schema, + propSchema: func(key string) (Schema, bool) { + return nil, false + }, + } + } + return types.NewErr("invalid object type, expected either Properties or AdditionalProperties with Allows=true and non-empty Schema") + } + + if schema.Type() == "array" { + l, ok := unstructured.([]interface{}) + if !ok { + return types.NewErr("invalid data, expected an array for the provided schema with type=array") + } + if schema.Items() == nil { + return types.NewErr("invalid array type, expected Items with a non-empty Schema") + } + typedList := unstructuredList{elements: l, itemsSchema: schema.Items()} + listType := schema.XListType() + if listType != "" { + switch listType { + case "map": + mapKeys := schema.XListMapKeys() + return &unstructuredMapList{unstructuredList: typedList, escapedKeyProps: escapeKeyProps(mapKeys)} + case "set": + return &unstructuredSetList{unstructuredList: typedList} + case "atomic": + return &typedList + default: + return types.NewErr("invalid x-kubernetes-list-type, expected 'map', 'set' or 'atomic' but got %s", listType) + } + } + return &typedList + } + + if schema.Type() == "string" { + str, ok := unstructured.(string) + if !ok { + return types.NewErr("invalid data, expected string, got %T", unstructured) + } + switch schema.Format() { + case "duration": + d, err := strfmt.ParseDuration(str) + if err != nil { + return types.NewErr("Invalid duration %s: %v", str, err) + } + return types.Duration{Duration: d} + case "date": + d, err := time.Parse(strfmt.RFC3339FullDate, str) // strfmt uses this format for OpenAPIv3 value validation + if err != nil { + return types.NewErr("Invalid date formatted string %s: %v", str, err) + } + return types.Timestamp{Time: d} + case "date-time": + d, err := strfmt.ParseDateTime(str) + if err != nil { + return types.NewErr("Invalid date-time formatted string %s: %v", str, err) + } + return types.Timestamp{Time: time.Time(d)} + case "byte": + base64 := strfmt.Base64{} + err := base64.UnmarshalText([]byte(str)) + if err != nil { + return types.NewErr("Invalid byte formatted string %s: %v", str, err) + } + return types.Bytes(base64) + } + + return types.String(str) + } + if schema.Type() == "number" { + switch v := unstructured.(type) { + // float representations of whole numbers (e.g. 1.0, 0.0) can convert to int representations (e.g. 1, 0) in yaml + // to json translation, and then get parsed as int64s + case int: + return types.Double(v) + case int32: + return types.Double(v) + case int64: + return types.Double(v) + + case float32: + return types.Double(v) + case float64: + return types.Double(v) + default: + return types.NewErr("invalid data, expected float, got %T", unstructured) + } + } + if schema.Type() == "integer" { + switch v := unstructured.(type) { + case int: + return types.Int(v) + case int32: + return types.Int(v) + case int64: + return types.Int(v) + default: + return types.NewErr("invalid data, expected int, got %T", unstructured) + } + } + if schema.Type() == "boolean" { + b, ok := unstructured.(bool) + if !ok { + return types.NewErr("invalid data, expected bool, got %T", unstructured) + } + return types.Bool(b) + } + + if schema.IsXPreserveUnknownFields() { + return &unknownPreserved{u: unstructured} + } + + return types.NewErr("invalid type, expected object, array, number, integer, boolean or string, or no type with x-kubernetes-int-or-string or x-kubernetes-preserve-unknown-fields is true, got %s", schema.Type()) +} + +// unknownPreserved represents unknown data preserved in custom resources via x-kubernetes-preserve-unknown-fields. +// It preserves the data at runtime without assuming it is of any particular type and supports only equality checking. +// unknownPreserved should be used only for values are not directly accessible in CEL expressions, i.e. for data +// where there is no corresponding CEL type declaration. +type unknownPreserved struct { + u interface{} +} + +func (t *unknownPreserved) ConvertToNative(refType reflect.Type) (interface{}, error) { + return nil, fmt.Errorf("type conversion to '%s' not supported for values preserved by x-kubernetes-preserve-unknown-fields", refType) +} + +func (t *unknownPreserved) ConvertToType(typeValue ref.Type) ref.Val { + return types.NewErr("type conversion to '%s' not supported for values preserved by x-kubernetes-preserve-unknown-fields", typeValue.TypeName()) +} + +func (t *unknownPreserved) Equal(other ref.Val) ref.Val { + return types.Bool(equality.Semantic.DeepEqual(t.u, other.Value())) +} + +func (t *unknownPreserved) Type() ref.Type { + return types.UnknownType +} + +func (t *unknownPreserved) Value() interface{} { + return t.u // used by Equal checks +} + +// unstructuredMapList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=map. +type unstructuredMapList struct { + unstructuredList + escapedKeyProps []string + + sync.Once // for for lazy load of mapOfList since it is only needed if Equals is called + mapOfList map[interface{}]interface{} +} + +func (t *unstructuredMapList) getMap() map[interface{}]interface{} { + t.Do(func() { + t.mapOfList = make(map[interface{}]interface{}, len(t.elements)) + for _, e := range t.elements { + t.mapOfList[t.toMapKey(e)] = e + } + }) + return t.mapOfList +} + +// toMapKey returns a valid golang map key for the given element of the map list. +// element must be a valid map list entry where all map key props are scalar types (which are comparable in go +// and valid for use in a golang map key). +func (t *unstructuredMapList) toMapKey(element interface{}) interface{} { + eObj, ok := element.(map[string]interface{}) + if !ok { + return types.NewErr("unexpected data format for element of array with x-kubernetes-list-type=map: %T", element) + } + // Arrays are comparable in go and may be used as map keys, but maps and slices are not. + // So we can special case small numbers of key props as arrays and fall back to serialization + // for larger numbers of key props + if len(t.escapedKeyProps) == 1 { + return eObj[t.escapedKeyProps[0]] + } + if len(t.escapedKeyProps) == 2 { + return [2]interface{}{eObj[t.escapedKeyProps[0]], eObj[t.escapedKeyProps[1]]} + } + if len(t.escapedKeyProps) == 3 { + return [3]interface{}{eObj[t.escapedKeyProps[0]], eObj[t.escapedKeyProps[1]], eObj[t.escapedKeyProps[2]]} + } + + key := make([]interface{}, len(t.escapedKeyProps)) + for i, kf := range t.escapedKeyProps { + key[i] = eObj[kf] + } + return fmt.Sprintf("%v", key) +} + +// Equal on a map list ignores list element order. +func (t *unstructuredMapList) Equal(other ref.Val) ref.Val { + oMapList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + sz := types.Int(len(t.elements)) + if sz != oMapList.Size() { + return types.False + } + tMap := t.getMap() + for it := oMapList.Iterator(); it.HasNext() == types.True; { + v := it.Next() + k := t.toMapKey(v.Value()) + tVal, ok := tMap[k] + if !ok { + return types.False + } + eq := UnstructuredToVal(tVal, t.itemsSchema).Equal(v) + if eq != types.True { + return eq // either false or error + } + } + return types.True +} + +// Add for a map list `X + Y` performs a merge where the array positions of all keys in `X` are preserved but the values +// are overwritten by values in `Y` when the key sets of `X` and `Y` intersect. Elements in `Y` with +// non-intersecting keys are appended, retaining their partial order. +func (t *unstructuredMapList) Add(other ref.Val) ref.Val { + oMapList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + elements := make([]interface{}, len(t.elements)) + keyToIdx := map[interface{}]int{} + for i, e := range t.elements { + k := t.toMapKey(e) + keyToIdx[k] = i + elements[i] = e + } + for it := oMapList.Iterator(); it.HasNext() == types.True; { + v := it.Next().Value() + k := t.toMapKey(v) + if overwritePosition, ok := keyToIdx[k]; ok { + elements[overwritePosition] = v + } else { + elements = append(elements, v) + } + } + return &unstructuredMapList{ + unstructuredList: unstructuredList{elements: elements, itemsSchema: t.itemsSchema}, + escapedKeyProps: t.escapedKeyProps, + } +} + +// escapeKeyProps returns identifiers with Escape applied to each. +// Identifiers that cannot be escaped are left as-is. They are inaccessible to CEL programs but are +// are still needed internally to perform equality checks. +func escapeKeyProps(idents []string) []string { + result := make([]string, len(idents)) + for i, prop := range idents { + if escaped, ok := cel.Escape(prop); ok { + result[i] = escaped + } else { + result[i] = prop + } + } + return result +} + +// unstructuredSetList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=set. +type unstructuredSetList struct { + unstructuredList + escapedKeyProps []string + + sync.Once // for for lazy load of setOfList since it is only needed if Equals is called + set map[interface{}]struct{} +} + +func (t *unstructuredSetList) getSet() map[interface{}]struct{} { + // sets are only allowed to contain scalar elements, which are comparable in go, and can safely be used as + // golang map keys + t.Do(func() { + t.set = make(map[interface{}]struct{}, len(t.elements)) + for _, e := range t.elements { + t.set[e] = struct{}{} + } + }) + return t.set +} + +// Equal on a map list ignores list element order. +func (t *unstructuredSetList) Equal(other ref.Val) ref.Val { + oSetList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + sz := types.Int(len(t.elements)) + if sz != oSetList.Size() { + return types.False + } + tSet := t.getSet() + for it := oSetList.Iterator(); it.HasNext() == types.True; { + next := it.Next().Value() + _, ok := tSet[next] + if !ok { + return types.False + } + } + return types.True +} + +// Add for a set list `X + Y` performs a union where the array positions of all elements in `X` are preserved and +// non-intersecting elements in `Y` are appended, retaining their partial order. +func (t *unstructuredSetList) Add(other ref.Val) ref.Val { + oSetList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + elements := t.elements + set := t.getSet() + for it := oSetList.Iterator(); it.HasNext() == types.True; { + next := it.Next().Value() + if _, ok := set[next]; !ok { + set[next] = struct{}{} + elements = append(elements, next) + } + } + return &unstructuredSetList{ + unstructuredList: unstructuredList{elements: elements, itemsSchema: t.itemsSchema}, + escapedKeyProps: t.escapedKeyProps, + } +} + +// unstructuredList represents an unstructured data instance of an OpenAPI array with x-kubernetes-list-type=atomic (the default). +type unstructuredList struct { + elements []interface{} + itemsSchema Schema +} + +var _ = traits.Lister(&unstructuredList{}) + +func (t *unstructuredList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Slice: + switch t.itemsSchema.Type() { + // Workaround for https://github.com/kubernetes/kubernetes/issues/117590 until we + // resolve the desired behavior in cel-go via https://github.com/google/cel-go/issues/688 + case "string": + var result []string + for _, e := range t.elements { + s, ok := e.(string) + if !ok { + return nil, fmt.Errorf("expected all elements to be of type string, but got %T", e) + } + result = append(result, s) + } + return result, nil + default: + return t.elements, nil + } + } + return nil, fmt.Errorf("type conversion error from '%s' to '%s'", t.Type(), typeDesc) +} + +func (t *unstructuredList) ConvertToType(typeValue ref.Type) ref.Val { + switch typeValue { + case types.ListType: + return t + case types.TypeType: + return types.ListType + } + return types.NewErr("type conversion error from '%s' to '%s'", t.Type(), typeValue.TypeName()) +} + +func (t *unstructuredList) Equal(other ref.Val) ref.Val { + oList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + sz := types.Int(len(t.elements)) + if sz != oList.Size() { + return types.False + } + for i := types.Int(0); i < sz; i++ { + eq := t.Get(i).Equal(oList.Get(i)) + if eq != types.True { + return eq // either false or error + } + } + return types.True +} + +func (t *unstructuredList) Type() ref.Type { + return types.ListType +} + +func (t *unstructuredList) Value() interface{} { + return t.elements +} + +func (t *unstructuredList) Add(other ref.Val) ref.Val { + oList, ok := other.(traits.Lister) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + elements := t.elements + for it := oList.Iterator(); it.HasNext() == types.True; { + next := it.Next().Value() + elements = append(elements, next) + } + + return &unstructuredList{elements: elements, itemsSchema: t.itemsSchema} +} + +func (t *unstructuredList) Contains(val ref.Val) ref.Val { + if types.IsUnknownOrError(val) { + return val + } + var err ref.Val + sz := len(t.elements) + for i := 0; i < sz; i++ { + elem := UnstructuredToVal(t.elements[i], t.itemsSchema) + cmp := elem.Equal(val) + b, ok := cmp.(types.Bool) + if !ok && err == nil { + err = types.MaybeNoSuchOverloadErr(cmp) + } + if b == types.True { + return types.True + } + } + if err != nil { + return err + } + return types.False +} + +func (t *unstructuredList) Get(idx ref.Val) ref.Val { + iv, isInt := idx.(types.Int) + if !isInt { + return types.ValOrErr(idx, "unsupported index: %v", idx) + } + i := int(iv) + if i < 0 || i >= len(t.elements) { + return types.NewErr("index out of bounds: %v", idx) + } + return UnstructuredToVal(t.elements[i], t.itemsSchema) +} + +func (t *unstructuredList) Iterator() traits.Iterator { + items := make([]ref.Val, len(t.elements)) + for i, item := range t.elements { + itemCopy := item + items[i] = UnstructuredToVal(itemCopy, t.itemsSchema) + } + return &listIterator{unstructuredList: t, items: items} +} + +type listIterator struct { + *unstructuredList + items []ref.Val + idx int +} + +func (it *listIterator) HasNext() ref.Val { + return types.Bool(it.idx < len(it.items)) +} + +func (it *listIterator) Next() ref.Val { + item := it.items[it.idx] + it.idx++ + return item +} + +func (t *unstructuredList) Size() ref.Val { + return types.Int(len(t.elements)) +} + +// unstructuredMap represented an unstructured data instance of an OpenAPI object. +type unstructuredMap struct { + value map[string]interface{} + schema Schema + // propSchema finds the schema to use for a particular map key. + propSchema func(key string) (Schema, bool) +} + +var _ = traits.Mapper(&unstructuredMap{}) + +func (t *unstructuredMap) ConvertToNative(typeDesc reflect.Type) (interface{}, error) { + switch typeDesc.Kind() { + case reflect.Map: + return t.value, nil + } + return nil, fmt.Errorf("type conversion error from '%s' to '%s'", t.Type(), typeDesc) +} + +func (t *unstructuredMap) ConvertToType(typeValue ref.Type) ref.Val { + switch typeValue { + case types.MapType: + return t + case types.TypeType: + return types.MapType + } + return types.NewErr("type conversion error from '%s' to '%s'", t.Type(), typeValue.TypeName()) +} + +func (t *unstructuredMap) Equal(other ref.Val) ref.Val { + oMap, isMap := other.(traits.Mapper) + if !isMap { + return types.MaybeNoSuchOverloadErr(other) + } + if t.Size() != oMap.Size() { + return types.False + } + for key, value := range t.value { + if propSchema, ok := t.propSchema(key); ok { + ov, found := oMap.Find(types.String(key)) + if !found { + return types.False + } + v := UnstructuredToVal(value, propSchema) + vEq := v.Equal(ov) + if vEq != types.True { + return vEq // either false or error + } + } else { + // Must be an object with properties. + // Since we've encountered an unknown field, fallback to unstructured equality checking. + ouMap, ok := other.(*unstructuredMap) + if !ok { + // The compiler ensures equality is against the same type of object, so this should be unreachable + return types.MaybeNoSuchOverloadErr(other) + } + if oValue, ok := ouMap.value[key]; ok { + if !equality.Semantic.DeepEqual(value, oValue) { + return types.False + } + } + } + } + return types.True +} + +func (t *unstructuredMap) Type() ref.Type { + return types.MapType +} + +func (t *unstructuredMap) Value() interface{} { + return t.value +} + +func (t *unstructuredMap) Contains(key ref.Val) ref.Val { + v, found := t.Find(key) + if v != nil && types.IsUnknownOrError(v) { + return v + } + + return types.Bool(found) +} + +func (t *unstructuredMap) Get(key ref.Val) ref.Val { + v, found := t.Find(key) + if found { + return v + } + return types.ValOrErr(key, "no such key: %v", key) +} + +func (t *unstructuredMap) Iterator() traits.Iterator { + isObject := t.schema.Properties() != nil + keys := make([]ref.Val, len(t.value)) + i := 0 + for k := range t.value { + if _, ok := t.propSchema(k); ok { + mapKey := k + if isObject { + if escaped, ok := cel.Escape(k); ok { + mapKey = escaped + } + } + keys[i] = types.String(mapKey) + i++ + } + } + return &mapIterator{unstructuredMap: t, keys: keys} +} + +type mapIterator struct { + *unstructuredMap + keys []ref.Val + idx int +} + +func (it *mapIterator) HasNext() ref.Val { + return types.Bool(it.idx < len(it.keys)) +} + +func (it *mapIterator) Next() ref.Val { + key := it.keys[it.idx] + it.idx++ + return key +} + +func (t *unstructuredMap) Size() ref.Val { + return types.Int(len(t.value)) +} + +func (t *unstructuredMap) Find(key ref.Val) (ref.Val, bool) { + isObject := t.schema.Properties() != nil + keyStr, ok := key.(types.String) + if !ok { + return types.MaybeNoSuchOverloadErr(key), true + } + k := keyStr.Value().(string) + if isObject { + k, ok = cel.Unescape(k) + if !ok { + return nil, false + } + } + if v, ok := t.value[k]; ok { + // If this is an object with properties, not an object with additionalProperties, + // then null valued nullable fields are treated the same as absent optional fields. + if isObject && v == nil { + return nil, false + } + if propSchema, ok := t.propSchema(k); ok { + return UnstructuredToVal(v, propSchema), true + } + } + + return nil, false +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/composited.go b/vendor/k8s.io/apiserver/pkg/cel/composited.go new file mode 100644 index 000000000..9e5e634d0 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/composited.go @@ -0,0 +1,119 @@ +/* +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 cel + +import ( + "github.com/google/cel-go/common/types/ref" + exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" +) + +var _ ref.TypeProvider = (*CompositedTypeProvider)(nil) +var _ ref.TypeAdapter = (*CompositedTypeAdapter)(nil) + +// CompositedTypeProvider is the provider that tries each of the underlying +// providers in order, and returns result of the first successful attempt. +type CompositedTypeProvider struct { + // Providers contains the underlying type providers. + // If Providers is empty, the CompositedTypeProvider becomes no-op provider. + Providers []ref.TypeProvider +} + +// EnumValue finds out the numeric value of the given enum name. +// The result comes from first provider that returns non-nil. +func (c *CompositedTypeProvider) EnumValue(enumName string) ref.Val { + for _, p := range c.Providers { + val := p.EnumValue(enumName) + if val != nil { + return val + } + } + return nil +} + +// FindIdent takes a qualified identifier name and returns a Value if one +// exists. The result comes from first provider that returns non-nil. +func (c *CompositedTypeProvider) FindIdent(identName string) (ref.Val, bool) { + for _, p := range c.Providers { + val, ok := p.FindIdent(identName) + if ok { + return val, ok + } + } + return nil, false +} + +// FindType finds the Type given a qualified type name, or return false +// if none of the providers finds the type. +// If any of the providers find the type, the first provider that returns true +// will be the result. +func (c *CompositedTypeProvider) FindType(typeName string) (*exprpb.Type, bool) { + for _, p := range c.Providers { + typ, ok := p.FindType(typeName) + if ok { + return typ, ok + } + } + return nil, false +} + +// FindFieldType returns the field type for a checked type value. Returns +// false if none of the providers can find the type. +// If multiple providers can find the field, the result is taken from +// the first that does. +func (c *CompositedTypeProvider) FindFieldType(messageType string, fieldName string) (*ref.FieldType, bool) { + for _, p := range c.Providers { + ft, ok := p.FindFieldType(messageType, fieldName) + if ok { + return ft, ok + } + } + return nil, false +} + +// NewValue creates a new type value from a qualified name and map of field +// name to value. +// If multiple providers can create the new type, the first that returns +// non-nil will decide the result. +func (c *CompositedTypeProvider) NewValue(typeName string, fields map[string]ref.Val) ref.Val { + for _, p := range c.Providers { + v := p.NewValue(typeName, fields) + if v != nil { + return v + } + } + return nil +} + +// CompositedTypeAdapter is the adapter that tries each of the underlying +// type adapter in order until the first successfully conversion. +type CompositedTypeAdapter struct { + // Adapters contains underlying type adapters. + // If Adapters is empty, the CompositedTypeAdapter becomes a no-op adapter. + Adapters []ref.TypeAdapter +} + +// NativeToValue takes the value and convert it into a ref.Val +// The result comes from the first TypeAdapter that returns non-nil. +func (c *CompositedTypeAdapter) NativeToValue(value interface{}) ref.Val { + for _, a := range c.Adapters { + v := a.NativeToValue(value) + if v != nil { + return v + } + } + return nil +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/authz.go b/vendor/k8s.io/apiserver/pkg/cel/library/authz.go new file mode 100644 index 000000000..606e5769a --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/library/authz.go @@ -0,0 +1,580 @@ +/* +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 library + +import ( + "context" + "fmt" + "reflect" + "strings" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + + apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" +) + +// Authz provides a CEL function library extension for performing authorization checks. +// Note that authorization checks are only supported for CEL expression fields in the API +// where an 'authorizer' variable is provided to the CEL expression. See the +// documentation of API fields where CEL expressions are used to learn if the 'authorizer' +// variable is provided. +// +// path +// +// Returns a PathCheck configured to check authorization for a non-resource request +// path (e.g. /healthz). If path is an empty string, an error is returned. +// Note that the leading '/' is not required. +// +// .path() +// +// Examples: +// +// authorizer.path('/healthz') // returns a PathCheck for the '/healthz' API path +// authorizer.path('') // results in "path must not be empty" error +// authorizer.path(' ') // results in "path must not be empty" error +// +// group +// +// Returns a GroupCheck configured to check authorization for the API resources for +// a particular API group. +// Note that authorization checks are only supported for CEL expression fields in the API +// where an 'authorizer' variable is provided to the CEL expression. Check the +// documentation of API fields where CEL expressions are used to learn if the 'authorizer' +// variable is provided. +// +// .group() +// +// Examples: +// +// authorizer.group('apps') // returns a GroupCheck for the 'apps' API group +// authorizer.group('') // returns a GroupCheck for the core API group +// authorizer.group('example.com') // returns a GroupCheck for the custom resources in the 'example.com' API group +// +// serviceAccount +// +// Returns an Authorizer configured to check authorization for the provided service account namespace and name. +// If the name is not a valid DNS subdomain string (as defined by RFC 1123), an error is returned. +// If the namespace is not a valid DNS label (as defined by RFC 1123), an error is returned. +// +// .serviceAccount(, ) +// +// Examples: +// +// authorizer.serviceAccount('default', 'myserviceaccount') // returns an Authorizer for the service account with namespace 'default' and name 'myserviceaccount' +// authorizer.serviceAccount('not@a#valid!namespace', 'validname') // returns an error +// authorizer.serviceAccount('valid.example.com', 'invalid@*name') // returns an error +// +// resource +// +// Returns a ResourceCheck configured to check authorization for a particular API resource. +// Note that the provided resource string should be a lower case plural name of a Kubernetes API resource. +// +// .resource() +// +// Examples: +// +// authorizer.group('apps').resource('deployments') // returns a ResourceCheck for the 'deployments' resources in the 'apps' group. +// authorizer.group('').resource('pods') // returns a ResourceCheck for the 'pods' resources in the core group. +// authorizer.group('apps').resource('') // results in "resource must not be empty" error +// authorizer.group('apps').resource(' ') // results in "resource must not be empty" error +// +// subresource +// +// Returns a ResourceCheck configured to check authorization for a particular subresource of an API resource. +// If subresource is set to "", the subresource field of this ResourceCheck is considered unset. +// +// .subresource() +// +// Examples: +// +// authorizer.group('').resource('pods').subresource('status') // returns a ResourceCheck the 'status' subresource of 'pods' +// authorizer.group('apps').resource('deployments').subresource('scale') // returns a ResourceCheck the 'scale' subresource of 'deployments' +// authorizer.group('example.com').resource('widgets').subresource('scale') // returns a ResourceCheck for the 'scale' subresource of the 'widgets' custom resource +// authorizer.group('example.com').resource('widgets').subresource('') // returns a ResourceCheck for the 'widgets' resource. +// +// namespace +// +// Returns a ResourceCheck configured to check authorization for a particular namespace. +// For cluster scoped resources, namespace() does not need to be called; namespace defaults +// to "", which is the correct namespace value to use to check cluster scoped resources. +// If namespace is set to "", the ResourceCheck will check authorization for the cluster scope. +// +// .namespace() +// +// Examples: +// +// authorizer.group('apps').resource('deployments').namespace('test') // returns a ResourceCheck for 'deployments' in the 'test' namespace +// authorizer.group('').resource('pods').namespace('default') // returns a ResourceCheck for 'pods' in the 'default' namespace +// authorizer.group('').resource('widgets').namespace('') // returns a ResourceCheck for 'widgets' in the cluster scope +// +// name +// +// Returns a ResourceCheck configured to check authorization for a particular resource name. +// If name is set to "", the name field of this ResourceCheck is considered unset. +// +// .name() +// +// Examples: +// +// authorizer.group('apps').resource('deployments').namespace('test').name('backend') // returns a ResourceCheck for the 'backend' 'deployments' resource in the 'test' namespace +// authorizer.group('apps').resource('deployments').namespace('test').name('') // returns a ResourceCheck for the 'deployments' resource in the 'test' namespace +// +// check +// +// For PathCheck, checks if the principal (user or service account) that sent the request is authorized for the HTTP request verb of the path. +// For ResourceCheck, checks if the principal (user or service account) that sent the request is authorized for the API verb and the configured authorization checks of the ResourceCheck. +// The check operation can be expensive, particularly in clusters using the webhook authorization mode. +// +// .check() +// .check() +// +// Examples: +// +// authorizer.group('').resource('pods').namespace('default').check('create') // Checks if the principal (user or service account) is authorized create pods in the 'default' namespace. +// authorizer.path('/healthz').check('get') // Checks if the principal (user or service account) is authorized to make HTTP GET requests to the /healthz API path. +// +// allowed +// +// Returns true if the authorizer's decision for the check is "allow". Note that if the authorizer's decision is +// "no opinion", that the 'allowed' function will return false. +// +// .allowed() +// +// Examples: +// +// authorizer.group('').resource('pods').namespace('default').check('create').allowed() // Returns true if the principal (user or service account) is allowed create pods in the 'default' namespace. +// authorizer.path('/healthz').check('get').allowed() // Returns true if the principal (user or service account) is allowed to make HTTP GET requests to the /healthz API path. +// +// reason +// +// Returns a string reason for the authorization decision +// +// .reason() +// +// Examples: +// +// authorizer.path('/healthz').check('GET').reason() +func Authz() cel.EnvOption { + return cel.Lib(authzLib) +} + +var authzLib = &authz{} + +type authz struct{} + +var authzLibraryDecls = map[string][]cel.FunctionOpt{ + "path": { + cel.MemberOverload("authorizer_path", []*cel.Type{AuthorizerType, cel.StringType}, PathCheckType, + cel.BinaryBinding(authorizerPath))}, + "group": { + cel.MemberOverload("authorizer_group", []*cel.Type{AuthorizerType, cel.StringType}, GroupCheckType, + cel.BinaryBinding(authorizerGroup))}, + "serviceAccount": { + cel.MemberOverload("authorizer_serviceaccount", []*cel.Type{AuthorizerType, cel.StringType, cel.StringType}, AuthorizerType, + cel.FunctionBinding(authorizerServiceAccount))}, + "resource": { + cel.MemberOverload("groupcheck_resource", []*cel.Type{GroupCheckType, cel.StringType}, ResourceCheckType, + cel.BinaryBinding(groupCheckResource))}, + "subresource": { + cel.MemberOverload("resourcecheck_subresource", []*cel.Type{ResourceCheckType, cel.StringType}, ResourceCheckType, + cel.BinaryBinding(resourceCheckSubresource))}, + "namespace": { + cel.MemberOverload("resourcecheck_namespace", []*cel.Type{ResourceCheckType, cel.StringType}, ResourceCheckType, + cel.BinaryBinding(resourceCheckNamespace))}, + "name": { + cel.MemberOverload("resourcecheck_name", []*cel.Type{ResourceCheckType, cel.StringType}, ResourceCheckType, + cel.BinaryBinding(resourceCheckName))}, + "check": { + cel.MemberOverload("pathcheck_check", []*cel.Type{PathCheckType, cel.StringType}, DecisionType, + cel.BinaryBinding(pathCheckCheck)), + cel.MemberOverload("resourcecheck_check", []*cel.Type{ResourceCheckType, cel.StringType}, DecisionType, + cel.BinaryBinding(resourceCheckCheck))}, + "allowed": { + cel.MemberOverload("decision_allowed", []*cel.Type{DecisionType}, cel.BoolType, + cel.UnaryBinding(decisionAllowed))}, + "reason": { + cel.MemberOverload("decision_reason", []*cel.Type{DecisionType}, cel.StringType, + cel.UnaryBinding(decisionReason))}, +} + +func (*authz) CompileOptions() []cel.EnvOption { + options := make([]cel.EnvOption, 0, len(authzLibraryDecls)) + for name, overloads := range authzLibraryDecls { + options = append(options, cel.Function(name, overloads...)) + } + return options +} + +func (*authz) ProgramOptions() []cel.ProgramOption { + return []cel.ProgramOption{} +} + +func authorizerPath(arg1, arg2 ref.Val) ref.Val { + authz, ok := arg1.(authorizerVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + path, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + if len(strings.TrimSpace(path)) == 0 { + return types.NewErr("path must not be empty") + } + + return authz.pathCheck(path) +} + +func authorizerGroup(arg1, arg2 ref.Val) ref.Val { + authz, ok := arg1.(authorizerVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + group, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + return authz.groupCheck(group) +} + +func authorizerServiceAccount(args ...ref.Val) ref.Val { + argn := len(args) + if argn != 3 { + return types.NoSuchOverloadErr() + } + + authz, ok := args[0].(authorizerVal) + if !ok { + return types.MaybeNoSuchOverloadErr(args[0]) + } + + namespace, ok := args[1].Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(args[1]) + } + + name, ok := args[2].Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(args[2]) + } + + if errors := apimachineryvalidation.ValidateServiceAccountName(name, false); len(errors) > 0 { + return types.NewErr("Invalid service account name") + } + if errors := apimachineryvalidation.ValidateNamespaceName(namespace, false); len(errors) > 0 { + return types.NewErr("Invalid service account namespace") + } + return authz.serviceAccount(namespace, name) +} + +func groupCheckResource(arg1, arg2 ref.Val) ref.Val { + groupCheck, ok := arg1.(groupCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + resource, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + if len(strings.TrimSpace(resource)) == 0 { + return types.NewErr("resource must not be empty") + } + return groupCheck.resourceCheck(resource) +} + +func resourceCheckSubresource(arg1, arg2 ref.Val) ref.Val { + resourceCheck, ok := arg1.(resourceCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + subresource, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + result := resourceCheck + result.subresource = subresource + return result +} + +func resourceCheckNamespace(arg1, arg2 ref.Val) ref.Val { + resourceCheck, ok := arg1.(resourceCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + namespace, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + result := resourceCheck + result.namespace = namespace + return result +} + +func resourceCheckName(arg1, arg2 ref.Val) ref.Val { + resourceCheck, ok := arg1.(resourceCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + name, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + result := resourceCheck + result.name = name + return result +} + +func pathCheckCheck(arg1, arg2 ref.Val) ref.Val { + pathCheck, ok := arg1.(pathCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + httpRequestVerb, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + return pathCheck.Authorize(context.TODO(), httpRequestVerb) +} + +func resourceCheckCheck(arg1, arg2 ref.Val) ref.Val { + resourceCheck, ok := arg1.(resourceCheckVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + apiVerb, ok := arg2.Value().(string) + if !ok { + return types.MaybeNoSuchOverloadErr(arg1) + } + + return resourceCheck.Authorize(context.TODO(), apiVerb) +} + +func decisionAllowed(arg ref.Val) ref.Val { + decision, ok := arg.(decisionVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + return types.Bool(decision.authDecision == authorizer.DecisionAllow) +} + +func decisionReason(arg ref.Val) ref.Val { + decision, ok := arg.(decisionVal) + if !ok { + return types.MaybeNoSuchOverloadErr(arg) + } + + return types.String(decision.reason) +} + +var ( + AuthorizerType = cel.ObjectType("kubernetes.authorization.Authorizer") + PathCheckType = cel.ObjectType("kubernetes.authorization.PathCheck") + GroupCheckType = cel.ObjectType("kubernetes.authorization.GroupCheck") + ResourceCheckType = cel.ObjectType("kubernetes.authorization.ResourceCheck") + DecisionType = cel.ObjectType("kubernetes.authorization.Decision") +) + +// Resource represents an API resource +type Resource interface { + // GetName returns the name of the object as presented in the request. On a CREATE operation, the client + // may omit name and rely on the server to generate the name. If that is the case, this method will return + // the empty string + GetName() string + // GetNamespace is the namespace associated with the request (if any) + GetNamespace() string + // GetResource is the name of the resource being requested. This is not the kind. For example: pods + GetResource() schema.GroupVersionResource + // GetSubresource is the name of the subresource being requested. This is a different resource, scoped to the parent resource, but it may have a different kind. + // For instance, /pods has the resource "pods" and the kind "Pod", while /pods/foo/status has the resource "pods", the sub resource "status", and the kind "Pod" + // (because status operates on pods). The binding resource for a pod though may be /pods/foo/binding, which has resource "pods", subresource "binding", and kind "Binding". + GetSubresource() string +} + +func NewAuthorizerVal(userInfo user.Info, authorizer authorizer.Authorizer) ref.Val { + return authorizerVal{receiverOnlyObjectVal: receiverOnlyVal(AuthorizerType), userInfo: userInfo, authAuthorizer: authorizer} +} + +func NewResourceAuthorizerVal(userInfo user.Info, authorizer authorizer.Authorizer, requestResource Resource) ref.Val { + a := authorizerVal{receiverOnlyObjectVal: receiverOnlyVal(AuthorizerType), userInfo: userInfo, authAuthorizer: authorizer} + resource := requestResource.GetResource() + g := a.groupCheck(resource.Group) + r := g.resourceCheck(resource.Resource) + r.subresource = requestResource.GetSubresource() + r.namespace = requestResource.GetNamespace() + r.name = requestResource.GetName() + return r +} + +type authorizerVal struct { + receiverOnlyObjectVal + userInfo user.Info + authAuthorizer authorizer.Authorizer +} + +func (a authorizerVal) pathCheck(path string) pathCheckVal { + return pathCheckVal{receiverOnlyObjectVal: receiverOnlyVal(PathCheckType), authorizer: a, path: path} +} + +func (a authorizerVal) groupCheck(group string) groupCheckVal { + return groupCheckVal{receiverOnlyObjectVal: receiverOnlyVal(GroupCheckType), authorizer: a, group: group} +} + +func (a authorizerVal) serviceAccount(namespace, name string) authorizerVal { + sa := &serviceaccount.ServiceAccountInfo{Name: name, Namespace: namespace} + return authorizerVal{ + receiverOnlyObjectVal: receiverOnlyVal(AuthorizerType), + userInfo: sa.UserInfo(), + authAuthorizer: a.authAuthorizer, + } +} + +type pathCheckVal struct { + receiverOnlyObjectVal + authorizer authorizerVal + path string +} + +func (a pathCheckVal) Authorize(ctx context.Context, verb string) ref.Val { + attr := &authorizer.AttributesRecord{ + Path: a.path, + Verb: verb, + User: a.authorizer.userInfo, + } + + decision, reason, err := a.authorizer.authAuthorizer.Authorize(ctx, attr) + if err != nil { + return types.NewErr("error in authorization check: %v", err) + } + return newDecision(decision, reason) +} + +type groupCheckVal struct { + receiverOnlyObjectVal + authorizer authorizerVal + group string +} + +func (g groupCheckVal) resourceCheck(resource string) resourceCheckVal { + return resourceCheckVal{receiverOnlyObjectVal: receiverOnlyVal(ResourceCheckType), groupCheck: g, resource: resource} +} + +type resourceCheckVal struct { + receiverOnlyObjectVal + groupCheck groupCheckVal + resource string + subresource string + namespace string + name string +} + +func (a resourceCheckVal) Authorize(ctx context.Context, verb string) ref.Val { + attr := &authorizer.AttributesRecord{ + ResourceRequest: true, + APIGroup: a.groupCheck.group, + APIVersion: "*", + Resource: a.resource, + Subresource: a.subresource, + Namespace: a.namespace, + Name: a.name, + Verb: verb, + User: a.groupCheck.authorizer.userInfo, + } + decision, reason, err := a.groupCheck.authorizer.authAuthorizer.Authorize(ctx, attr) + if err != nil { + return types.NewErr("error in authorization check: %v", err) + } + return newDecision(decision, reason) +} + +func newDecision(authDecision authorizer.Decision, reason string) decisionVal { + return decisionVal{receiverOnlyObjectVal: receiverOnlyVal(DecisionType), authDecision: authDecision, reason: reason} +} + +type decisionVal struct { + receiverOnlyObjectVal + authDecision authorizer.Decision + reason string +} + +// receiverOnlyObjectVal provides an implementation of ref.Val for +// any object type that has receiver functions but does not expose any fields to +// CEL. +type receiverOnlyObjectVal struct { + typeValue *types.TypeValue +} + +// receiverOnlyVal returns a receiverOnlyObjectVal for the given type. +func receiverOnlyVal(objectType *cel.Type) receiverOnlyObjectVal { + return receiverOnlyObjectVal{typeValue: types.NewTypeValue(objectType.String())} +} + +// ConvertToNative implements ref.Val.ConvertToNative. +func (a receiverOnlyObjectVal) ConvertToNative(typeDesc reflect.Type) (any, error) { + return nil, fmt.Errorf("type conversion error from '%s' to '%v'", a.typeValue.String(), typeDesc) +} + +// ConvertToType implements ref.Val.ConvertToType. +func (a receiverOnlyObjectVal) ConvertToType(typeVal ref.Type) ref.Val { + switch typeVal { + case a.typeValue: + return a + case types.TypeType: + return a.typeValue + } + return types.NewErr("type conversion error from '%s' to '%s'", a.typeValue, typeVal) +} + +// Equal implements ref.Val.Equal. +func (a receiverOnlyObjectVal) Equal(other ref.Val) ref.Val { + o, ok := other.(receiverOnlyObjectVal) + if !ok { + return types.MaybeNoSuchOverloadErr(other) + } + return types.Bool(a == o) +} + +// Type implements ref.Val.Type. +func (a receiverOnlyObjectVal) Type() ref.Type { + return a.typeValue +} + +// Value implements ref.Val.Value. +func (a receiverOnlyObjectVal) Value() any { + return types.NoSuchOverloadErr() +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/cost.go b/vendor/k8s.io/apiserver/pkg/cel/library/cost.go index 39098e3f6..6cc629032 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/library/cost.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/cost.go @@ -36,6 +36,15 @@ type CostEstimator struct { func (l *CostEstimator) CallCost(function, overloadId string, args []ref.Val, result ref.Val) *uint64 { switch function { + case "check": + // An authorization check has a fixed cost + // This cost is set to allow for only two authorization checks per expression + cost := uint64(350000) + return &cost + case "serviceAccount", "path", "group", "resource", "subresource", "namespace", "name", "allowed", "denied", "reason": + // All authorization builder and accessor functions have a nominal cost + cost := uint64(1) + return &cost case "isSorted", "sum", "max", "min", "indexOf", "lastIndexOf": var cost uint64 if len(args) > 0 { @@ -78,6 +87,13 @@ func (l *CostEstimator) EstimateCallCost(function, overloadId string, target *ch // WARNING: Any changes to this code impact API compatibility! The estimated cost is used to determine which CEL rules may be written to a // CRD and any change (cost increases and cost decreases) are breaking. switch function { + case "check": + // An authorization check has a fixed cost + // This cost is set to allow for only two authorization checks per expression + return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 350000, Max: 350000}} + case "serviceAccount", "path", "group", "resource", "subresource", "namespace", "name", "allowed", "denied", "reason": + // All authorization builder and accessor functions have a nominal cost + return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 1, Max: 1}} case "isSorted", "sum", "max", "min", "indexOf", "lastIndexOf": if target != nil { // Charge 1 cost for comparing each element in the list @@ -94,7 +110,6 @@ func (l *CostEstimator) EstimateCallCost(function, overloadId string, target *ch } else { // the target is a string, which is supported by indexOf and lastIndexOf return &checker.CallEstimate{CostEstimate: l.sizeEstimate(*target).MultiplyByCostFactor(common.StringTraversalCostFactor)} } - } case "url": if len(args) == 1 { diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/libraries.go b/vendor/k8s.io/apiserver/pkg/cel/library/libraries.go index 18f6d7a7c..e2e8fc29b 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/library/libraries.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/libraries.go @@ -29,6 +29,7 @@ var k8sExtensionLibs = []cel.EnvOption{ URLs(), Regex(), Lists(), + Authz(), } var ExtensionLibRegexOptimizations = []*interpreter.RegexOptimization{FindRegexOptimization, FindAllRegexOptimization} diff --git a/vendor/k8s.io/apiserver/pkg/cel/library/urls.go b/vendor/k8s.io/apiserver/pkg/cel/library/urls.go index afe80f493..7be054ece 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/library/urls.go +++ b/vendor/k8s.io/apiserver/pkg/cel/library/urls.go @@ -61,9 +61,9 @@ import ( // // - getScheme: If absent in the URL, returns an empty string. // -// - getHostname: IPv6 addresses are returned with braces, e.g. "[::1]". If absent in the URL, returns an empty string. +// - getHostname: IPv6 addresses are returned without braces, e.g. "::1". If absent in the URL, returns an empty string. // -// - getHost: IPv6 addresses are returned without braces, e.g. "::1". If absent in the URL, returns an empty string. +// - getHost: IPv6 addresses are returned with braces, e.g. "[::1]". If absent in the URL, returns an empty string. // // - getEscapedPath: The string returned by getEscapedPath is URL escaped, e.g. "with space" becomes "with%20space". // If absent in the URL, returns an empty string. diff --git a/vendor/k8s.io/apiserver/pkg/cel/limits.go b/vendor/k8s.io/apiserver/pkg/cel/limits.go index 7bdb958d0..65c6ad5f3 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/limits.go +++ b/vendor/k8s.io/apiserver/pkg/cel/limits.go @@ -16,9 +16,11 @@ limitations under the License. package cel +import celconfig "k8s.io/apiserver/pkg/apis/cel" + const ( // DefaultMaxRequestSizeBytes is the size of the largest request that will be accepted - DefaultMaxRequestSizeBytes = int64(3 * 1024 * 1024) + DefaultMaxRequestSizeBytes = celconfig.MaxRequestSizeBytes // MaxDurationSizeJSON // OpenAPI duration strings follow RFC 3339, section 5.6 - see the comment on maxDatetimeSizeJSON diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go new file mode 100644 index 000000000..0e2cc6e2b --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/adaptor.go @@ -0,0 +1,147 @@ +/* +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 openapi + +import ( + "github.com/google/cel-go/common/types/ref" + + apiservercel "k8s.io/apiserver/pkg/cel" + "k8s.io/apiserver/pkg/cel/common" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +var _ common.Schema = (*Schema)(nil) +var _ common.SchemaOrBool = (*SchemaOrBool)(nil) + +type Schema struct { + Schema *spec.Schema +} + +type SchemaOrBool struct { + SchemaOrBool *spec.SchemaOrBool +} + +func (sb *SchemaOrBool) Schema() common.Schema { + return &Schema{Schema: sb.SchemaOrBool.Schema} +} + +func (sb *SchemaOrBool) Allows() bool { + return sb.SchemaOrBool.Allows +} + +func (s *Schema) Type() string { + if len(s.Schema.Type) == 0 { + return "" + } + return s.Schema.Type[0] +} + +func (s *Schema) Format() string { + return s.Schema.Format +} + +func (s *Schema) Items() common.Schema { + if s.Schema.Items == nil || s.Schema.Items.Schema == nil { + return nil + } + return &Schema{Schema: s.Schema.Items.Schema} +} + +func (s *Schema) Properties() map[string]common.Schema { + if s.Schema.Properties == nil { + return nil + } + res := make(map[string]common.Schema, len(s.Schema.Properties)) + for n, prop := range s.Schema.Properties { + // map value is unaddressable, create a shallow copy + // this is a shallow non-recursive copy + s := prop + res[n] = &Schema{Schema: &s} + } + return res +} + +func (s *Schema) AdditionalProperties() common.SchemaOrBool { + if s.Schema.AdditionalProperties == nil { + return nil + } + return &SchemaOrBool{SchemaOrBool: s.Schema.AdditionalProperties} +} + +func (s *Schema) Default() any { + return s.Schema.Default +} + +func (s *Schema) MaxItems() *int64 { + return s.Schema.MaxItems +} + +func (s *Schema) MaxLength() *int64 { + return s.Schema.MaxLength +} + +func (s *Schema) MaxProperties() *int64 { + return s.Schema.MaxProperties +} + +func (s *Schema) Required() []string { + return s.Schema.Required +} + +func (s *Schema) Enum() []any { + return s.Schema.Enum +} + +func (s *Schema) Nullable() bool { + return s.Schema.Nullable +} + +func (s *Schema) IsXIntOrString() bool { + return isXIntOrString(s.Schema) +} + +func (s *Schema) IsXEmbeddedResource() bool { + return isXEmbeddedResource(s.Schema) +} + +func (s *Schema) IsXPreserveUnknownFields() bool { + return isXPreserveUnknownFields(s.Schema) +} + +func (s *Schema) XListType() string { + return getXListType(s.Schema) +} + +func (s *Schema) XListMapKeys() []string { + return getXListMapKeys(s.Schema) +} + +func (s *Schema) WithTypeAndObjectMeta() common.Schema { + return &Schema{common.WithTypeAndObjectMeta(s.Schema)} +} + +func UnstructuredToVal(unstructured any, schema *spec.Schema) ref.Val { + return common.UnstructuredToVal(unstructured, &Schema{schema}) +} + +func SchemaDeclType(s *spec.Schema, isResourceRoot bool) *apiservercel.DeclType { + return common.SchemaDeclType(&Schema{Schema: s}, isResourceRoot) +} + +func MakeMapList(sts *spec.Schema, items []interface{}) (rv common.MapList) { + return common.MakeMapList(&Schema{Schema: sts}, items) +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/extensions.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/extensions.go new file mode 100644 index 000000000..6a2f83032 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/extensions.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 openapi + +import ( + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +var intOrStringFormat = intstr.IntOrString{}.OpenAPISchemaFormat() + +func isExtension(schema *spec.Schema, key string) bool { + v, ok := schema.Extensions.GetBool(key) + return v && ok +} + +func isXIntOrString(schema *spec.Schema) bool { + // built-in types have the Format while CRDs use extension + // both are valid, checking both + return schema.Format == intOrStringFormat || isExtension(schema, extIntOrString) +} + +func isXEmbeddedResource(schema *spec.Schema) bool { + return isExtension(schema, extEmbeddedResource) +} + +func isXPreserveUnknownFields(schema *spec.Schema) bool { + return isExtension(schema, extPreserveUnknownFields) +} + +func getXListType(schema *spec.Schema) string { + s, _ := schema.Extensions.GetString(extListType) + return s +} + +func getXListMapKeys(schema *spec.Schema) []string { + mapKeys, ok := schema.Extensions.GetStringSlice(extListMapKeys) + if !ok { + return nil + } + return mapKeys +} + +const extIntOrString = "x-kubernetes-int-or-string" +const extEmbeddedResource = "x-kubernetes-embedded-resource" +const extPreserveUnknownFields = "x-kubernetes-preserve-unknown-fields" +const extListType = "x-kubernetes-list-type" +const extListMapKeys = "x-kubernetes-list-map-keys" diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/definitions.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/definitions.go new file mode 100644 index 000000000..df7357f77 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/definitions.go @@ -0,0 +1,115 @@ +/* +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 resolver + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/endpoints/openapi" + "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// DefinitionsSchemaResolver resolves the schema of a built-in type +// by looking up the OpenAPI definitions. +type DefinitionsSchemaResolver struct { + defs map[string]common.OpenAPIDefinition + gvkToSchema map[schema.GroupVersionKind]*spec.Schema +} + +// NewDefinitionsSchemaResolver creates a new DefinitionsSchemaResolver. +// An example working setup: +// scheme = "k8s.io/client-go/kubernetes/scheme".Scheme +// getDefinitions = "k8s.io/kubernetes/pkg/generated/openapi".GetOpenAPIDefinitions +func NewDefinitionsSchemaResolver(scheme *runtime.Scheme, getDefinitions common.GetOpenAPIDefinitions) *DefinitionsSchemaResolver { + gvkToSchema := make(map[schema.GroupVersionKind]*spec.Schema) + namer := openapi.NewDefinitionNamer(scheme) + defs := getDefinitions(func(path string) spec.Ref { + return spec.MustCreateRef(path) + }) + for name, def := range defs { + _, e := namer.GetDefinitionName(name) + gvks := extensionsToGVKs(e) + s := def.Schema // map value not addressable, make copy + for _, gvk := range gvks { + gvkToSchema[gvk] = &s + } + } + return &DefinitionsSchemaResolver{ + gvkToSchema: gvkToSchema, + defs: defs, + } +} + +func (d *DefinitionsSchemaResolver) ResolveSchema(gvk schema.GroupVersionKind) (*spec.Schema, error) { + s, ok := d.gvkToSchema[gvk] + if !ok { + return nil, fmt.Errorf("cannot resolve %v: %w", gvk, ErrSchemaNotFound) + } + s, err := populateRefs(func(ref string) (*spec.Schema, bool) { + // find the schema by the ref string, and return a deep copy + def, ok := d.defs[ref] + if !ok { + return nil, false + } + s := def.Schema + return &s, true + }, s) + if err != nil { + return nil, err + } + return s, nil +} + +func extensionsToGVKs(extensions spec.Extensions) []schema.GroupVersionKind { + gvksAny, ok := extensions[extGVK] + if !ok { + return nil + } + gvks, ok := gvksAny.([]any) + if !ok { + return nil + } + result := make([]schema.GroupVersionKind, 0, len(gvks)) + for _, gvkAny := range gvks { + // type check the map and all fields + gvkMap, ok := gvkAny.(map[string]any) + if !ok { + return nil + } + g, ok := gvkMap["group"].(string) + if !ok { + return nil + } + v, ok := gvkMap["version"].(string) + if !ok { + return nil + } + k, ok := gvkMap["kind"].(string) + if !ok { + return nil + } + result = append(result, schema.GroupVersionKind{ + Group: g, + Version: v, + Kind: k, + }) + } + return result +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/discovery.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/discovery.go new file mode 100644 index 000000000..53cbc7054 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/discovery.go @@ -0,0 +1,104 @@ +/* +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 resolver + +import ( + "encoding/json" + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/discovery" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// ClientDiscoveryResolver uses client-go discovery to resolve schemas at run time. +type ClientDiscoveryResolver struct { + Discovery discovery.DiscoveryInterface +} + +var _ SchemaResolver = (*ClientDiscoveryResolver)(nil) + +func (r *ClientDiscoveryResolver) ResolveSchema(gvk schema.GroupVersionKind) (*spec.Schema, error) { + p, err := r.Discovery.OpenAPIV3().Paths() + if err != nil { + return nil, err + } + resourcePath := resourcePathFromGV(gvk.GroupVersion()) + c, ok := p[resourcePath] + if !ok { + return nil, fmt.Errorf("cannot resolve group version %q: %w", gvk.GroupVersion(), ErrSchemaNotFound) + } + b, err := c.Schema(runtime.ContentTypeJSON) + if err != nil { + return nil, err + } + resp := new(schemaResponse) + err = json.Unmarshal(b, resp) + if err != nil { + return nil, err + } + s, err := resolveType(resp, gvk) + if err != nil { + return nil, err + } + s, err = populateRefs(func(ref string) (*spec.Schema, bool) { + s, ok := resp.Components.Schemas[strings.TrimPrefix(ref, refPrefix)] + return s, ok + }, s) + if err != nil { + return nil, err + } + return s, nil +} + +func resolveType(resp *schemaResponse, gvk schema.GroupVersionKind) (*spec.Schema, error) { + for _, s := range resp.Components.Schemas { + var gvks []schema.GroupVersionKind + err := s.Extensions.GetObject(extGVK, &gvks) + if err != nil { + return nil, err + } + for _, g := range gvks { + if g == gvk { + return s, nil + } + } + } + return nil, fmt.Errorf("cannot resolve group version kind %q: %w", gvk, ErrSchemaNotFound) +} + +func resourcePathFromGV(gv schema.GroupVersion) string { + var resourcePath string + if len(gv.Group) == 0 { + resourcePath = fmt.Sprintf("api/%s", gv.Version) + } else { + resourcePath = fmt.Sprintf("apis/%s/%s", gv.Group, gv.Version) + } + return resourcePath +} + +type schemaResponse struct { + Components struct { + Schemas map[string]*spec.Schema `json:"schemas"` + } `json:"components"` +} + +const refPrefix = "#/components/schemas/" + +const extGVK = "x-kubernetes-group-version-kind" diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go new file mode 100644 index 000000000..49321bab4 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/refs.go @@ -0,0 +1,100 @@ +/* +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 resolver + +import ( + "fmt" + + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// populateRefs recursively replaces Refs in the schema with the referred one. +// schemaOf is the callback to find the corresponding schema by the ref. +// This function will not mutate the original schema. If the schema needs to be +// mutated, a copy will be returned, otherwise it returns the original schema. +func populateRefs(schemaOf func(ref string) (*spec.Schema, bool), schema *spec.Schema) (*spec.Schema, error) { + result := *schema + changed := false + + ref, isRef := refOf(schema) + if isRef { + // replace the whole schema with the referred one. + resolved, ok := schemaOf(ref) + if !ok { + return nil, fmt.Errorf("internal error: cannot resolve Ref %q: %w", ref, ErrSchemaNotFound) + } + result = *resolved + changed = true + } + // schema is an object, populate its properties and additionalProperties + props := make(map[string]spec.Schema, len(schema.Properties)) + propsChanged := false + for name, prop := range result.Properties { + populated, err := populateRefs(schemaOf, &prop) + if err != nil { + return nil, err + } + if populated != &prop { + propsChanged = true + } + props[name] = *populated + } + if propsChanged { + changed = true + result.Properties = props + } + if result.AdditionalProperties != nil && result.AdditionalProperties.Schema != nil { + populated, err := populateRefs(schemaOf, result.AdditionalProperties.Schema) + if err != nil { + return nil, err + } + if populated != result.AdditionalProperties.Schema { + changed = true + result.AdditionalProperties.Schema = populated + } + } + // schema is a list, populate its items + if result.Items != nil && result.Items.Schema != nil { + populated, err := populateRefs(schemaOf, result.Items.Schema) + if err != nil { + return nil, err + } + if populated != result.Items.Schema { + changed = true + result.Items.Schema = populated + } + } + if changed { + return &result, nil + } + return schema, nil +} + +func refOf(schema *spec.Schema) (string, bool) { + if schema.Ref.GetURL() != nil { + return schema.Ref.String(), true + } + // A Ref may be wrapped in allOf to preserve its description + // see https://github.com/kubernetes/kubernetes/issues/106387 + // For kube-openapi, allOf is only used for wrapping a Ref. + for _, allOf := range schema.AllOf { + if ref, isRef := refOf(&allOf); isRef { + return ref, isRef + } + } + return "", false +} diff --git a/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/resolver.go b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/resolver.go new file mode 100644 index 000000000..4060c86ce --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/cel/openapi/resolver/resolver.go @@ -0,0 +1,39 @@ +/* +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 resolver + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kube-openapi/pkg/validation/spec" +) + +// SchemaResolver finds the OpenAPI schema for the given GroupVersionKind. +// This interface uses the type defined by k8s.io/kube-openapi +type SchemaResolver interface { + // ResolveSchema takes a GroupVersionKind (GVK) and returns the OpenAPI schema + // identified by the GVK. + // The function returns a non-nil error if the schema cannot be found or fail + // to resolve. The returned error wraps ErrSchemaNotFound if the resolution is + // attempted but the corresponding schema cannot be found. + ResolveSchema(gvk schema.GroupVersionKind) (*spec.Schema, error) +} + +// ErrSchemaNotFound is wrapped and returned if the schema cannot be located +// by the resolver. +var ErrSchemaNotFound = fmt.Errorf("schema not found") diff --git a/vendor/k8s.io/apiserver/pkg/cel/types.go b/vendor/k8s.io/apiserver/pkg/cel/types.go index 13171ad21..b2cc92d59 100644 --- a/vendor/k8s.io/apiserver/pkg/cel/types.go +++ b/vendor/k8s.io/apiserver/pkg/cel/types.go @@ -360,6 +360,23 @@ func (rt *RuleTypes) EnvOptions(tp ref.TypeProvider) ([]cel.EnvOption, error) { if rt == nil { return []cel.EnvOption{}, nil } + rtWithTypes, err := rt.WithTypeProvider(tp) + if err != nil { + return nil, err + } + return []cel.EnvOption{ + cel.CustomTypeProvider(rtWithTypes), + cel.CustomTypeAdapter(rtWithTypes), + cel.Variable("rule", rt.ruleSchemaDeclTypes.root.CelType()), + }, nil +} + +// WithTypeProvider returns a new RuleTypes that sets the given TypeProvider +// If the original RuleTypes is nil, the returned RuleTypes is still nil. +func (rt *RuleTypes) WithTypeProvider(tp ref.TypeProvider) (*RuleTypes, error) { + if rt == nil { + return nil, nil + } var ta ref.TypeAdapter = types.DefaultTypeAdapter tpa, ok := tp.(ref.TypeAdapter) if ok { @@ -382,11 +399,7 @@ func (rt *RuleTypes) EnvOptions(tp ref.TypeProvider) ([]cel.EnvOption, error) { "type %s definition differs between CEL environment and rule", name) } } - return []cel.EnvOption{ - cel.CustomTypeProvider(rtWithTypes), - cel.CustomTypeAdapter(rtWithTypes), - cel.Variable("rule", rt.ruleSchemaDeclTypes.root.CelType()), - }, nil + return rtWithTypes, nil } // FindType attempts to resolve the typeName provided from the rule's rule-schema, or if not diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/OWNERS b/vendor/k8s.io/apiserver/pkg/endpoints/OWNERS new file mode 100644 index 000000000..7fb6b78f2 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/endpoints/OWNERS @@ -0,0 +1,2 @@ +approvers: + - apelisse diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/OWNERS b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/OWNERS new file mode 100644 index 000000000..49d71eba5 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/OWNERS @@ -0,0 +1,5 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +reviewers: + - alexzielenski + - jefftree diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/etag.go b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/etag.go index d74e376c7..0151f6c10 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/etag.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/etag.go @@ -35,8 +35,7 @@ import ( // - Replies with 304 Not Modified, if If-None-Match header matches hash // // hash should be the value of calculateETag on object. If hash is empty, then -// -// the object is simply serialized without E-Tag functionality +// the object is simply serialized without E-Tag functionality func ServeHTTPWithETag( object runtime.Object, hash string, @@ -55,7 +54,7 @@ func ServeHTTPWithETag( // Otherwise, we delegate to the handler for actual content // // According to documentation, An Etag within an If-None-Match - // header will be enclosed within doule quotes: + // header will be enclosed within double quotes: // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match#directives if clientCachedHash := req.Header.Get("If-None-Match"); quotedHash == clientCachedHash { w.WriteHeader(http.StatusNotModified) diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/fake.go b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/fake.go index ea5039c7c..a819fe28f 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/fake.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/fake.go @@ -169,3 +169,7 @@ func (f *recorderResourceManager) WebService() *restful.WebService { func (f *recorderResourceManager) ServeHTTP(http.ResponseWriter, *http.Request) { panic("unimplemented") } + +func (f *recorderResourceManager) WithSource(source Source) ResourceManager { + panic("unimplemented") +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/handler.go b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/handler.go index 14497baad..61a7fd70d 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/handler.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/handler.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/version" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" + "k8s.io/apiserver/pkg/endpoints/metrics" "sync/atomic" @@ -35,6 +36,15 @@ import ( "k8s.io/klog/v2" ) +type Source uint + +// The GroupVersion from the lowest Source takes precedence +const ( + AggregatorSource Source = 0 + BuiltinSource Source = 100 + CRDSource Source = 200 +) + // This handler serves the /apis endpoint for an aggregated list of // api resources indexed by their group version. type ResourceManager interface { @@ -64,19 +74,67 @@ type ResourceManager interface { // Thread-Safe SetGroups([]apidiscoveryv2beta1.APIGroupDiscovery) + // Returns the same resource manager using a different source + // The source is used to decide how to de-duplicate groups. + // The group from the least-numbered source is used + WithSource(source Source) ResourceManager + http.Handler } +type resourceManager struct { + source Source + *resourceDiscoveryManager +} + +func (rm resourceManager) AddGroupVersion(groupName string, value apidiscoveryv2beta1.APIVersionDiscovery) { + rm.resourceDiscoveryManager.AddGroupVersion(rm.source, groupName, value) +} +func (rm resourceManager) SetGroupVersionPriority(gv metav1.GroupVersion, grouppriority, versionpriority int) { + rm.resourceDiscoveryManager.SetGroupVersionPriority(rm.source, gv, grouppriority, versionpriority) +} +func (rm resourceManager) RemoveGroup(groupName string) { + rm.resourceDiscoveryManager.RemoveGroup(rm.source, groupName) +} +func (rm resourceManager) RemoveGroupVersion(gv metav1.GroupVersion) { + rm.resourceDiscoveryManager.RemoveGroupVersion(rm.source, gv) +} +func (rm resourceManager) SetGroups(groups []apidiscoveryv2beta1.APIGroupDiscovery) { + rm.resourceDiscoveryManager.SetGroups(rm.source, groups) +} + +func (rm resourceManager) WithSource(source Source) ResourceManager { + return resourceManager{ + source: source, + resourceDiscoveryManager: rm.resourceDiscoveryManager, + } +} + +type groupKey struct { + name string + + // Source identifies where this group came from and dictates which group + // among duplicates is chosen to be used for discovery. + source Source +} + +type groupVersionKey struct { + metav1.GroupVersion + source Source +} + type resourceDiscoveryManager struct { serializer runtime.NegotiatedSerializer // cache is an atomic pointer to avoid the use of locks cache atomic.Pointer[cachedGroupList] + serveHTTPFunc http.HandlerFunc + // Writes protected by the lock. // List of all apigroups & resources indexed by the resource manager lock sync.RWMutex - apiGroups map[string]*apidiscoveryv2beta1.APIGroupDiscovery - versionPriorities map[metav1.GroupVersion]priorityInfo + apiGroups map[groupKey]*apidiscoveryv2beta1.APIGroupDiscovery + versionPriorities map[groupVersionKey]priorityInfo } type priorityInfo struct { @@ -84,25 +142,46 @@ type priorityInfo struct { VersionPriority int } -func NewResourceManager() ResourceManager { +func NewResourceManager(path string) ResourceManager { scheme := runtime.NewScheme() codecs := serializer.NewCodecFactory(scheme) utilruntime.Must(apidiscoveryv2beta1.AddToScheme(scheme)) - return &resourceDiscoveryManager{serializer: codecs, versionPriorities: make(map[metav1.GroupVersion]priorityInfo)} + rdm := &resourceDiscoveryManager{ + serializer: codecs, + versionPriorities: make(map[groupVersionKey]priorityInfo), + } + rdm.serveHTTPFunc = metrics.InstrumentHandlerFunc("GET", + /* group = */ "", + /* version = */ "", + /* resource = */ "", + /* subresource = */ path, + /* scope = */ "", + /* component = */ metrics.APIServerComponent, + /* deprecated */ false, + /* removedRelease */ "", + rdm.serveHTTP) + return resourceManager{ + source: BuiltinSource, + resourceDiscoveryManager: rdm, + } } -func (rdm *resourceDiscoveryManager) SetGroupVersionPriority(gv metav1.GroupVersion, groupPriorityMinimum, versionPriority int) { +func (rdm *resourceDiscoveryManager) SetGroupVersionPriority(source Source, gv metav1.GroupVersion, groupPriorityMinimum, versionPriority int) { rdm.lock.Lock() defer rdm.lock.Unlock() - rdm.versionPriorities[gv] = priorityInfo{ + key := groupVersionKey{ + GroupVersion: gv, + source: source, + } + rdm.versionPriorities[key] = priorityInfo{ GroupPriorityMinimum: groupPriorityMinimum, VersionPriority: versionPriority, } rdm.cache.Store(nil) } -func (rdm *resourceDiscoveryManager) SetGroups(groups []apidiscoveryv2beta1.APIGroupDiscovery) { +func (rdm *resourceDiscoveryManager) SetGroups(source Source, groups []apidiscoveryv2beta1.APIGroupDiscovery) { rdm.lock.Lock() defer rdm.lock.Unlock() @@ -111,13 +190,17 @@ func (rdm *resourceDiscoveryManager) SetGroups(groups []apidiscoveryv2beta1.APIG for _, group := range groups { for _, version := range group.Versions { - rdm.addGroupVersionLocked(group.Name, version) + rdm.addGroupVersionLocked(source, group.Name, version) } } // Filter unused out priority entries for gv := range rdm.versionPriorities { - entry, exists := rdm.apiGroups[gv.Group] + key := groupKey{ + source: source, + name: gv.Group, + } + entry, exists := rdm.apiGroups[key] if !exists { delete(rdm.versionPriorities, gv) continue @@ -138,21 +221,26 @@ func (rdm *resourceDiscoveryManager) SetGroups(groups []apidiscoveryv2beta1.APIG } } -func (rdm *resourceDiscoveryManager) AddGroupVersion(groupName string, value apidiscoveryv2beta1.APIVersionDiscovery) { +func (rdm *resourceDiscoveryManager) AddGroupVersion(source Source, groupName string, value apidiscoveryv2beta1.APIVersionDiscovery) { rdm.lock.Lock() defer rdm.lock.Unlock() - rdm.addGroupVersionLocked(groupName, value) + rdm.addGroupVersionLocked(source, groupName, value) } -func (rdm *resourceDiscoveryManager) addGroupVersionLocked(groupName string, value apidiscoveryv2beta1.APIVersionDiscovery) { +func (rdm *resourceDiscoveryManager) addGroupVersionLocked(source Source, groupName string, value apidiscoveryv2beta1.APIVersionDiscovery) { klog.Infof("Adding GroupVersion %s %s to ResourceManager", groupName, value.Version) if rdm.apiGroups == nil { - rdm.apiGroups = make(map[string]*apidiscoveryv2beta1.APIGroupDiscovery) + rdm.apiGroups = make(map[groupKey]*apidiscoveryv2beta1.APIGroupDiscovery) } - if existing, groupExists := rdm.apiGroups[groupName]; groupExists { + key := groupKey{ + source: source, + name: groupName, + } + + if existing, groupExists := rdm.apiGroups[key]; groupExists { // If this version already exists, replace it versionExists := false @@ -165,6 +253,7 @@ func (rdm *resourceDiscoveryManager) addGroupVersionLocked(groupName string, val if reflect.DeepEqual(existing.Versions[i], value) { return } + existing.Versions[i] = value versionExists = true break @@ -182,12 +271,16 @@ func (rdm *resourceDiscoveryManager) addGroupVersionLocked(groupName string, val }, Versions: []apidiscoveryv2beta1.APIVersionDiscovery{value}, } - rdm.apiGroups[groupName] = group + rdm.apiGroups[key] = group } gv := metav1.GroupVersion{Group: groupName, Version: value.Version} - if _, ok := rdm.versionPriorities[gv]; !ok { - rdm.versionPriorities[gv] = priorityInfo{ + gvKey := groupVersionKey{ + GroupVersion: gv, + source: source, + } + if _, ok := rdm.versionPriorities[gvKey]; !ok { + rdm.versionPriorities[gvKey] = priorityInfo{ GroupPriorityMinimum: 1000, VersionPriority: 15, } @@ -197,10 +290,16 @@ func (rdm *resourceDiscoveryManager) addGroupVersionLocked(groupName string, val rdm.cache.Store(nil) } -func (rdm *resourceDiscoveryManager) RemoveGroupVersion(apiGroup metav1.GroupVersion) { +func (rdm *resourceDiscoveryManager) RemoveGroupVersion(source Source, apiGroup metav1.GroupVersion) { rdm.lock.Lock() defer rdm.lock.Unlock() - group, exists := rdm.apiGroups[apiGroup.Group] + + key := groupKey{ + source: source, + name: apiGroup.Group, + } + + group, exists := rdm.apiGroups[key] if !exists { return } @@ -218,23 +317,33 @@ func (rdm *resourceDiscoveryManager) RemoveGroupVersion(apiGroup metav1.GroupVer return } - delete(rdm.versionPriorities, apiGroup) + gvKey := groupVersionKey{ + GroupVersion: apiGroup, + source: source, + } + + delete(rdm.versionPriorities, gvKey) if len(group.Versions) == 0 { - delete(rdm.apiGroups, group.Name) + delete(rdm.apiGroups, key) } // Reset response document so it is recreated lazily rdm.cache.Store(nil) } -func (rdm *resourceDiscoveryManager) RemoveGroup(groupName string) { +func (rdm *resourceDiscoveryManager) RemoveGroup(source Source, groupName string) { rdm.lock.Lock() defer rdm.lock.Unlock() - delete(rdm.apiGroups, groupName) + key := groupKey{ + source: source, + name: groupName, + } + + delete(rdm.apiGroups, key) for k := range rdm.versionPriorities { - if k.Group == groupName { + if k.Group == groupName && k.source == source { delete(rdm.versionPriorities, k) } } @@ -246,19 +355,66 @@ func (rdm *resourceDiscoveryManager) RemoveGroup(groupName string) { // Prepares the api group list for serving by converting them from map into // list and sorting them according to insertion order func (rdm *resourceDiscoveryManager) calculateAPIGroupsLocked() []apidiscoveryv2beta1.APIGroupDiscovery { + regenerationCounter.Inc() // Re-order the apiGroups by their priority. groups := []apidiscoveryv2beta1.APIGroupDiscovery{} - for _, group := range rdm.apiGroups { - copied := *group.DeepCopy() + + groupsToUse := map[string]apidiscoveryv2beta1.APIGroupDiscovery{} + sourcesUsed := map[metav1.GroupVersion]Source{} + + for key, group := range rdm.apiGroups { + if existing, ok := groupsToUse[key.name]; ok { + for _, v := range group.Versions { + gv := metav1.GroupVersion{Group: key.name, Version: v.Version} + + // Skip groupversions we've already seen before. Only DefaultSource + // takes precedence + if usedSource, seen := sourcesUsed[gv]; seen && key.source >= usedSource { + continue + } else if seen { + // Find the index of the duplicate version and replace + for i := 0; i < len(existing.Versions); i++ { + if existing.Versions[i].Version == v.Version { + existing.Versions[i] = v + break + } + } + + } else { + // New group-version, just append + existing.Versions = append(existing.Versions, v) + } + + sourcesUsed[gv] = key.source + groupsToUse[key.name] = existing + } + // Check to see if we have overlapping versions. If we do, take the one + // with highest source precedence + } else { + groupsToUse[key.name] = *group.DeepCopy() + for _, v := range group.Versions { + gv := metav1.GroupVersion{Group: key.name, Version: v.Version} + sourcesUsed[gv] = key.source + } + } + } + + for _, group := range groupsToUse { // Re-order versions based on their priority. Use kube-aware string // comparison as a tie breaker - sort.SliceStable(copied.Versions, func(i, j int) bool { - iVersion := copied.Versions[i].Version - jVersion := copied.Versions[j].Version + sort.SliceStable(group.Versions, func(i, j int) bool { + iVersion := group.Versions[i].Version + jVersion := group.Versions[j].Version - iPriority := rdm.versionPriorities[metav1.GroupVersion{Group: group.Name, Version: iVersion}].VersionPriority - jPriority := rdm.versionPriorities[metav1.GroupVersion{Group: group.Name, Version: jVersion}].VersionPriority + iGV := metav1.GroupVersion{Group: group.Name, Version: iVersion} + jGV := metav1.GroupVersion{Group: group.Name, Version: jVersion} + + iSource := sourcesUsed[iGV] + jSource := sourcesUsed[jGV] + + iPriority := rdm.versionPriorities[groupVersionKey{iGV, iSource}].VersionPriority + jPriority := rdm.versionPriorities[groupVersionKey{jGV, jSource}].VersionPriority // Sort by version string comparator if priority is equal if iPriority == jPriority { @@ -269,13 +425,16 @@ func (rdm *resourceDiscoveryManager) calculateAPIGroupsLocked() []apidiscoveryv2 return iPriority > jPriority }) - groups = append(groups, *copied.DeepCopy()) - + groups = append(groups, group) } // For each group, determine the highest minimum group priority and use that priorities := map[string]int{} for gv, info := range rdm.versionPriorities { + if source := sourcesUsed[gv.GroupVersion]; source != gv.source { + continue + } + if existing, exists := priorities[gv.Group]; exists { if existing < info.GroupPriorityMinimum { priorities[gv.Group] = info.GroupPriorityMinimum @@ -338,6 +497,10 @@ type cachedGroupList struct { } func (rdm *resourceDiscoveryManager) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + rdm.serveHTTPFunc(resp, req) +} + +func (rdm *resourceDiscoveryManager) serveHTTP(resp http.ResponseWriter, req *http.Request) { cache := rdm.fetchFromCache() response := cache.cachedResponse etag := cache.cachedResponseETag diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/feature.go b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/metrics.go similarity index 54% rename from vendor/k8s.io/controller-manager/pkg/leadermigration/feature.go rename to vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/metrics.go index fec07edb1..816cf177f 100644 --- a/vendor/k8s.io/controller-manager/pkg/leadermigration/feature.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/aggregated/metrics.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. @@ -14,15 +14,23 @@ See the License for the specific language governing permissions and limitations under the License. */ -package leadermigration +package aggregated import ( - "k8s.io/apiserver/pkg/util/feature" - "k8s.io/controller-manager/pkg/features" - _ "k8s.io/controller-manager/pkg/features/register" + "k8s.io/component-base/metrics" + "k8s.io/component-base/metrics/legacyregistry" ) -// FeatureEnabled tells if leader migration is enabled through the feature gate. -func FeatureEnabled() bool { - return feature.DefaultMutableFeatureGate.Enabled(features.ControllerManagerLeaderMigration) +var ( + regenerationCounter = metrics.NewCounter( + &metrics.CounterOpts{ + Name: "aggregator_discovery_aggregation_count_total", + Help: "Counter of number of times discovery was aggregated", + StabilityLevel: metrics.ALPHA, + }, + ) +) + +func init() { + legacyregistry.MustRegister(regenerationCounter) } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/storageversionhash.go b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/storageversionhash.go index d72d4ba20..f47e9632b 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/discovery/storageversionhash.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/discovery/storageversionhash.go @@ -27,9 +27,6 @@ import ( // this function. func StorageVersionHash(group, version, kind string) string { gvk := group + "/" + version + "/" + kind - if gvk == "" { - return "" - } bytes := sha256.Sum256([]byte(gvk)) // Assuming there are N kinds in the cluster, and the hash is X-byte long, // the chance of colliding hash P(N,X) approximates to 1-e^(-(N^2)/2^(8X+1)). diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/audit.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/audit.go index b310c94ee..ccb628b44 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/audit.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/audit.go @@ -133,10 +133,10 @@ func evaluatePolicyAndCreateAuditEvent(req *http.Request, policy audit.PolicyRul return ac, fmt.Errorf("failed to GetAuthorizerAttributes: %v", err) } - ls := policy.EvaluatePolicyRule(attribs) - audit.ObservePolicyLevel(ctx, ls.Level) - ac.RequestAuditConfig = ls.RequestAuditConfig - if ls.Level == auditinternal.LevelNone { + rac := policy.EvaluatePolicyRule(attribs) + audit.ObservePolicyLevel(ctx, rac.Level) + ac.RequestAuditConfig = rac + if rac.Level == auditinternal.LevelNone { // Don't audit. return ac, nil } @@ -145,7 +145,7 @@ func evaluatePolicyAndCreateAuditEvent(req *http.Request, policy audit.PolicyRul if !ok { requestReceivedTimestamp = time.Now() } - ev, err := audit.NewEventFromRequest(req, requestReceivedTimestamp, ls.Level, attribs) + ev, err := audit.NewEventFromRequest(req, requestReceivedTimestamp, rac.Level, attribs) if err != nil { return nil, fmt.Errorf("failed to complete audit event from request: %v", err) } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/authentication.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/authentication.go index d69cfef32..d6741bf3a 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/authentication.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/authentication.go @@ -27,6 +27,8 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/authentication/authenticator" + "k8s.io/apiserver/pkg/authentication/authenticatorfactory" + "k8s.io/apiserver/pkg/authentication/request/headerrequest" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/klog/v2" @@ -38,15 +40,20 @@ type recordMetrics func(context.Context, *authenticator.Response, bool, error, a // stores any such user found onto the provided context for the request. If authentication fails or returns an error // the failed handler is used. On success, "Authorization" header is removed from the request and handler // is invoked to serve the request. -func WithAuthentication(handler http.Handler, auth authenticator.Request, failed http.Handler, apiAuds authenticator.Audiences) http.Handler { - return withAuthentication(handler, auth, failed, apiAuds, recordAuthMetrics) +func WithAuthentication(handler http.Handler, auth authenticator.Request, failed http.Handler, apiAuds authenticator.Audiences, requestHeaderConfig *authenticatorfactory.RequestHeaderConfig) http.Handler { + return withAuthentication(handler, auth, failed, apiAuds, requestHeaderConfig, recordAuthMetrics) } -func withAuthentication(handler http.Handler, auth authenticator.Request, failed http.Handler, apiAuds authenticator.Audiences, metrics recordMetrics) http.Handler { +func withAuthentication(handler http.Handler, auth authenticator.Request, failed http.Handler, apiAuds authenticator.Audiences, requestHeaderConfig *authenticatorfactory.RequestHeaderConfig, metrics recordMetrics) http.Handler { if auth == nil { klog.Warning("Authentication is disabled") return handler } + standardRequestHeaderConfig := &authenticatorfactory.RequestHeaderConfig{ + UsernameHeaders: headerrequest.StaticStringSlice{"X-Remote-User"}, + GroupHeaders: headerrequest.StaticStringSlice{"X-Remote-Group"}, + ExtraHeaderPrefixes: headerrequest.StaticStringSlice{"X-Remote-Extra-"}, + } return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { authenticationStart := time.Now() @@ -76,6 +83,24 @@ func withAuthentication(handler http.Handler, auth authenticator.Request, failed // authorization header is not required anymore in case of a successful authentication. req.Header.Del("Authorization") + // delete standard front proxy headers + headerrequest.ClearAuthenticationHeaders( + req.Header, + standardRequestHeaderConfig.UsernameHeaders, + standardRequestHeaderConfig.GroupHeaders, + standardRequestHeaderConfig.ExtraHeaderPrefixes, + ) + + // also delete any custom front proxy headers + if requestHeaderConfig != nil { + headerrequest.ClearAuthenticationHeaders( + req.Header, + requestHeaderConfig.UsernameHeaders, + requestHeaderConfig.GroupHeaders, + requestHeaderConfig.ExtraHeaderPrefixes, + ) + } + req = req.WithContext(genericapirequest.WithUser(req.Context(), resp.User)) handler.ServeHTTP(w, req) }) diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/authorization.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/authorization.go index fba588283..f7648d41c 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/authorization.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/authorization.go @@ -70,7 +70,7 @@ func WithAuthorization(handler http.Handler, a authorizer.Authorizer, s runtime. return } - klog.V(4).InfoS("Forbidden", "URI", req.RequestURI, "Reason", reason) + klog.V(4).InfoS("Forbidden", "URI", req.RequestURI, "reason", reason) audit.AddAuditAnnotations(ctx, decisionAnnotationKey, decisionForbid, reasonAnnotationKey, reason) diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go index 1dc1fe4a5..4803975a7 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go @@ -109,14 +109,14 @@ func WithImpersonation(handler http.Handler, a authorizer.Authorizer, s runtime. actingAsAttributes.Resource = "uids" default: - klog.V(4).InfoS("unknown impersonation request type", "Request", impersonationRequest) + klog.V(4).InfoS("unknown impersonation request type", "request", impersonationRequest) responsewriters.Forbidden(ctx, actingAsAttributes, w, req, fmt.Sprintf("unknown impersonation request type: %v", impersonationRequest), s) return } decision, reason, err := a.Authorize(ctx, actingAsAttributes) if err != nil || decision != authorizer.DecisionAllow { - klog.V(4).InfoS("Forbidden", "URI", req.RequestURI, "Reason", reason, "Error", err) + klog.V(4).InfoS("Forbidden", "URI", req.RequestURI, "reason", reason, "err", err) responsewriters.Forbidden(ctx, actingAsAttributes, w, req, reason, s) return } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/filters/storageversion.go b/vendor/k8s.io/apiserver/pkg/endpoints/filters/storageversion.go index 414fc194e..d6cf708cf 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/filters/storageversion.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/filters/storageversion.go @@ -100,13 +100,13 @@ func WithStorageVersionPrecondition(handler http.Handler, svm storageversion.Man } // If the resource's StorageVersion is not in the to-be-updated list, let it pass. // Non-persisted resources are not in the to-be-updated list, so they will pass. - gr := schema.GroupResource{requestInfo.APIGroup, requestInfo.Resource} + gr := schema.GroupResource{Group: requestInfo.APIGroup, Resource: requestInfo.Resource} if !svm.PendingUpdate(gr) { handler.ServeHTTP(w, req) return } - gv := schema.GroupVersion{requestInfo.APIGroup, requestInfo.APIVersion} + gv := schema.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion} responsewriters.ErrorNegotiated(apierrors.NewServiceUnavailable(fmt.Sprintf("wait for storage version registration to complete for resource: %v, last seen error: %v", gr, svm.LastUpdateError(gr))), s, gv, w, req) }) } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/groupversion.go b/vendor/k8s.io/apiserver/pkg/endpoints/groupversion.go index 34b80b449..3c70e89ec 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/groupversion.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/groupversion.go @@ -27,14 +27,13 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/managedfields" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/endpoints/discovery" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/storageversion" - openapiproto "k8s.io/kube-openapi/pkg/util/proto" ) // ConvertabilityChecker indicates what versions a GroupKind is available in. @@ -82,7 +81,7 @@ type APIGroupVersion struct { Defaulter runtime.ObjectDefaulter Namer runtime.Namer UnsafeConvertor runtime.ObjectConvertor - TypeConverter fieldmanager.TypeConverter + TypeConverter managedfields.TypeConverter EquivalentResourceRegistry runtime.EquivalentResourceRegistry @@ -95,9 +94,6 @@ type APIGroupVersion struct { MinRequestTimeout time.Duration - // OpenAPIModels exposes the OpenAPI models to each individual handler. - OpenAPIModels openapiproto.Models - // The limit on the request body size that would be accepted and decoded in a write request. // 0 means no limit. MaxRequestBodyBytes int64 diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/create.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/create.go index 71f4990a0..78c1d2f52 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/create.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/create.go @@ -162,8 +162,13 @@ func createHandler(r rest.NamedCreater, scope *RequestScope, admit admission.Int userInfo, _ := request.UserFrom(ctx) if objectMeta, err := meta.Accessor(obj); err == nil { - // Wipe fields which cannot take user-provided values - rest.WipeObjectMetaSystemFields(objectMeta) + preserveObjectMetaSystemFields := false + if c, ok := r.(rest.SubresourceObjectMetaPreserver); ok && len(scope.Subresource) > 0 { + preserveObjectMetaSystemFields = c.PreserveRequestObjectMetaSystemFieldsOnSubresourceCreate() + } + if !preserveObjectMetaSystemFields { + rest.WipeObjectMetaSystemFields(objectMeta) + } // ensure namespace on the object is correct, or error if a conflicting namespace was set in the object if err := rest.EnsureObjectNamespaceMatchesRequestNamespace(rest.ExpectedNamespaceForResource(namespace, scope.Resource), objectMeta); err != nil { diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/delete.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/delete.go index f9aae3fbd..663fd8d52 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/delete.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/delete.go @@ -38,8 +38,10 @@ import ( requestmetrics "k8s.io/apiserver/pkg/endpoints/handlers/metrics" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/util/dryrun" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/component-base/tracing" ) @@ -196,7 +198,8 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope *RequestSc return } - if errs := metainternalversionvalidation.ValidateListOptions(&listOptions); len(errs) > 0 { + metainternalversion.SetListOptionsDefaults(&listOptions, utilfeature.DefaultFeatureGate.Enabled(features.WatchList)) + if errs := metainternalversionvalidation.ValidateListOptions(&listOptions, utilfeature.DefaultFeatureGate.Enabled(features.WatchList)); len(errs) > 0 { err := errors.NewInvalid(schema.GroupKind{Group: metav1.GroupName, Kind: "ListOptions"}, "", errs) scope.err(err, w, req) return diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/admission.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/admission.go index 26d264fe8..bbc657168 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/admission.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/admission.go @@ -21,6 +21,7 @@ import ( "fmt" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/util/managedfields" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/warning" ) @@ -70,7 +71,7 @@ func (admit *managedFieldsValidatingAdmissionController) Admit(ctx context.Conte return err } managedFieldsAfterAdmission := objectMeta.GetManagedFields() - if _, err := DecodeManagedFields(managedFieldsAfterAdmission); err != nil { + if err := managedfields.ValidateManagedFields(managedFieldsAfterAdmission); err != nil { objectMeta.SetManagedFields(managedFieldsBeforeAdmission) warning.AddWarning(ctx, "", fmt.Sprintf(InvalidManagedFieldsAfterMutatingAdmissionWarningFormat, diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter.go deleted file mode 100644 index fc40546f1..000000000 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/typeconverter.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright 2018 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 fieldmanager - -import ( - "fmt" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/managedfields" - "k8s.io/kube-openapi/pkg/util/proto" - "sigs.k8s.io/structured-merge-diff/v4/typed" - "sigs.k8s.io/structured-merge-diff/v4/value" -) - -// TypeConverter allows you to convert from runtime.Object to -// typed.TypedValue and the other way around. -type TypeConverter interface { - ObjectToTyped(runtime.Object) (*typed.TypedValue, error) - TypedToObject(*typed.TypedValue) (runtime.Object, error) -} - -// DeducedTypeConverter is a TypeConverter for CRDs that don't have a -// schema. It does implement the same interface though (and create the -// same types of objects), so that everything can still work the same. -// CRDs are merged with all their fields being "atomic" (lists -// included). -// -// Note that this is not going to be sufficient for converting to/from -// CRDs that have a schema defined (we don't support that schema yet). -// TODO(jennybuckley): Use the schema provided by a CRD if it exists. -type DeducedTypeConverter struct{} - -var _ TypeConverter = DeducedTypeConverter{} - -// ObjectToTyped converts an object into a TypedValue with a "deduced type". -func (DeducedTypeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { - switch o := obj.(type) { - case *unstructured.Unstructured: - return typed.DeducedParseableType.FromUnstructured(o.UnstructuredContent()) - default: - return typed.DeducedParseableType.FromStructured(obj) - } -} - -// TypedToObject transforms the typed value into a runtime.Object. That -// is not specific to deduced type. -func (DeducedTypeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { - return valueToObject(value.AsValue()) -} - -type typeConverter struct { - parser *managedfields.GvkParser -} - -var _ TypeConverter = &typeConverter{} - -// NewTypeConverter builds a TypeConverter from a proto.Models. This -// will automatically find the proper version of the object, and the -// corresponding schema information. -func NewTypeConverter(models proto.Models, preserveUnknownFields bool) (TypeConverter, error) { - parser, err := managedfields.NewGVKParser(models, preserveUnknownFields) - if err != nil { - return nil, err - } - return &typeConverter{parser: parser}, nil -} - -func (c *typeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { - gvk := obj.GetObjectKind().GroupVersionKind() - t := c.parser.Type(gvk) - if t == nil { - return nil, newNoCorrespondingTypeError(gvk) - } - switch o := obj.(type) { - case *unstructured.Unstructured: - return t.FromUnstructured(o.UnstructuredContent()) - default: - return t.FromStructured(obj) - } -} - -func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { - return valueToObject(value.AsValue()) -} - -func valueToObject(val value.Value) (runtime.Object, error) { - vu := val.Unstructured() - switch o := vu.(type) { - case map[string]interface{}: - return &unstructured.Unstructured{Object: o}, nil - default: - return nil, fmt.Errorf("failed to convert value to unstructured for type %T", vu) - } -} - -type noCorrespondingTypeErr struct { - gvk schema.GroupVersionKind -} - -func newNoCorrespondingTypeError(gvk schema.GroupVersionKind) error { - return &noCorrespondingTypeErr{gvk: gvk} -} - -func (k *noCorrespondingTypeErr) Error() string { - return fmt.Sprintf("no corresponding type for %v", k.gvk) -} - -func isNoCorrespondingTypeError(err error) bool { - if err == nil { - return false - } - _, ok := err.(*noCorrespondingTypeErr) - return ok -} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/get.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/get.go index 2f8c6fbc2..c110964fc 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/get.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/get.go @@ -39,7 +39,9 @@ import ( "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/metrics" "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/registry/rest" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/component-base/tracing" "k8s.io/klog/v2" ) @@ -198,7 +200,8 @@ func ListResource(r rest.Lister, rw rest.Watcher, scope *RequestScope, forceWatc return } - if errs := metainternalversionvalidation.ValidateListOptions(&opts); len(errs) > 0 { + metainternalversion.SetListOptionsDefaults(&opts, utilfeature.DefaultFeatureGate.Enabled(features.WatchList)) + if errs := metainternalversionvalidation.ValidateListOptions(&opts, utilfeature.DefaultFeatureGate.Enabled(features.WatchList)); len(errs) > 0 { err := errors.NewInvalid(schema.GroupKind{Group: metav1.GroupName, Kind: "ListOptions"}, "", errs) scope.err(err, w, req) return diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/patch.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/patch.go index 8f396b057..4f5533f34 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/patch.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/patch.go @@ -36,6 +36,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/managedfields" "k8s.io/apimachinery/pkg/util/mergepatch" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/strategicpatch" @@ -297,7 +298,7 @@ type patchMechanism interface { type jsonPatcher struct { *patcher - fieldManager *fieldmanager.FieldManager + fieldManager *managedfields.FieldManager } func (p *jsonPatcher) applyPatchToCurrentObject(requestContext context.Context, currentObject runtime.Object) (runtime.Object, error) { @@ -417,7 +418,7 @@ type smpPatcher struct { // Schema schemaReferenceObj runtime.Object - fieldManager *fieldmanager.FieldManager + fieldManager *managedfields.FieldManager } func (p *smpPatcher) applyPatchToCurrentObject(requestContext context.Context, currentObject runtime.Object) (runtime.Object, error) { @@ -455,7 +456,7 @@ type applyPatcher struct { options *metav1.PatchOptions creater runtime.ObjectCreater kind schema.GroupVersionKind - fieldManager *fieldmanager.FieldManager + fieldManager *managedfields.FieldManager userAgent string validationDirective string } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/rest.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/rest.go index f582c668f..7f6756e78 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/rest.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/rest.go @@ -38,16 +38,14 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/managedfields" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/authorization/authorizer" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" requestmetrics "k8s.io/apiserver/pkg/endpoints/handlers/metrics" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" "k8s.io/apiserver/pkg/endpoints/metrics" "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/registry/rest" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/apiserver/pkg/warning" ) @@ -91,7 +89,7 @@ type RequestScope struct { EquivalentResourceMapper runtime.EquivalentResourceMapper TableConvertor rest.TableConvertor - FieldManager *fieldmanager.FieldManager + FieldManager *managedfields.FieldManager Resource schema.GroupVersionResource Kind schema.GroupVersionKind @@ -406,13 +404,10 @@ func isDryRun(url *url.URL) bool { // fieldValidation checks that the field validation feature is enabled // and returns a valid directive of either -// - Ignore (default when feature is disabled) -// - Warn (default when feature is enabled) +// - Ignore +// - Warn (default) // - Strict func fieldValidation(directive string) string { - if !utilfeature.DefaultFeatureGate.Enabled(features.ServerSideFieldValidation) { - return metav1.FieldValidationIgnore - } if directive == "" { return metav1.FieldValidationWarn } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/watch.go b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/watch.go index 9b8917caa..c76cc194a 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/handlers/watch.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/handlers/watch.go @@ -34,6 +34,7 @@ import ( "k8s.io/apimachinery/pkg/watch" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/metrics" + apirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/util/wsstream" ) @@ -105,6 +106,11 @@ func serveWatch(watcher watch.Interface, scope *RequestScope, mediaTypeOptions n embeddedEncoder = scope.Serializer.EncoderForVersion(serializer.Serializer, contentKind.GroupVersion()) } + var serverShuttingDownCh <-chan struct{} + if signals := apirequest.ServerShutdownSignalFrom(req.Context()); signals != nil { + serverShuttingDownCh = signals.ShuttingDown() + } + ctx := req.Context() server := &WatchServer{ @@ -132,7 +138,8 @@ func serveWatch(watcher watch.Interface, scope *RequestScope, mediaTypeOptions n return result }, - TimeoutFactory: &realTimeoutFactory{timeout}, + TimeoutFactory: &realTimeoutFactory{timeout}, + ServerShuttingDownCh: serverShuttingDownCh, } server.ServeHTTP(w, req) @@ -156,7 +163,8 @@ type WatchServer struct { // used to correct the object before we send it to the serializer Fixup func(runtime.Object) runtime.Object - TimeoutFactory TimeoutFactory + TimeoutFactory TimeoutFactory + ServerShuttingDownCh <-chan struct{} } // ServeHTTP serves a series of encoded events via HTTP with Transfer-Encoding: chunked @@ -230,6 +238,15 @@ func (s *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { for { select { + case <-s.ServerShuttingDownCh: + // the server has signaled that it is shutting down (not accepting + // any new request), all active watch request(s) should return + // immediately here. The WithWatchTerminationDuringShutdown server + // filter will ensure that the response to the client is rate + // limited in order to avoid any thundering herd issue when the + // client(s) try to reestablish the WATCH on the other + // available apiserver instance(s). + return case <-done: return case <-timeoutCh: diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/installer.go b/vendor/k8s.io/apiserver/pkg/endpoints/installer.go index b0af449f0..3f8b6807e 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/installer.go @@ -32,12 +32,12 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/managedfields" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/endpoints/deprecation" "k8s.io/apiserver/pkg/endpoints/discovery" "k8s.io/apiserver/pkg/endpoints/handlers" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/metrics" utilwarning "k8s.io/apiserver/pkg/endpoints/warning" @@ -345,13 +345,6 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag isCreater = true } - var resetFields map[fieldpath.APIVersion]*fieldpath.Set - if a.group.OpenAPIModels != nil { - if resetFieldsStrategy, isResetFieldsStrategy := storage.(rest.ResetFieldsStrategy); isResetFieldsStrategy { - resetFields = resetFieldsStrategy.GetResetFields() - } - } - var versionedList interface{} if isLister { list := lister.NewList() @@ -622,11 +615,6 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag } } - var disabledParams []string - if !utilfeature.DefaultFeatureGate.Enabled(features.ServerSideFieldValidation) { - disabledParams = []string{"fieldValidation"} - } - // Create Routes for the actions. // TODO: Add status documentation using Returns() // Errors (see api/errors/errors.go as well as go-restful router): @@ -685,8 +673,17 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if a.group.MetaGroupVersion != nil { reqScope.MetaGroupVersion = *a.group.MetaGroupVersion } - if a.group.OpenAPIModels != nil { - reqScope.FieldManager, err = fieldmanager.NewDefaultFieldManager( + + // Use TypeConverter's nil-ness as a proxy for whether SSA/OpenAPI is enabled + // This should be removed in the future and made unconditional + // https://github.com/kubernetes/kubernetes/pull/114998 + if a.group.TypeConverter != nil { + var resetFields map[fieldpath.APIVersion]*fieldpath.Set + if resetFieldsStrategy, isResetFieldsStrategy := storage.(rest.ResetFieldsStrategy); isResetFieldsStrategy { + resetFields = resetFieldsStrategy.GetResetFields() + } + + reqScope.FieldManager, err = managedfields.NewDefaultFieldManager( a.group.TypeConverter, a.group.UnsafeConvertor, a.group.Defaulter, @@ -700,6 +697,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag return nil, nil, fmt.Errorf("failed to create field manager: %v", err) } } + for _, action := range actions { producedObject := storageMeta.ProducesObject(action.Verb) if producedObject == nil { @@ -857,7 +855,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Returns(http.StatusCreated, "Created", producedObject). Reads(defaultVersionedObject). Writes(producedObject) - if err := AddObjectParams(ws, route, versionedUpdateOptions, disabledParams...); err != nil { + if err := AddObjectParams(ws, route, versionedUpdateOptions); err != nil { return nil, nil, err } addParams(route, action.Params) @@ -886,7 +884,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Returns(http.StatusCreated, "Created", producedObject). Reads(metav1.Patch{}). Writes(producedObject) - if err := AddObjectParams(ws, route, versionedPatchOptions, disabledParams...); err != nil { + if err := AddObjectParams(ws, route, versionedPatchOptions); err != nil { return nil, nil, err } addParams(route, action.Params) @@ -917,7 +915,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Returns(http.StatusAccepted, "Accepted", producedObject). Reads(defaultVersionedObject). Writes(producedObject) - if err := AddObjectParams(ws, route, versionedCreateOptions, disabledParams...); err != nil { + if err := AddObjectParams(ws, route, versionedCreateOptions); err != nil { return nil, nil, err } addParams(route, action.Params) @@ -1080,6 +1078,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if categoriesProvider, ok := storage.(rest.CategoriesProvider); ok { apiResource.Categories = categoriesProvider.Categories() } + if !isSubresource { + singularNameProvider, ok := storage.(rest.SingularNameProvider) + if !ok { + return nil, nil, fmt.Errorf("resource %s must implement SingularNameProvider", resource) + } + apiResource.SingularName = singularNameProvider.GetSingularName() + } + if gvkProvider, ok := storage.(rest.GroupVersionKindProvider); ok { gvk := gvkProvider.GroupVersionKind(a.group.GroupVersion) apiResource.Group = gvk.Group diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go index 18340107d..450a6653d 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go @@ -33,8 +33,6 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/endpoints/responsewriter" - "k8s.io/apiserver/pkg/features" - utilfeature "k8s.io/apiserver/pkg/util/feature" compbasemetrics "k8s.io/component-base/metrics" "k8s.io/component-base/metrics/legacyregistry" ) @@ -108,7 +106,7 @@ var ( &compbasemetrics.HistogramOpts{ Subsystem: APIServerComponent, Name: "request_slo_duration_seconds", - Help: "Response latency distribution (not counting webhook duration) in seconds for each verb, group, version, resource, subresource, scope and component.", + Help: "Response latency distribution (not counting webhook duration and priority & fairness queue wait times) in seconds for each verb, group, version, resource, subresource, scope and component.", // This metric is supplementary to the requestLatencies metric. // It measures request duration excluding webhooks as they are mostly // dependant on user configuration. @@ -123,7 +121,7 @@ var ( &compbasemetrics.HistogramOpts{ Subsystem: APIServerComponent, Name: "request_sli_duration_seconds", - Help: "Response latency distribution (not counting webhook duration) in seconds for each verb, group, version, resource, subresource, scope and component.", + Help: "Response latency distribution (not counting webhook duration and priority & fairness queue wait times) in seconds for each verb, group, version, resource, subresource, scope and component.", // This metric is supplementary to the requestLatencies metric. // It measures request duration excluding webhooks as they are mostly // dependant on user configuration. @@ -136,7 +134,7 @@ var ( fieldValidationRequestLatencies = compbasemetrics.NewHistogramVec( &compbasemetrics.HistogramOpts{ Name: "field_validation_request_duration_seconds", - Help: "Response latency distribution in seconds for each field validation value and whether field validation is enabled or not", + Help: "Response latency distribution in seconds for each field validation value", // This metric is supplementary to the requestLatencies metric. // It measures request durations for the various field validation // values. @@ -144,7 +142,7 @@ var ( 4, 5, 6, 8, 10, 15, 20, 30, 45, 60}, StabilityLevel: compbasemetrics.ALPHA, }, - []string{"field_validation", "enabled"}, + []string{"field_validation"}, ) responseSizes = compbasemetrics.NewHistogramVec( &compbasemetrics.HistogramOpts{ @@ -321,6 +319,14 @@ var ( "UPDATE", "WATCH", "WATCHLIST") + + // These are the valid connect requests which we report in our metrics. + validConnectRequests = utilsets.NewString( + "log", + "exec", + "portforward", + "attach", + "proxy") ) const ( @@ -427,7 +433,7 @@ func RecordRequestAbort(req *http.Request, requestInfo *request.RequestInfo) { } scope := CleanScope(requestInfo) - reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), getVerbIfWatch(req), req) + reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), "", req, requestInfo) resource := requestInfo.Resource subresource := requestInfo.Subresource group := requestInfo.APIGroup @@ -448,7 +454,7 @@ func RecordDroppedRequest(req *http.Request, requestInfo *request.RequestInfo, c // InstrumentRouteFunc which is registered in installer.go with predefined // list of verbs (different than those translated to RequestInfo). // However, we need to tweak it e.g. to differentiate GET from LIST. - reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), getVerbIfWatch(req), req) + reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), "", req, requestInfo) if requestInfo.IsResourceRequest { requestCounter.WithContext(req.Context()).WithLabelValues(reportedVerb, dryRun, requestInfo.APIGroup, requestInfo.APIVersion, requestInfo.Resource, requestInfo.Subresource, scope, component, codeToString(http.StatusTooManyRequests)).Inc() @@ -471,7 +477,7 @@ func RecordRequestTermination(req *http.Request, requestInfo *request.RequestInf // InstrumentRouteFunc which is registered in installer.go with predefined // list of verbs (different than those translated to RequestInfo). // However, we need to tweak it e.g. to differentiate GET from LIST. - reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), getVerbIfWatch(req), req) + reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), "", req, requestInfo) if requestInfo.IsResourceRequest { requestTerminationsTotal.WithContext(req.Context()).WithLabelValues(reportedVerb, requestInfo.APIGroup, requestInfo.APIVersion, requestInfo.Resource, requestInfo.Subresource, scope, component, codeToString(code)).Inc() @@ -493,7 +499,7 @@ func RecordLongRunning(req *http.Request, requestInfo *request.RequestInfo, comp // InstrumentRouteFunc which is registered in installer.go with predefined // list of verbs (different than those translated to RequestInfo). // However, we need to tweak it e.g. to differentiate GET from LIST. - reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), getVerbIfWatch(req), req) + reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), "", req, requestInfo) if requestInfo.IsResourceRequest { g = longRunningRequestsGauge.WithContext(req.Context()).WithLabelValues(reportedVerb, requestInfo.APIGroup, requestInfo.APIVersion, requestInfo.Resource, requestInfo.Subresource, scope, component) @@ -508,11 +514,15 @@ func RecordLongRunning(req *http.Request, requestInfo *request.RequestInfo, comp // MonitorRequest handles standard transformations for client and the reported verb and then invokes Monitor to record // a request. verb must be uppercase to be backwards compatible with existing monitoring tooling. func MonitorRequest(req *http.Request, verb, group, version, resource, subresource, scope, component string, deprecated bool, removedRelease string, httpCode, respSize int, elapsed time.Duration) { + requestInfo, ok := request.RequestInfoFrom(req.Context()) + if !ok || requestInfo == nil { + requestInfo = &request.RequestInfo{Verb: req.Method, Path: req.URL.Path} + } // We don't use verb from , as this may be propagated from // InstrumentRouteFunc which is registered in installer.go with predefined // list of verbs (different than those translated to RequestInfo). // However, we need to tweak it e.g. to differentiate GET from LIST. - reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), verb, req) + reportedVerb := cleanVerb(CanonicalVerb(strings.ToUpper(req.Method), scope), verb, req, requestInfo) dryRun := cleanDryRun(req.URL) elapsedSeconds := elapsed.Seconds() @@ -531,11 +541,10 @@ func MonitorRequest(req *http.Request, verb, group, version, resource, subresour } requestLatencies.WithContext(req.Context()).WithLabelValues(reportedVerb, dryRun, group, version, resource, subresource, scope, component).Observe(elapsedSeconds) fieldValidation := cleanFieldValidation(req.URL) - fieldValidationEnabled := strconv.FormatBool(utilfeature.DefaultFeatureGate.Enabled(features.ServerSideFieldValidation)) - fieldValidationRequestLatencies.WithContext(req.Context()).WithLabelValues(fieldValidation, fieldValidationEnabled) + fieldValidationRequestLatencies.WithContext(req.Context()).WithLabelValues(fieldValidation) if wd, ok := request.LatencyTrackersFrom(req.Context()); ok { - sliLatency := elapsedSeconds - (wd.MutatingWebhookTracker.GetLatency() + wd.ValidatingWebhookTracker.GetLatency()).Seconds() + sliLatency := elapsedSeconds - (wd.MutatingWebhookTracker.GetLatency() + wd.ValidatingWebhookTracker.GetLatency() + wd.APFQueueWaitTracker.GetLatency()).Seconds() requestSloLatencies.WithContext(req.Context()).WithLabelValues(reportedVerb, group, version, resource, subresource, scope, component).Observe(sliLatency) requestSliLatencies.WithContext(req.Context()).WithLabelValues(reportedVerb, group, version, resource, subresource, scope, component).Observe(sliLatency) } @@ -585,15 +594,16 @@ func InstrumentHandlerFunc(verb, group, version, resource, subresource, scope, c // NormalizedVerb returns normalized verb func NormalizedVerb(req *http.Request) string { verb := req.Method - if requestInfo, ok := request.RequestInfoFrom(req.Context()); ok { + requestInfo, ok := request.RequestInfoFrom(req.Context()) + if ok { // If we can find a requestInfo, we can get a scope, and then // we can convert GETs to LISTs when needed. scope := CleanScope(requestInfo) verb = CanonicalVerb(strings.ToUpper(verb), scope) } - // mark APPLY requests and WATCH requests correctly. - return CleanVerb(verb, req) + // mark APPLY requests, WATCH requests and CONNECT requests correctly. + return CleanVerb(verb, req, requestInfo) } // CleanScope returns the scope of the request. @@ -626,8 +636,8 @@ func CanonicalVerb(verb string, scope string) string { } // CleanVerb returns a normalized verb, so that it is easy to tell WATCH from -// LIST and APPLY from PATCH. -func CleanVerb(verb string, request *http.Request) string { +// LIST, APPLY from PATCH and CONNECT from others. +func CleanVerb(verb string, request *http.Request, requestInfo *request.RequestInfo) string { reportedVerb := verb if suggestedVerb := getVerbIfWatch(request); suggestedVerb == "WATCH" { reportedVerb = "WATCH" @@ -639,21 +649,22 @@ func CleanVerb(verb string, request *http.Request) string { if verb == "PATCH" && request.Header.Get("Content-Type") == string(types.ApplyPatchType) { reportedVerb = "APPLY" } + if requestInfo != nil && requestInfo.IsResourceRequest && len(requestInfo.Subresource) > 0 && validConnectRequests.Has(requestInfo.Subresource) { + reportedVerb = "CONNECT" + } return reportedVerb } // cleanVerb additionally ensures that unknown verbs don't clog up the metrics. -func cleanVerb(verb, suggestedVerb string, request *http.Request) string { +func cleanVerb(verb, suggestedVerb string, request *http.Request, requestInfo *request.RequestInfo) string { // CanonicalVerb (being an input for this function) doesn't handle correctly the // deprecated path pattern for watch of: // GET /api/{version}/watch/{resource} // We correct it manually based on the pass verb from the installer. - var reportedVerb string if suggestedVerb == "WATCH" || suggestedVerb == "WATCHLIST" { - reportedVerb = "WATCH" - } else { - reportedVerb = CleanVerb(verb, request) + return "WATCH" } + reportedVerb := CleanVerb(verb, request, requestInfo) if validRequestMethods.Has(reportedVerb) { return reportedVerb } diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go index 2bc00a66e..2558494bd 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go @@ -211,7 +211,7 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er opts := metainternalversion.ListOptions{} if err := metainternalversionscheme.ParameterCodec.DecodeParameters(req.URL.Query(), metav1.SchemeGroupVersion, &opts); err != nil { // An error in parsing request will result in default to "list" and not setting "name" field. - klog.ErrorS(err, "Couldn't parse request", "Request", req.URL.Query()) + klog.ErrorS(err, "Couldn't parse request", "request", req.URL.Query()) // Reset opts to not rely on partial results from parsing. // However, if watch is set, let's report it. opts = metainternalversion.ListOptions{} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/server_shutdown_signal.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/server_shutdown_signal.go new file mode 100644 index 000000000..d06275b83 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/endpoints/request/server_shutdown_signal.go @@ -0,0 +1,55 @@ +/* +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 request + +import ( + "context" +) + +// The serverShutdownSignalKeyType type is unexported to prevent collisions +type serverShutdownSignalKeyType int + +// serverShutdownSignalKey is the context key for storing the +// watch termination interface instance for a WATCH request. +const serverShutdownSignalKey serverShutdownSignalKeyType = iota + +// ServerShutdownSignal is associated with the request context so +// the request handler logic has access to signals rlated to +// the server shutdown events +type ServerShutdownSignal interface { + // Signaled when the apiserver is not receiving any new request + ShuttingDown() <-chan struct{} +} + +// ServerShutdownSignalFrom returns the ServerShutdownSignal instance +// associated with the request context. +// If there is no ServerShutdownSignal asscoaied with the context, +// nil is returned. +func ServerShutdownSignalFrom(ctx context.Context) ServerShutdownSignal { + ev, _ := ctx.Value(serverShutdownSignalKey).(ServerShutdownSignal) + return ev +} + +// WithServerShutdownSignal returns a new context that stores +// the ServerShutdownSignal interface instance. +func WithServerShutdownSignal(parent context.Context, window ServerShutdownSignal) context.Context { + if ServerShutdownSignalFrom(parent) != nil { + return parent // Avoid double registering. + } + + return context.WithValue(parent, serverShutdownSignalKey, window) +} diff --git a/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go b/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go index 120bc46bf..612c671d8 100644 --- a/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go +++ b/vendor/k8s.io/apiserver/pkg/endpoints/request/webhook_duration.go @@ -116,6 +116,10 @@ type LatencyTrackers struct { // Validate webhooks are done in parallel, so max function is used. ValidatingWebhookTracker DurationTracker + // APFQueueWaitTracker tracks the latency incurred by queue wait times + // from priority & fairness. + APFQueueWaitTracker DurationTracker + // StorageTracker tracks the latency incurred inside the storage layer, // it accounts for the time it takes to send data to the underlying // storage layer (etcd) and get the complete response back. @@ -168,6 +172,7 @@ func WithLatencyTrackersAndCustomClock(parent context.Context, c clock.Clock) co return WithValue(parent, latencyTrackersKey, &LatencyTrackers{ MutatingWebhookTracker: newSumLatencyTracker(c), ValidatingWebhookTracker: newMaxLatencyTracker(c), + APFQueueWaitTracker: newMaxLatencyTracker(c), StorageTracker: newSumLatencyTracker(c), TransformTracker: newSumLatencyTracker(c), SerializationTracker: newSumLatencyTracker(c), @@ -230,6 +235,14 @@ func TrackResponseWriteLatency(ctx context.Context, d time.Duration) { } } +// TrackAPFQueueWaitLatency is used to track latency incurred +// by priority and fairness queues. +func TrackAPFQueueWaitLatency(ctx context.Context, d time.Duration) { + if tracker, ok := LatencyTrackersFrom(ctx); ok { + tracker.APFQueueWaitTracker.TrackDuration(d) + } +} + // AuditAnnotationsFromLatencyTrackers will inspect each latency tracker // associated with the request context and return a set of audit // annotations that can be added to the API audit entry. diff --git a/vendor/k8s.io/apiserver/pkg/features/kube_features.go b/vendor/k8s.io/apiserver/pkg/features/kube_features.go index aa903587d..72cd49375 100644 --- a/vendor/k8s.io/apiserver/pkg/features/kube_features.go +++ b/vendor/k8s.io/apiserver/pkg/features/kube_features.go @@ -35,8 +35,16 @@ const ( // of code conflicts because changes are more likely to be scattered // across the file. + // owner: @ivelichkovich, @tallclair + // alpha: v1.27 + // kep: https://kep.k8s.io/3716 + // + // Enables usage of MatchConditions fields to use CEL expressions for matching on admission webhooks + AdmissionWebhookMatchConditions featuregate.Feature = "AdmissionWebhookMatchConditions" + // owner: @jefftree @alexzielenski // alpha: v1.26 + // beta: v1.27 // // Enables an single HTTP endpoint /discovery/ which supports native HTTP // caching with ETags containing all APIResources known to the apiserver. @@ -74,6 +82,7 @@ const ( // owner: @dashpole // alpha: v1.22 + // beta: v1.27 // // Add support for distributed tracing in the API Server APIServerTracing featuregate.Feature = "APIServerTracing" @@ -124,6 +133,7 @@ const ( // owner: @aramase // kep: https://kep.k8s.io/3299 // alpha: v1.25 + // beta: v1.27 // // Enables KMS v2 API for encryption at rest. KMSv2 featuregate.Feature = "KMSv2" @@ -141,6 +151,7 @@ const ( // kep: https://kep.k8s.io/2896 // alpha: v1.23 // beta: v1.24 + // stable: v1.27 // // Enables kubernetes to publish OpenAPI v3 OpenAPIV3 featuregate.Feature = "OpenAPIV3" @@ -198,6 +209,19 @@ const ( // // Enables support for watch bookmark events. WatchBookmark featuregate.Feature = "WatchBookmark" + + // owner: @vinaykul + // kep: http://kep.k8s.io/1287 + // alpha: v1.27 + // + // Enables In-Place Pod Vertical Scaling + InPlacePodVerticalScaling featuregate.Feature = "InPlacePodVerticalScaling" + + // owner: @p0lyn0mial + // alpha: v1.27 + // + // Allow the API server to stream individual items instead of chunking + WatchList featuregate.Feature = "WatchList" ) func init() { @@ -208,7 +232,10 @@ func init() { // To add a new feature, define a key for it above and add it here. The features will be // available throughout Kubernetes binaries. var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ - AggregatedDiscoveryEndpoint: {Default: false, PreRelease: featuregate.Alpha}, + + AggregatedDiscoveryEndpoint: {Default: true, PreRelease: featuregate.Beta}, + + AdmissionWebhookMatchConditions: {Default: false, PreRelease: featuregate.Alpha}, APIListChunking: {Default: true, PreRelease: featuregate.Beta}, @@ -218,9 +245,9 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS APIServerIdentity: {Default: true, PreRelease: featuregate.Beta}, - APIServerTracing: {Default: false, PreRelease: featuregate.Alpha}, + APIServerTracing: {Default: true, PreRelease: featuregate.Beta}, - AdvancedAuditing: {Default: true, PreRelease: featuregate.GA}, + AdvancedAuditing: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28 ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Alpha}, @@ -230,11 +257,11 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS EfficientWatchResumption: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, - KMSv2: {Default: false, PreRelease: featuregate.Alpha}, + KMSv2: {Default: true, PreRelease: featuregate.Beta}, OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta}, - OpenAPIV3: {Default: true, PreRelease: featuregate.Beta}, + OpenAPIV3: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 RemainingItemCount: {Default: true, PreRelease: featuregate.Beta}, @@ -242,11 +269,15 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS ServerSideApply: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 - ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta}, + ServerSideFieldValidation: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha}, StorageVersionHash: {Default: true, PreRelease: featuregate.Beta}, WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, + + InPlacePodVerticalScaling: {Default: false, PreRelease: featuregate.Alpha}, + + WatchList: {Default: false, PreRelease: featuregate.Alpha}, } diff --git a/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go b/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go index 40bca4966..fa23d29d6 100644 --- a/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go +++ b/vendor/k8s.io/apiserver/pkg/registry/generic/registry/store.go @@ -25,6 +25,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/validation" "k8s.io/apimachinery/pkg/api/validation/path" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -110,6 +111,9 @@ type Store struct { // See qualifiedResourceFromContext for details. DefaultQualifiedResource schema.GroupResource + // SingularQualifiedResource is the singular name of the resource. + SingularQualifiedResource schema.GroupResource + // KeyRootFunc returns the root etcd key for this resource; should not // include trailing "/". This is used for operations that work on the // entire collection (listing and watching). @@ -229,6 +233,8 @@ var _ rest.StandardStorage = &Store{} var _ rest.TableConvertor = &Store{} var _ GenericStore = &Store{} +var _ rest.SingularNameProvider = &Store{} + const ( OptimisticLockErrorMsg = "the object has been modified; please apply your changes to the latest version and try again" resourceCountPollPeriodJitter = 1.2 @@ -359,6 +365,16 @@ func (e *Store) ListPredicate(ctx context.Context, p storage.SelectionPredicate, Predicate: p, Recursive: true, } + + // if we're not already namespace-scoped, see if the field selector narrows the scope of the watch + if requestNamespace, _ := genericapirequest.NamespaceFrom(ctx); len(requestNamespace) == 0 { + if selectorNamespace, ok := p.MatchesSingleNamespace(); ok { + if len(validation.ValidateNamespaceName(selectorNamespace, false)) == 0 { + ctx = genericapirequest.WithNamespace(ctx, selectorNamespace) + } + } + } + if name, ok := p.MatchesSingle(); ok { if key, err := e.KeyFunc(ctx, name); err == nil { storageOpts.Recursive = false @@ -1122,11 +1138,6 @@ func (e *Store) DeleteReturnsDeletedObject() bool { // DeleteCollection is currently NOT atomic. It can happen that only subset of objects // will be deleted from storage, and then an error will be returned. // In case of success, the list of deleted objects will be returned. -// -// TODO: Currently, there is no easy way to remove 'directory' entry from storage (if we -// are removing all objects of a given type) with the current API (it's technically -// possibly with storage API, but watch is not delivered correctly then). -// It will be possible to fix it with v3 etcd API. func (e *Store) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { if listOptions == nil { listOptions = &metainternalversion.ListOptions{} @@ -1162,23 +1173,6 @@ func (e *Store) DeleteCollection(ctx context.Context, deleteValidation rest.Vali toProcess := make(chan int, 2*workersNumber) errs := make(chan error, workersNumber+1) workersExited := make(chan struct{}) - distributorExited := make(chan struct{}) - - go func() { - defer utilruntime.HandleCrash(func(panicReason interface{}) { - errs <- fmt.Errorf("DeleteCollection distributor panicked: %v", panicReason) - }) - defer close(distributorExited) - for i := 0; i < len(items); i++ { - select { - case toProcess <- i: - case <-workersExited: - klog.V(4).InfoS("workers already exited, and there are some items waiting to be processed", "finished", i, "total", len(items)) - return - } - } - close(toProcess) - }() wg.Add(workersNumber) for i := 0; i < workersNumber; i++ { @@ -1207,10 +1201,31 @@ func (e *Store) DeleteCollection(ctx context.Context, deleteValidation rest.Vali } }() } - wg.Wait() - // notify distributor to exit - close(workersExited) - <-distributorExited + // In case of all workers exit, notify distributor. + go func() { + defer utilruntime.HandleCrash(func(panicReason interface{}) { + errs <- fmt.Errorf("DeleteCollection workers closer panicked: %v", panicReason) + }) + wg.Wait() + close(workersExited) + }() + + func() { + defer close(toProcess) + + for i := 0; i < len(items); i++ { + select { + case toProcess <- i: + case <-workersExited: + klog.V(4).InfoS("workers already exited, and there are some items waiting to be processed", "finished", i, "total", len(items)) + return + } + } + }() + + // Wait for all workers to exist. + <-workersExited + select { case err := <-errs: return nil, err @@ -1268,12 +1283,21 @@ func (e *Store) Watch(ctx context.Context, options *metainternalversion.ListOpti resourceVersion = options.ResourceVersion predicate.AllowWatchBookmarks = options.AllowWatchBookmarks } - return e.WatchPredicate(ctx, predicate, resourceVersion) + return e.WatchPredicate(ctx, predicate, resourceVersion, options.SendInitialEvents) } // WatchPredicate starts a watch for the items that matches. -func (e *Store) WatchPredicate(ctx context.Context, p storage.SelectionPredicate, resourceVersion string) (watch.Interface, error) { - storageOpts := storage.ListOptions{ResourceVersion: resourceVersion, Predicate: p, Recursive: true} +func (e *Store) WatchPredicate(ctx context.Context, p storage.SelectionPredicate, resourceVersion string, sendInitialEvents *bool) (watch.Interface, error) { + storageOpts := storage.ListOptions{ResourceVersion: resourceVersion, Predicate: p, Recursive: true, SendInitialEvents: sendInitialEvents} + + // if we're not already namespace-scoped, see if the field selector narrows the scope of the watch + if requestNamespace, _ := genericapirequest.NamespaceFrom(ctx); len(requestNamespace) == 0 { + if selectorNamespace, ok := p.MatchesSingleNamespace(); ok { + if len(validation.ValidateNamespaceName(selectorNamespace, false)) == 0 { + ctx = genericapirequest.WithNamespace(ctx, selectorNamespace) + } + } + } key := e.KeyRootFunc(ctx) if name, ok := p.MatchesSingle(); ok { @@ -1320,6 +1344,12 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error { if e.DefaultQualifiedResource.Empty() { return fmt.Errorf("store %#v must have a non-empty qualified resource", e) } + if e.SingularQualifiedResource.Empty() { + return fmt.Errorf("store %#v must have a non-empty singular qualified resource", e) + } + if e.DefaultQualifiedResource.Group != e.SingularQualifiedResource.Group { + return fmt.Errorf("store for %#v, singular and plural qualified resource's group name's must match", e) + } if e.NewFunc == nil { return fmt.Errorf("store for %s must have NewFunc set", e.DefaultQualifiedResource.String()) } @@ -1515,6 +1545,10 @@ func (e *Store) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set { return e.ResetFieldsStrategy.GetResetFields() } +func (e *Store) GetSingularName() string { + return e.SingularQualifiedResource.Resource +} + // validateIndexers will check the prefix of indexers. func validateIndexers(indexers *cache.Indexers) error { if indexers == nil { diff --git a/vendor/k8s.io/apiserver/pkg/registry/rest/rest.go b/vendor/k8s.io/apiserver/pkg/registry/rest/rest.go index 6330ea8f5..78b6ea8b0 100644 --- a/vendor/k8s.io/apiserver/pkg/registry/rest/rest.go +++ b/vendor/k8s.io/apiserver/pkg/registry/rest/rest.go @@ -89,6 +89,12 @@ type CategoriesProvider interface { Categories() []string } +// SingularNameProvider returns singular name of resources. This is used by kubectl discovery to have singular +// name representation of resources. In case of shortcut conflicts(with CRD shortcuts) singular name should always map to this resource. +type SingularNameProvider interface { + GetSingularName() string +} + // GroupVersionKindProvider is used to specify a particular GroupVersionKind to discovery. This is used for polymorphic endpoints // which generally point to foreign versions. Scale refers to Scale.v1beta1.extensions for instance. // This trumps KindProvider since it is capable of providing the information required. @@ -203,6 +209,13 @@ type NamedCreater interface { Create(ctx context.Context, name string, obj runtime.Object, createValidation ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) } +// SubresourceObjectMetaPreserver adds configuration options to a Creater for subresources. +type SubresourceObjectMetaPreserver interface { + // PreserveRequestObjectMetaSystemFieldsOnSubresourceCreate indicates that a + // handler should preserve fields of ObjectMeta that are managed by the system. + PreserveRequestObjectMetaSystemFieldsOnSubresourceCreate() bool +} + // UpdatedObjectInfo provides information about an updated object to an Updater. // It requires access to the old object in order to return the newly updated object. type UpdatedObjectInfo interface { diff --git a/vendor/k8s.io/apiserver/pkg/server/config.go b/vendor/k8s.io/apiserver/pkg/server/config.go index b572d3359..9dc87506a 100644 --- a/vendor/k8s.io/apiserver/pkg/server/config.go +++ b/vendor/k8s.io/apiserver/pkg/server/config.go @@ -34,6 +34,7 @@ import ( jsonpatch "github.com/evanphx/json-patch" "github.com/google/uuid" + "golang.org/x/crypto/cryptobyte" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -126,6 +127,7 @@ type Config struct { EnableIndex bool EnableProfiling bool + DebugSocketPath string EnableDiscovery bool // Requires generic profiling enabled @@ -155,8 +157,14 @@ type Config struct { // BuildHandlerChainFunc allows you to build custom handler chains by decorating the apiHandler. BuildHandlerChainFunc func(apiHandler http.Handler, c *Config) (secure http.Handler) - // HandlerChainWaitGroup allows you to wait for all chain handlers exit after the server shutdown. - HandlerChainWaitGroup *utilwaitgroup.SafeWaitGroup + // NonLongRunningRequestWaitGroup allows you to wait for all chain + // handlers associated with non long-running requests + // to complete while the server is shuting down. + NonLongRunningRequestWaitGroup *utilwaitgroup.SafeWaitGroup + // WatchRequestWaitGroup allows us to wait for all chain + // handlers associated with active watch requests to + // complete while the server is shuting down. + WatchRequestWaitGroup *utilwaitgroup.RateLimitedSafeWaitGroup // DiscoveryAddresses is used to build the IPs pass to discovery. If nil, the ExternalAddress is // always reported DiscoveryAddresses discovery.Addresses @@ -268,6 +276,23 @@ type Config struct { // AggregatedDiscoveryGroupManager serves /apis in an aggregated form. AggregatedDiscoveryGroupManager discoveryendpoint.ResourceManager + + // ShutdownWatchTerminationGracePeriod, if set to a positive value, + // is the maximum duration the apiserver will wait for all active + // watch request(s) to drain. + // Once this grace period elapses, the apiserver will no longer + // wait for any active watch request(s) in flight to drain, it will + // proceed to the next step in the graceful server shutdown process. + // If set to a positive value, the apiserver will keep track of the + // number of active watch request(s) in flight and during shutdown + // it will wait, at most, for the specified duration and allow these + // active watch requests to drain with some rate limiting in effect. + // The default is zero, which implies the apiserver will not keep + // track of active watch request(s) in flight and will not wait + // for them to drain, this maintains backward compatibility. + // This grace period is orthogonal to other grace periods, and + // it is not overridden by any other grace period. + ShutdownWatchTerminationGracePeriod time.Duration } type RecommendedConfig struct { @@ -320,6 +345,8 @@ type AuthenticationInfo struct { APIAudiences authenticator.Audiences // Authenticator determines which subject is making the request Authenticator authenticator.Request + + RequestHeaderConfig *authenticatorfactory.RequestHeaderConfig } type AuthorizationInfo struct { @@ -342,31 +369,49 @@ func NewConfig(codecs serializer.CodecFactory) *Config { klog.Fatalf("error getting hostname for apiserver identity: %v", err) } - hash := sha256.Sum256([]byte(hostname)) - id = "kube-apiserver-" + strings.ToLower(base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(hash[:16])) + // Since the hash needs to be unique across each kube-apiserver and aggregated apiservers, + // the hash used for the identity should include both the hostname and the identity value. + // TODO: receive the identity value as a parameter once the apiserver identity lease controller + // post start hook is moved to generic apiserver. + b := cryptobyte.NewBuilder(nil) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(hostname)) + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte("kube-apiserver")) + }) + hashData, err := b.Bytes() + if err != nil { + klog.Fatalf("error building hash data for apiserver identity: %v", err) + } + + hash := sha256.Sum256(hashData) + id = "apiserver-" + strings.ToLower(base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(hash[:16])) } lifecycleSignals := newLifecycleSignals() return &Config{ - Serializer: codecs, - BuildHandlerChainFunc: DefaultBuildHandlerChain, - HandlerChainWaitGroup: new(utilwaitgroup.SafeWaitGroup), - LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix), - DisabledPostStartHooks: sets.NewString(), - PostStartHooks: map[string]PostStartHookConfigEntry{}, - HealthzChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...), - ReadyzChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...), - LivezChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...), - EnableIndex: true, - EnableDiscovery: true, - EnableProfiling: true, - EnableMetrics: true, - MaxRequestsInFlight: 400, - MaxMutatingRequestsInFlight: 200, - RequestTimeout: time.Duration(60) * time.Second, - MinRequestTimeout: 1800, - LivezGracePeriod: time.Duration(0), - ShutdownDelayDuration: time.Duration(0), + Serializer: codecs, + BuildHandlerChainFunc: DefaultBuildHandlerChain, + NonLongRunningRequestWaitGroup: new(utilwaitgroup.SafeWaitGroup), + WatchRequestWaitGroup: &utilwaitgroup.RateLimitedSafeWaitGroup{}, + LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix), + DisabledPostStartHooks: sets.NewString(), + PostStartHooks: map[string]PostStartHookConfigEntry{}, + HealthzChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...), + ReadyzChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...), + LivezChecks: append([]healthz.HealthChecker{}, defaultHealthChecks...), + EnableIndex: true, + EnableDiscovery: true, + EnableProfiling: true, + DebugSocketPath: "", + EnableMetrics: true, + MaxRequestsInFlight: 400, + MaxMutatingRequestsInFlight: 200, + RequestTimeout: time.Duration(60) * time.Second, + MinRequestTimeout: 1800, + LivezGracePeriod: time.Duration(0), + ShutdownDelayDuration: time.Duration(0), // 1.5MB is the default client request size in bytes // the etcd server should accept. See // https://github.com/etcd-io/etcd/blob/release-3.4/embed/config.go#L56. @@ -387,9 +432,10 @@ func NewConfig(codecs serializer.CodecFactory) *Config { // Default to treating watch as a long-running operation // Generic API servers have no inherent long-running subresources - LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(sets.NewString("watch"), sets.NewString()), - lifecycleSignals: lifecycleSignals, - StorageObjectCountTracker: flowcontrolrequest.NewStorageObjectCountTracker(), + LongRunningFunc: genericfilters.BasicLongRunningRequestCheck(sets.NewString("watch"), sets.NewString()), + lifecycleSignals: lifecycleSignals, + StorageObjectCountTracker: flowcontrolrequest.NewStorageObjectCountTracker(), + ShutdownWatchTerminationGracePeriod: time.Duration(0), APIServerID: id, StorageVersionManager: storageversion.NewDefaultManager(), @@ -631,28 +677,36 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G return c.BuildHandlerChainFunc(handler, c.Config) } + var debugSocket *routes.DebugSocket + if c.DebugSocketPath != "" { + debugSocket = routes.NewDebugSocket(c.DebugSocketPath) + } + apiServerHandler := NewAPIServerHandler(name, c.Serializer, handlerChainBuilder, delegationTarget.UnprotectedHandler()) s := &GenericAPIServer{ - discoveryAddresses: c.DiscoveryAddresses, - LoopbackClientConfig: c.LoopbackClientConfig, - legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes, - admissionControl: c.AdmissionControl, - Serializer: c.Serializer, - AuditBackend: c.AuditBackend, - Authorizer: c.Authorization.Authorizer, - delegationTarget: delegationTarget, - EquivalentResourceRegistry: c.EquivalentResourceRegistry, - HandlerChainWaitGroup: c.HandlerChainWaitGroup, - Handler: apiServerHandler, + discoveryAddresses: c.DiscoveryAddresses, + LoopbackClientConfig: c.LoopbackClientConfig, + legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes, + admissionControl: c.AdmissionControl, + Serializer: c.Serializer, + AuditBackend: c.AuditBackend, + Authorizer: c.Authorization.Authorizer, + delegationTarget: delegationTarget, + EquivalentResourceRegistry: c.EquivalentResourceRegistry, + NonLongRunningRequestWaitGroup: c.NonLongRunningRequestWaitGroup, + WatchRequestWaitGroup: c.WatchRequestWaitGroup, + Handler: apiServerHandler, + UnprotectedDebugSocket: debugSocket, listedPathProvider: apiServerHandler, - minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, - ShutdownTimeout: c.RequestTimeout, - ShutdownDelayDuration: c.ShutdownDelayDuration, - SecureServingInfo: c.SecureServing, - ExternalAddress: c.ExternalAddress, + minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, + ShutdownTimeout: c.RequestTimeout, + ShutdownDelayDuration: c.ShutdownDelayDuration, + ShutdownWatchTerminationGracePeriod: c.ShutdownWatchTerminationGracePeriod, + SecureServingInfo: c.SecureServing, + ExternalAddress: c.ExternalAddress, openAPIConfig: c.OpenAPIConfig, openAPIV3Config: c.OpenAPIV3Config, @@ -686,10 +740,10 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AggregatedDiscoveryEndpoint) { manager := c.AggregatedDiscoveryGroupManager if manager == nil { - manager = discoveryendpoint.NewResourceManager() + manager = discoveryendpoint.NewResourceManager("apis") } s.AggregatedDiscoveryGroupManager = manager - s.AggregatedLegacyDiscoveryGroupManager = discoveryendpoint.NewResourceManager() + s.AggregatedLegacyDiscoveryGroupManager = discoveryendpoint.NewResourceManager("api") } for { if c.JSONPatchMaxCopyBytes <= 0 { @@ -868,7 +922,7 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler { failedHandler = filterlatency.TrackCompleted(failedHandler) handler = filterlatency.TrackCompleted(handler) - handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences) + handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences, c.Authentication.RequestHeaderConfig) handler = filterlatency.TrackStarted(handler, c.TracerProvider, "authentication") handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true") @@ -879,7 +933,10 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler { handler = genericapifilters.WithRequestDeadline(handler, c.AuditBackend, c.AuditPolicyRuleEvaluator, c.LongRunningFunc, c.Serializer, c.RequestTimeout) - handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup) + handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.NonLongRunningRequestWaitGroup) + if c.ShutdownWatchTerminationGracePeriod > 0 { + handler = genericfilters.WithWatchTerminationDuringShutdown(handler, c.lifecycleSignals, c.WatchRequestWaitGroup) + } if c.SecureServing != nil && !c.SecureServing.DisableHTTP2 && c.GoawayChance > 0 { handler = genericfilters.WithProbabilisticGoaway(handler, c.GoawayChance) } @@ -914,6 +971,13 @@ func installAPI(s *GenericAPIServer, c *Config) { // so far, only logging related endpoints are considered valid to add for these debug flags. routes.DebugFlags{}.Install(s.Handler.NonGoRestfulMux, "v", routes.StringFlagPutHandler(logs.GlogSetter)) } + if s.UnprotectedDebugSocket != nil { + s.UnprotectedDebugSocket.InstallProfiling() + s.UnprotectedDebugSocket.InstallDebugFlag("v", routes.StringFlagPutHandler(logs.GlogSetter)) + if c.EnableContentionProfiling { + goruntime.SetBlockProfileRate(1) + } + } if c.EnableMetrics { if c.EnableProfiling { diff --git a/vendor/k8s.io/apiserver/pkg/server/filters/cors.go b/vendor/k8s.io/apiserver/pkg/server/filters/cors.go index 29c46e4c7..ca078cb05 100644 --- a/vendor/k8s.io/apiserver/pkg/server/filters/cors.go +++ b/vendor/k8s.io/apiserver/pkg/server/filters/cors.go @@ -38,44 +38,76 @@ func WithCORS(handler http.Handler, allowedOriginPatterns []string, allowedMetho return handler } allowedOriginPatternsREs := allowedOriginRegexps(allowedOriginPatterns) + + // Set defaults for methods and headers if nothing was passed + if allowedMethods == nil { + allowedMethods = []string{"POST", "GET", "OPTIONS", "PUT", "DELETE", "PATCH"} + } + allowMethodsResponseHeader := strings.Join(allowedMethods, ", ") + + if allowedHeaders == nil { + allowedHeaders = []string{"Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "X-Requested-With", "If-Modified-Since"} + } + allowHeadersResponseHeader := strings.Join(allowedHeaders, ", ") + + if exposedHeaders == nil { + exposedHeaders = []string{"Date"} + } + exposeHeadersResponseHeader := strings.Join(exposedHeaders, ", ") + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { origin := req.Header.Get("Origin") - if origin != "" { - allowed := false - for _, re := range allowedOriginPatternsREs { - if allowed = re.MatchString(origin); allowed { - break - } - } - if allowed { - w.Header().Set("Access-Control-Allow-Origin", origin) - // Set defaults for methods and headers if nothing was passed - if allowedMethods == nil { - allowedMethods = []string{"POST", "GET", "OPTIONS", "PUT", "DELETE", "PATCH"} - } - if allowedHeaders == nil { - allowedHeaders = []string{"Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "X-Requested-With", "If-Modified-Since"} - } - if exposedHeaders == nil { - exposedHeaders = []string{"Date"} - } - w.Header().Set("Access-Control-Allow-Methods", strings.Join(allowedMethods, ", ")) - w.Header().Set("Access-Control-Allow-Headers", strings.Join(allowedHeaders, ", ")) - w.Header().Set("Access-Control-Expose-Headers", strings.Join(exposedHeaders, ", ")) - w.Header().Set("Access-Control-Allow-Credentials", allowCredentials) - - // Stop here if its a preflight OPTIONS request - if req.Method == "OPTIONS" { - w.WriteHeader(http.StatusNoContent) - return - } - } + if origin == "" { + handler.ServeHTTP(w, req) + return } + if !isOriginAllowed(origin, allowedOriginPatternsREs) { + handler.ServeHTTP(w, req) + return + } + + w.Header().Set("Access-Control-Allow-Origin", origin) + w.Header().Set("Access-Control-Allow-Methods", allowMethodsResponseHeader) + w.Header().Set("Access-Control-Allow-Headers", allowHeadersResponseHeader) + w.Header().Set("Access-Control-Expose-Headers", exposeHeadersResponseHeader) + w.Header().Set("Access-Control-Allow-Credentials", allowCredentials) + + // Stop here if its a preflight OPTIONS request + if req.Method == "OPTIONS" { + w.WriteHeader(http.StatusNoContent) + return + } + // Dispatch to the next handler handler.ServeHTTP(w, req) }) } +// isOriginAllowed returns true if the given origin header in the +// request is allowed CORS. +// +// From https://www.rfc-editor.org/rfc/rfc6454#page-13 +// +// a) The origin header can contain host and/or port +// serialized-origin = scheme "://" host [ ":" port ] +// +// b) In some cases, a number of origins contribute to causing the user +// agents to issue an HTTP request. In those cases, the user agent MAY +// list all the origins in the Origin header field. For example, if the +// HTTP request was initially issued by one origin but then later +// redirected by another origin, the user agent MAY inform the server +// that two origins were involved in causing the user agent to issue the +// request +// origin-list = serialized-origin *( SP serialized-origin ) +func isOriginAllowed(originHeader string, allowedOriginPatternsREs []*regexp.Regexp) bool { + for _, re := range allowedOriginPatternsREs { + if re.MatchString(originHeader) { + return true + } + } + return false +} + func allowedOriginRegexps(allowedOrigins []string) []*regexp.Regexp { res, err := compileRegexps(allowedOrigins) if err != nil { diff --git a/vendor/k8s.io/apiserver/pkg/server/filters/waitgroup.go b/vendor/k8s.io/apiserver/pkg/server/filters/waitgroup.go index 70b32c766..4cab1f86d 100644 --- a/vendor/k8s.io/apiserver/pkg/server/filters/waitgroup.go +++ b/vendor/k8s.io/apiserver/pkg/server/filters/waitgroup.go @@ -24,20 +24,34 @@ import ( "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" - utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" apirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/client-go/kubernetes/scheme" ) +// RequestWaitGroup helps with the accounting of request(s) that are in +// flight: the caller is expected to invoke Add(1) before executing the +// request handler and then invoke Done() when the handler finishes. +// NOTE: implementations must ensure that it is thread-safe +// when invoked from multiple goroutines. +type RequestWaitGroup interface { + // Add adds delta, which may be negative, similar to sync.WaitGroup. + // If Add with a positive delta happens after Wait, it will return error, + // which prevent unsafe Add. + Add(delta int) error + + // Done decrements the WaitGroup counter. + Done() +} + // WithWaitGroup adds all non long-running requests to wait group, which is used for graceful shutdown. -func WithWaitGroup(handler http.Handler, longRunning apirequest.LongRunningRequestCheck, wg *utilwaitgroup.SafeWaitGroup) http.Handler { +func WithWaitGroup(handler http.Handler, longRunning apirequest.LongRunningRequestCheck, wg RequestWaitGroup) http.Handler { // NOTE: both WithWaitGroup and WithRetryAfter must use the same exact isRequestExemptFunc 'isRequestExemptFromRetryAfter, // otherwise SafeWaitGroup might wait indefinitely and will prevent the server from shutting down gracefully. return withWaitGroup(handler, longRunning, wg, isRequestExemptFromRetryAfter) } -func withWaitGroup(handler http.Handler, longRunning apirequest.LongRunningRequestCheck, wg *utilwaitgroup.SafeWaitGroup, isRequestExemptFn isRequestExemptFunc) http.Handler { +func withWaitGroup(handler http.Handler, longRunning apirequest.LongRunningRequestCheck, wg RequestWaitGroup, isRequestExemptFn isRequestExemptFunc) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { ctx := req.Context() requestInfo, ok := apirequest.RequestInfoFrom(ctx) @@ -64,12 +78,7 @@ func withWaitGroup(handler http.Handler, longRunning apirequest.LongRunningReque // When apiserver is shutting down, signal clients to retry // There is a good chance the client hit a different server, so a tight retry is good for client responsiveness. - w.Header().Add("Retry-After", "1") - w.Header().Set("Content-Type", runtime.ContentTypeJSON) - w.Header().Set("X-Content-Type-Options", "nosniff") - statusErr := apierrors.NewServiceUnavailable("apiserver is shutting down").Status() - w.WriteHeader(int(statusErr.Code)) - fmt.Fprintln(w, runtime.EncodeOrDie(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &statusErr)) + waitGroupWriteRetryAfterToResponse(w) return } @@ -77,3 +86,12 @@ func withWaitGroup(handler http.Handler, longRunning apirequest.LongRunningReque handler.ServeHTTP(w, req) }) } + +func waitGroupWriteRetryAfterToResponse(w http.ResponseWriter) { + w.Header().Add("Retry-After", "1") + w.Header().Set("Content-Type", runtime.ContentTypeJSON) + w.Header().Set("X-Content-Type-Options", "nosniff") + statusErr := apierrors.NewServiceUnavailable("apiserver is shutting down").Status() + w.WriteHeader(int(statusErr.Code)) + fmt.Fprintln(w, runtime.EncodeOrDie(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &statusErr)) +} diff --git a/vendor/k8s.io/apiserver/pkg/server/filters/watch_termination.go b/vendor/k8s.io/apiserver/pkg/server/filters/watch_termination.go new file mode 100644 index 000000000..515f38e51 --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/server/filters/watch_termination.go @@ -0,0 +1,62 @@ +/* +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 filters + +import ( + "errors" + "net/http" + + "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" + apirequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/klog/v2" +) + +func WithWatchTerminationDuringShutdown(handler http.Handler, termination apirequest.ServerShutdownSignal, wg RequestWaitGroup) http.Handler { + if termination == nil || wg == nil { + klog.Warningf("watch termination during shutdown not attached to the handler chain") + return handler + } + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + ctx := req.Context() + requestInfo, ok := apirequest.RequestInfoFrom(ctx) + if !ok { + // if this happens, the handler chain isn't setup correctly because there is no request info + responsewriters.InternalError(w, req, errors.New("no RequestInfo found in the context")) + return + } + if !watchVerbs.Has(requestInfo.Verb) { + handler.ServeHTTP(w, req) + return + } + + if err := wg.Add(1); err != nil { + // When apiserver is shutting down, signal clients to retry + // There is a good chance the client hit a different server, so a tight retry is good for client responsiveness. + waitGroupWriteRetryAfterToResponse(w) + return + } + + // attach ServerShutdownSignal to the watch request so that the + // watch handler loop can return as soon as the server signals + // that it is shutting down. + ctx = apirequest.WithServerShutdownSignal(req.Context(), termination) + req = req.WithContext(ctx) + + defer wg.Done() + handler.ServeHTTP(w, req) + }) +} diff --git a/vendor/k8s.io/apiserver/pkg/server/filters/wrap.go b/vendor/k8s.io/apiserver/pkg/server/filters/wrap.go index d37fc49c6..a981eae78 100644 --- a/vendor/k8s.io/apiserver/pkg/server/filters/wrap.go +++ b/vendor/k8s.io/apiserver/pkg/server/filters/wrap.go @@ -55,7 +55,7 @@ func WithPanicRecovery(handler http.Handler, resolver request.RequestInfoResolve return } http.Error(w, "This request caused apiserver to panic. Look in the logs for details.", http.StatusInternalServerError) - klog.ErrorS(nil, "apiserver panic'd", "method", req.Method, "URI", req.RequestURI, "audit-ID", audit.GetAuditIDTruncated(req.Context())) + klog.ErrorS(nil, "apiserver panic'd", "method", req.Method, "URI", req.RequestURI, "auditID", audit.GetAuditIDTruncated(req.Context())) }) } diff --git a/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go b/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go index 2868187f0..52c865f8a 100644 --- a/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go +++ b/vendor/k8s.io/apiserver/pkg/server/genericapiserver.go @@ -17,6 +17,7 @@ limitations under the License. package server import ( + "context" "fmt" "net/http" gpath "path" @@ -26,12 +27,15 @@ import ( systemd "github.com/coreos/go-systemd/v22/daemon" + "golang.org/x/time/rate" apidiscoveryv2beta1 "k8s.io/api/apidiscovery/v2beta1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/managedfields" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/sets" utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup" "k8s.io/apimachinery/pkg/version" @@ -41,22 +45,19 @@ import ( genericapi "k8s.io/apiserver/pkg/endpoints" "k8s.io/apiserver/pkg/endpoints/discovery" discoveryendpoint "k8s.io/apiserver/pkg/endpoints/discovery/aggregated" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/routes" "k8s.io/apiserver/pkg/storageversion" utilfeature "k8s.io/apiserver/pkg/util/feature" - utilopenapi "k8s.io/apiserver/pkg/util/openapi" restclient "k8s.io/client-go/rest" "k8s.io/klog/v2" - openapibuilder2 "k8s.io/kube-openapi/pkg/builder" + openapibuilder3 "k8s.io/kube-openapi/pkg/builder3" openapicommon "k8s.io/kube-openapi/pkg/common" "k8s.io/kube-openapi/pkg/handler" "k8s.io/kube-openapi/pkg/handler3" openapiutil "k8s.io/kube-openapi/pkg/util" - openapiproto "k8s.io/kube-openapi/pkg/util/proto" "k8s.io/kube-openapi/pkg/validation/spec" "k8s.io/utils/clock" ) @@ -88,7 +89,7 @@ type APIGroupInfo struct { // StaticOpenAPISpec is the spec derived from the definitions of all resources installed together. // It is set during InstallAPIGroups, InstallAPIGroup, and InstallLegacyAPIGroup. - StaticOpenAPISpec *spec.Swagger + StaticOpenAPISpec map[string]*spec.Schema } func (a *APIGroupInfo) destroyStorage() { @@ -136,6 +137,10 @@ type GenericAPIServer struct { // Handler holds the handlers being used by this API server Handler *APIServerHandler + // UnprotectedDebugSocket is used to serve pprof information in a unix-domain socket. This socket is + // not protected by authentication/authorization. + UnprotectedDebugSocket *routes.DebugSocket + // listedPathProvider is a lister which provides the set of paths to show at / listedPathProvider routes.ListedPathProvider @@ -214,8 +219,14 @@ type GenericAPIServer struct { // delegationTarget is the next delegate in the chain. This is never nil. delegationTarget DelegationTarget - // HandlerChainWaitGroup allows you to wait for all chain handlers finish after the server shutdown. - HandlerChainWaitGroup *utilwaitgroup.SafeWaitGroup + // NonLongRunningRequestWaitGroup allows you to wait for all chain + // handlers associated with non long-running requests + // to complete while the server is shuting down. + NonLongRunningRequestWaitGroup *utilwaitgroup.SafeWaitGroup + // WatchRequestWaitGroup allows us to wait for all chain + // handlers associated with active watch requests to + // complete while the server is shuting down. + WatchRequestWaitGroup *utilwaitgroup.RateLimitedSafeWaitGroup // ShutdownDelayDuration allows to block shutdown for some time, e.g. until endpoints pointing to this API server // have converged on all node. During this time, the API server keeps serving, /healthz will return 200, @@ -255,6 +266,23 @@ type GenericAPIServer struct { // If enabled, after ShutdownDelayDuration elapses, any incoming request is // rejected with a 429 status code and a 'Retry-After' response. ShutdownSendRetryAfter bool + + // ShutdownWatchTerminationGracePeriod, if set to a positive value, + // is the maximum duration the apiserver will wait for all active + // watch request(s) to drain. + // Once this grace period elapses, the apiserver will no longer + // wait for any active watch request(s) in flight to drain, it will + // proceed to the next step in the graceful server shutdown process. + // If set to a positive value, the apiserver will keep track of the + // number of active watch request(s) in flight and during shutdown + // it will wait, at most, for the specified duration and allow these + // active watch requests to drain with some rate limiting in effect. + // The default is zero, which implies the apiserver will not keep + // track of active watch request(s) in flight and will not wait + // for them to drain, this maintains backward compatibility. + // This grace period is orthogonal to other grace periods, and + // it is not overridden by any other grace period. + ShutdownWatchTerminationGracePeriod time.Duration } // DelegationTarget is an interface which allows for composition of API servers with top level handling that works @@ -442,23 +470,27 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer { // | NotAcceptingNewRequest (notAcceptingNewRequestCh) // | | // | | -// | |---------------------------------------------------------| -// | | | | | -// | [without [with | | -// | ShutdownSendRetryAfter] ShutdownSendRetryAfter] | | -// | | | | | -// | | ---------------| | -// | | | | -// | | (HandlerChainWaitGroup::Wait) | -// | | | | -// | | InFlightRequestsDrained (drainedCh) | -// | | | | -// | ----------------------------------------|-----------------| -// | | | +// | |----------------------------------------------------------------------------------| +// | | | | | +// | [without [with | | +// | ShutdownSendRetryAfter] ShutdownSendRetryAfter] | | +// | | | | | +// | | ---------------| | +// | | | | +// | | |----------------|-----------------------| | +// | | | | | +// | | (NonLongRunningRequestWaitGroup::Wait) (WatchRequestWaitGroup::Wait) | +// | | | | | +// | | |------------------|---------------------| | +// | | | | +// | | InFlightRequestsDrained (drainedCh) | +// | | | | +// | |-------------------|---------------------|----------------------------------------| +// | | | // | stopHttpServerCh (AuditBackend::Shutdown()) -// | | +// | | // | listenerStoppedCh -// | | +// | | // | HTTPServerStoppedListening (httpServerStoppedListeningCh) func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { delayedStopCh := s.lifecycleSignals.AfterShutdownDelayDuration @@ -467,6 +499,14 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { // Clean up resources on shutdown. defer s.Destroy() + // If UDS profiling is enabled, start a local http server listening on that socket + if s.UnprotectedDebugSocket != nil { + go func() { + defer utilruntime.HandleCrash() + klog.Error(s.UnprotectedDebugSocket.Run(stopCh)) + }() + } + // spawn a new goroutine for closing the MuxAndDiscoveryComplete signal // registration happens during construction of the generic api server // the last server in the chain aggregates signals from the previous instances @@ -509,7 +549,7 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { // net/http waits for 1s for the peer to respond to a GO_AWAY frame, so // we should wait for a minimum of 2s shutdownTimeout = 2 * time.Second - klog.V(1).InfoS("[graceful-termination] using HTTP Server shutdown timeout", "ShutdownTimeout", shutdownTimeout) + klog.V(1).InfoS("[graceful-termination] using HTTP Server shutdown timeout", "shutdownTimeout", shutdownTimeout) } notAcceptingNewRequestCh := s.lifecycleSignals.NotAcceptingNewRequest @@ -563,15 +603,17 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { <-preShutdownHooksHasStoppedCh.Signaled() }() + // wait for all in-flight non-long running requests to finish + nonLongRunningRequestDrainedCh := make(chan struct{}) go func() { - defer klog.V(1).InfoS("[graceful-termination] shutdown event", "name", drainedCh.Name()) - defer drainedCh.Signal() + defer close(nonLongRunningRequestDrainedCh) + defer klog.V(1).Info("[graceful-termination] in-flight non long-running request(s) have drained") // wait for the delayed stopCh before closing the handler chain (it rejects everything after Wait has been called). <-notAcceptingNewRequestCh.Signaled() // Wait for all requests to finish, which are bounded by the RequestTimeout variable. - // once HandlerChainWaitGroup.Wait is invoked, the apiserver is + // once NonLongRunningRequestWaitGroup.Wait is invoked, the apiserver is // expected to reject any incoming request with a {503, Retry-After} // response via the WithWaitGroup filter. On the contrary, we observe // that incoming request(s) get a 'connection refused' error, this is @@ -583,7 +625,48 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error { // 'Server.Shutdown' will be invoked only after in-flight requests // have been drained. // TODO: can we consolidate these two modes of graceful termination? - s.HandlerChainWaitGroup.Wait() + s.NonLongRunningRequestWaitGroup.Wait() + }() + + // wait for all in-flight watches to finish + activeWatchesDrainedCh := make(chan struct{}) + go func() { + defer close(activeWatchesDrainedCh) + + <-notAcceptingNewRequestCh.Signaled() + if s.ShutdownWatchTerminationGracePeriod <= time.Duration(0) { + klog.V(1).InfoS("[graceful-termination] not going to wait for active watch request(s) to drain") + return + } + + // Wait for all active watches to finish + grace := s.ShutdownWatchTerminationGracePeriod + activeBefore, activeAfter, err := s.WatchRequestWaitGroup.Wait(func(count int) (utilwaitgroup.RateLimiter, context.Context, context.CancelFunc) { + qps := float64(count) / grace.Seconds() + // TODO: we don't want the QPS (max requests drained per second) to + // get below a certain floor value, since we want the server to + // drain the active watch requests as soon as possible. + // For now, it's hard coded to 200, and it is subject to change + // based on the result from the scale testing. + if qps < 200 { + qps = 200 + } + + ctx, cancel := context.WithTimeout(context.Background(), grace) + // We don't expect more than one token to be consumed + // in a single Wait call, so setting burst to 1. + return rate.NewLimiter(rate.Limit(qps), 1), ctx, cancel + }) + klog.V(1).InfoS("[graceful-termination] active watch request(s) have drained", + "duration", grace, "activeWatchesBefore", activeBefore, "activeWatchesAfter", activeAfter, "error", err) + }() + + go func() { + defer klog.V(1).InfoS("[graceful-termination] shutdown event", "name", drainedCh.Name()) + defer drainedCh.Signal() + + <-nonLongRunningRequestDrainedCh + <-activeWatchesDrainedCh }() klog.V(1).Info("[graceful-termination] waiting for shutdown to be initiated") @@ -653,7 +736,16 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}, shutdow } // installAPIResources is a private method for installing the REST storage backing each api groupversionresource -func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo, openAPIModels openapiproto.Models) error { +func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *APIGroupInfo, openAPIModels map[string]*spec.Schema) error { + var typeConverter managedfields.TypeConverter + + if len(openAPIModels) > 0 { + var err error + typeConverter, err = managedfields.NewTypeConverter(openAPIModels, false) + if err != nil { + return err + } + } var resourceInfos []*storageversion.ResourceInfo for _, groupVersion := range apiGroupInfo.PrioritizedVersions { if len(apiGroupInfo.VersionedResourcesStorageMap[groupVersion.Version]) == 0 { @@ -668,16 +760,7 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A if apiGroupInfo.OptionsExternalVersion != nil { apiGroupVersion.OptionsExternalVersion = apiGroupInfo.OptionsExternalVersion } - apiGroupVersion.OpenAPIModels = openAPIModels - - if openAPIModels != nil { - typeConverter, err := fieldmanager.NewTypeConverter(openAPIModels, false) - if err != nil { - return err - } - apiGroupVersion.TypeConverter = typeConverter - } - + apiGroupVersion.TypeConverter = typeConverter apiGroupVersion.MaxRequestBodyBytes = s.maxRequestBodyBytes discoveryAPIResources, r, err := apiGroupVersion.InstallREST(s.Handler.GoRestfulContainer) @@ -693,6 +776,7 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A s.AggregatedDiscoveryGroupManager.AddGroupVersion( groupVersion.Group, apidiscoveryv2beta1.APIVersionDiscovery{ + Freshness: apidiscoveryv2beta1.DiscoveryFreshnessCurrent, Version: groupVersion.Version, Resources: discoveryAPIResources, }, @@ -702,6 +786,7 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A s.AggregatedLegacyDiscoveryGroupManager.AddGroupVersion( groupVersion.Group, apidiscoveryv2beta1.APIVersionDiscovery{ + Freshness: apidiscoveryv2beta1.DiscoveryFreshnessCurrent, Version: groupVersion.Version, Resources: discoveryAPIResources, }, @@ -868,8 +953,10 @@ func NewDefaultAPIGroupInfo(group string, scheme *runtime.Scheme, parameterCodec } // getOpenAPIModels is a private method for getting the OpenAPI models -func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*APIGroupInfo) (openapiproto.Models, error) { - if s.openAPIConfig == nil { +func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*APIGroupInfo) (map[string]*spec.Schema, error) { + if s.openAPIV3Config == nil { + //!TODO: A future work should add a requirement that + // OpenAPIV3 config is required. May require some refactoring of tests. return nil, nil } pathsToIgnore := openapiutil.NewTrie(s.openAPIConfig.IgnorePrefixes) @@ -883,14 +970,14 @@ func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...* } // Build the openapi definitions for those resources and convert it to proto models - openAPISpec, err := openapibuilder2.BuildOpenAPIDefinitionsForResources(s.openAPIConfig, resourceNames...) + openAPISpec, err := openapibuilder3.BuildOpenAPIDefinitionsForResources(s.openAPIV3Config, resourceNames...) if err != nil { return nil, err } for _, apiGroupInfo := range apiGroupInfos { apiGroupInfo.StaticOpenAPISpec = openAPISpec } - return utilopenapi.ToProtoModels(openAPISpec) + return openAPISpec, nil } // getResourceNamesForGroup is a private method for getting the canonical names for each resource to build in an api group diff --git a/vendor/k8s.io/apiserver/pkg/server/lifecycle_signals.go b/vendor/k8s.io/apiserver/pkg/server/lifecycle_signals.go index ce4c1b4a6..e71de4d87 100644 --- a/vendor/k8s.io/apiserver/pkg/server/lifecycle_signals.go +++ b/vendor/k8s.io/apiserver/pkg/server/lifecycle_signals.go @@ -146,6 +146,14 @@ type lifecycleSignals struct { MuxAndDiscoveryComplete lifecycleSignal } +// ShuttingDown returns the lifecycle signal that is signaled when +// the server is not accepting any new requests. +// this is the lifecycle event that is exported to the request handler +// logic to indicate that the server is shutting down. +func (s lifecycleSignals) ShuttingDown() <-chan struct{} { + return s.NotAcceptingNewRequest.Signaled() +} + // newLifecycleSignals returns an instance of lifecycleSignals interface to be used // to coordinate lifecycle of the apiserver func newLifecycleSignals() lifecycleSignals { diff --git a/vendor/k8s.io/apiserver/pkg/server/options/authentication.go b/vendor/k8s.io/apiserver/pkg/server/options/authentication.go index 296d8530e..e9a61d30b 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/authentication.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/authentication.go @@ -76,6 +76,16 @@ func (s *RequestHeaderAuthenticationOptions) Validate() []error { allErrors = append(allErrors, err) } + if len(s.UsernameHeaders) > 0 && !caseInsensitiveHas(s.UsernameHeaders, "X-Remote-User") { + klog.Warningf("--requestheader-username-headers is set without specifying the standard X-Remote-User header - API aggregation will not work") + } + if len(s.GroupHeaders) > 0 && !caseInsensitiveHas(s.GroupHeaders, "X-Remote-Group") { + klog.Warningf("--requestheader-group-headers is set without specifying the standard X-Remote-Group header - API aggregation will not work") + } + if len(s.ExtraHeaderPrefixes) > 0 && !caseInsensitiveHas(s.ExtraHeaderPrefixes, "X-Remote-Extra-") { + klog.Warningf("--requestheader-extra-headers-prefix is set without specifying the standard X-Remote-Extra- header prefix - API aggregation will not work") + } + return allErrors } @@ -89,6 +99,15 @@ func checkForWhiteSpaceOnly(flag string, headerNames ...string) error { return nil } +func caseInsensitiveHas(headers []string, header string) bool { + for _, h := range headers { + if strings.EqualFold(h, header) { + return true + } + } + return false +} + func (s *RequestHeaderAuthenticationOptions) AddFlags(fs *pflag.FlagSet) { if s == nil { return @@ -357,6 +376,7 @@ func (s *DelegatingAuthenticationOptions) ApplyTo(authenticationInfo *server.Aut } if requestHeaderConfig != nil { cfg.RequestHeaderConfig = requestHeaderConfig + authenticationInfo.RequestHeaderConfig = requestHeaderConfig if err = authenticationInfo.ApplyClientCert(cfg.RequestHeaderConfig.CAContentProvider, servingInfo); err != nil { return fmt.Errorf("unable to load request-header-client-ca-file: %v", err) } diff --git a/vendor/k8s.io/apiserver/pkg/server/options/authorization.go b/vendor/k8s.io/apiserver/pkg/server/options/authorization.go index c31ce47f8..9b2dcb3ff 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/authorization.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/authorization.go @@ -38,9 +38,8 @@ import ( // DelegatingAuthorizationOptions provides an easy way for composing API servers to delegate their authorization to // the root kube API server. // WARNING: never assume that every authenticated incoming request already does authorization. -// -// The aggregator in the kube API server does this today, but this behaviour is not -// guaranteed in the future. +// The aggregator in the kube API server does this today, but this behaviour is not +// guaranteed in the future. type DelegatingAuthorizationOptions struct { // RemoteKubeConfigFile is the file to use to connect to a "normal" kube API server which hosts the // SubjectAccessReview.authorization.k8s.io endpoint for checking tokens. diff --git a/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go b/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go index c95717c53..796cc6b03 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go @@ -36,6 +36,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/serializer" utilerrors "k8s.io/apimachinery/pkg/util/errors" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/wait" apiserverconfig "k8s.io/apiserver/pkg/apis/config" apiserverconfigv1 "k8s.io/apiserver/pkg/apis/config/v1" @@ -46,9 +47,12 @@ import ( aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope" envelopekmsv2 "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" "k8s.io/apiserver/pkg/storage/value/encrypt/identity" "k8s.io/apiserver/pkg/storage/value/encrypt/secretbox" utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/klog/v2" + kmsservice "k8s.io/kms/pkg/service" ) const ( @@ -57,11 +61,46 @@ const ( secretboxTransformerPrefixV1 = "k8s:enc:secretbox:v1:" kmsTransformerPrefixV1 = "k8s:enc:kms:v1:" kmsTransformerPrefixV2 = "k8s:enc:kms:v2:" - kmsPluginHealthzNegativeTTL = 3 * time.Second - kmsPluginHealthzPositiveTTL = 20 * time.Second - kmsAPIVersionV1 = "v1" - kmsAPIVersionV2 = "v2" - kmsReloadHealthCheckName = "kms-providers" + + // these constants relate to how the KMS v2 plugin status poll logic + // and the DEK generation logic behave. In particular, the positive + // interval and max TTL are closely related as the difference between + // these values defines the worst case window in which the write DEK + // could expire due to the plugin going into an error state. The + // worst case window divided by the negative interval defines the + // minimum amount of times the server will attempt to return to a + // healthy state before the DEK expires and writes begin to fail. + // + // For now, these values are kept small and hardcoded to support being + // able to perform a "passive" storage migration while tolerating some + // amount of plugin downtime. + // + // With the current approach, a user can update the key ID their plugin + // is using and then can simply schedule a migration for 3 + N + M minutes + // later where N is how long it takes their plugin to pick up new config + // and M is extra buffer to allow the API server to process the config. + // At that point, they are guaranteed to either migrate to the new key + // or get errors during the migration. + // + // If the API server coasted forever on the last DEK, they would need + // to actively check if it had observed the new key ID before starting + // a migration - otherwise it could keep using the old DEK and their + // storage migration would not do what they thought it did. + kmsv2PluginHealthzPositiveInterval = 1 * time.Minute + kmsv2PluginHealthzNegativeInterval = 10 * time.Second + kmsv2PluginWriteDEKMaxTTL = 3 * time.Minute + + kmsPluginHealthzNegativeTTL = 3 * time.Second + kmsPluginHealthzPositiveTTL = 20 * time.Second + kmsAPIVersionV1 = "v1" + kmsAPIVersionV2 = "v2" + // this name is used for two different healthz endpoints: + // - when one or more KMS v2 plugins are in use and no KMS v1 plugins are in use + // in this case, all v2 plugins are probed via this single endpoint + // - when automatic reload of encryption config is enabled + // in this case, all KMS plugins are probed via this single endpoint + // the endpoint is present even if there are no KMS plugins configured (it is a no-op then) + kmsReloadHealthCheckName = "kms-providers" ) type kmsPluginHealthzResponse struct { @@ -78,9 +117,10 @@ type kmsPluginProbe struct { } type kmsv2PluginProbe struct { + state atomic.Pointer[envelopekmsv2.State] name string ttl time.Duration - service envelopekmsv2.Service + service kmsservice.Service lastResponse *kmsPluginHealthzResponse l *sync.Mutex } @@ -133,15 +173,16 @@ type EncryptionConfiguration struct { } // LoadEncryptionConfig parses and validates the encryption config specified by filepath. -// It may launch multiple go routines whose lifecycle is controlled by stopCh. +// It may launch multiple go routines whose lifecycle is controlled by ctx. +// In case of an error, the caller is responsible for canceling ctx to clean up any go routines that may have been launched. // If reload is true, or KMS v2 plugins are used with no KMS v1 plugins, the returned slice of health checkers will always be of length 1. -func LoadEncryptionConfig(filepath string, reload bool, stopCh <-chan struct{}) (*EncryptionConfiguration, error) { +func LoadEncryptionConfig(ctx context.Context, filepath string, reload bool) (*EncryptionConfiguration, error) { config, contentHash, err := loadConfig(filepath, reload) if err != nil { return nil, fmt.Errorf("error while parsing file: %w", err) } - transformers, kmsHealthChecks, kmsUsed, err := getTransformerOverridesAndKMSPluginHealthzCheckers(config, stopCh) + transformers, kmsHealthChecks, kmsUsed, err := getTransformerOverridesAndKMSPluginHealthzCheckers(ctx, config) if err != nil { return nil, fmt.Errorf("error while building transformers: %w", err) } @@ -150,7 +191,7 @@ func LoadEncryptionConfig(filepath string, reload bool, stopCh <-chan struct{}) kmsHealthChecks = []healthz.HealthChecker{kmsHealthChecker(kmsHealthChecks)} } - // KMSTimeout is the duration we will wait before closing old transformers. + // KMSCloseGracePeriod is the duration we will wait before closing old transformers. // The way we calculate is as follows: // 1. Sum all timeouts across all KMS plugins. (check kmsPrefixTransformer for differences between v1 and v2) // 2. Multiply that by 2 (to allow for some buffer) @@ -160,12 +201,15 @@ func LoadEncryptionConfig(filepath string, reload bool, stopCh <-chan struct{}) HealthChecks: kmsHealthChecks, EncryptionFileContentHash: contentHash, KMSCloseGracePeriod: 2 * kmsUsed.kmsTimeoutSum, - }, err + }, nil } -func getTransformerOverridesAndKMSPluginHealthzCheckers(config *apiserverconfig.EncryptionConfiguration, stopCh <-chan struct{}) (map[schema.GroupResource]value.Transformer, []healthz.HealthChecker, *kmsState, error) { +// getTransformerOverridesAndKMSPluginHealthzCheckers creates the set of transformers and KMS healthz checks based on the given config. +// It may launch multiple go routines whose lifecycle is controlled by ctx. +// In case of an error, the caller is responsible for canceling ctx to clean up any go routines that may have been launched. +func getTransformerOverridesAndKMSPluginHealthzCheckers(ctx context.Context, config *apiserverconfig.EncryptionConfiguration) (map[schema.GroupResource]value.Transformer, []healthz.HealthChecker, *kmsState, error) { var kmsHealthChecks []healthz.HealthChecker - transformers, probes, kmsUsed, err := getTransformerOverridesAndKMSPluginProbes(config, stopCh) + transformers, probes, kmsUsed, err := getTransformerOverridesAndKMSPluginProbes(ctx, config) if err != nil { return nil, nil, nil, err } @@ -181,7 +225,10 @@ type healthChecker interface { toHealthzCheck(idx int) healthz.HealthChecker } -func getTransformerOverridesAndKMSPluginProbes(config *apiserverconfig.EncryptionConfiguration, stopCh <-chan struct{}) (map[schema.GroupResource]value.Transformer, []healthChecker, *kmsState, error) { +// getTransformerOverridesAndKMSPluginProbes creates the set of transformers and KMS probes based on the given config. +// It may launch multiple go routines whose lifecycle is controlled by ctx. +// In case of an error, the caller is responsible for canceling ctx to clean up any go routines that may have been launched. +func getTransformerOverridesAndKMSPluginProbes(ctx context.Context, config *apiserverconfig.EncryptionConfiguration) (map[schema.GroupResource]value.Transformer, []healthChecker, *kmsState, error) { resourceToPrefixTransformer := map[schema.GroupResource][]value.PrefixTransformer{} var probes []healthChecker var kmsUsed kmsState @@ -190,21 +237,32 @@ func getTransformerOverridesAndKMSPluginProbes(config *apiserverconfig.Encryptio for _, resourceConfig := range config.Resources { resourceConfig := resourceConfig - transformers, p, used, err := prefixTransformersAndProbes(resourceConfig, stopCh) + transformers, p, used, err := prefixTransformersAndProbes(ctx, resourceConfig) if err != nil { return nil, nil, nil, err } - kmsUsed.v1Used = kmsUsed.v1Used || used.v1Used - kmsUsed.v2Used = kmsUsed.v2Used || used.v2Used - - kmsUsed.kmsTimeoutSum += used.kmsTimeoutSum + kmsUsed.accumulate(used) // For each resource, create a list of providers to use for _, resource := range resourceConfig.Resources { resource := resource gr := schema.ParseGroupResource(resource) - resourceToPrefixTransformer[gr] = append( - resourceToPrefixTransformer[gr], transformers...) + + // check if resource is masked by *.group rule + anyResourceInGroup := schema.GroupResource{Group: gr.Group, Resource: "*"} + if _, masked := resourceToPrefixTransformer[anyResourceInGroup]; masked { + // an earlier rule already configured a transformer for *.group, masking this rule + // return error since this is not allowed + return nil, nil, nil, fmt.Errorf("resource %q is masked by earlier rule %q", grYAMLString(gr), grYAMLString(anyResourceInGroup)) + } + + if _, masked := resourceToPrefixTransformer[anyGroupAnyResource]; masked { + // an earlier rule already configured a transformer for *.*, masking this rule + // return error since this is not allowed + return nil, nil, nil, fmt.Errorf("resource %q is masked by earlier rule %q", grYAMLString(gr), grYAMLString(anyGroupAnyResource)) + } + + resourceToPrefixTransformer[gr] = append(resourceToPrefixTransformer[gr], transformers...) } probes = append(probes, p...) @@ -252,7 +310,7 @@ func (h *kmsv2PluginProbe) check(ctx context.Context) error { h.l.Lock() defer h.l.Unlock() - if (time.Since(h.lastResponse.received)) < h.ttl { + if time.Since(h.lastResponse.received) < h.ttl { return h.lastResponse.err } @@ -263,7 +321,7 @@ func (h *kmsv2PluginProbe) check(ctx context.Context) error { return fmt.Errorf("failed to perform status section of the healthz check for KMS Provider %s, error: %w", h.name, err) } - if err := isKMSv2ProviderHealthy(h.name, p); err != nil { + if err := h.isKMSv2ProviderHealthyAndMaybeRotateDEK(ctx, p); err != nil { h.lastResponse = &kmsPluginHealthzResponse{err: err, received: time.Now()} h.ttl = kmsPluginHealthzNegativeTTL return err @@ -274,8 +332,93 @@ func (h *kmsv2PluginProbe) check(ctx context.Context) error { return nil } -// isKMSv2ProviderHealthy checks if the KMSv2-Plugin is healthy. -func isKMSv2ProviderHealthy(name string, response *envelopekmsv2.StatusResponse) error { +// rotateDEKOnKeyIDChange tries to rotate to a new DEK if the key ID returned by Status does not match the +// current state. If a successful rotation is performed, the new DEK and keyID overwrite the existing state. +// On any failure during rotation (including mismatch between status and encrypt calls), the current state is +// preserved and will remain valid to use for encryption until its expiration (the system attempts to coast). +// If the key ID returned by Status matches the current state, the expiration of the current state is extended +// and no rotation is performed. +func (h *kmsv2PluginProbe) rotateDEKOnKeyIDChange(ctx context.Context, statusKeyID, uid string) error { + // we do not check ValidateEncryptCapability here because it is fine to re-use an old key + // that was marked as expired during an unhealthy period. As long as the key ID matches + // what we expect then there is no need to rotate here. + state, errState := h.getCurrentState() + + // allow reads indefinitely in all cases + // allow writes indefinitely as long as there is no error + // allow writes for only up to kmsv2PluginWriteDEKMaxTTL from now when there are errors + // we start the timer before we make the network call because kmsv2PluginWriteDEKMaxTTL is meant to be the upper bound + expirationTimestamp := envelopekmsv2.NowFunc().Add(kmsv2PluginWriteDEKMaxTTL) + + // state is valid and status keyID is unchanged from when we generated this DEK so there is no need to rotate it + // just move the expiration of the current state forward by the reuse interval + if errState == nil && state.KeyID == statusKeyID { + state.ExpirationTimestamp = expirationTimestamp + h.state.Store(&state) + return nil + } + + transformer, resp, cacheKey, errGen := envelopekmsv2.GenerateTransformer(ctx, uid, h.service) + + if resp == nil { + resp = &kmsservice.EncryptResponse{} // avoid nil panics + } + + // happy path, should be the common case + // TODO maybe add success metrics? + if errGen == nil && resp.KeyID == statusKeyID { + h.state.Store(&envelopekmsv2.State{ + Transformer: transformer, + EncryptedDEK: resp.Ciphertext, + KeyID: resp.KeyID, + Annotations: resp.Annotations, + UID: uid, + ExpirationTimestamp: expirationTimestamp, + CacheKey: cacheKey, + }) + klog.V(6).InfoS("successfully rotated DEK", + "uid", uid, + "newKeyID", resp.KeyID, + "oldKeyID", state.KeyID, + "expirationTimestamp", expirationTimestamp.Format(time.RFC3339), + ) + return nil + } + + return fmt.Errorf("failed to rotate DEK uid=%q, errState=%v, errGen=%v, statusKeyID=%q, encryptKeyID=%q, stateKeyID=%q, expirationTimestamp=%s", + uid, errState, errGen, statusKeyID, resp.KeyID, state.KeyID, state.ExpirationTimestamp.Format(time.RFC3339)) +} + +// getCurrentState returns the latest state from the last status and encrypt calls. +// If the returned error is nil, the state is considered valid indefinitely for read requests. +// For write requests, the caller must also check that state.ValidateEncryptCapability does not error. +func (h *kmsv2PluginProbe) getCurrentState() (envelopekmsv2.State, error) { + state := *h.state.Load() + + if state.Transformer == nil { + return envelopekmsv2.State{}, fmt.Errorf("got unexpected nil transformer") + } + + if len(state.EncryptedDEK) == 0 { + return envelopekmsv2.State{}, fmt.Errorf("got unexpected empty EncryptedDEK") + } + + if len(state.KeyID) == 0 { + return envelopekmsv2.State{}, fmt.Errorf("got unexpected empty keyID") + } + + if state.ExpirationTimestamp.IsZero() { + return envelopekmsv2.State{}, fmt.Errorf("got unexpected zero expirationTimestamp") + } + + if len(state.CacheKey) == 0 { + return envelopekmsv2.State{}, fmt.Errorf("got unexpected empty cacheKey") + } + + return state, nil +} + +func (h *kmsv2PluginProbe) isKMSv2ProviderHealthyAndMaybeRotateDEK(ctx context.Context, response *kmsservice.StatusResponse) error { var errs []error if response.Healthz != "ok" { errs = append(errs, fmt.Errorf("got unexpected healthz status: %s", response.Healthz)) @@ -283,12 +426,18 @@ func isKMSv2ProviderHealthy(name string, response *envelopekmsv2.StatusResponse) if response.Version != envelopekmsv2.KMSAPIVersion { errs = append(errs, fmt.Errorf("expected KMSv2 API version %s, got %s", envelopekmsv2.KMSAPIVersion, response.Version)) } - if len(response.KeyID) == 0 { - errs = append(errs, fmt.Errorf("expected KMSv2 KeyID to be set, got %s", response.KeyID)) + + if errCode, err := envelopekmsv2.ValidateKeyID(response.KeyID); err != nil { + metrics.RecordInvalidKeyIDFromStatus(h.name, string(errCode)) + errs = append(errs, fmt.Errorf("got invalid KMSv2 KeyID %q: %w", response.KeyID, err)) + } else { + metrics.RecordKeyIDFromStatus(h.name, response.KeyID) + // unconditionally append as we filter out nil errors below + errs = append(errs, h.rotateDEKOnKeyIDChange(ctx, response.KeyID, string(uuid.NewUUID()))) } if err := utilerrors.Reduce(utilerrors.NewAggregate(errs)); err != nil { - return fmt.Errorf("kmsv2 Provider %s is not healthy, error: %w", name, err) + return fmt.Errorf("kmsv2 Provider %s is not healthy, error: %w", h.name, err) } return nil } @@ -316,7 +465,7 @@ func loadConfig(filepath string, reload bool) (*apiserverconfig.EncryptionConfig configObj, gvk, err := codecs.UniversalDecoder().Decode(data, nil, nil) if err != nil { - return nil, "", err + return nil, "", fmt.Errorf("error decoding encryption provider configuration file %q: %w", filepath, err) } config, ok := configObj.(*apiserverconfig.EncryptionConfiguration) if !ok { @@ -326,7 +475,10 @@ func loadConfig(filepath string, reload bool) (*apiserverconfig.EncryptionConfig return config, computeEncryptionConfigHash(data), validation.ValidateEncryptionConfiguration(config, reload).ToAggregate() } -func prefixTransformersAndProbes(config apiserverconfig.ResourceConfiguration, stopCh <-chan struct{}) ([]value.PrefixTransformer, []healthChecker, *kmsState, error) { +// prefixTransformersAndProbes creates the set of transformers and KMS probes based on the given resource config. +// It may launch multiple go routines whose lifecycle is controlled by ctx. +// In case of an error, the caller is responsible for canceling ctx to clean up any go routines that may have been launched. +func prefixTransformersAndProbes(ctx context.Context, config apiserverconfig.ResourceConfiguration) ([]value.PrefixTransformer, []healthChecker, *kmsState, error) { var transformers []value.PrefixTransformer var probes []healthChecker var kmsUsed kmsState @@ -345,20 +497,19 @@ func prefixTransformersAndProbes(config apiserverconfig.ResourceConfiguration, s transformer, transformerErr = aesPrefixTransformer(provider.AESGCM, aestransformer.NewGCMTransformer, aesGCMTransformerPrefixV1) case provider.AESCBC != nil: - transformer, transformerErr = aesPrefixTransformer(provider.AESCBC, aestransformer.NewCBCTransformer, aesCBCTransformerPrefixV1) + cbcTransformer := func(block cipher.Block) (value.Transformer, error) { + return aestransformer.NewCBCTransformer(block), nil + } + transformer, transformerErr = aesPrefixTransformer(provider.AESCBC, cbcTransformer, aesCBCTransformerPrefixV1) case provider.Secretbox != nil: transformer, transformerErr = secretboxPrefixTransformer(provider.Secretbox) case provider.KMS != nil: - transformer, probe, used, transformerErr = kmsPrefixTransformer(provider.KMS, stopCh) + transformer, probe, used, transformerErr = kmsPrefixTransformer(ctx, provider.KMS) if transformerErr == nil { probes = append(probes, probe) - kmsUsed.v1Used = kmsUsed.v1Used || used.v1Used - kmsUsed.v2Used = kmsUsed.v2Used || used.v2Used - - // calculate the maximum timeout for all KMS providers - kmsUsed.kmsTimeoutSum += used.kmsTimeoutSum + kmsUsed.accumulate(used) } case provider.Identity != nil: @@ -381,7 +532,7 @@ func prefixTransformersAndProbes(config apiserverconfig.ResourceConfiguration, s return transformers, probes, &kmsUsed, nil } -type blockTransformerFunc func(cipher.Block) value.Transformer +type blockTransformerFunc func(cipher.Block) (value.Transformer, error) func aesPrefixTransformer(config *apiserverconfig.AESConfiguration, fn blockTransformerFunc, prefix string) (value.PrefixTransformer, error) { var result value.PrefixTransformer @@ -405,17 +556,21 @@ func aesPrefixTransformer(config *apiserverconfig.AESConfiguration, fn blockTran keyData := keyData key, err := base64.StdEncoding.DecodeString(keyData.Secret) if err != nil { - return result, fmt.Errorf("could not obtain secret for named key %s: %s", keyData.Name, err) + return result, fmt.Errorf("could not obtain secret for named key %s: %w", keyData.Name, err) } block, err := aes.NewCipher(key) if err != nil { - return result, fmt.Errorf("error while creating cipher for named key %s: %s", keyData.Name, err) + return result, fmt.Errorf("error while creating cipher for named key %s: %w", keyData.Name, err) + } + transformer, err := fn(block) + if err != nil { + return result, fmt.Errorf("error while creating transformer for named key %s: %w", keyData.Name, err) } // Create a new PrefixTransformer for this key keyTransformers = append(keyTransformers, value.PrefixTransformer{ - Transformer: fn(block), + Transformer: transformer, Prefix: []byte(keyData.Name + ":"), }) } @@ -497,10 +652,20 @@ type kmsState struct { kmsTimeoutSum time.Duration } -func kmsPrefixTransformer(config *apiserverconfig.KMSConfiguration, stopCh <-chan struct{}) (value.PrefixTransformer, healthChecker, *kmsState, error) { - // we ignore the cancel func because this context should only be canceled when stopCh is closed - ctx, _ := wait.ContextForChannel(stopCh) +// accumulate computes the KMS state by: +// - determining which KMS plugin versions are in use +// - calculating kmsTimeoutSum which is used as transformTracker.kmsCloseGracePeriod +// DynamicTransformers.Set waits for this period before closing old transformers after a config reload +func (s *kmsState) accumulate(other *kmsState) { + s.v1Used = s.v1Used || other.v1Used + s.v2Used = s.v2Used || other.v2Used + s.kmsTimeoutSum += other.kmsTimeoutSum +} +// kmsPrefixTransformer creates a KMS transformer and probe based on the given KMS config. +// It may launch multiple go routines whose lifecycle is controlled by ctx. +// In case of an error, the caller is responsible for canceling ctx to clean up any go routines that may have been launched. +func kmsPrefixTransformer(ctx context.Context, config *apiserverconfig.KMSConfiguration) (value.PrefixTransformer, healthChecker, *kmsState, error) { kmsName := config.Name switch config.APIVersion { case kmsAPIVersionV1: @@ -530,7 +695,7 @@ func kmsPrefixTransformer(config *apiserverconfig.KMSConfiguration, stopCh <-cha return value.PrefixTransformer{}, nil, nil, fmt.Errorf("could not configure KMSv2 plugin %q, KMSv2 feature is not enabled", kmsName) } - envelopeService, err := EnvelopeKMSv2ServiceFactory(ctx, config.Endpoint, config.Timeout.Duration) + envelopeService, err := EnvelopeKMSv2ServiceFactory(ctx, config.Endpoint, config.Name, config.Timeout.Duration) if err != nil { return value.PrefixTransformer{}, nil, nil, fmt.Errorf("could not configure KMSv2-Plugin's probe %q, error: %w", kmsName, err) } @@ -542,10 +707,49 @@ func kmsPrefixTransformer(config *apiserverconfig.KMSConfiguration, stopCh <-cha l: &sync.Mutex{}, lastResponse: &kmsPluginHealthzResponse{}, } + // initialize state so that Load always works + probe.state.Store(&envelopekmsv2.State{}) + + runProbeCheckAndLog := func(ctx context.Context) error { + if err := probe.check(ctx); err != nil { + klog.VDepth(1, 2).ErrorS(err, "kms plugin failed health check probe", "name", kmsName) + return err + } + return nil + } + + // on the happy path where the plugin is healthy and available on server start, + // prime keyID and DEK by running the check inline once (this also prevents unit tests from flaking) + // ignore the error here since we want to support the plugin starting up async with the API server + _ = runProbeCheckAndLog(ctx) + // make sure that the plugin's key ID is reasonably up-to-date + // also, make sure that our DEK is up-to-date to with said key ID (if it expires the server will fail all writes) + // if this background loop ever stops running, the server will become unfunctional after kmsv2PluginWriteDEKMaxTTL + go wait.PollUntilWithContext( + ctx, + kmsv2PluginHealthzPositiveInterval, + func(ctx context.Context) (bool, error) { + if err := runProbeCheckAndLog(ctx); err == nil { + return false, nil + } + + // TODO add integration test for quicker error poll on failure + // if we fail, block the outer polling and start a new quicker poll inline + // this limits the chance that our DEK expires during a transient failure + _ = wait.PollUntilWithContext( + ctx, + kmsv2PluginHealthzNegativeInterval, + func(ctx context.Context) (bool, error) { + return runProbeCheckAndLog(ctx) == nil, nil + }, + ) + + return false, nil + }) // using AES-GCM by default for encrypting data with KMSv2 transformer := value.PrefixTransformer{ - Transformer: envelopekmsv2.NewEnvelopeTransformer(envelopeService, int(*config.CacheSize), aestransformer.NewGCMTransformer), + Transformer: envelopekmsv2.NewEnvelopeTransformer(envelopeService, kmsName, probe.getCurrentState), Prefix: []byte(kmsTransformerPrefixV2 + kmsName + ":"), } @@ -560,12 +764,17 @@ func kmsPrefixTransformer(config *apiserverconfig.KMSConfiguration, stopCh <-cha } func envelopePrefixTransformer(config *apiserverconfig.KMSConfiguration, envelopeService envelope.Service, prefix string) value.PrefixTransformer { - baseTransformerFunc := func(block cipher.Block) value.Transformer { + baseTransformerFunc := func(block cipher.Block) (value.Transformer, error) { + gcm, err := aestransformer.NewGCMTransformer(block) + if err != nil { + return nil, err + } + // v1.24: write using AES-CBC only but support reads via AES-CBC and AES-GCM (so we can move to AES-GCM) // v1.25: write using AES-GCM only but support reads via AES-GCM and fallback to AES-CBC for backwards compatibility // TODO(aramase): Post v1.25: We cannot drop CBC read support until we automate storage migration. // We could have a release note that hard requires users to perform storage migration. - return unionTransformers{aestransformer.NewGCMTransformer(block), aestransformer.NewCBCTransformer(block)} + return unionTransformers{gcm, aestransformer.NewCBCTransformer(block)}, nil } return value.PrefixTransformer{ @@ -606,6 +815,7 @@ func computeEncryptionConfigHash(data []byte) string { return fmt.Sprintf("%x", sha256.Sum256(data)) } +var _ ResourceTransformers = &DynamicTransformers{} var _ healthz.HealthChecker = &DynamicTransformers{} // DynamicTransformers holds transformers that may be dynamically updated via a single external actor, likely a controller. @@ -704,27 +914,49 @@ func (r *resourceTransformer) TransformToStorage(ctx context.Context, data []byt } func (r *resourceTransformer) transformer() value.Transformer { - transformer := r.transformTracker.Load().(*transformTracker).transformerOverrides[r.resource] - if transformer == nil { - return identity.NewEncryptCheckTransformer() - } - return transformer + return transformerFromOverrides(r.transformTracker.Load().(*transformTracker).transformerOverrides, r.resource) } type ResourceTransformers interface { TransformerForResource(resource schema.GroupResource) value.Transformer } -var _ ResourceTransformers = &DynamicTransformers{} var _ ResourceTransformers = &StaticTransformers{} type StaticTransformers map[schema.GroupResource]value.Transformer -// StaticTransformers func (s StaticTransformers) TransformerForResource(resource schema.GroupResource) value.Transformer { - transformer := s[resource] - if transformer == nil { - return identity.NewEncryptCheckTransformer() - } - return transformer + return transformerFromOverrides(s, resource) +} + +var anyGroupAnyResource = schema.GroupResource{ + Group: "*", + Resource: "*", +} + +func transformerFromOverrides(transformerOverrides map[schema.GroupResource]value.Transformer, resource schema.GroupResource) value.Transformer { + if transformer := transformerOverrides[resource]; transformer != nil { + return transformer + } + + if transformer := transformerOverrides[schema.GroupResource{ + Group: resource.Group, + Resource: "*", + }]; transformer != nil { + return transformer + } + + if transformer := transformerOverrides[anyGroupAnyResource]; transformer != nil { + return transformer + } + + return identity.NewEncryptCheckTransformer() +} + +func grYAMLString(gr schema.GroupResource) string { + if gr.Group == "" && gr.Resource == "*" { + return "*." + } + + return gr.String() } diff --git a/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/controller/controller.go b/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/controller/controller.go index 35fc1dea0..b8c66826b 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/controller/controller.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig/controller/controller.go @@ -49,27 +49,22 @@ type DynamicKMSEncryptionConfigContent struct { // dynamicTransformers updates the transformers when encryption config file changes. dynamicTransformers *encryptionconfig.DynamicTransformers - - // stopCh used here is a lifecycle signal of genericapiserver already drained while shutting down. - stopCh <-chan struct{} } -// NewDynamicKMSEncryptionConfiguration returns controller that dynamically reacts to changes in encryption config file. -func NewDynamicKMSEncryptionConfiguration( +// NewDynamicEncryptionConfiguration returns controller that dynamically reacts to changes in encryption config file. +func NewDynamicEncryptionConfiguration( name, filePath string, dynamicTransformers *encryptionconfig.DynamicTransformers, configContentHash string, - stopCh <-chan struct{}, ) *DynamicKMSEncryptionConfigContent { encryptionConfig := &DynamicKMSEncryptionConfigContent{ name: name, filePath: filePath, lastLoadedEncryptionConfigHash: configContentHash, dynamicTransformers: dynamicTransformers, - stopCh: stopCh, - queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), fmt.Sprintf("%s-hot-reload", name)), + queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), name), } - encryptionConfig.queue.Add(workqueueKey) + encryptionConfig.queue.Add(workqueueKey) // to avoid missing any file changes that occur in between the initial load and Run return encryptionConfig } @@ -83,21 +78,21 @@ func (d *DynamicKMSEncryptionConfigContent) Run(ctx context.Context) { defer klog.InfoS("Shutting down controller", "name", d.name) // start worker for processing content - go wait.Until(d.runWorker, time.Second, ctx.Done()) + go wait.UntilWithContext(ctx, d.runWorker, time.Second) // start the loop that watches the encryption config file until stopCh is closed. - go wait.Until(func() { - if err := d.watchEncryptionConfigFile(ctx.Done()); err != nil { + go wait.UntilWithContext(ctx, func(ctx context.Context) { + if err := d.watchEncryptionConfigFile(ctx); err != nil { // if there is an error while setting up or handling the watches, this will ensure that we will process the config file. defer d.queue.Add(workqueueKey) klog.ErrorS(err, "Failed to watch encryption config file, will retry later") } - }, time.Second, ctx.Done()) + }, time.Second) <-ctx.Done() } -func (d *DynamicKMSEncryptionConfigContent) watchEncryptionConfigFile(stopCh <-chan struct{}) error { +func (d *DynamicKMSEncryptionConfigContent) watchEncryptionConfigFile(ctx context.Context) error { watcher, err := fsnotify.NewWatcher() if err != nil { return fmt.Errorf("error creating fsnotify watcher: %w", err) @@ -116,7 +111,7 @@ func (d *DynamicKMSEncryptionConfigContent) watchEncryptionConfigFile(stopCh <-c } case err := <-watcher.Errors: return fmt.Errorf("received fsnotify error: %w", err) - case <-stopCh: + case <-ctx.Done(): return nil } } @@ -142,13 +137,13 @@ func (d *DynamicKMSEncryptionConfigContent) handleWatchEvent(event fsnotify.Even } // runWorker to process file content -func (d *DynamicKMSEncryptionConfigContent) runWorker() { - for d.processNextWorkItem() { +func (d *DynamicKMSEncryptionConfigContent) runWorker(ctx context.Context) { + for d.processNextWorkItem(ctx) { } } // processNextWorkItem processes file content when there is a message in the queue. -func (d *DynamicKMSEncryptionConfigContent) processNextWorkItem() bool { +func (d *DynamicKMSEncryptionConfigContent) processNextWorkItem(serverCtx context.Context) bool { // key here is dummy item in the queue to trigger file content processing. key, quit := d.queue.Get() if quit { @@ -163,12 +158,15 @@ func (d *DynamicKMSEncryptionConfigContent) processNextWorkItem() bool { configChanged bool ) - // get context to close the new transformers. - ctx, closeTransformers := wait.ContextForChannel(d.stopCh) + // get context to close the new transformers (on error cases and on the next reload) + // serverCtx is attached to the API server's lifecycle so we will always close transformers on shut down + ctx, closeTransformers := context.WithCancel(serverCtx) defer func() { // TODO: increment success metric when updatedEffectiveConfig=true + // TODO can work queue metrics help here? + if !updatedEffectiveConfig { // avoid leaking if we're not using the newly constructed transformers (due to an error or them not being changed) closeTransformers() @@ -222,7 +220,7 @@ func (d *DynamicKMSEncryptionConfigContent) processEncryptionConfig(ctx context. err error, ) { // this code path will only execute if reload=true. So passing true explicitly. - encryptionConfiguration, err = encryptionconfig.LoadEncryptionConfig(d.filePath, true, ctx.Done()) + encryptionConfiguration, err = encryptionconfig.LoadEncryptionConfig(ctx, d.filePath, true) if err != nil { return nil, false, err } @@ -247,7 +245,12 @@ func (d *DynamicKMSEncryptionConfigContent) validateNewTransformersHealth( kmsPluginCloseGracePeriod = 10 * time.Second } - pollErr := wait.PollImmediate(100*time.Millisecond, kmsPluginCloseGracePeriod, func() (bool, error) { + // really make sure that the immediate check does not hang + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, kmsPluginCloseGracePeriod) + defer cancel() + + pollErr := wait.PollImmediateWithContext(ctx, 100*time.Millisecond, kmsPluginCloseGracePeriod, func(ctx context.Context) (bool, error) { // create a fake http get request to health check endpoint req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("/healthz/%s", kmsPluginHealthzCheck.Name()), nil) if err != nil { diff --git a/vendor/k8s.io/apiserver/pkg/server/options/etcd.go b/vendor/k8s.io/apiserver/pkg/server/options/etcd.go index a570efc61..6aabbf255 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/etcd.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/etcd.go @@ -17,6 +17,7 @@ limitations under the License. package options import ( + "context" "fmt" "net/http" "strconv" @@ -33,7 +34,7 @@ import ( "k8s.io/apiserver/pkg/server" "k8s.io/apiserver/pkg/server/healthz" "k8s.io/apiserver/pkg/server/options/encryptionconfig" - kmsconfigcontroller "k8s.io/apiserver/pkg/server/options/encryptionconfig/controller" + encryptionconfigcontroller "k8s.io/apiserver/pkg/server/options/encryptionconfig/controller" serverstorage "k8s.io/apiserver/pkg/server/storage" "k8s.io/apiserver/pkg/storage/storagebackend" storagefactory "k8s.io/apiserver/pkg/storage/storagebackend/factory" @@ -228,10 +229,11 @@ func (s *EtcdOptions) Complete( } if len(s.EncryptionProviderConfigFilepath) != 0 { - ctxTransformers, closeTransformers := wait.ContextForChannel(stopCh) - ctxServer, _ := wait.ContextForChannel(stopCh) // explicitly ignore cancel here because we do not own the server's lifecycle + ctxServer := wait.ContextForChannel(stopCh) + // nolint:govet // The only code path where closeTransformers does not get called is when it gets stored in dynamicTransformers. + ctxTransformers, closeTransformers := context.WithCancel(ctxServer) - encryptionConfiguration, err := encryptionconfig.LoadEncryptionConfig(s.EncryptionProviderConfigFilepath, s.EncryptionProviderConfigAutomaticReload, ctxTransformers.Done()) + encryptionConfiguration, err := encryptionconfig.LoadEncryptionConfig(ctxTransformers, s.EncryptionProviderConfigFilepath, s.EncryptionProviderConfigAutomaticReload) if err != nil { // in case of error, we want to close partially initialized (if any) transformers closeTransformers() @@ -247,25 +249,22 @@ func (s *EtcdOptions) Complete( return fmt.Errorf("failed to start kms encryption config hot reload controller. only 1 health check should be available when reload is enabled") } + // Here the dynamic transformers take ownership of the transformers and their cancellation. dynamicTransformers := encryptionconfig.NewDynamicTransformers(encryptionConfiguration.Transformers, encryptionConfiguration.HealthChecks[0], closeTransformers, encryptionConfiguration.KMSCloseGracePeriod) - s.resourceTransformers = dynamicTransformers - s.kmsPluginHealthzChecks = []healthz.HealthChecker{dynamicTransformers} - // add post start hook to start hot reload controller // adding this hook here will ensure that it gets configured exactly once err = addPostStartHook( "start-encryption-provider-config-automatic-reload", - func(hookContext server.PostStartHookContext) error { - kmsConfigController := kmsconfigcontroller.NewDynamicKMSEncryptionConfiguration( - "kms-encryption-config", + func(_ server.PostStartHookContext) error { + dynamicEncryptionConfigController := encryptionconfigcontroller.NewDynamicEncryptionConfiguration( + "encryption-provider-config-automatic-reload-controller", s.EncryptionProviderConfigFilepath, dynamicTransformers, encryptionConfiguration.EncryptionFileContentHash, - ctxServer.Done(), ) - go kmsConfigController.Run(ctxServer) + go dynamicEncryptionConfigController.Run(ctxServer) return nil }, @@ -275,6 +274,9 @@ func (s *EtcdOptions) Complete( closeTransformers() return fmt.Errorf("failed to add post start hook for kms encryption config hot reload controller: %w", err) } + + s.resourceTransformers = dynamicTransformers + s.kmsPluginHealthzChecks = []healthz.HealthChecker{dynamicTransformers} } else { s.resourceTransformers = encryptionconfig.StaticTransformers(encryptionConfiguration.Transformers) s.kmsPluginHealthzChecks = encryptionConfiguration.HealthChecks @@ -285,6 +287,7 @@ func (s *EtcdOptions) Complete( s.complete = true + // nolint:govet // The only code path where closeTransformers does not get called is when it gets stored in dynamicTransformers. return nil } diff --git a/vendor/k8s.io/apiserver/pkg/server/options/feature.go b/vendor/k8s.io/apiserver/pkg/server/options/feature.go index e8a624184..35596fba6 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/feature.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/feature.go @@ -25,6 +25,7 @@ import ( type FeatureOptions struct { EnableProfiling bool + DebugSocketPath string EnableContentionProfiling bool } @@ -33,6 +34,7 @@ func NewFeatureOptions() *FeatureOptions { return &FeatureOptions{ EnableProfiling: defaults.EnableProfiling, + DebugSocketPath: defaults.DebugSocketPath, EnableContentionProfiling: defaults.EnableContentionProfiling, } } @@ -45,7 +47,9 @@ func (o *FeatureOptions) AddFlags(fs *pflag.FlagSet) { fs.BoolVar(&o.EnableProfiling, "profiling", o.EnableProfiling, "Enable profiling via web interface host:port/debug/pprof/") fs.BoolVar(&o.EnableContentionProfiling, "contention-profiling", o.EnableContentionProfiling, - "Enable lock contention profiling, if profiling is enabled") + "Enable block profiling, if profiling is enabled") + fs.StringVar(&o.DebugSocketPath, "debug-socket-path", o.DebugSocketPath, + "Use an unprotected (no authn/authz) unix-domain socket for profiling with the given path") } func (o *FeatureOptions) ApplyTo(c *server.Config) error { @@ -54,6 +58,7 @@ func (o *FeatureOptions) ApplyTo(c *server.Config) error { } c.EnableProfiling = o.EnableProfiling + c.DebugSocketPath = o.DebugSocketPath c.EnableContentionProfiling = o.EnableContentionProfiling return nil diff --git a/vendor/k8s.io/apiserver/pkg/server/options/server_run_options.go b/vendor/k8s.io/apiserver/pkg/server/options/server_run_options.go index 09668646a..f9d574d5d 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/server_run_options.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/server_run_options.go @@ -19,10 +19,10 @@ package options import ( "fmt" "net" + "regexp" "strings" "time" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apiserver/pkg/server" @@ -31,6 +31,16 @@ import ( "github.com/spf13/pflag" ) +const ( + corsAllowedOriginsHelpText = "List of allowed origins for CORS, comma separated. " + + "An allowed origin can be a regular expression to support subdomain matching. " + + "If this list is empty CORS will not be enabled. " + + "Please ensure each expression matches the entire hostname by anchoring " + + "to the start with '^' or including the '//' prefix, and by anchoring to the " + + "end with '$' or including the ':' port separator suffix. " + + "Examples of valid expressions are '//example\\.com(:|$)' and '^https://example\\.com(:|$)'" +) + // ServerRunOptions contains the options while running a generic api server. type ServerRunOptions struct { AdvertiseAddress net.IP @@ -63,21 +73,39 @@ type ServerRunOptions struct { // If enabled, after ShutdownDelayDuration elapses, any incoming request is // rejected with a 429 status code and a 'Retry-After' response. ShutdownSendRetryAfter bool + + // ShutdownWatchTerminationGracePeriod, if set to a positive value, + // is the maximum duration the apiserver will wait for all active + // watch request(s) to drain. + // Once this grace period elapses, the apiserver will no longer + // wait for any active watch request(s) in flight to drain, it will + // proceed to the next step in the graceful server shutdown process. + // If set to a positive value, the apiserver will keep track of the + // number of active watch request(s) in flight and during shutdown + // it will wait, at most, for the specified duration and allow these + // active watch requests to drain with some rate limiting in effect. + // The default is zero, which implies the apiserver will not keep + // track of active watch request(s) in flight and will not wait + // for them to drain, this maintains backward compatibility. + // This grace period is orthogonal to other grace periods, and + // it is not overridden by any other grace period. + ShutdownWatchTerminationGracePeriod time.Duration } func NewServerRunOptions() *ServerRunOptions { defaults := server.NewConfig(serializer.CodecFactory{}) return &ServerRunOptions{ - MaxRequestsInFlight: defaults.MaxRequestsInFlight, - MaxMutatingRequestsInFlight: defaults.MaxMutatingRequestsInFlight, - RequestTimeout: defaults.RequestTimeout, - LivezGracePeriod: defaults.LivezGracePeriod, - MinRequestTimeout: defaults.MinRequestTimeout, - ShutdownDelayDuration: defaults.ShutdownDelayDuration, - JSONPatchMaxCopyBytes: defaults.JSONPatchMaxCopyBytes, - MaxRequestBodyBytes: defaults.MaxRequestBodyBytes, - EnablePriorityAndFairness: true, - ShutdownSendRetryAfter: false, + MaxRequestsInFlight: defaults.MaxRequestsInFlight, + MaxMutatingRequestsInFlight: defaults.MaxMutatingRequestsInFlight, + RequestTimeout: defaults.RequestTimeout, + LivezGracePeriod: defaults.LivezGracePeriod, + MinRequestTimeout: defaults.MinRequestTimeout, + ShutdownDelayDuration: defaults.ShutdownDelayDuration, + ShutdownWatchTerminationGracePeriod: defaults.ShutdownWatchTerminationGracePeriod, + JSONPatchMaxCopyBytes: defaults.JSONPatchMaxCopyBytes, + MaxRequestBodyBytes: defaults.MaxRequestBodyBytes, + EnablePriorityAndFairness: true, + ShutdownSendRetryAfter: false, } } @@ -97,6 +125,7 @@ func (s *ServerRunOptions) ApplyTo(c *server.Config) error { c.MaxRequestBodyBytes = s.MaxRequestBodyBytes c.PublicAddress = s.AdvertiseAddress c.ShutdownSendRetryAfter = s.ShutdownSendRetryAfter + c.ShutdownWatchTerminationGracePeriod = s.ShutdownWatchTerminationGracePeriod return nil } @@ -150,6 +179,10 @@ func (s *ServerRunOptions) Validate() []error { errors = append(errors, fmt.Errorf("--shutdown-delay-duration can not be negative value")) } + if s.ShutdownWatchTerminationGracePeriod < 0 { + errors = append(errors, fmt.Errorf("shutdown-watch-termination-grace-period, if provided, can not be a negative value")) + } + if s.JSONPatchMaxCopyBytes < 0 { errors = append(errors, fmt.Errorf("ServerRunOptions.JSONPatchMaxCopyBytes can not be negative value")) } @@ -161,6 +194,10 @@ func (s *ServerRunOptions) Validate() []error { if err := validateHSTSDirectives(s.HSTSDirectives); err != nil { errors = append(errors, err) } + + if err := validateCorsAllowedOriginList(s.CorsAllowedOriginList); err != nil { + errors = append(errors, err) + } return errors } @@ -183,6 +220,57 @@ func validateHSTSDirectives(hstsDirectives []string) error { return errors.NewAggregate(allErrors) } +func validateCorsAllowedOriginList(corsAllowedOriginList []string) error { + allErrors := []error{} + validateRegexFn := func(regexpStr string) error { + if _, err := regexp.Compile(regexpStr); err != nil { + return err + } + + // the regular expression should pin to the start and end of the host + // in the origin header, this will prevent CVE-2022-1996. + // possible ways it can pin to the start of host in the origin header: + // - match the start of the origin with '^' + // - match what separates the scheme and host with '//' or '://', + // this pins to the start of host in the origin header. + // possible ways it can match the end of the host in the origin header: + // - match the end of the origin with '$' + // - with a capture group that matches the host and port separator '(:|$)' + // We will relax the validation to check if these regex markers + // are present in the user specified expression. + var pinStart, pinEnd bool + for _, prefix := range []string{"^", "//"} { + if strings.Contains(regexpStr, prefix) { + pinStart = true + break + } + } + for _, suffix := range []string{"$", ":"} { + if strings.Contains(regexpStr, suffix) { + pinEnd = true + break + } + } + if !pinStart || !pinEnd { + return fmt.Errorf("regular expression does not pin to start/end of host in the origin header") + } + return nil + } + + for _, regexp := range corsAllowedOriginList { + if len(regexp) == 0 { + allErrors = append(allErrors, fmt.Errorf("empty value in --cors-allowed-origins, help: %s", corsAllowedOriginsHelpText)) + continue + } + + if err := validateRegexFn(regexp); err != nil { + err = fmt.Errorf("--cors-allowed-origins has an invalid regular expression: %v, help: %s", err, corsAllowedOriginsHelpText) + allErrors = append(allErrors, err) + } + } + return errors.NewAggregate(allErrors) +} + // AddUniversalFlags adds flags for a specific APIServer to the specified FlagSet func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) { // Note: the weird ""+ in below lines seems to be the only way to get gofmt to @@ -194,9 +282,7 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) { "will be used. If --bind-address is unspecified, the host's default interface will "+ "be used.") - fs.StringSliceVar(&s.CorsAllowedOriginList, "cors-allowed-origins", s.CorsAllowedOriginList, ""+ - "List of allowed origins for CORS, comma separated. An allowed origin can be a regular "+ - "expression to support subdomain matching. If this list is empty CORS will not be enabled.") + fs.StringSliceVar(&s.CorsAllowedOriginList, "cors-allowed-origins", s.CorsAllowedOriginList, corsAllowedOriginsHelpText) fs.StringSliceVar(&s.HSTSDirectives, "strict-transport-security-directives", s.HSTSDirectives, ""+ "List of directives for HSTS, comma separated. If this list is empty, then HSTS directives will not "+ @@ -205,11 +291,6 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) { fs.StringVar(&s.ExternalHost, "external-hostname", s.ExternalHost, "The hostname to use when generating externalized URLs for this master (e.g. Swagger API Docs or OpenID Discovery).") - deprecatedMasterServiceNamespace := metav1.NamespaceDefault - fs.StringVar(&deprecatedMasterServiceNamespace, "master-service-namespace", deprecatedMasterServiceNamespace, ""+ - "DEPRECATED: the namespace from which the Kubernetes master services should be injected into pods.") - fs.MarkDeprecated("master-service-namespace", "This flag will be removed in v1.27") - fs.IntVar(&s.MaxRequestsInFlight, "max-requests-inflight", s.MaxRequestsInFlight, ""+ "This and --max-mutating-requests-inflight are summed to determine the server's total concurrency limit "+ "(which must be positive) if --enable-priority-and-fairness is true. "+ @@ -257,5 +338,9 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) { "during this window all incoming requests will be rejected with a status code 429 and a 'Retry-After' response header, "+ "in addition 'Connection: close' response header is set in order to tear down the TCP connection when idle.") + fs.DurationVar(&s.ShutdownWatchTerminationGracePeriod, "shutdown-watch-termination-grace-period", s.ShutdownWatchTerminationGracePeriod, ""+ + "This option, if set, represents the maximum amount of grace period the apiserver will wait "+ + "for active watch request(s) to drain during the graceful server shutdown window.") + utilfeature.DefaultMutableFeatureGate.AddFlag(fs) } diff --git a/vendor/k8s.io/apiserver/pkg/server/options/tracing.go b/vendor/k8s.io/apiserver/pkg/server/options/tracing.go index 1a135e83d..d56e7df51 100644 --- a/vendor/k8s.io/apiserver/pkg/server/options/tracing.go +++ b/vendor/k8s.io/apiserver/pkg/server/options/tracing.go @@ -154,9 +154,5 @@ func ReadTracingConfiguration(configFilePath string) (*tracingapi.TracingConfigu if err := runtime.DecodeInto(codecs.UniversalDecoder(), data, internalConfig); err != nil { return nil, fmt.Errorf("unable to decode tracing configuration data: %v", err) } - tc := &tracingapi.TracingConfiguration{ - Endpoint: internalConfig.Endpoint, - SamplingRatePerMillion: internalConfig.SamplingRatePerMillion, - } - return tc, nil + return &internalConfig.TracingConfiguration, nil } diff --git a/vendor/k8s.io/apiserver/pkg/server/routes/debugsocket.go b/vendor/k8s.io/apiserver/pkg/server/routes/debugsocket.go new file mode 100644 index 000000000..e7297b35f --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/server/routes/debugsocket.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 routes + +import ( + "fmt" + "net" + "net/http" + "net/http/pprof" + "os" + "path" +) + +// DebugSocket installs profiling and debugflag as a Unix-Domain socket. +type DebugSocket struct { + path string + mux *http.ServeMux +} + +// NewDebugSocket creates a new DebugSocket for the given path. +func NewDebugSocket(path string) *DebugSocket { + return &DebugSocket{ + path: path, + mux: http.NewServeMux(), + } +} + +// InstallProfiling installs profiling endpoints in the socket. +func (s *DebugSocket) InstallProfiling() { + s.mux.HandleFunc("/debug/pprof", redirectTo("/debug/pprof/")) + s.mux.HandleFunc("/debug/pprof/", pprof.Index) + s.mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + s.mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + s.mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + s.mux.HandleFunc("/debug/pprof/trace", pprof.Trace) +} + +// InstallDebugFlag installs debug flag endpoints in the socket. +func (s *DebugSocket) InstallDebugFlag(flag string, handler func(http.ResponseWriter, *http.Request)) { + f := DebugFlags{} + s.mux.HandleFunc("/debug/flags", f.Index) + s.mux.HandleFunc("/debug/flags/", f.Index) + + url := path.Join("/debug/flags", flag) + s.mux.HandleFunc(url, handler) + + f.addFlag(flag) +} + +// Run starts the server and waits for stopCh to be closed to close the server. +func (s *DebugSocket) Run(stopCh <-chan struct{}) error { + if err := os.Remove(s.path); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("failed to remove (%v): %v", s.path, err) + } + + l, err := net.Listen("unix", s.path) + if err != nil { + return fmt.Errorf("listen error (%v): %v", s.path, err) + } + defer l.Close() + + srv := http.Server{Handler: s.mux} + go func() { + <-stopCh + srv.Close() + }() + return srv.Serve(l) +} diff --git a/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go b/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go index e6459ce3e..17cc1f85a 100644 --- a/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go +++ b/vendor/k8s.io/apiserver/pkg/server/routes/openapi.go @@ -24,6 +24,7 @@ import ( builder2 "k8s.io/kube-openapi/pkg/builder" "k8s.io/kube-openapi/pkg/builder3" "k8s.io/kube-openapi/pkg/common" + "k8s.io/kube-openapi/pkg/common/restfuladapter" "k8s.io/kube-openapi/pkg/handler" "k8s.io/kube-openapi/pkg/handler3" "k8s.io/kube-openapi/pkg/validation/spec" @@ -36,16 +37,12 @@ type OpenAPI struct { // Install adds the SwaggerUI webservice to the given mux. func (oa OpenAPI) InstallV2(c *restful.Container, mux *mux.PathRecorderMux) (*handler.OpenAPIService, *spec.Swagger) { - spec, err := builder2.BuildOpenAPISpec(c.RegisteredWebServices(), oa.Config) + spec, err := builder2.BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(c.RegisteredWebServices()), oa.Config) if err != nil { klog.Fatalf("Failed to build open api spec for root: %v", err) } spec.Definitions = handler.PruneDefaults(spec.Definitions) - openAPIVersionedService, err := handler.NewOpenAPIService(spec) - if err != nil { - klog.Fatalf("Failed to create OpenAPIService: %v", err) - } - + openAPIVersionedService := handler.NewOpenAPIService(spec) err = openAPIVersionedService.RegisterOpenAPIVersionedService("/openapi/v2", mux) if err != nil { klog.Fatalf("Failed to register versioned open api spec for root: %v", err) @@ -56,12 +53,8 @@ func (oa OpenAPI) InstallV2(c *restful.Container, mux *mux.PathRecorderMux) (*ha // InstallV3 adds the static group/versions defined in the RegisteredWebServices to the OpenAPI v3 spec func (oa OpenAPI) InstallV3(c *restful.Container, mux *mux.PathRecorderMux) *handler3.OpenAPIService { - openAPIVersionedService, err := handler3.NewOpenAPIService(nil) - if err != nil { - klog.Fatalf("Failed to create OpenAPIService: %v", err) - } - - err = openAPIVersionedService.RegisterOpenAPIV3VersionedService("/openapi/v3", mux) + openAPIVersionedService := handler3.NewOpenAPIService() + err := openAPIVersionedService.RegisterOpenAPIV3VersionedService("/openapi/v3", mux) if err != nil { klog.Fatalf("Failed to register versioned open api spec for root: %v", err) } @@ -75,7 +68,7 @@ func (oa OpenAPI) InstallV3(c *restful.Container, mux *mux.PathRecorderMux) *han } for gv, ws := range grouped { - spec, err := builder3.BuildOpenAPISpec(ws, oa.Config) + spec, err := builder3.BuildOpenAPISpecFromRoutes(restfuladapter.AdaptWebServices(ws), oa.Config) if err != nil { klog.Errorf("Failed to build OpenAPI v3 for group %s, %q", gv, err) diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/cache_watcher.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/cache_watcher.go new file mode 100644 index 000000000..478d2151d --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/cache_watcher.go @@ -0,0 +1,543 @@ +/* +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 cacher + +import ( + "context" + "fmt" + "sync" + "time" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage/cacher/metrics" + utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol" + + "k8s.io/klog/v2" +) + +// possible states of the cache watcher +const ( + // cacheWatcherWaitingForBookmark indicates the cacher + // is waiting for a bookmark event with a specific RV set + cacheWatcherWaitingForBookmark = iota + + // cacheWatcherBookmarkReceived indicates that the cacher + // has received a bookmark event with required RV + cacheWatcherBookmarkReceived + + // cacheWatcherBookmarkSent indicates that the cacher + // has already sent a bookmark event to a client + cacheWatcherBookmarkSent +) + +// cacheWatcher implements watch.Interface +// this is not thread-safe +type cacheWatcher struct { + input chan *watchCacheEvent + result chan watch.Event + done chan struct{} + filter filterWithAttrsFunc + stopped bool + forget func(bool) + versioner storage.Versioner + // The watcher will be closed by server after the deadline, + // save it here to send bookmark events before that. + deadline time.Time + allowWatchBookmarks bool + groupResource schema.GroupResource + + // human readable identifier that helps assigning cacheWatcher + // instance with request + identifier string + + // drainInputBuffer indicates whether we should delay closing this watcher + // and send all event in the input buffer. + drainInputBuffer bool + + // bookmarkAfterResourceVersion holds an RV that indicates + // when we should start delivering bookmark events. + // If this field holds the value of 0 that means + // we don't have any special preferences toward delivering bookmark events. + // Note that this field is used in conjunction with the state field. + // It should not be changed once the watcher has been started. + bookmarkAfterResourceVersion uint64 + + // stateMutex protects state + stateMutex sync.Mutex + + // state holds a numeric value indicating the current state of the watcher + state int +} + +func newCacheWatcher( + chanSize int, + filter filterWithAttrsFunc, + forget func(bool), + versioner storage.Versioner, + deadline time.Time, + allowWatchBookmarks bool, + groupResource schema.GroupResource, + identifier string, +) *cacheWatcher { + return &cacheWatcher{ + input: make(chan *watchCacheEvent, chanSize), + result: make(chan watch.Event, chanSize), + done: make(chan struct{}), + filter: filter, + stopped: false, + forget: forget, + versioner: versioner, + deadline: deadline, + allowWatchBookmarks: allowWatchBookmarks, + groupResource: groupResource, + identifier: identifier, + } +} + +// Implements watch.Interface. +func (c *cacheWatcher) ResultChan() <-chan watch.Event { + return c.result +} + +// Implements watch.Interface. +func (c *cacheWatcher) Stop() { + c.forget(false) +} + +// we rely on the fact that stopLocked is actually protected by Cacher.Lock() +func (c *cacheWatcher) stopLocked() { + if !c.stopped { + c.stopped = true + // stop without draining the input channel was requested. + if !c.drainInputBuffer { + close(c.done) + } + close(c.input) + } + + // Even if the watcher was already stopped, if it previously was + // using draining mode and it's not using it now we need to + // close the done channel now. Otherwise we could leak the + // processing goroutine if it will be trying to put more objects + // into result channel, the channel will be full and there will + // already be noone on the processing the events on the receiving end. + if !c.drainInputBuffer && !c.isDoneChannelClosedLocked() { + close(c.done) + } +} + +func (c *cacheWatcher) nonblockingAdd(event *watchCacheEvent) bool { + // if the bookmarkAfterResourceVersion hasn't been seen + // we will try to deliver a bookmark event every second. + // the following check will discard a bookmark event + // if it is < than the bookmarkAfterResourceVersion + // so that we don't pollute the input channel + if event.Type == watch.Bookmark && event.ResourceVersion < c.bookmarkAfterResourceVersion { + return false + } + select { + case c.input <- event: + c.markBookmarkAfterRvAsReceived(event) + return true + default: + return false + } +} + +// Nil timer means that add will not block (if it can't send event immediately, it will break the watcher) +// +// Note that bookmark events are never added via the add method only via the nonblockingAdd. +// Changing this behaviour will require moving the markBookmarkAfterRvAsReceived method +func (c *cacheWatcher) add(event *watchCacheEvent, timer *time.Timer) bool { + // Try to send the event immediately, without blocking. + if c.nonblockingAdd(event) { + return true + } + + closeFunc := func() { + // This means that we couldn't send event to that watcher. + // Since we don't want to block on it infinitely, + // we simply terminate it. + klog.V(1).Infof("Forcing %v watcher close due to unresponsiveness: %v. len(c.input) = %v, len(c.result) = %v", c.groupResource.String(), c.identifier, len(c.input), len(c.result)) + metrics.TerminatedWatchersCounter.WithLabelValues(c.groupResource.String()).Inc() + // This means that we couldn't send event to that watcher. + // Since we don't want to block on it infinitely, we simply terminate it. + + // we are graceful = false, when: + // + // (a) The bookmarkAfterResourceVersionReceived hasn't been received, + // we can safely terminate the watcher. Because the client is waiting + // for this specific bookmark, and we even haven't received one. + // (b) We have seen the bookmarkAfterResourceVersion, and it was sent already to the client. + // We can simply terminate the watcher. + + // we are graceful = true, when: + // + // (a) We have seen a bookmark, but it hasn't been sent to the client yet. + // That means we should drain the input buffer which contains + // the bookmarkAfterResourceVersion we want. We do that to make progress + // as clients can re-establish a new watch with the given RV and receive + // further notifications. + graceful := func() bool { + c.stateMutex.Lock() + defer c.stateMutex.Unlock() + return c.state == cacheWatcherBookmarkReceived + }() + klog.V(1).Infof("Forcing %v watcher close due to unresponsiveness: %v. len(c.input) = %v, len(c.result) = %v, graceful = %v", c.groupResource.String(), c.identifier, len(c.input), len(c.result), graceful) + c.forget(graceful) + } + + if timer == nil { + closeFunc() + return false + } + + // OK, block sending, but only until timer fires. + select { + case c.input <- event: + return true + case <-timer.C: + closeFunc() + return false + } +} + +func (c *cacheWatcher) nextBookmarkTime(now time.Time, bookmarkFrequency time.Duration) (time.Time, bool) { + // We try to send bookmarks: + // + // (a) right before the watcher timeout - for now we simply set it 2s before + // the deadline + // + // (b) roughly every minute + // + // (c) immediately when the bookmarkAfterResourceVersion wasn't confirmed + // in this scenario the client have already seen (or is in the process of sending) + // all initial data and is interested in seeing + // a specific RV value (aka. the bookmarkAfterResourceVersion) + // since we don't know when the cacher will see the RV we increase frequency + // + // (b) gives us periodicity if the watch breaks due to unexpected + // conditions, (a) ensures that on timeout the watcher is as close to + // now as possible - this covers 99% of cases. + + if !c.wasBookmarkAfterRvReceived() { + return time.Time{}, true // schedule immediately + } + + heartbeatTime := now.Add(bookmarkFrequency) + if c.deadline.IsZero() { + // Timeout is set by our client libraries (e.g. reflector) as well as defaulted by + // apiserver if properly configured. So this shoudln't happen in practice. + return heartbeatTime, true + } + if pretimeoutTime := c.deadline.Add(-2 * time.Second); pretimeoutTime.Before(heartbeatTime) { + heartbeatTime = pretimeoutTime + } + + if heartbeatTime.Before(now) { + return time.Time{}, false + } + return heartbeatTime, true +} + +// wasBookmarkAfterRvReceived same as wasBookmarkAfterRvReceivedLocked just acquires a lock +func (c *cacheWatcher) wasBookmarkAfterRvReceived() bool { + c.stateMutex.Lock() + defer c.stateMutex.Unlock() + return c.wasBookmarkAfterRvReceivedLocked() +} + +// wasBookmarkAfterRvReceivedLocked checks if the given cacheWatcher +// have seen a bookmark event >= bookmarkAfterResourceVersion +func (c *cacheWatcher) wasBookmarkAfterRvReceivedLocked() bool { + return c.state != cacheWatcherWaitingForBookmark +} + +// markBookmarkAfterRvAsReceived indicates that the given cacheWatcher +// have seen a bookmark event >= bookmarkAfterResourceVersion +func (c *cacheWatcher) markBookmarkAfterRvAsReceived(event *watchCacheEvent) { + if event.Type == watch.Bookmark { + c.stateMutex.Lock() + defer c.stateMutex.Unlock() + if c.wasBookmarkAfterRvReceivedLocked() { + return + } + // bookmark events are scheduled by startDispatchingBookmarkEvents method + // since we received a bookmark event that means we have + // converged towards the expected RV and it is okay to update the state so that + // this cacher can be scheduler for a regular bookmark events + c.state = cacheWatcherBookmarkReceived + } +} + +// wasBookmarkAfterRvSentLocked checks if a bookmark event +// with an RV >= the bookmarkAfterResourceVersion has been sent by this watcher +func (c *cacheWatcher) wasBookmarkAfterRvSentLocked() bool { + return c.state == cacheWatcherBookmarkSent +} + +// wasBookmarkAfterRvSent same as wasBookmarkAfterRvSentLocked just acquires a lock +func (c *cacheWatcher) wasBookmarkAfterRvSent() bool { + c.stateMutex.Lock() + defer c.stateMutex.Unlock() + return c.wasBookmarkAfterRvSentLocked() +} + +// markBookmarkAfterRvSent indicates that the given cacheWatcher +// have sent a bookmark event with an RV >= the bookmarkAfterResourceVersion +// +// this function relies on the fact that the nonblockingAdd method +// won't admit a bookmark event with an RV < the bookmarkAfterResourceVersion +// so the first received bookmark event is considered to match the bookmarkAfterResourceVersion +func (c *cacheWatcher) markBookmarkAfterRvSent(event *watchCacheEvent) { + // note that bookmark events are not so common so will acquire a lock every ~60 second or so + if event.Type == watch.Bookmark { + c.stateMutex.Lock() + defer c.stateMutex.Unlock() + if !c.wasBookmarkAfterRvSentLocked() { + c.state = cacheWatcherBookmarkSent + } + } +} + +// setBookmarkAfterResourceVersion sets the bookmarkAfterResourceVersion and the state associated with it +func (c *cacheWatcher) setBookmarkAfterResourceVersion(bookmarkAfterResourceVersion uint64) { + state := cacheWatcherWaitingForBookmark + if bookmarkAfterResourceVersion == 0 { + state = cacheWatcherBookmarkSent // if no specific RV was requested we assume no-op + } + c.state = state + c.bookmarkAfterResourceVersion = bookmarkAfterResourceVersion +} + +// setDrainInputBufferLocked if set to true indicates that we should delay closing this watcher +// until we send all events residing in the input buffer. +func (c *cacheWatcher) setDrainInputBufferLocked(drain bool) { + c.drainInputBuffer = drain +} + +// isDoneChannelClosed checks if c.done channel is closed +func (c *cacheWatcher) isDoneChannelClosedLocked() bool { + select { + case <-c.done: + return true + default: + } + return false +} + +func getMutableObject(object runtime.Object) runtime.Object { + if _, ok := object.(*cachingObject); ok { + // It is safe to return without deep-copy, because the underlying + // object will lazily perform deep-copy on the first try to change + // any of its fields. + return object + } + return object.DeepCopyObject() +} + +func updateResourceVersion(object runtime.Object, versioner storage.Versioner, resourceVersion uint64) { + if err := versioner.UpdateObject(object, resourceVersion); err != nil { + utilruntime.HandleError(fmt.Errorf("failure to version api object (%d) %#v: %v", resourceVersion, object, err)) + } +} + +func (c *cacheWatcher) convertToWatchEvent(event *watchCacheEvent) *watch.Event { + if event.Type == watch.Bookmark { + e := &watch.Event{Type: watch.Bookmark, Object: event.Object.DeepCopyObject()} + if !c.wasBookmarkAfterRvSent() { + objMeta, err := meta.Accessor(e.Object) + if err != nil { + utilruntime.HandleError(fmt.Errorf("error while accessing object's metadata gr: %v, identifier: %v, obj: %#v, err: %v", c.groupResource, c.identifier, e.Object, err)) + return nil + } + objAnnotations := objMeta.GetAnnotations() + if objAnnotations == nil { + objAnnotations = map[string]string{} + } + objAnnotations["k8s.io/initial-events-end"] = "true" + objMeta.SetAnnotations(objAnnotations) + } + return e + } + + curObjPasses := event.Type != watch.Deleted && c.filter(event.Key, event.ObjLabels, event.ObjFields) + oldObjPasses := false + if event.PrevObject != nil { + oldObjPasses = c.filter(event.Key, event.PrevObjLabels, event.PrevObjFields) + } + if !curObjPasses && !oldObjPasses { + // Watcher is not interested in that object. + return nil + } + + switch { + case curObjPasses && !oldObjPasses: + return &watch.Event{Type: watch.Added, Object: getMutableObject(event.Object)} + case curObjPasses && oldObjPasses: + return &watch.Event{Type: watch.Modified, Object: getMutableObject(event.Object)} + case !curObjPasses && oldObjPasses: + // return a delete event with the previous object content, but with the event's resource version + oldObj := getMutableObject(event.PrevObject) + // We know that if oldObj is cachingObject (which can only be set via + // setCachingObjects), its resourceVersion is already set correctly and + // we don't need to update it. However, since cachingObject efficiently + // handles noop updates, we avoid this microoptimization here. + updateResourceVersion(oldObj, c.versioner, event.ResourceVersion) + return &watch.Event{Type: watch.Deleted, Object: oldObj} + } + + return nil +} + +// NOTE: sendWatchCacheEvent is assumed to not modify !!! +func (c *cacheWatcher) sendWatchCacheEvent(event *watchCacheEvent) { + watchEvent := c.convertToWatchEvent(event) + if watchEvent == nil { + // Watcher is not interested in that object. + return + } + + // We need to ensure that if we put event X to the c.result, all + // previous events were already put into it before, no matter whether + // c.done is close or not. + // Thus we cannot simply select from c.done and c.result and this + // would give us non-determinism. + // At the same time, we don't want to block infinitely on putting + // to c.result, when c.done is already closed. + // + // This ensures that with c.done already close, we at most once go + // into the next select after this. With that, no matter which + // statement we choose there, we will deliver only consecutive + // events. + select { + case <-c.done: + return + default: + } + + select { + case c.result <- *watchEvent: + c.markBookmarkAfterRvSent(event) + case <-c.done: + } +} + +func (c *cacheWatcher) processInterval(ctx context.Context, cacheInterval *watchCacheInterval, resourceVersion uint64) { + defer utilruntime.HandleCrash() + defer close(c.result) + defer c.Stop() + + // Check how long we are processing initEvents. + // As long as these are not processed, we are not processing + // any incoming events, so if it takes long, we may actually + // block all watchers for some time. + // TODO: From the logs it seems that there happens processing + // times even up to 1s which is very long. However, this doesn't + // depend that much on the number of initEvents. E.g. from the + // 2000-node Kubemark run we have logs like this, e.g.: + // ... processing 13862 initEvents took 66.808689ms + // ... processing 14040 initEvents took 993.532539ms + // We should understand what is blocking us in those cases (e.g. + // is it lack of CPU, network, or sth else) and potentially + // consider increase size of result buffer in those cases. + const initProcessThreshold = 500 * time.Millisecond + startTime := time.Now() + + initEventCount := 0 + for { + event, err := cacheInterval.Next() + if err != nil { + // An error indicates that the cache interval + // has been invalidated and can no longer serve + // events. + // + // Initially we considered sending an "out-of-history" + // Error event in this case, but because historically + // such events weren't sent out of the watchCache, we + // decided not to. This is still ok, because on watch + // closure, the watcher will try to re-instantiate the + // watch and then will get an explicit "out-of-history" + // window. There is potential for optimization, but for + // now, in order to be on the safe side and not break + // custom clients, the cost of it is something that we + // are fully accepting. + klog.Warningf("couldn't retrieve watch event to serve: %#v", err) + return + } + if event == nil { + break + } + c.sendWatchCacheEvent(event) + + // With some events already sent, update resourceVersion so that + // events that were buffered and not yet processed won't be delivered + // to this watcher second time causing going back in time. + // + // There is one case where events are not necessary ordered by + // resourceVersion, being a case of watching from resourceVersion=0, + // which at the beginning returns the state of each objects. + // For the purpose of it, we need to max it with the resource version + // that we have so far. + if event.ResourceVersion > resourceVersion { + resourceVersion = event.ResourceVersion + } + initEventCount++ + } + + if initEventCount > 0 { + metrics.InitCounter.WithLabelValues(c.groupResource.String()).Add(float64(initEventCount)) + } + processingTime := time.Since(startTime) + if processingTime > initProcessThreshold { + klog.V(2).Infof("processing %d initEvents of %s (%s) took %v", initEventCount, c.groupResource, c.identifier, processingTime) + } + + c.process(ctx, resourceVersion) +} + +func (c *cacheWatcher) process(ctx context.Context, resourceVersion uint64) { + // At this point we already start processing incoming watch events. + // However, the init event can still be processed because their serialization + // and sending to the client happens asynchrnously. + // TODO: As describe in the KEP, we would like to estimate that by delaying + // the initialization signal proportionally to the number of events to + // process, but we're leaving this to the tuning phase. + utilflowcontrol.WatchInitialized(ctx) + + for { + select { + case event, ok := <-c.input: + if !ok { + return + } + // only send events newer than resourceVersion + // or a bookmark event with an RV equal to resourceVersion + // if we haven't sent one to the client + if event.ResourceVersion > resourceVersion || (event.Type == watch.Bookmark && event.ResourceVersion == resourceVersion && !c.wasBookmarkAfterRvSent()) { + c.sendWatchCacheEvent(event) + } + case <-ctx.Done(): + return + } + } +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go index dfa211579..eada35b1d 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/cacher.go @@ -21,6 +21,7 @@ import ( "fmt" "net/http" "reflect" + "strconv" "sync" "time" @@ -34,17 +35,17 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/apiserver/pkg/audit" + "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/cacher/metrics" utilfeature "k8s.io/apiserver/pkg/util/feature" - utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol" "k8s.io/client-go/tools/cache" "k8s.io/component-base/tracing" + "k8s.io/klog/v2" "k8s.io/utils/clock" ) @@ -127,29 +128,37 @@ func (wm watchersMap) terminateAll(done func(*cacheWatcher)) { } type indexedWatchers struct { - allWatchers watchersMap + allWatchers map[namespacedName]watchersMap valueWatchers map[string]watchersMap } -func (i *indexedWatchers) addWatcher(w *cacheWatcher, number int, value string, supported bool) { +func (i *indexedWatchers) addWatcher(w *cacheWatcher, number int, scope namespacedName, value string, supported bool) { if supported { if _, ok := i.valueWatchers[value]; !ok { i.valueWatchers[value] = watchersMap{} } i.valueWatchers[value].addWatcher(w, number) } else { - i.allWatchers.addWatcher(w, number) + scopedWatchers, ok := i.allWatchers[scope] + if !ok { + scopedWatchers = watchersMap{} + i.allWatchers[scope] = scopedWatchers + } + scopedWatchers.addWatcher(w, number) } } -func (i *indexedWatchers) deleteWatcher(number int, value string, supported bool, done func(*cacheWatcher)) { +func (i *indexedWatchers) deleteWatcher(number int, scope namespacedName, value string, supported bool, done func(*cacheWatcher)) { if supported { i.valueWatchers[value].deleteWatcher(number, done) if len(i.valueWatchers[value]) == 0 { delete(i.valueWatchers, value) } } else { - i.allWatchers.deleteWatcher(number, done) + i.allWatchers[scope].deleteWatcher(number, done) + if len(i.allWatchers[scope]) == 0 { + delete(i.allWatchers, scope) + } } } @@ -161,10 +170,13 @@ func (i *indexedWatchers) terminateAll(groupResource schema.GroupResource, done if len(i.allWatchers) > 0 || len(i.valueWatchers) > 0 { klog.Warningf("Terminating all watchers from cacher %v", groupResource) } - i.allWatchers.terminateAll(done) + for _, watchers := range i.allWatchers { + watchers.terminateAll(done) + } for _, watchers := range i.valueWatchers { watchers.terminateAll(done) } + i.allWatchers = map[namespacedName]watchersMap{} i.valueWatchers = map[string]watchersMap{} } @@ -278,6 +290,9 @@ type Cacher struct { // newFunc is a function that creates new empty object storing a object of type Type. newFunc func() runtime.Object + // newListFunc is a function that creates new empty list for storing objects of type Type. + newListFunc func() runtime.Object + // indexedTrigger is used for optimizing amount of watchers that needs to process // an incoming event. indexedTrigger *indexedTriggerFunc @@ -359,10 +374,11 @@ func NewCacherFromConfig(config Config) (*Cacher, error) { groupResource: config.GroupResource, versioner: config.Versioner, newFunc: config.NewFunc, + newListFunc: config.NewListFunc, indexedTrigger: indexedTrigger, watcherIdx: 0, watchers: indexedWatchers{ - allWatchers: make(map[int]*cacheWatcher), + allWatchers: make(map[namespacedName]watchersMap), valueWatchers: make(map[string]watchersMap), }, // TODO: Figure out the correct value for the buffer size. @@ -399,6 +415,9 @@ func NewCacherFromConfig(config Config) (*Cacher, error) { // We don't want to terminate all watchers as recreating all watchers puts high load on api-server. // In most of the cases, leader is reelected within few cycles. reflector.MaxInternalErrorRetryDuration = time.Second * 30 + // since the watch-list is provided by the watch cache instruct + // the reflector to issue a regular LIST against the store + reflector.UseWatchList = false cacher.watchCache = watchCache cacher.reflector = reflector @@ -479,18 +498,50 @@ func (c *Cacher) Delete( return c.storage.Delete(ctx, key, out, preconditions, validateDeletion, nil) } +type namespacedName struct { + namespace string + name string +} + // Watch implements storage.Interface. func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { pred := opts.Predicate - watchRV, err := c.versioner.ParseResourceVersion(opts.ResourceVersion) + // if the watch-list feature wasn't set and the resourceVersion is unset + // ensure that the rv from which the watch is being served, is the latest + // one. "latest" is ensured by serving the watch from + // the underlying storage. + // + // it should never happen due to our validation but let's just be super-safe here + // and disable sendingInitialEvents when the feature wasn't enabled + if !utilfeature.DefaultFeatureGate.Enabled(features.WatchList) && opts.SendInitialEvents != nil { + opts.SendInitialEvents = nil + } + if opts.SendInitialEvents == nil && opts.ResourceVersion == "" { + return c.storage.Watch(ctx, key, opts) + } + requestedWatchRV, err := c.versioner.ParseResourceVersion(opts.ResourceVersion) if err != nil { return nil, err } - if err := c.ready.wait(); err != nil { + readyGeneration, err := c.ready.waitAndReadGeneration(ctx) + if err != nil { return nil, errors.NewServiceUnavailable(err.Error()) } + // determine the namespace and name scope of the watch, first from the request, secondarily from the field selector + scope := namespacedName{} + if requestNamespace, ok := request.NamespaceFrom(ctx); ok && len(requestNamespace) > 0 { + scope.namespace = requestNamespace + } else if selectorNamespace, ok := pred.Field.RequiresExactMatch("metadata.namespace"); ok { + scope.namespace = selectorNamespace + } + if requestInfo, ok := request.RequestInfoFrom(ctx); ok && requestInfo != nil && len(requestInfo.Name) > 0 { + scope.name = requestInfo.Name + } else if selectorName, ok := pred.Field.RequiresExactMatch("metadata.name"); ok { + scope.name = selectorName + } + triggerValue, triggerSupported := "", false if c.indexedTrigger != nil { for _, field := range pred.IndexFields { @@ -509,6 +560,18 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions // watchers on our watcher having a processing hiccup chanSize := c.watchCache.suggestedWatchChannelSize(c.indexedTrigger != nil, triggerSupported) + // Determine a function that computes the bookmarkAfterResourceVersion + bookmarkAfterResourceVersionFn, err := c.getBookmarkAfterResourceVersionLockedFunc(ctx, requestedWatchRV, opts) + if err != nil { + return newErrWatcher(err), nil + } + + // Determine a function that computes the watchRV we should start from + startWatchResourceVersionFn, err := c.getStartResourceVersionForWatchLockedFunc(ctx, requestedWatchRV, opts) + if err != nil { + return newErrWatcher(err), nil + } + // Determine watch timeout('0' means deadline is not set, ignore checking) deadline, _ := ctx.Deadline() @@ -536,7 +599,17 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions // underlying watchCache is calling processEvent under its lock. c.watchCache.RLock() defer c.watchCache.RUnlock() - cacheInterval, err := c.watchCache.getAllEventsSinceLocked(watchRV) + forceAllEvents, err := c.waitUntilWatchCacheFreshAndForceAllEvents(ctx, requestedWatchRV, opts) + if err != nil { + return newErrWatcher(err), nil + } + startWatchRV := startWatchResourceVersionFn() + var cacheInterval *watchCacheInterval + if forceAllEvents { + cacheInterval, err = c.watchCache.getIntervalFromStoreLocked() + } else { + cacheInterval, err = c.watchCache.getAllEventsSinceLocked(startWatchRV) + } if err != nil { // To match the uncached watch implementation, once we have passed authn/authz/admission, // and successfully parsed a resource version, other errors must fail with a watch event of type ERROR, @@ -544,12 +617,24 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions return newErrWatcher(err), nil } + addedWatcher := false func() { c.Lock() defer c.Unlock() + + if generation, ok := c.ready.checkAndReadGeneration(); generation != readyGeneration || !ok { + // We went unready or are already on a different generation. + // Avoid registering and starting the watch as it will have to be + // terminated immediately anyway. + return + } + // Update watcher.forget function once we can compute it. - watcher.forget = forgetWatcher(c, watcher, c.watcherIdx, triggerValue, triggerSupported) - c.watchers.addWatcher(watcher, c.watcherIdx, triggerValue, triggerSupported) + watcher.forget = forgetWatcher(c, watcher, c.watcherIdx, scope, triggerValue, triggerSupported) + // Update the bookMarkAfterResourceVersion + watcher.setBookmarkAfterResourceVersion(bookmarkAfterResourceVersionFn()) + c.watchers.addWatcher(watcher, c.watcherIdx, scope, triggerValue, triggerSupported) + addedWatcher = true // Add it to the queue only when the client support watch bookmarks. if watcher.allowWatchBookmarks { @@ -558,7 +643,15 @@ func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions c.watcherIdx++ }() - go watcher.processInterval(ctx, cacheInterval, watchRV) + if !addedWatcher { + // Watcher isn't really started at this point, so it's safe to just drop it. + // + // We're simulating the immediate watch termination, which boils down to simply + // closing the watcher. + return newImmediateCloseWatcher(), nil + } + + go watcher.processInterval(ctx, cacheInterval, startWatchRV) return watcher, nil } @@ -586,7 +679,7 @@ func (c *Cacher) Get(ctx context.Context, key string, opts storage.GetOptions, o // Do not create a trace - it's not for free and there are tons // of Get requests. We can add it if it will be really needed. - if err := c.ready.wait(); err != nil { + if err := c.ready.wait(ctx); err != nil { return errors.NewServiceUnavailable(err.Error()) } @@ -621,9 +714,11 @@ func (c *Cacher) Get(ctx context.Context, key string, opts storage.GetOptions, o func shouldDelegateList(opts storage.ListOptions) bool { resourceVersion := opts.ResourceVersion pred := opts.Predicate + match := opts.ResourceVersionMatch pagingEnabled := utilfeature.DefaultFeatureGate.Enabled(features.APIListChunking) hasContinuation := pagingEnabled && len(pred.Continue) > 0 hasLimit := pagingEnabled && pred.Limit > 0 && resourceVersion != "0" + unsupportedMatch := match != "" && match != metav1.ResourceVersionMatchNotOlderThan // If resourceVersion is not specified, serve it from underlying // storage (for backward compatibility). If a continuation is @@ -631,7 +726,7 @@ func shouldDelegateList(opts storage.ListOptions) bool { // Limits are only sent to storage when resourceVersion is non-zero // since the watch cache isn't able to perform continuations, and // limits are ignored when resource version is zero - return resourceVersion == "" || hasContinuation || hasLimit || opts.ResourceVersionMatch == metav1.ResourceVersionMatchExact + return resourceVersion == "" || hasContinuation || hasLimit || unsupportedMatch } func (c *Cacher) listItems(ctx context.Context, listRV uint64, key string, pred storage.SelectionPredicate, recursive bool) ([]interface{}, uint64, string, error) { @@ -676,7 +771,7 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio attribute.Stringer("type", c.groupResource)) defer span.End(500 * time.Millisecond) - if err := c.ready.wait(); err != nil { + if err := c.ready.wait(ctx); err != nil { return errors.NewServiceUnavailable(err.Error()) } span.AddEvent("Ready") @@ -715,6 +810,10 @@ func (c *Cacher) GetList(ctx context.Context, key string, opts storage.ListOptio listVal.Set(reflect.Append(listVal, reflect.ValueOf(elem.Object).Elem())) } } + if listVal.IsNil() { + // Ensure that we never return a nil Items pointer in the result for consistency. + listVal.Set(reflect.MakeSlice(listVal.Type(), 0, 0)) + } span.AddEvent("Filtered items", attribute.Int("count", listVal.Len())) if c.versioner != nil { if err := c.versioner.UpdateList(listObj, readResourceVersion, "", nil); err != nil { @@ -974,10 +1073,32 @@ func (c *Cacher) startDispatching(event *watchCacheEvent) { return } - // Iterate over "allWatchers" no matter what the trigger function is. - for _, watcher := range c.watchers.allWatchers { + // iterate over watchers for each applicable namespace/name tuple + namespace := event.ObjFields["metadata.namespace"] + name := event.ObjFields["metadata.name"] + if len(namespace) > 0 { + if len(name) > 0 { + // namespaced watchers scoped by name + for _, watcher := range c.watchers.allWatchers[namespacedName{namespace: namespace, name: name}] { + c.watchersBuffer = append(c.watchersBuffer, watcher) + } + } + // namespaced watchers not scoped by name + for _, watcher := range c.watchers.allWatchers[namespacedName{namespace: namespace}] { + c.watchersBuffer = append(c.watchersBuffer, watcher) + } + } + if len(name) > 0 { + // cluster-wide watchers scoped by name + for _, watcher := range c.watchers.allWatchers[namespacedName{name: name}] { + c.watchersBuffer = append(c.watchersBuffer, watcher) + } + } + // cluster-wide watchers unscoped by name + for _, watcher := range c.watchers.allWatchers[namespacedName{}] { c.watchersBuffer = append(c.watchersBuffer, watcher) } + if supported { // Iterate over watchers interested in the given values of the trigger. for _, triggerValue := range triggerValues { @@ -1059,7 +1180,7 @@ func (c *Cacher) Stop() { c.stopWg.Wait() } -func forgetWatcher(c *Cacher, w *cacheWatcher, index int, triggerValue string, triggerSupported bool) func(bool) { +func forgetWatcher(c *Cacher, w *cacheWatcher, index int, scope namespacedName, triggerValue string, triggerSupported bool) func(bool) { return func(drainWatcher bool) { c.Lock() defer c.Unlock() @@ -1069,7 +1190,7 @@ func forgetWatcher(c *Cacher, w *cacheWatcher, index int, triggerValue string, t // It's possible that the watcher is already not in the structure (e.g. in case of // simultaneous Stop() and terminateAllWatchers(), but it is safe to call stopLocked() // on a watcher multiple times. - c.watchers.deleteWatcher(index, triggerValue, triggerSupported, c.stopWatcherLocked) + c.watchers.deleteWatcher(index, scope, triggerValue, triggerSupported, c.stopWatcherLocked) } } @@ -1085,7 +1206,7 @@ func filterWithAttrsFunction(key string, p storage.SelectionPredicate) filterWit // LastSyncResourceVersion returns resource version to which the underlying cache is synced. func (c *Cacher) LastSyncResourceVersion() (uint64, error) { - if err := c.ready.wait(); err != nil { + if err := c.ready.wait(context.Background()); err != nil { return 0, errors.NewServiceUnavailable(err.Error()) } @@ -1093,6 +1214,101 @@ func (c *Cacher) LastSyncResourceVersion() (uint64, error) { return c.versioner.ParseResourceVersion(resourceVersion) } +// getCurrentResourceVersionFromStorage gets the current resource version from the underlying storage engine. +// this method issues an empty list request and reads only the ResourceVersion from the object metadata +func (c *Cacher) getCurrentResourceVersionFromStorage(ctx context.Context) (uint64, error) { + if c.newListFunc == nil { + return 0, fmt.Errorf("newListFunction wasn't provided for %v", c.objectType) + } + emptyList := c.newListFunc() + pred := storage.SelectionPredicate{ + Label: labels.Everything(), + Field: fields.Everything(), + Limit: 1, // just in case we actually hit something + } + + err := c.storage.GetList(ctx, c.resourcePrefix, storage.ListOptions{Predicate: pred}, emptyList) + if err != nil { + return 0, err + } + emptyListAccessor, err := meta.ListAccessor(emptyList) + if err != nil { + return 0, err + } + if emptyListAccessor == nil { + return 0, fmt.Errorf("unable to extract a list accessor from %T", emptyList) + } + + currentResourceVersion, err := strconv.Atoi(emptyListAccessor.GetResourceVersion()) + if err != nil { + return 0, err + } + + if currentResourceVersion == 0 { + return 0, fmt.Errorf("the current resource version must be greater than 0") + } + return uint64(currentResourceVersion), nil +} + +// getBookmarkAfterResourceVersionLockedFunc returns a function that +// spits a ResourceVersion after which the bookmark event will be delivered. +// +// The returned function must be called under the watchCache lock. +func (c *Cacher) getBookmarkAfterResourceVersionLockedFunc(ctx context.Context, parsedResourceVersion uint64, opts storage.ListOptions) (func() uint64, error) { + if opts.SendInitialEvents == nil || *opts.SendInitialEvents == false || !opts.Predicate.AllowWatchBookmarks { + return func() uint64 { return 0 }, nil + } + return c.getCommonResourceVersionLockedFunc(ctx, parsedResourceVersion, opts) +} + +// getStartResourceVersionForWatchLockedFunc returns a function that +// spits a ResourceVersion the watch will be started from. +// Depending on the input parameters the semantics of the returned ResourceVersion are: +// - start at Exact (return parsedWatchResourceVersion) +// - start at Most Recent (return an RV from etcd) +// - start at Any (return the current watchCache's RV) +// +// The returned function must be called under the watchCache lock. +func (c *Cacher) getStartResourceVersionForWatchLockedFunc(ctx context.Context, parsedWatchResourceVersion uint64, opts storage.ListOptions) (func() uint64, error) { + if opts.SendInitialEvents == nil || *opts.SendInitialEvents == true { + return func() uint64 { return parsedWatchResourceVersion }, nil + } + return c.getCommonResourceVersionLockedFunc(ctx, parsedWatchResourceVersion, opts) +} + +// getCommonResourceVersionLockedFunc a helper that simply computes a ResourceVersion +// based on the input parameters. Please examine callers of this method to get more context. +// +// The returned function must be called under the watchCache lock. +func (c *Cacher) getCommonResourceVersionLockedFunc(ctx context.Context, parsedWatchResourceVersion uint64, opts storage.ListOptions) (func() uint64, error) { + switch { + case len(opts.ResourceVersion) == 0: + rv, err := c.getCurrentResourceVersionFromStorage(ctx) + if err != nil { + return nil, err + } + return func() uint64 { return rv }, nil + case parsedWatchResourceVersion == 0: + // here we assume that watchCache locked is already held + return func() uint64 { return c.watchCache.resourceVersion }, nil + default: + return func() uint64 { return parsedWatchResourceVersion }, nil + } +} + +// waitUntilWatchCacheFreshAndForceAllEvents waits until cache is at least +// as fresh as given requestedWatchRV if sendInitialEvents was requested. +// Additionally, it instructs the caller whether it should ask for +// all events from the cache (full state) or not. +func (c *Cacher) waitUntilWatchCacheFreshAndForceAllEvents(ctx context.Context, requestedWatchRV uint64, opts storage.ListOptions) (bool, error) { + if opts.SendInitialEvents != nil && *opts.SendInitialEvents == true { + err := c.watchCache.waitUntilFreshAndBlock(ctx, requestedWatchRV) + defer c.watchCache.RUnlock() + return err == nil, err + } + return false, nil +} + // cacherListerWatcher opaques storage.Interface to expose cache.ListerWatcher. type cacherListerWatcher struct { storage storage.Interface @@ -1181,339 +1397,23 @@ func (c *errWatcher) Stop() { // no-op } -// cacheWatcher implements watch.Interface -// this is not thread-safe -type cacheWatcher struct { - input chan *watchCacheEvent - result chan watch.Event - done chan struct{} - filter filterWithAttrsFunc - stopped bool - forget func(bool) - versioner storage.Versioner - // The watcher will be closed by server after the deadline, - // save it here to send bookmark events before that. - deadline time.Time - allowWatchBookmarks bool - groupResource schema.GroupResource - - // human readable identifier that helps assigning cacheWatcher - // instance with request - identifier string - - // drainInputBuffer indicates whether we should delay closing this watcher - // and send all event in the input buffer. - drainInputBuffer bool +// immediateCloseWatcher implements watch.Interface that is immediately closed +type immediateCloseWatcher struct { + result chan watch.Event } -func newCacheWatcher( - chanSize int, - filter filterWithAttrsFunc, - forget func(bool), - versioner storage.Versioner, - deadline time.Time, - allowWatchBookmarks bool, - groupResource schema.GroupResource, - identifier string, -) *cacheWatcher { - return &cacheWatcher{ - input: make(chan *watchCacheEvent, chanSize), - result: make(chan watch.Event, chanSize), - done: make(chan struct{}), - filter: filter, - stopped: false, - forget: forget, - versioner: versioner, - deadline: deadline, - allowWatchBookmarks: allowWatchBookmarks, - groupResource: groupResource, - identifier: identifier, - } +func newImmediateCloseWatcher() *immediateCloseWatcher { + watcher := &immediateCloseWatcher{result: make(chan watch.Event)} + close(watcher.result) + return watcher } // Implements watch.Interface. -func (c *cacheWatcher) ResultChan() <-chan watch.Event { +func (c *immediateCloseWatcher) ResultChan() <-chan watch.Event { return c.result } // Implements watch.Interface. -func (c *cacheWatcher) Stop() { - c.forget(false) -} - -// we rely on the fact that stopLocked is actually protected by Cacher.Lock() -func (c *cacheWatcher) stopLocked() { - if !c.stopped { - c.stopped = true - // stop without draining the input channel was requested. - if !c.drainInputBuffer { - close(c.done) - } - close(c.input) - } - - // Even if the watcher was already stopped, if it previously was - // using draining mode and it's not using it now we need to - // close the done channel now. Otherwise we could leak the - // processing goroutine if it will be trying to put more objects - // into result channel, the channel will be full and there will - // already be noone on the processing the events on the receiving end. - if !c.drainInputBuffer && !c.isDoneChannelClosedLocked() { - close(c.done) - } -} - -func (c *cacheWatcher) nonblockingAdd(event *watchCacheEvent) bool { - select { - case c.input <- event: - return true - default: - return false - } -} - -// Nil timer means that add will not block (if it can't send event immediately, it will break the watcher) -func (c *cacheWatcher) add(event *watchCacheEvent, timer *time.Timer) bool { - // Try to send the event immediately, without blocking. - if c.nonblockingAdd(event) { - return true - } - - closeFunc := func() { - // This means that we couldn't send event to that watcher. - // Since we don't want to block on it infinitely, - // we simply terminate it. - klog.V(1).Infof("Forcing %v watcher close due to unresponsiveness: %v. len(c.input) = %v, len(c.result) = %v", c.groupResource.String(), c.identifier, len(c.input), len(c.result)) - metrics.TerminatedWatchersCounter.WithLabelValues(c.groupResource.String()).Inc() - c.forget(false) - } - - if timer == nil { - closeFunc() - return false - } - - // OK, block sending, but only until timer fires. - select { - case c.input <- event: - return true - case <-timer.C: - closeFunc() - return false - } -} - -func (c *cacheWatcher) nextBookmarkTime(now time.Time, bookmarkFrequency time.Duration) (time.Time, bool) { - // We try to send bookmarks: - // - // (a) right before the watcher timeout - for now we simply set it 2s before - // the deadline - // - // (b) roughly every minute - // - // (b) gives us periodicity if the watch breaks due to unexpected - // conditions, (a) ensures that on timeout the watcher is as close to - // now as possible - this covers 99% of cases. - - heartbeatTime := now.Add(bookmarkFrequency) - if c.deadline.IsZero() { - // Timeout is set by our client libraries (e.g. reflector) as well as defaulted by - // apiserver if properly configured. So this shoudln't happen in practice. - return heartbeatTime, true - } - if pretimeoutTime := c.deadline.Add(-2 * time.Second); pretimeoutTime.Before(heartbeatTime) { - heartbeatTime = pretimeoutTime - } - - if heartbeatTime.Before(now) { - return time.Time{}, false - } - return heartbeatTime, true -} - -// setDrainInputBufferLocked if set to true indicates that we should delay closing this watcher -// until we send all events residing in the input buffer. -func (c *cacheWatcher) setDrainInputBufferLocked(drain bool) { - c.drainInputBuffer = drain -} - -// isDoneChannelClosed checks if c.done channel is closed -func (c *cacheWatcher) isDoneChannelClosedLocked() bool { - select { - case <-c.done: - return true - default: - } - return false -} - -func getMutableObject(object runtime.Object) runtime.Object { - if _, ok := object.(*cachingObject); ok { - // It is safe to return without deep-copy, because the underlying - // object will lazily perform deep-copy on the first try to change - // any of its fields. - return object - } - return object.DeepCopyObject() -} - -func updateResourceVersion(object runtime.Object, versioner storage.Versioner, resourceVersion uint64) { - if err := versioner.UpdateObject(object, resourceVersion); err != nil { - utilruntime.HandleError(fmt.Errorf("failure to version api object (%d) %#v: %v", resourceVersion, object, err)) - } -} - -func (c *cacheWatcher) convertToWatchEvent(event *watchCacheEvent) *watch.Event { - if event.Type == watch.Bookmark { - return &watch.Event{Type: watch.Bookmark, Object: event.Object.DeepCopyObject()} - } - - curObjPasses := event.Type != watch.Deleted && c.filter(event.Key, event.ObjLabels, event.ObjFields) - oldObjPasses := false - if event.PrevObject != nil { - oldObjPasses = c.filter(event.Key, event.PrevObjLabels, event.PrevObjFields) - } - if !curObjPasses && !oldObjPasses { - // Watcher is not interested in that object. - return nil - } - - switch { - case curObjPasses && !oldObjPasses: - return &watch.Event{Type: watch.Added, Object: getMutableObject(event.Object)} - case curObjPasses && oldObjPasses: - return &watch.Event{Type: watch.Modified, Object: getMutableObject(event.Object)} - case !curObjPasses && oldObjPasses: - // return a delete event with the previous object content, but with the event's resource version - oldObj := getMutableObject(event.PrevObject) - // We know that if oldObj is cachingObject (which can only be set via - // setCachingObjects), its resourceVersion is already set correctly and - // we don't need to update it. However, since cachingObject efficiently - // handles noop updates, we avoid this microoptimization here. - updateResourceVersion(oldObj, c.versioner, event.ResourceVersion) - return &watch.Event{Type: watch.Deleted, Object: oldObj} - } - - return nil -} - -// NOTE: sendWatchCacheEvent is assumed to not modify !!! -func (c *cacheWatcher) sendWatchCacheEvent(event *watchCacheEvent) { - watchEvent := c.convertToWatchEvent(event) - if watchEvent == nil { - // Watcher is not interested in that object. - return - } - - // We need to ensure that if we put event X to the c.result, all - // previous events were already put into it before, no matter whether - // c.done is close or not. - // Thus we cannot simply select from c.done and c.result and this - // would give us non-determinism. - // At the same time, we don't want to block infinitely on putting - // to c.result, when c.done is already closed. - // - // This ensures that with c.done already close, we at most once go - // into the next select after this. With that, no matter which - // statement we choose there, we will deliver only consecutive - // events. - select { - case <-c.done: - return - default: - } - - select { - case c.result <- *watchEvent: - case <-c.done: - } -} - -func (c *cacheWatcher) processInterval(ctx context.Context, cacheInterval *watchCacheInterval, resourceVersion uint64) { - defer utilruntime.HandleCrash() - defer close(c.result) - defer c.Stop() - - // Check how long we are processing initEvents. - // As long as these are not processed, we are not processing - // any incoming events, so if it takes long, we may actually - // block all watchers for some time. - // TODO: From the logs it seems that there happens processing - // times even up to 1s which is very long. However, this doesn't - // depend that much on the number of initEvents. E.g. from the - // 2000-node Kubemark run we have logs like this, e.g.: - // ... processing 13862 initEvents took 66.808689ms - // ... processing 14040 initEvents took 993.532539ms - // We should understand what is blocking us in those cases (e.g. - // is it lack of CPU, network, or sth else) and potentially - // consider increase size of result buffer in those cases. - const initProcessThreshold = 500 * time.Millisecond - startTime := time.Now() - - initEventCount := 0 - for { - event, err := cacheInterval.Next() - if err != nil { - // An error indicates that the cache interval - // has been invalidated and can no longer serve - // events. - // - // Initially we considered sending an "out-of-history" - // Error event in this case, but because historically - // such events weren't sent out of the watchCache, we - // decided not to. This is still ok, because on watch - // closure, the watcher will try to re-instantiate the - // watch and then will get an explicit "out-of-history" - // window. There is potential for optimization, but for - // now, in order to be on the safe side and not break - // custom clients, the cost of it is something that we - // are fully accepting. - klog.Warningf("couldn't retrieve watch event to serve: %#v", err) - return - } - if event == nil { - break - } - c.sendWatchCacheEvent(event) - // With some events already sent, update resourceVersion so that - // events that were buffered and not yet processed won't be delivered - // to this watcher second time causing going back in time. - resourceVersion = event.ResourceVersion - initEventCount++ - } - - if initEventCount > 0 { - metrics.InitCounter.WithLabelValues(c.groupResource.String()).Add(float64(initEventCount)) - } - processingTime := time.Since(startTime) - if processingTime > initProcessThreshold { - klog.V(2).Infof("processing %d initEvents of %s (%s) took %v", initEventCount, c.groupResource, c.identifier, processingTime) - } - - c.process(ctx, resourceVersion) -} - -func (c *cacheWatcher) process(ctx context.Context, resourceVersion uint64) { - // At this point we already start processing incoming watch events. - // However, the init event can still be processed because their serialization - // and sending to the client happens asynchrnously. - // TODO: As describe in the KEP, we would like to estimate that by delaying - // the initialization signal proportionally to the number of events to - // process, but we're leaving this to the tuning phase. - utilflowcontrol.WatchInitialized(ctx) - - for { - select { - case event, ok := <-c.input: - if !ok { - return - } - // only send events newer than resourceVersion - if event.ResourceVersion > resourceVersion { - c.sendWatchCacheEvent(event) - } - case <-ctx.Done(): - return - } - } +func (c *immediateCloseWatcher) Stop() { + // no-op } diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/metrics/metrics.go index ffebf5e5b..d0b3cdc90 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/metrics/metrics.go @@ -74,6 +74,17 @@ var ( []string{"resource"}, ) + EventsReceivedCounter = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "events_received_total", + Help: "Counter of events received in watch cache broken by resource type.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) + EventsCounter = compbasemetrics.NewCounterVec( &compbasemetrics.CounterOpts{ Namespace: namespace, @@ -147,6 +158,7 @@ func Register() { legacyregistry.MustRegister(listCacheNumFetched) legacyregistry.MustRegister(listCacheNumReturned) legacyregistry.MustRegister(InitCounter) + legacyregistry.MustRegister(EventsReceivedCounter) legacyregistry.MustRegister(EventsCounter) legacyregistry.MustRegister(TerminatedWatchersCounter) legacyregistry.MustRegister(watchCacheCapacityIncreaseTotal) @@ -167,7 +179,7 @@ func RecordListCacheMetrics(resourcePrefix, indexName string, numFetched, numRet func RecordsWatchCacheCapacityChange(objType string, old, new int) { WatchCacheCapacity.WithLabelValues(objType).Set(float64(new)) if old < new { - WatchCacheCapacity.WithLabelValues(objType).Inc() + watchCacheCapacityIncreaseTotal.WithLabelValues(objType).Inc() return } watchCacheCapacityDecreaseTotal.WithLabelValues(objType).Inc() diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/ready.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/ready.go index 8278dd2b2..012d6d585 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/ready.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/ready.go @@ -17,6 +17,7 @@ limitations under the License. package cacher import ( + "context" "fmt" "sync" ) @@ -30,67 +31,127 @@ const ( ) // ready is a three state condition variable that blocks until is Ready if is not Stopped. -// Its initial state is Pending. +// Its initial state is Pending and its state machine diagram is as follow. +// +// Pending <------> Ready -----> Stopped +// +// | ^ +// └---------------------------┘ type ready struct { - state status - c *sync.Cond + state status // represent the state of the variable + generation int // represent the number of times we have transtioned to ready + lock sync.RWMutex // protect the state and generation variables + restartLock sync.Mutex // protect the transition from ready to pending where the channel is recreated + waitCh chan struct{} // blocks until is ready or stopped } func newReady() *ready { return &ready{ - c: sync.NewCond(&sync.RWMutex{}), - state: Pending, + waitCh: make(chan struct{}), + state: Pending, } } +// done close the channel once the state is Ready or Stopped +func (r *ready) done() chan struct{} { + r.restartLock.Lock() + defer r.restartLock.Unlock() + return r.waitCh +} + // wait blocks until it is Ready or Stopped, it returns an error if is Stopped. -func (r *ready) wait() error { - r.c.L.Lock() - defer r.c.L.Unlock() - for r.state == Pending { - r.c.Wait() - } - switch r.state { - case Ready: - return nil - case Stopped: - return fmt.Errorf("apiserver cacher is stopped") - default: - return fmt.Errorf("unexpected apiserver cache state: %v", r.state) +func (r *ready) wait(ctx context.Context) error { + _, err := r.waitAndReadGeneration(ctx) + return err +} + +// waitAndReadGenration blocks until it is Ready or Stopped and returns number +// of times we entered ready state if Ready and error otherwise. +func (r *ready) waitAndReadGeneration(ctx context.Context) (int, error) { + for { + // r.done() only blocks if state is Pending + select { + case <-ctx.Done(): + return 0, ctx.Err() + case <-r.done(): + } + + r.lock.RLock() + switch r.state { + case Pending: + // since we allow to switch between the states Pending and Ready + // if there is a quick transition from Pending -> Ready -> Pending + // a process that was waiting can get unblocked and see a Pending + // state again. If the state is Pending we have to wait again to + // avoid an inconsistent state on the system, with some processes not + // waiting despite the state moved back to Pending. + r.lock.RUnlock() + case Ready: + generation := r.generation + r.lock.RUnlock() + return generation, nil + case Stopped: + r.lock.RUnlock() + return 0, fmt.Errorf("apiserver cacher is stopped") + default: + r.lock.RUnlock() + return 0, fmt.Errorf("unexpected apiserver cache state: %v", r.state) + } } } // check returns true only if it is Ready. func (r *ready) check() bool { - // TODO: Make check() function more sophisticated, in particular - // allow it to behave as "waitWithTimeout". - rwMutex := r.c.L.(*sync.RWMutex) - rwMutex.RLock() - defer rwMutex.RUnlock() - return r.state == Ready + _, ok := r.checkAndReadGeneration() + return ok +} + +// checkAndReadGeneration returns the current generation and whether it is Ready. +func (r *ready) checkAndReadGeneration() (int, bool) { + r.lock.RLock() + defer r.lock.RUnlock() + return r.generation, r.state == Ready } // set the state to Pending (false) or Ready (true), it does not have effect if the state is Stopped. func (r *ready) set(ok bool) { - r.c.L.Lock() - defer r.c.L.Unlock() + r.lock.Lock() + defer r.lock.Unlock() if r.state == Stopped { return } - if ok { + if ok && r.state == Pending { r.state = Ready - } else { + r.generation++ + select { + case <-r.waitCh: + default: + close(r.waitCh) + } + } else if !ok && r.state == Ready { + // creating the waitCh can be racy if + // something enter the wait() method + select { + case <-r.waitCh: + r.restartLock.Lock() + r.waitCh = make(chan struct{}) + r.restartLock.Unlock() + default: + } r.state = Pending } - r.c.Broadcast() } // stop the condition variable and set it as Stopped. This state is irreversible. func (r *ready) stop() { - r.c.L.Lock() - defer r.c.L.Unlock() + r.lock.Lock() + defer r.lock.Unlock() if r.state != Stopped { r.state = Stopped - r.c.Broadcast() + } + select { + case <-r.waitCh: + default: + close(r.waitCh) } } diff --git a/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go index bbbeee361..4d86018e5 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go +++ b/vendor/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go @@ -156,14 +156,15 @@ type watchCache struct { // getAttrsFunc is used to get labels and fields of an object. getAttrsFunc func(runtime.Object) (labels.Set, fields.Set, error) - // cache is used a cyclic buffer - its first element (with the smallest - // resourceVersion) is defined by startIndex, its last element is defined - // by endIndex (if cache is full it will be startIndex + capacity). - // Both startIndex and endIndex can be greater than buffer capacity - - // you should always apply modulo capacity to get an index in cache array. + // cache is used a cyclic buffer - the "current" contents of it are + // stored in [start_index%capacity, end_index%capacity) - so the + // "current" contents have exactly end_index-start_index items. cache []*watchCacheEvent startIndex int endIndex int + // removedEventSinceRelist holds the information whether any of the events + // were already removed from the `cache` cyclic buffer since the last relist + removedEventSinceRelist bool // store will effectively support LIST operation from the "end of cache // history" i.e. from the moment just after the newest cached watched event. @@ -280,6 +281,8 @@ func (w *watchCache) objectToVersionedRuntimeObject(obj interface{}) (runtime.Ob // processEvent is safe as long as there is at most one call to it in flight // at any point in time. func (w *watchCache) processEvent(event watch.Event, resourceVersion uint64, updateFunc func(*storeElement) error) error { + metrics.EventsReceivedCounter.WithLabelValues(w.groupResource.String()).Inc() + key, err := w.keyFunc(event.Object) if err != nil { return fmt.Errorf("couldn't compute key: %v", err) @@ -344,6 +347,7 @@ func (w *watchCache) updateCache(event *watchCacheEvent) { if w.isCacheFullLocked() { // Cache is full - remove the oldest element. w.startIndex++ + w.removedEventSinceRelist = true } w.cache[w.endIndex%w.capacity] = event w.endIndex++ @@ -463,6 +467,20 @@ func (w *watchCache) waitUntilFreshAndBlock(ctx context.Context, resourceVersion return nil } +type sortableStoreElements []interface{} + +func (s sortableStoreElements) Len() int { + return len(s) +} + +func (s sortableStoreElements) Less(i, j int) bool { + return s[i].(*storeElement).Key < s[j].(*storeElement).Key +} + +func (s sortableStoreElements) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + // WaitUntilFreshAndList returns list of pointers to `storeElement` objects along // with their ResourceVersion and the name of the index, if any, that was used. func (w *watchCache) WaitUntilFreshAndList(ctx context.Context, resourceVersion uint64, matchValues []storage.MatchValue) ([]interface{}, uint64, string, error) { @@ -472,16 +490,21 @@ func (w *watchCache) WaitUntilFreshAndList(ctx context.Context, resourceVersion return nil, 0, "", err } - // This isn't the place where we do "final filtering" - only some "prefiltering" is happening here. So the only - // requirement here is to NOT miss anything that should be returned. We can return as many non-matching items as we - // want - they will be filtered out later. The fact that we return less things is only further performance improvement. - // TODO: if multiple indexes match, return the one with the fewest items, so as to do as much filtering as possible. - for _, matchValue := range matchValues { - if result, err := w.store.ByIndex(matchValue.IndexName, matchValue.Value); err == nil { - return result, w.resourceVersion, matchValue.IndexName, nil + result, rv, index, err := func() ([]interface{}, uint64, string, error) { + // This isn't the place where we do "final filtering" - only some "prefiltering" is happening here. So the only + // requirement here is to NOT miss anything that should be returned. We can return as many non-matching items as we + // want - they will be filtered out later. The fact that we return less things is only further performance improvement. + // TODO: if multiple indexes match, return the one with the fewest items, so as to do as much filtering as possible. + for _, matchValue := range matchValues { + if result, err := w.store.ByIndex(matchValue.IndexName, matchValue.Value); err == nil { + return result, w.resourceVersion, matchValue.IndexName, nil + } } - } - return w.store.List(), w.resourceVersion, "", nil + return w.store.List(), w.resourceVersion, "", nil + }() + + sort.Sort(sortableStoreElements(result)) + return result, rv, index, err } // WaitUntilFreshAndGet returns a pointers to object. @@ -551,8 +574,15 @@ func (w *watchCache) Replace(objs []interface{}, resourceVersion string) error { w.Lock() defer w.Unlock() - w.startIndex = 0 - w.endIndex = 0 + // Ensure startIndex never decreases, so that existing watchCacheInterval + // instances get "invalid" errors if the try to download from the buffer + // using their own start/end indexes calculated from previous buffer + // content. + + // Empty the cyclic buffer, ensuring startIndex doesn't decrease. + w.startIndex = w.endIndex + w.removedEventSinceRelist = false + if err := w.store.Replace(toReplace, resourceVersion); err != nil { return err } @@ -643,7 +673,7 @@ func (w *watchCache) getAllEventsSinceLocked(resourceVersion uint64) (*watchCach size := w.endIndex - w.startIndex var oldest uint64 switch { - case w.listResourceVersion > 0 && w.startIndex == 0: + case w.listResourceVersion > 0 && !w.removedEventSinceRelist: // If no event was removed from the buffer since last relist, the oldest watch // event we can deliver is one greater than the resource version of the list. oldest = w.listResourceVersion + 1 @@ -665,11 +695,7 @@ func (w *watchCache) getAllEventsSinceLocked(resourceVersion uint64) (*watchCach // current state and only then start watching from that point. // // TODO: In v2 api, we should stop returning the current state - #13969. - ci, err := newCacheIntervalFromStore(w.resourceVersion, w.store, w.getAttrsFunc) - if err != nil { - return nil, err - } - return ci, nil + return w.getIntervalFromStoreLocked() } if resourceVersion < oldest-1 { return nil, errors.NewResourceExpired(fmt.Sprintf("too old resource version: %d (%d)", resourceVersion, oldest-1)) @@ -686,3 +712,14 @@ func (w *watchCache) getAllEventsSinceLocked(resourceVersion uint64) (*watchCach ci := newCacheInterval(w.startIndex+first, w.endIndex, indexerFunc, w.indexValidator, &w.RWMutex) return ci, nil } + +// getIntervalFromStoreLocked returns a watchCacheInterval +// that covers the entire storage state. +// This function assumes to be called under the watchCache lock. +func (w *watchCache) getIntervalFromStoreLocked() (*watchCacheInterval, error) { + ci, err := newCacheIntervalFromStore(w.resourceVersion, w.store, w.getAttrsFunc) + if err != nil { + return nil, err + } + return ci, nil +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go index 96d592e79..f60210f96 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/latency_tracker.go @@ -47,8 +47,7 @@ func NewETCDLatencyTracker(delegate clientv3.KV) clientv3.KV { // tracking function TrackStorageLatency is thread safe. // // NOTE: Compact is an asynchronous process and is not associated with -// -// any request, so we will not be tracking its latency. +// any request, so we will not be tracking its latency. type clientV3KVLatencyTracker struct { clientv3.KV } diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go index 825582294..6f155c0ad 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/metrics/metrics.go @@ -64,6 +64,15 @@ var ( }, []string{"endpoint"}, ) + etcdEventsReceivedCounts = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Subsystem: "apiserver", + Name: "storage_events_received_total", + Help: "Number of etcd events received split by kind.", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) etcdBookmarkCounts = compbasemetrics.NewGaugeVec( &compbasemetrics.GaugeOpts{ Name: "etcd_bookmark_counts", @@ -113,6 +122,15 @@ var ( }, []string{"resource"}, ) + decodeErrorCounts = compbasemetrics.NewCounterVec( + &compbasemetrics.CounterOpts{ + Namespace: "apiserver", + Name: "storage_decode_errors_total", + Help: "Number of stored object decode errors split by object type", + StabilityLevel: compbasemetrics.ALPHA, + }, + []string{"resource"}, + ) ) var registerMetrics sync.Once @@ -130,6 +148,7 @@ func Register() { legacyregistry.MustRegister(listStorageNumFetched) legacyregistry.MustRegister(listStorageNumSelectorEvals) legacyregistry.MustRegister(listStorageNumReturned) + legacyregistry.MustRegister(decodeErrorCounts) }) } @@ -143,11 +162,21 @@ func RecordEtcdRequestLatency(verb, resource string, startTime time.Time) { etcdRequestLatency.WithLabelValues(verb, resource).Observe(sinceInSeconds(startTime)) } +// RecordEtcdEvent updated the etcd_events_received_total metric. +func RecordEtcdEvent(resource string) { + etcdEventsReceivedCounts.WithLabelValues(resource).Inc() +} + // RecordEtcdBookmark updates the etcd_bookmark_counts metric. func RecordEtcdBookmark(resource string) { etcdBookmarkCounts.WithLabelValues(resource).Inc() } +// RecordDecodeError sets the storage_decode_errors metrics. +func RecordDecodeError(resource string) { + decodeErrorCounts.WithLabelValues(resource).Inc() +} + // Reset resets the etcd_request_duration_seconds metric. func Reset() { etcdRequestLatency.Reset() diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go index 51e5b9012..2fc237de3 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/store.go @@ -33,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/conversion" @@ -156,7 +157,12 @@ func (s *store) Get(ctx context.Context, key string, opts storage.GetOptions, ou return storage.NewInternalError(err.Error()) } - return decode(s.codec, s.versioner, data, out, kv.ModRevision) + err = decode(s.codec, s.versioner, data, out, kv.ModRevision) + if err != nil { + recordDecodeError(s.groupResourceString, preparedKey) + return err + } + return nil } // Create implements storage.Interface.Create. @@ -220,6 +226,7 @@ func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object, err = decode(s.codec, s.versioner, data, out, putResp.Header.Revision) if err != nil { span.AddEvent("decode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + recordDecodeError(s.groupResourceString, preparedKey) return err } span.AddEvent("decode succeeded", attribute.Int("len", len(data))) @@ -352,7 +359,12 @@ func (s *store) conditionalDelete( if deleteResp.Header == nil { return errors.New("invalid DeleteRange response - nil header") } - return decode(s.codec, s.versioner, origState.data, out, deleteResp.Header.Revision) + err = decode(s.codec, s.versioner, origState.data, out, deleteResp.Header.Revision) + if err != nil { + recordDecodeError(s.groupResourceString, key) + return err + } + return nil } } @@ -470,7 +482,12 @@ func (s *store) GuaranteedUpdate( } // recheck that the data from etcd is not stale before short-circuiting a write if !origState.stale { - return decode(s.codec, s.versioner, origState.data, destination, origState.rev) + err = decode(s.codec, s.versioner, origState.data, destination, origState.rev) + if err != nil { + recordDecodeError(s.groupResourceString, preparedKey) + return err + } + return nil } } @@ -518,6 +535,7 @@ func (s *store) GuaranteedUpdate( err = decode(s.codec, s.versioner, data, destination, putResp.Header.Revision) if err != nil { span.AddEvent("decode failed", attribute.Int("len", len(data)), attribute.String("err", err.Error())) + recordDecodeError(s.groupResourceString, preparedKey) return err } span.AddEvent("decode succeeded", attribute.Int("len", len(data))) @@ -745,6 +763,7 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption } if err := appendListItem(v, data, uint64(kv.ModRevision), pred, s.codec, s.versioner, newItemFunc); err != nil { + recordDecodeError(s.groupResourceString, string(kv.Key)) return err } numEvald++ @@ -782,6 +801,10 @@ func (s *store) GetList(ctx context.Context, key string, opts storage.ListOption options = append(options, clientv3.WithRev(withRev)) } } + if v.IsNil() { + // Ensure that we never return a nil Items pointer in the result for consistency. + v.Set(reflect.MakeSlice(v.Type(), 0, 0)) + } // instruct the client to begin querying from immediately after the last key we returned // we never return a key that the client wouldn't be allowed to see @@ -841,6 +864,13 @@ func growSlice(v reflect.Value, maxCapacity int, sizes ...int) { // Watch implements storage.Interface.Watch. func (s *store) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) { + if opts.SendInitialEvents != nil { + return nil, apierrors.NewInvalid( + schema.GroupKind{Group: s.groupResource.Group, Kind: s.groupResource.Resource}, + "", + field.ErrorList{field.Forbidden(field.NewPath("sendInitialEvents"), "for watch is unsupported by an etcd cluster")}, + ) + } preparedKey, err := s.prepareKey(key) if err != nil { return nil, err @@ -880,6 +910,7 @@ func (s *store) getState(ctx context.Context, getResp *clientv3.GetResponse, key state.data = data state.stale = stale if err := decode(s.codec, s.versioner, state.data, state.obj, state.rev); err != nil { + recordDecodeError(s.groupResourceString, key) return nil, err } } @@ -1018,6 +1049,12 @@ func appendListItem(v reflect.Value, data []byte, rev uint64, pred storage.Selec return nil } +// recordDecodeError record decode error split by object type. +func recordDecodeError(resource string, key string) { + metrics.RecordDecodeError(resource) + klog.V(4).Infof("Decoding %s \"%s\" failed", resource, key) +} + func notFound(key string) clientv3.Cmp { return clientv3.Compare(clientv3.ModRevision(key), "=", 0) } diff --git a/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go b/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go index c0b7be35c..49d9005fc 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go +++ b/vendor/k8s.io/apiserver/pkg/storage/etcd3/watcher.go @@ -25,6 +25,9 @@ import ( "strings" "sync" + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -35,6 +38,7 @@ import ( utilflowcontrol "k8s.io/apiserver/pkg/util/flowcontrol" clientv3 "go.etcd.io/etcd/client/v3" + "k8s.io/klog/v2" ) @@ -152,6 +156,31 @@ func (w *watcher) createWatchChan(ctx context.Context, key string, rev int64, re return wc } +type etcdError interface { + Code() grpccodes.Code + Error() string +} + +type grpcError interface { + GRPCStatus() *grpcstatus.Status +} + +func isCancelError(err error) bool { + if err == nil { + return false + } + if err == context.Canceled { + return true + } + if etcdErr, ok := err.(etcdError); ok && etcdErr.Code() == grpccodes.Canceled { + return true + } + if grpcErr, ok := err.(grpcError); ok && grpcErr.GRPCStatus().Code() == grpccodes.Canceled { + return true + } + return false +} + func (wc *watchChan) run() { watchClosedCh := make(chan struct{}) go wc.startWatching(watchClosedCh) @@ -162,7 +191,7 @@ func (wc *watchChan) run() { select { case err := <-wc.errChan: - if err == context.Canceled { + if isCancelError(err) { break } errResult := transformErrorToEvent(err) @@ -213,12 +242,15 @@ func (wc *watchChan) sync() error { return nil } -// logWatchChannelErr checks whether the error is about mvcc revision compaction which is regarded as warning func logWatchChannelErr(err error) { - if !strings.Contains(err.Error(), "mvcc: required revision has been compacted") { - klog.Errorf("watch chan error: %v", err) - } else { + switch { + case strings.Contains(err.Error(), "mvcc: required revision has been compacted"): + // mvcc revision compaction which is regarded as warning, not error klog.Warningf("watch chan error: %v", err) + case isCancelError(err): + // expected when watches close, no need to log + default: + klog.Errorf("watch chan error: %v", err) } } @@ -256,6 +288,7 @@ func (wc *watchChan) startWatching(watchClosedCh chan struct{}) { } for _, e := range wres.Events { + metrics.RecordEtcdEvent(wc.watcher.groupResource.String()) parsedEvent, err := parseEvent(e) if err != nil { logWatchChannelErr(err) diff --git a/vendor/k8s.io/apiserver/pkg/storage/interfaces.go b/vendor/k8s.io/apiserver/pkg/storage/interfaces.go index 812aa412b..daf30a242 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/interfaces.go +++ b/vendor/k8s.io/apiserver/pkg/storage/interfaces.go @@ -268,4 +268,10 @@ type ListOptions struct { // ProgressNotify determines whether storage-originated bookmark (progress notify) events should // be delivered to the users. The option is ignored for non-watch requests. ProgressNotify bool + // SendInitialEvents, when set together with Watch option, + // begin the watch stream with synthetic init events to build the + // whole state of all resources followed by a synthetic "Bookmark" + // event containing a ResourceVersion after which the server + // continues streaming events. + SendInitialEvents *bool } diff --git a/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go b/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go index 7370518e3..a0a14366f 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go +++ b/vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go @@ -112,6 +112,18 @@ func (s *SelectionPredicate) MatchesObjectAttributes(l labels.Set, f fields.Set) return matched } +// MatchesSingleNamespace will return (namespace, true) if and only if s.Field matches on the object's +// namespace. +func (s *SelectionPredicate) MatchesSingleNamespace() (string, bool) { + if len(s.Continue) > 0 { + return "", false + } + if namespace, ok := s.Field.RequiresExactMatch("metadata.namespace"); ok { + return namespace, true + } + return "", false +} + // MatchesSingle will return (name, true) if and only if s.Field matches on the object's // name. func (s *SelectionPredicate) MatchesSingle() (string, bool) { diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go index 69930c039..b26c92e2d 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes/aes.go @@ -23,14 +23,24 @@ import ( "crypto/aes" "crypto/cipher" "crypto/rand" + "encoding/binary" "errors" "fmt" "io" + "sync/atomic" + "time" "k8s.io/apiserver/pkg/storage/value" + "k8s.io/klog/v2" ) -// gcm implements AEAD encryption of the provided values given a cipher.Block algorithm. +type gcm struct { + aead cipher.AEAD + nonceFunc func([]byte) error +} + +// NewGCMTransformer takes the given block cipher and performs encryption and decryption on the given data. +// It implements AEAD encryption of the provided values given a cipher.Block algorithm. // The authenticated data provided as part of the value.Context method must match when the same // value is set to and loaded from storage. In order to ensure that values cannot be copied by // an attacker from a location under their control, use characteristics of the storage location @@ -43,44 +53,148 @@ import ( // therefore transformers using this implementation *must* ensure they allow for frequent key // rotation. Future work should include investigation of AES-GCM-SIV as an alternative to // random nonces. -type gcm struct { - block cipher.Block +func NewGCMTransformer(block cipher.Block) (value.Transformer, error) { + aead, err := newGCM(block) + if err != nil { + return nil, err + } + + return &gcm{aead: aead, nonceFunc: randomNonce}, nil } -// NewGCMTransformer takes the given block cipher and performs encryption and decryption on the given -// data. -func NewGCMTransformer(block cipher.Block) value.Transformer { - return &gcm{block: block} +// NewGCMTransformerWithUniqueKeyUnsafe is the same as NewGCMTransformer but is unsafe for general +// use because it makes assumptions about the key underlying the block cipher. Specifically, +// it uses a 96-bit nonce where the first 32 bits are random data and the remaining 64 bits are +// a monotonically incrementing atomic counter. This means that the key must be randomly generated +// on process startup and must never be used for encryption outside the lifetime of the process. +// Unlike NewGCMTransformer, this function is immune to the birthday attack and thus the key can +// be used for 2^64-1 writes without rotation. Furthermore, cryptographic wear out of AES-GCM with +// a sequential nonce occurs after 2^64 encryptions, which is not a concern for our use cases. +// Even if that occurs, the nonce counter would overflow and crash the process. We have no concerns +// around plaintext length because all stored items are small (less than 2 MB). To prevent the +// chance of the block cipher being accidentally re-used, it is not taken in as input. Instead, +// a new random key is generated and returned on every invocation of this function. This key is +// used as the input to the block cipher. If the key is stored and retrieved at a later point, +// it can be passed to NewGCMTransformer(aes.NewCipher(key)) to construct a transformer capable +// of decrypting values encrypted by this transformer (that transformer must not be used for encryption). +func NewGCMTransformerWithUniqueKeyUnsafe() (value.Transformer, []byte, error) { + key, err := generateKey(32) + if err != nil { + return nil, nil, err + } + block, err := aes.NewCipher(key) + if err != nil { + return nil, nil, err + } + + nonceGen := &nonceGenerator{ + // we start the nonce counter at one billion so that we are + // guaranteed to detect rollover across different go routines + zero: 1_000_000_000, + fatal: die, + } + nonceGen.nonce.Add(nonceGen.zero) + + transformer, err := newGCMTransformerWithUniqueKeyUnsafe(block, nonceGen) + if err != nil { + return nil, nil, err + } + return transformer, key, nil +} + +func newGCMTransformerWithUniqueKeyUnsafe(block cipher.Block, nonceGen *nonceGenerator) (value.Transformer, error) { + aead, err := newGCM(block) + if err != nil { + return nil, err + } + + nonceFunc := func(b []byte) error { + // we only need 8 bytes to store our 64 bit incrementing nonce + // instead of leaving the unused bytes as zeros, set those to random bits + // this mostly protects us from weird edge cases like a VM restore that rewinds our atomic counter + randNonceSize := len(b) - 8 + + if err := randomNonce(b[:randNonceSize]); err != nil { + return err + } + + nonceGen.next(b[randNonceSize:]) + + return nil + } + + return &gcm{aead: aead, nonceFunc: nonceFunc}, nil +} + +func newGCM(block cipher.Block) (cipher.AEAD, error) { + aead, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + if nonceSize := aead.NonceSize(); nonceSize != 12 { // all data in etcd will be broken if this ever changes + return nil, fmt.Errorf("crypto/cipher.NewGCM returned unexpected nonce size: %d", nonceSize) + } + return aead, nil +} + +func randomNonce(b []byte) error { + _, err := rand.Read(b) + return err +} + +type nonceGenerator struct { + // even at one million encryptions per second, this counter is enough for half a million years + // using this struct avoids alignment bugs: https://pkg.go.dev/sync/atomic#pkg-note-BUG + nonce atomic.Uint64 + zero uint64 + fatal func(msg string) +} + +func (n *nonceGenerator) next(b []byte) { + incrementingNonce := n.nonce.Add(1) + if incrementingNonce <= n.zero { + // this should never happen, and is unrecoverable if it does + n.fatal("aes-gcm detected nonce overflow - cryptographic wear out has occurred") + } + binary.LittleEndian.PutUint64(b, incrementingNonce) +} + +func die(msg string) { + // nolint:logcheck // we want the stack traces, log flushing, and process exiting logic from FatalDepth + klog.FatalDepth(1, msg) +} + +// generateKey generates a random key using system randomness. +func generateKey(length int) (key []byte, err error) { + defer func(start time.Time) { + value.RecordDataKeyGeneration(start, err) + }(time.Now()) + key = make([]byte, length) + if _, err = rand.Read(key); err != nil { + return nil, err + } + + return key, nil } func (t *gcm) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { - aead, err := cipher.NewGCM(t.block) - if err != nil { - return nil, false, err - } - nonceSize := aead.NonceSize() + nonceSize := t.aead.NonceSize() if len(data) < nonceSize { - return nil, false, fmt.Errorf("the stored data was shorter than the required size") + return nil, false, errors.New("the stored data was shorter than the required size") } - result, err := aead.Open(nil, data[:nonceSize], data[nonceSize:], dataCtx.AuthenticatedData()) + result, err := t.aead.Open(nil, data[:nonceSize], data[nonceSize:], dataCtx.AuthenticatedData()) return result, false, err } func (t *gcm) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { - aead, err := cipher.NewGCM(t.block) - if err != nil { - return nil, err + nonceSize := t.aead.NonceSize() + result := make([]byte, nonceSize+t.aead.Overhead()+len(data)) + + if err := t.nonceFunc(result[:nonceSize]); err != nil { + return nil, fmt.Errorf("failed to write nonce for AES-GCM: %w", err) } - nonceSize := aead.NonceSize() - result := make([]byte, nonceSize+aead.Overhead()+len(data)) - n, err := rand.Read(result[:nonceSize]) - if err != nil { - return nil, err - } - if n != nonceSize { - return nil, fmt.Errorf("unable to read sufficient random bytes") - } - cipherText := aead.Seal(result[nonceSize:nonceSize], result[:nonceSize], data, dataCtx.AuthenticatedData()) + + cipherText := t.aead.Seal(result[nonceSize:nonceSize], result[:nonceSize], data, dataCtx.AuthenticatedData()) return result[:nonceSize+len(cipherText)], nil } @@ -96,7 +210,7 @@ func NewCBCTransformer(block cipher.Block) value.Transformer { } var ( - ErrInvalidBlockSize = fmt.Errorf("the stored data is not a multiple of the block size") + errInvalidBlockSize = errors.New("the stored data is not a multiple of the block size") errInvalidPKCS7Data = errors.New("invalid PKCS7 data (empty or not padded)") errInvalidPKCS7Padding = errors.New("invalid padding on input") ) @@ -104,13 +218,13 @@ var ( func (t *cbc) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { blockSize := aes.BlockSize if len(data) < blockSize { - return nil, false, fmt.Errorf("the stored data was shorter than the required size") + return nil, false, errors.New("the stored data was shorter than the required size") } iv := data[:blockSize] data = data[blockSize:] if len(data)%blockSize != 0 { - return nil, false, ErrInvalidBlockSize + return nil, false, errInvalidBlockSize } result := make([]byte, len(data)) @@ -140,7 +254,7 @@ func (t *cbc) TransformToStorage(ctx context.Context, data []byte, dataCtx value result := make([]byte, blockSize+len(data)+paddingSize) iv := result[:blockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { - return nil, fmt.Errorf("unable to read sufficient random bytes") + return nil, errors.New("unable to read sufficient random bytes") } copy(result[blockSize:], data) diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go index 43d2e00a2..4bb18ee8b 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/envelope.go @@ -53,7 +53,7 @@ type envelopeTransformer struct { transformers *lru.Cache // baseTransformerFunc creates a new transformer for encrypting the data with the DEK. - baseTransformerFunc func(cipher.Block) value.Transformer + baseTransformerFunc func(cipher.Block) (value.Transformer, error) cacheSize int cacheEnabled bool @@ -63,7 +63,7 @@ type envelopeTransformer struct { // It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to // the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently // used decrypted DEKs in memory. -func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) value.Transformer { +func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) (value.Transformer, error)) value.Transformer { var ( cache *lru.Cache ) @@ -161,7 +161,11 @@ func (t *envelopeTransformer) addTransformer(encKey []byte, key []byte) (value.T if err != nil { return nil, err } - transformer := t.baseTransformerFunc(block) + transformer, err := t.baseTransformerFunc(block) + if err != nil { + return nil, err + } + // Use base64 of encKey as the key into the cache because hashicorp/golang-lru // cannot hash []uint8. if t.cacheEnabled { diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go index 2b7014460..b2a5fd145 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/grpc_service.go @@ -28,9 +28,9 @@ import ( "google.golang.org/grpc/credentials/insecure" utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util" "k8s.io/klog/v2" kmsapi "k8s.io/kms/apis/v1beta1" + "k8s.io/kms/pkg/util" ) const ( @@ -53,7 +53,7 @@ type gRPCService struct { // NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider. func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (Service, error) { - klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint) + klog.V(4).InfoS("Configure KMS provider", "endpoint", endpoint) addr, err := util.ParseEndpoint(endpoint) if err != nil { @@ -72,9 +72,9 @@ func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Durat // addr - comes from the closure c, err := net.DialUnix(unixProtocol, nil, &net.UnixAddr{Name: addr}) if err != nil { - klog.Errorf("failed to create connection to unix socket: %s, error: %v", addr, err) + klog.ErrorS(err, "failed to create connection to unix socket", "addr", addr) } else { - klog.V(4).Infof("Successfully dialed Unix socket %v", addr) + klog.V(4).InfoS("Successfully dialed Unix socket", "addr", addr) } return c, err })) @@ -113,7 +113,7 @@ func (g *gRPCService) checkAPIVersion(ctx context.Context) error { } g.versionChecked = true - klog.V(4).Infof("Version of KMS provider is %s", response.Version) + klog.V(4).InfoS("KMS provider api version verified", "version", response.Version) return nil } diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/cache.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/cache.go new file mode 100644 index 000000000..3c1fbbf8a --- /dev/null +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/cache.go @@ -0,0 +1,108 @@ +/* +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 kmsv2 transforms values for storage at rest using a Envelope v2 provider +package kmsv2 + +import ( + "context" + "crypto/sha256" + "hash" + "sync" + "time" + "unsafe" + + utilcache "k8s.io/apimachinery/pkg/util/cache" + "k8s.io/apiserver/pkg/storage/value" + "k8s.io/utils/clock" +) + +// prevent decryptTransformer from drifting from value.Transformer +var _ decryptTransformer = value.Transformer(nil) + +// decryptTransformer is the decryption subset of value.Transformer. +// this exists purely to statically enforce that transformers placed in the cache are not used for encryption. +// this is relevant in the context of nonce collision since transformers that are created +// from encrypted DEKs retrieved from etcd cannot maintain their nonce counter state. +type decryptTransformer interface { + TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) (out []byte, stale bool, err error) +} + +type simpleCache struct { + cache *utilcache.Expiring + ttl time.Duration + // hashPool is a per cache pool of hash.Hash (to avoid allocations from building the Hash) + // SHA-256 is used to prevent collisions + hashPool *sync.Pool +} + +func newSimpleCache(clock clock.Clock, ttl time.Duration) *simpleCache { + return &simpleCache{ + cache: utilcache.NewExpiringWithClock(clock), + ttl: ttl, + hashPool: &sync.Pool{ + New: func() interface{} { + return sha256.New() + }, + }, + } +} + +// given a key, return the transformer, or nil if it does not exist in the cache +func (c *simpleCache) get(key []byte) decryptTransformer { + record, ok := c.cache.Get(c.keyFunc(key)) + if !ok { + return nil + } + return record.(decryptTransformer) +} + +// set caches the record for the key +func (c *simpleCache) set(key []byte, transformer decryptTransformer) { + if len(key) == 0 { + panic("key must not be empty") + } + if transformer == nil { + panic("transformer must not be nil") + } + c.cache.Set(c.keyFunc(key), transformer, c.ttl) +} + +// keyFunc generates a string key by hashing the inputs. +// This lowers the memory requirement of the cache. +func (c *simpleCache) keyFunc(s []byte) string { + h := c.hashPool.Get().(hash.Hash) + h.Reset() + + if _, err := h.Write(s); err != nil { + panic(err) // Write() on hash never fails + } + key := toString(h.Sum(nil)) // skip base64 encoding to save an allocation + c.hashPool.Put(h) + + return key +} + +// toString performs unholy acts to avoid allocations +func toString(b []byte) string { + // unsafe.SliceData relies on cap whereas we want to rely on len + if len(b) == 0 { + return "" + } + // Copied from go 1.20.1 strings.Builder.String + // https://github.com/golang/go/blob/202a1a57064127c3f19d96df57b9f9586145e21c/src/strings/builder.go#L48 + return unsafe.String(unsafe.SliceData(b), len(b)) +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go index 726e3053e..43ba22d65 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go @@ -20,120 +20,148 @@ package kmsv2 import ( "context" "crypto/aes" - "crypto/cipher" - "crypto/rand" - "encoding/base64" "fmt" + "sort" "time" + "unsafe" "github.com/gogo/protobuf/proto" + "golang.org/x/crypto/cryptobyte" + utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/storage/value" - kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1" + aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" + kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" "k8s.io/klog/v2" - "k8s.io/utils/lru" + kmsservice "k8s.io/kms/pkg/service" + "k8s.io/utils/clock" ) +func init() { + value.RegisterMetrics() + metrics.RegisterMetrics() +} + const ( // KMSAPIVersion is the version of the KMS API. - KMSAPIVersion = "v2alpha1" + KMSAPIVersion = "v2beta1" // annotationsMaxSize is the maximum size of the annotations. annotationsMaxSize = 32 * 1024 // 32 kB - // keyIDMaxSize is the maximum size of the keyID. - keyIDMaxSize = 1 * 1024 // 1 kB + // KeyIDMaxSize is the maximum size of the keyID. + KeyIDMaxSize = 1 * 1024 // 1 kB // encryptedDEKMaxSize is the maximum size of the encrypted DEK. encryptedDEKMaxSize = 1 * 1024 // 1 kB + // cacheTTL is the default time-to-live for the cache entry. + // this allows the cache to grow to an infinite size for up to a day. + // this is meant as a temporary solution until the cache is re-written to not have a TTL. + // there is unlikely to be any meaningful memory impact on the server + // because the cache will likely never have more than a few thousand entries + // and each entry is roughly ~200 bytes in size. with DEK reuse + // and no storage migration, the number of entries in this cache + // would be approximated by unique key IDs used by the KMS plugin + // combined with the number of server restarts. If storage migration + // is performed after key ID changes, and the number of restarts + // is limited, this cache size may be as small as the number of API + // servers in use (once old entries expire out from the TTL). + cacheTTL = 24 * time.Hour + // error code + errKeyIDOKCode ErrCodeKeyID = "ok" + errKeyIDEmptyCode ErrCodeKeyID = "empty" + errKeyIDTooLongCode ErrCodeKeyID = "too_long" ) -// Service allows encrypting and decrypting data using an external Key Management Service. -type Service interface { - // Decrypt a given bytearray to obtain the original data as bytes. - Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) - // Encrypt bytes to a ciphertext. - Encrypt(ctx context.Context, uid string, data []byte) (*EncryptResponse, error) - // Status returns the status of the KMS. - Status(ctx context.Context) (*StatusResponse, error) +// NowFunc is exported so tests can override it. +var NowFunc = time.Now + +type StateFunc func() (State, error) +type ErrCodeKeyID string + +type State struct { + Transformer value.Transformer + EncryptedDEK []byte + KeyID string + Annotations map[string][]byte + + UID string + + ExpirationTimestamp time.Time + + // CacheKey is the key used to cache the DEK in transformer.cache. + CacheKey []byte +} + +func (s *State) ValidateEncryptCapability() error { + if now := NowFunc(); now.After(s.ExpirationTimestamp) { + return fmt.Errorf("EDEK with keyID %q expired at %s (current time is %s)", + s.KeyID, s.ExpirationTimestamp.Format(time.RFC3339), now.Format(time.RFC3339)) + } + return nil } type envelopeTransformer struct { - envelopeService Service + envelopeService kmsservice.Service + providerName string + stateFunc StateFunc - // transformers is a thread-safe LRU cache which caches decrypted DEKs indexed by their encrypted form. - transformers *lru.Cache - - // baseTransformerFunc creates a new transformer for encrypting the data with the DEK. - baseTransformerFunc func(cipher.Block) value.Transformer - - cacheSize int - cacheEnabled bool -} - -// EncryptResponse is the response from the Envelope service when encrypting data. -type EncryptResponse struct { - Ciphertext []byte - KeyID string - Annotations map[string][]byte -} - -// DecryptRequest is the request to the Envelope service when decrypting data. -type DecryptRequest struct { - Ciphertext []byte - KeyID string - Annotations map[string][]byte -} - -// StatusResponse is the response from the Envelope service when getting the status of the service. -type StatusResponse struct { - Version string - Healthz string - KeyID string + // cache is a thread-safe expiring lru cache which caches decrypted DEKs indexed by their encrypted form. + cache *simpleCache } // NewEnvelopeTransformer returns a transformer which implements a KEK-DEK based envelope encryption scheme. // It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to -// the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently -// used decrypted DEKs in memory. -func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) value.Transformer { - var cache *lru.Cache - - if cacheSize > 0 { - // TODO(aramase): Switch to using expiring cache: kubernetes/kubernetes/staging/src/k8s.io/apimachinery/pkg/util/cache/expiring.go. - // It handles scans a lot better, doesn't have to be right sized, and don't have a global lock on reads. - cache = lru.New(cacheSize) - } +// the data items they encrypt. +func NewEnvelopeTransformer(envelopeService kmsservice.Service, providerName string, stateFunc StateFunc) value.Transformer { + return newEnvelopeTransformerWithClock(envelopeService, providerName, stateFunc, cacheTTL, clock.RealClock{}) +} +func newEnvelopeTransformerWithClock(envelopeService kmsservice.Service, providerName string, stateFunc StateFunc, cacheTTL time.Duration, clock clock.Clock) value.Transformer { return &envelopeTransformer{ - envelopeService: envelopeService, - transformers: cache, - baseTransformerFunc: baseTransformerFunc, - cacheEnabled: cacheSize > 0, - cacheSize: cacheSize, + envelopeService: envelopeService, + providerName: providerName, + stateFunc: stateFunc, + cache: newSimpleCache(clock, cacheTTL), } } // TransformFromStorage decrypts data encrypted by this transformer using envelope encryption. func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) { - metrics.RecordArrival(metrics.FromStorageLabel, time.Now()) - // Deserialize the EncryptedObject from the data. encryptedObject, err := t.doDecode(data) if err != nil { return nil, false, err } - // Look up the decrypted DEK from cache or Envelope. - transformer := t.getTransformer(encryptedObject.EncryptedDEK) + // TODO: consider marking state.EncryptedDEK != encryptedObject.EncryptedDEK as a stale read to support DEK defragmentation + // at a minimum we should have a metric that helps the user understand if DEK fragmentation is high + state, err := t.stateFunc() // no need to call state.ValidateEncryptCapability on reads + if err != nil { + return nil, false, err + } + + encryptedObjectCacheKey, err := generateCacheKey(encryptedObject.EncryptedDEK, encryptedObject.KeyID, encryptedObject.Annotations) + if err != nil { + return nil, false, err + } + + // Look up the decrypted DEK from cache first + transformer := t.cache.get(encryptedObjectCacheKey) + + // fallback to the envelope service if we do not have the transformer locally if transformer == nil { - if t.cacheEnabled { - value.RecordCacheMiss() - } + value.RecordCacheMiss() + + requestInfo := getRequestInfoFromContext(ctx) uid := string(uuid.NewUUID()) - klog.V(6).InfoS("Decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) - key, err := t.envelopeService.Decrypt(ctx, uid, &DecryptRequest{ + klog.V(6).InfoS("decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData()), + "group", requestInfo.APIGroup, "version", requestInfo.APIVersion, "resource", requestInfo.Resource, "subresource", requestInfo.Subresource, + "verb", requestInfo.Verb, "namespace", requestInfo.Namespace, "name", requestInfo.Name) + + key, err := t.envelopeService.Decrypt(ctx, uid, &kmsservice.DecryptRequest{ Ciphertext: encryptedObject.EncryptedDEK, KeyID: encryptedObject.KeyID, Annotations: encryptedObject.Annotations, @@ -142,80 +170,79 @@ func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []b return nil, false, fmt.Errorf("failed to decrypt DEK, error: %w", err) } - transformer, err = t.addTransformer(encryptedObject.EncryptedDEK, key) + transformer, err = t.addTransformerForDecryption(encryptedObjectCacheKey, key) if err != nil { return nil, false, err } } + metrics.RecordKeyID(metrics.FromStorageLabel, t.providerName, encryptedObject.KeyID) + + out, stale, err := transformer.TransformFromStorage(ctx, encryptedObject.EncryptedData, dataCtx) + if err != nil { + return nil, false, err + } + + // data is considered stale if the key ID does not match our current write transformer + return out, stale || encryptedObject.KeyID != state.KeyID, nil - return transformer.TransformFromStorage(ctx, encryptedObject.EncryptedData, dataCtx) } // TransformToStorage encrypts data to be written to disk using envelope encryption. func (t *envelopeTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) { - metrics.RecordArrival(metrics.ToStorageLabel, time.Now()) - newKey, err := generateKey(32) + state, err := t.stateFunc() + if err != nil { + return nil, err + } + if err := state.ValidateEncryptCapability(); err != nil { + return nil, err + } + + // this prevents a cache miss every time the DEK rotates + // this has the side benefit of causing the cache to perform a GC + // TODO see if we can do this inside the stateFunc control loop + // TODO(aramase): Add metrics for cache fill percentage with custom cache implementation. + t.cache.set(state.CacheKey, state.Transformer) + + requestInfo := getRequestInfoFromContext(ctx) + klog.V(6).InfoS("encrypting content using DEK", "uid", state.UID, "key", string(dataCtx.AuthenticatedData()), + "group", requestInfo.APIGroup, "version", requestInfo.APIVersion, "resource", requestInfo.Resource, "subresource", requestInfo.Subresource, + "verb", requestInfo.Verb, "namespace", requestInfo.Namespace, "name", requestInfo.Name) + + result, err := state.Transformer.TransformToStorage(ctx, data, dataCtx) if err != nil { return nil, err } - uid := string(uuid.NewUUID()) - klog.V(6).InfoS("Encrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) - resp, err := t.envelopeService.Encrypt(ctx, uid, newKey) - if err != nil { - return nil, fmt.Errorf("failed to encrypt DEK, error: %w", err) - } - - transformer, err := t.addTransformer(resp.Ciphertext, newKey) - if err != nil { - return nil, err - } - - result, err := transformer.TransformToStorage(ctx, data, dataCtx) - if err != nil { - return nil, err - } + metrics.RecordKeyID(metrics.ToStorageLabel, t.providerName, state.KeyID) encObject := &kmstypes.EncryptedObject{ - KeyID: resp.KeyID, - EncryptedDEK: resp.Ciphertext, + KeyID: state.KeyID, + EncryptedDEK: state.EncryptedDEK, EncryptedData: result, - Annotations: resp.Annotations, + Annotations: state.Annotations, } // Serialize the EncryptedObject to a byte array. return t.doEncode(encObject) } -// addTransformer inserts a new transformer to the Envelope cache of DEKs for future reads. -func (t *envelopeTransformer) addTransformer(encKey []byte, key []byte) (value.Transformer, error) { +// addTransformerForDecryption inserts a new transformer to the Envelope cache of DEKs for future reads. +func (t *envelopeTransformer) addTransformerForDecryption(cacheKey []byte, key []byte) (decryptTransformer, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } - transformer := t.baseTransformerFunc(block) - // Use base64 of encKey as the key into the cache because hashicorp/golang-lru - // cannot hash []uint8. - if t.cacheEnabled { - t.transformers.Add(base64.StdEncoding.EncodeToString(encKey), transformer) - metrics.RecordDekCacheFillPercent(float64(t.transformers.Len()) / float64(t.cacheSize)) + // this is compatible with NewGCMTransformerWithUniqueKeyUnsafe for decryption + // it would use random nonces for encryption but we never do that + transformer, err := aestransformer.NewGCMTransformer(block) + if err != nil { + return nil, err } + // TODO(aramase): Add metrics for cache fill percentage with custom cache implementation. + t.cache.set(cacheKey, transformer) return transformer, nil } -// getTransformer fetches the transformer corresponding to encKey from cache, if it exists. -func (t *envelopeTransformer) getTransformer(encKey []byte) value.Transformer { - if !t.cacheEnabled { - return nil - } - - _transformer, found := t.transformers.Get(base64.StdEncoding.EncodeToString(encKey)) - if found { - return _transformer.(value.Transformer) - } - return nil -} - // doEncode encodes the EncryptedObject to a byte array. func (t *envelopeTransformer) doEncode(request *kmstypes.EncryptedObject) ([]byte, error) { if err := validateEncryptedObject(request); err != nil { @@ -238,17 +265,34 @@ func (t *envelopeTransformer) doDecode(originalData []byte) (*kmstypes.Encrypted return o, nil } -// generateKey generates a random key using system randomness. -func generateKey(length int) (key []byte, err error) { - defer func(start time.Time) { - value.RecordDataKeyGeneration(start, err) - }(time.Now()) - key = make([]byte, length) - if _, err = rand.Read(key); err != nil { - return nil, err +func GenerateTransformer(ctx context.Context, uid string, envelopeService kmsservice.Service) (value.Transformer, *kmsservice.EncryptResponse, []byte, error) { + transformer, newKey, err := aestransformer.NewGCMTransformerWithUniqueKeyUnsafe() + if err != nil { + return nil, nil, nil, err } - return key, nil + klog.V(6).InfoS("encrypting content using envelope service", "uid", uid) + + resp, err := envelopeService.Encrypt(ctx, uid, newKey) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to encrypt DEK, error: %w", err) + } + + if err := validateEncryptedObject(&kmstypes.EncryptedObject{ + KeyID: resp.KeyID, + EncryptedDEK: resp.Ciphertext, + EncryptedData: []byte{0}, // any non-empty value to pass validation + Annotations: resp.Annotations, + }); err != nil { + return nil, nil, nil, err + } + + cacheKey, err := generateCacheKey(resp.Ciphertext, resp.KeyID, resp.Annotations) + if err != nil { + return nil, nil, nil, err + } + + return transformer, resp, cacheKey, nil } func validateEncryptedObject(o *kmstypes.EncryptedObject) error { @@ -261,7 +305,7 @@ func validateEncryptedObject(o *kmstypes.EncryptedObject) error { if err := validateEncryptedDEK(o.EncryptedDEK); err != nil { return fmt.Errorf("failed to validate encrypted DEK: %w", err) } - if err := validateKeyID(o.KeyID); err != nil { + if _, err := ValidateKeyID(o.KeyID); err != nil { return fmt.Errorf("failed to validate key id: %w", err) } if err := validateAnnotations(o.Annotations); err != nil { @@ -301,15 +345,78 @@ func validateAnnotations(annotations map[string][]byte) error { return utilerrors.NewAggregate(errs) } -// validateKeyID tests the following: +// ValidateKeyID tests the following: // 1. The keyID is not empty. // 2. The size of keyID is less than 1 kB. -func validateKeyID(keyID string) error { +func ValidateKeyID(keyID string) (ErrCodeKeyID, error) { if len(keyID) == 0 { - return fmt.Errorf("keyID is empty") + return errKeyIDEmptyCode, fmt.Errorf("keyID is empty") } - if len(keyID) > keyIDMaxSize { - return fmt.Errorf("keyID is %d bytes, which exceeds the max size of %d", len(keyID), keyIDMaxSize) + if len(keyID) > KeyIDMaxSize { + return errKeyIDTooLongCode, fmt.Errorf("keyID is %d bytes, which exceeds the max size of %d", len(keyID), KeyIDMaxSize) } - return nil + return errKeyIDOKCode, nil +} + +func getRequestInfoFromContext(ctx context.Context) *genericapirequest.RequestInfo { + if reqInfo, found := genericapirequest.RequestInfoFrom(ctx); found { + return reqInfo + } + return &genericapirequest.RequestInfo{} +} + +// generateCacheKey returns a key for the cache. +// The key is a concatenation of: +// 1. encryptedDEK +// 2. keyID +// 3. length of annotations +// 4. annotations (sorted by key) - each annotation is a concatenation of: +// a. annotation key +// b. annotation value +func generateCacheKey(encryptedDEK []byte, keyID string, annotations map[string][]byte) ([]byte, error) { + // TODO(aramase): use sync pool buffer to avoid allocations + b := cryptobyte.NewBuilder(nil) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(encryptedDEK) + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(toBytes(keyID)) + }) + if len(annotations) == 0 { + return b.Bytes() + } + + // add the length of annotations to the cache key + b.AddUint32(uint32(len(annotations))) + + // Sort the annotations by key. + keys := make([]string, 0, len(annotations)) + for k := range annotations { + k := k + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + // The maximum size of annotations is annotationsMaxSize (32 kB) so we can safely + // assume that the length of the key and value will fit in a uint16. + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(toBytes(k)) + }) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(annotations[k]) + }) + } + + return b.Bytes() +} + +// toBytes performs unholy acts to avoid allocations +func toBytes(s string) []byte { + // unsafe.StringData is unspecified for the empty string, so we provide a strict interpretation + if len(s) == 0 { + return nil + } + // Copied from go 1.20.1 os.File.WriteString + // https://github.com/golang/go/blob/202a1a57064127c3f19d96df57b9f9586145e21c/src/os/file.go#L246 + return unsafe.Slice(unsafe.StringData(s), len(s)) } diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go index 692aeef53..67f7bc79e 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go @@ -27,9 +27,11 @@ import ( "google.golang.org/grpc/credentials/insecure" utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util" + "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" "k8s.io/klog/v2" - kmsapi "k8s.io/kms/apis/v2alpha1" + kmsapi "k8s.io/kms/apis/v2" + kmsservice "k8s.io/kms/pkg/service" + "k8s.io/kms/pkg/util" ) const ( @@ -45,8 +47,8 @@ type gRPCService struct { } // NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider. -func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (Service, error) { - klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint) +func NewGRPCService(ctx context.Context, endpoint, providerName string, callTimeout time.Duration) (kmsservice.Service, error) { + klog.V(4).InfoS("Configure KMS provider", "endpoint", endpoint) addr, err := util.ParseEndpoint(endpoint) if err != nil { @@ -64,12 +66,14 @@ func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Durat // addr - comes from the closure c, err := net.DialUnix(unixProtocol, nil, &net.UnixAddr{Name: addr}) if err != nil { - klog.Errorf("failed to create connection to unix socket: %s, error: %v", addr, err) + klog.ErrorS(err, "failed to create connection to unix socket", "addr", addr) } else { - klog.V(4).Infof("Successfully dialed Unix socket %v", addr) + klog.V(4).InfoS("Successfully dialed Unix socket", "addr", addr) } return c, err - })) + }), + grpc.WithChainUnaryInterceptor(recordMetricsInterceptor(providerName)), + ) if err != nil { return nil, fmt.Errorf("failed to create connection to %s, error: %v", endpoint, err) @@ -88,7 +92,7 @@ func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Durat } // Decrypt a given data string to obtain the original byte data. -func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) { +func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *kmsservice.DecryptRequest) ([]byte, error) { ctx, cancel := context.WithTimeout(ctx, g.callTimeout) defer cancel() @@ -106,7 +110,7 @@ func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *DecryptReque } // Encrypt bytes to a string ciphertext. -func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) (*EncryptResponse, error) { +func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) (*kmsservice.EncryptResponse, error) { ctx, cancel := context.WithTimeout(ctx, g.callTimeout) defer cancel() @@ -118,7 +122,7 @@ func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) if err != nil { return nil, err } - return &EncryptResponse{ + return &kmsservice.EncryptResponse{ Ciphertext: response.Ciphertext, KeyID: response.KeyId, Annotations: response.Annotations, @@ -126,7 +130,7 @@ func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) } // Status returns the status of the KMSv2 provider. -func (g *gRPCService) Status(ctx context.Context) (*StatusResponse, error) { +func (g *gRPCService) Status(ctx context.Context) (*kmsservice.StatusResponse, error) { ctx, cancel := context.WithTimeout(ctx, g.callTimeout) defer cancel() @@ -135,5 +139,15 @@ func (g *gRPCService) Status(ctx context.Context) (*StatusResponse, error) { if err != nil { return nil, err } - return &StatusResponse{Version: response.Version, Healthz: response.Healthz, KeyID: response.KeyId}, nil + return &kmsservice.StatusResponse{Version: response.Version, Healthz: response.Healthz, KeyID: response.KeyId}, nil +} + +func recordMetricsInterceptor(providerName string) grpc.UnaryClientInterceptor { + return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + start := NowFunc() + respErr := invoker(ctx, method, req, reply, cc, opts...) + elapsed := NowFunc().Sub(start) + metrics.RecordKMSOperationLatency(providerName, method, elapsed, respErr) + return respErr + } } diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/OWNERS b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/OWNERS similarity index 100% rename from vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/OWNERS rename to vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/OWNERS diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.pb.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.pb.go similarity index 68% rename from vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.pb.go rename to vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.pb.go index 307b0b248..c7bdd66f0 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.pb.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.pb.go @@ -17,7 +17,7 @@ limitations under the License. // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: api.proto -package v2alpha1 +package v2 import ( fmt "fmt" @@ -104,25 +104,28 @@ func (m *EncryptedObject) GetAnnotations() map[string][]byte { } func init() { - proto.RegisterType((*EncryptedObject)(nil), "v2alpha1.EncryptedObject") - proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.EncryptedObject.AnnotationsEntry") + proto.RegisterType((*EncryptedObject)(nil), "v2.EncryptedObject") + proto.RegisterMapType((map[string][]byte)(nil), "v2.EncryptedObject.AnnotationsEntry") } func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 200 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x2c, 0xc8, 0xd4, - 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x28, 0x33, 0x4a, 0xcc, 0x29, 0xc8, 0x48, 0x34, 0x54, - 0xfa, 0xcf, 0xc8, 0xc5, 0xef, 0x9a, 0x97, 0x5c, 0x54, 0x59, 0x50, 0x92, 0x9a, 0xe2, 0x9f, 0x94, - 0x95, 0x9a, 0x5c, 0x22, 0xa4, 0xc2, 0xc5, 0x9b, 0x0a, 0x13, 0x72, 0x49, 0x2c, 0x49, 0x94, 0x60, - 0x54, 0x60, 0xd4, 0xe0, 0x09, 0x42, 0x15, 0x14, 0x12, 0xe1, 0x62, 0xcd, 0x4e, 0xad, 0xf4, 0x74, - 0x91, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x70, 0x84, 0x94, 0xb8, 0x78, 0x10, 0xca, 0x5c, - 0xbd, 0x25, 0x98, 0xc1, 0x5a, 0x51, 0xc4, 0x84, 0x7c, 0xb8, 0xb8, 0x13, 0xf3, 0xf2, 0xf2, 0x4b, - 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0x25, 0x58, 0x14, 0x98, 0x35, 0xb8, 0x8d, 0xb4, 0xf4, 0x60, - 0x6e, 0xd2, 0x43, 0x73, 0x8f, 0x9e, 0x23, 0x42, 0xb1, 0x6b, 0x5e, 0x49, 0x51, 0x65, 0x10, 0xb2, - 0x76, 0x29, 0x3b, 0x2e, 0x01, 0x74, 0x05, 0x42, 0x02, 0x5c, 0xcc, 0xd9, 0xa9, 0x95, 0x60, 0x77, - 0x73, 0x06, 0x81, 0x98, 0x20, 0xd7, 0x96, 0x25, 0xe6, 0x94, 0xa6, 0x82, 0x5d, 0xcb, 0x13, 0x04, - 0xe1, 0x58, 0x31, 0x59, 0x30, 0x26, 0xb1, 0x81, 0x83, 0xc4, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, - 0x88, 0x8c, 0xbb, 0x4e, 0x1f, 0x01, 0x00, 0x00, + // 244 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xb1, 0x4b, 0x03, 0x31, + 0x14, 0xc6, 0xc9, 0x9d, 0x0a, 0x97, 0x9e, 0x58, 0x82, 0xc3, 0xe1, 0x74, 0x94, 0x0e, 0x37, 0x25, + 0x10, 0x97, 0x22, 0x52, 0x50, 0x7a, 0x82, 0x38, 0x08, 0x19, 0xdd, 0xd2, 0xfa, 0x28, 0x67, 0x6a, + 0x12, 0x92, 0x18, 0xc8, 0x9f, 0xee, 0x26, 0x4d, 0x95, 0xda, 0xdb, 0xde, 0xf7, 0xf1, 0xfb, 0xe0, + 0xc7, 0xc3, 0x95, 0xb4, 0x03, 0xb5, 0xce, 0x04, 0x43, 0x8a, 0xc8, 0x67, 0xdf, 0x08, 0x5f, 0xf5, + 0x7a, 0xe3, 0x92, 0x0d, 0xf0, 0xfe, 0xba, 0xfe, 0x80, 0x4d, 0x20, 0x73, 0x7c, 0x09, 0x7f, 0xd5, + 0x4a, 0x06, 0xd9, 0xa0, 0x16, 0x75, 0xb5, 0x38, 0x2d, 0xc9, 0x35, 0x3e, 0x57, 0x90, 0x9e, 0x57, + 0x4d, 0xd1, 0xa2, 0xae, 0x12, 0x87, 0x40, 0x66, 0xb8, 0x3e, 0x62, 0xfd, 0x4b, 0x53, 0xe6, 0xe9, + 0x49, 0x47, 0x9e, 0xf0, 0x44, 0x6a, 0x6d, 0x82, 0x0c, 0x83, 0xd1, 0xbe, 0x39, 0x6b, 0xcb, 0x6e, + 0xc2, 0xe7, 0x34, 0x72, 0x3a, 0x32, 0xa1, 0x0f, 0x47, 0xac, 0xd7, 0xc1, 0x25, 0xf1, 0x7f, 0x78, + 0xb3, 0xc4, 0xd3, 0x31, 0x40, 0xa6, 0xb8, 0x54, 0x90, 0xb2, 0x71, 0x25, 0xf6, 0xe7, 0xde, 0x33, + 0xca, 0xdd, 0x17, 0x64, 0xcf, 0x5a, 0x1c, 0xc2, 0x5d, 0xb1, 0x40, 0x8f, 0xcb, 0xb7, 0x7b, 0xb5, + 0xf0, 0x74, 0x30, 0x4c, 0xda, 0xc1, 0x83, 0x8b, 0xe0, 0x98, 0x55, 0x5b, 0xe6, 0x83, 0x71, 0x72, + 0x0b, 0x2c, 0x93, 0xec, 0x57, 0x9d, 0x81, 0x8e, 0xb0, 0x33, 0x16, 0x98, 0xfa, 0xf4, 0x91, 0xb3, + 0xc8, 0xd7, 0x17, 0xf9, 0x8d, 0xb7, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x80, 0x43, 0x93, + 0x53, 0x01, 0x00, 0x00, } diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.proto b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.proto similarity index 86% rename from vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.proto rename to vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.proto index e3b978b05..9ca2ccf96 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/api.proto +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/api.proto @@ -14,10 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// To regenerate api.pb.go run hack/update-generated-kms.sh +// To regenerate api.pb.go run `hack/update-codegen.sh protobindings` syntax = "proto3"; -package v2alpha1; +package v2; +option go_package = "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2"; // EncryptedObject is the representation of data stored in etcd after envelope encryption. message EncryptedObject { diff --git a/vendor/k8s.io/kms/apis/v2alpha1/v2alpha1.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/v2.go similarity index 86% rename from vendor/k8s.io/kms/apis/v2alpha1/v2alpha1.go rename to vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/v2.go index 546c4074e..878b19f22 100644 --- a/vendor/k8s.io/kms/apis/v2alpha1/v2alpha1.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2/v2.go @@ -14,5 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package v2alpha1 contains definition of kms-plugin's gRPC service. -package v2alpha1 +// Package v2 contains definition of kms-plugin's serialized types. +package v2 diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go index ca0e0ad0f..ff3903805 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics/metrics.go @@ -17,11 +17,20 @@ limitations under the License. package metrics import ( + "crypto/sha256" + "errors" + "fmt" + "hash" "sync" "time" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "k8s.io/component-base/metrics" "k8s.io/component-base/metrics/legacyregistry" + "k8s.io/klog/v2" + "k8s.io/utils/lru" ) const ( @@ -31,6 +40,12 @@ const ( ToStorageLabel = "to_storage" ) +type metricLabels struct { + transformationType string + providerName string + keyIDHash string +} + /* * By default, all the following metrics are defined as falling under * ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes) @@ -40,12 +55,18 @@ const ( * the metric stability policy. */ var ( - lockLastFromStorage sync.Mutex - lockLastToStorage sync.Mutex + lockLastFromStorage sync.Mutex + lockLastToStorage sync.Mutex + lockRecordKeyID sync.Mutex + lockRecordKeyIDStatus sync.Mutex - lastFromStorage time.Time - lastToStorage time.Time + lastFromStorage time.Time + lastToStorage time.Time + keyIDHashTotalMetricLabels *lru.Cache + keyIDHashStatusLastTimestampSecondsMetricLabels *lru.Cache + cacheSize = 100 + // This metric is only used for KMS v1 API. dekCacheFillPercent = metrics.NewGauge( &metrics.GaugeOpts{ Namespace: namespace, @@ -56,6 +77,7 @@ var ( }, ) + // This metric is only used for KMS v1 API. dekCacheInterArrivals = metrics.NewHistogramVec( &metrics.HistogramOpts{ Namespace: namespace, @@ -67,17 +89,145 @@ var ( }, []string{"transformation_type"}, ) + + // These metrics are made public to be used by unit tests. + KMSOperationsLatencyMetric = metrics.NewHistogramVec( + &metrics.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "kms_operations_latency_seconds", + Help: "KMS operation duration with gRPC error code status total.", + StabilityLevel: metrics.ALPHA, + // Use custom buckets to avoid the default buckets which are too small for KMS operations. + // Start 0.1ms with the last bucket being [~52s, +Inf) + Buckets: metrics.ExponentialBuckets(0.0001, 2, 20), + }, + []string{"provider_name", "method_name", "grpc_status_code"}, + ) + + // keyIDHashTotal is the number of times a keyID is used + // e.g. apiserver_envelope_encryption_key_id_hash_total counter + // apiserver_envelope_encryption_key_id_hash_total{key_id_hash="sha256", + // provider_name="providerName",transformation_type="from_storage"} 1 + KeyIDHashTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "key_id_hash_total", + Help: "Number of times a keyID is used split by transformation type and provider.", + StabilityLevel: metrics.ALPHA, + }, + []string{"transformation_type", "provider_name", "key_id_hash"}, + ) + + // keyIDHashLastTimestampSeconds is the last time in seconds when a keyID was used + // e.g. apiserver_envelope_encryption_key_id_hash_last_timestamp_seconds{key_id_hash="sha256", provider_name="providerName",transformation_type="from_storage"} 1.674865558833728e+09 + KeyIDHashLastTimestampSeconds = metrics.NewGaugeVec( + &metrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "key_id_hash_last_timestamp_seconds", + Help: "The last time in seconds when a keyID was used.", + StabilityLevel: metrics.ALPHA, + }, + []string{"transformation_type", "provider_name", "key_id_hash"}, + ) + + // keyIDHashStatusLastTimestampSeconds is the last time in seconds when a keyID was returned by the Status RPC call. + // e.g. apiserver_envelope_encryption_key_id_hash_status_last_timestamp_seconds{key_id_hash="sha256", provider_name="providerName"} 1.674865558833728e+09 + KeyIDHashStatusLastTimestampSeconds = metrics.NewGaugeVec( + &metrics.GaugeOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "key_id_hash_status_last_timestamp_seconds", + Help: "The last time in seconds when a keyID was returned by the Status RPC call.", + StabilityLevel: metrics.ALPHA, + }, + []string{"provider_name", "key_id_hash"}, + ) + + InvalidKeyIDFromStatusTotal = metrics.NewCounterVec( + &metrics.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "invalid_key_id_from_status_total", + Help: "Number of times an invalid keyID is returned by the Status RPC call split by error.", + StabilityLevel: metrics.ALPHA, + }, + []string{"provider_name", "error"}, + ) ) var registerMetricsFunc sync.Once +var hashPool *sync.Pool +func registerLRUMetrics() { + if keyIDHashTotalMetricLabels != nil { + keyIDHashTotalMetricLabels.Clear() + } + if keyIDHashStatusLastTimestampSecondsMetricLabels != nil { + keyIDHashStatusLastTimestampSecondsMetricLabels.Clear() + } + + keyIDHashTotalMetricLabels = lru.NewWithEvictionFunc(cacheSize, func(key lru.Key, _ interface{}) { + item := key.(metricLabels) + if deleted := KeyIDHashTotal.DeleteLabelValues(item.transformationType, item.providerName, item.keyIDHash); deleted { + klog.InfoS("Deleted keyIDHashTotalMetricLabels", "transformationType", item.transformationType, + "providerName", item.providerName, "keyIDHash", item.keyIDHash) + } + if deleted := KeyIDHashLastTimestampSeconds.DeleteLabelValues(item.transformationType, item.providerName, item.keyIDHash); deleted { + klog.InfoS("Deleted keyIDHashLastTimestampSecondsMetricLabels", "transformationType", item.transformationType, + "providerName", item.providerName, "keyIDHash", item.keyIDHash) + } + }) + keyIDHashStatusLastTimestampSecondsMetricLabels = lru.NewWithEvictionFunc(cacheSize, func(key lru.Key, _ interface{}) { + item := key.(metricLabels) + if deleted := KeyIDHashStatusLastTimestampSeconds.DeleteLabelValues(item.providerName, item.keyIDHash); deleted { + klog.InfoS("Deleted keyIDHashStatusLastTimestampSecondsMetricLabels", "providerName", item.providerName, "keyIDHash", item.keyIDHash) + } + }) +} func RegisterMetrics() { registerMetricsFunc.Do(func() { + registerLRUMetrics() + hashPool = &sync.Pool{ + New: func() interface{} { + return sha256.New() + }, + } legacyregistry.MustRegister(dekCacheFillPercent) legacyregistry.MustRegister(dekCacheInterArrivals) + legacyregistry.MustRegister(KeyIDHashTotal) + legacyregistry.MustRegister(KeyIDHashLastTimestampSeconds) + legacyregistry.MustRegister(KeyIDHashStatusLastTimestampSeconds) + legacyregistry.MustRegister(InvalidKeyIDFromStatusTotal) + legacyregistry.MustRegister(KMSOperationsLatencyMetric) }) } +// RecordKeyID records total count and last time in seconds when a KeyID was used for TransformFromStorage and TransformToStorage operations +func RecordKeyID(transformationType, providerName, keyID string) { + lockRecordKeyID.Lock() + defer lockRecordKeyID.Unlock() + + keyIDHash := addLabelToCache(keyIDHashTotalMetricLabels, transformationType, providerName, keyID) + KeyIDHashTotal.WithLabelValues(transformationType, providerName, keyIDHash).Inc() + KeyIDHashLastTimestampSeconds.WithLabelValues(transformationType, providerName, keyIDHash).SetToCurrentTime() +} + +// RecordKeyIDFromStatus records last time in seconds when a KeyID was returned by the Status RPC call. +func RecordKeyIDFromStatus(providerName, keyID string) { + lockRecordKeyIDStatus.Lock() + defer lockRecordKeyIDStatus.Unlock() + + keyIDHash := addLabelToCache(keyIDHashStatusLastTimestampSecondsMetricLabels, "", providerName, keyID) + KeyIDHashStatusLastTimestampSeconds.WithLabelValues(providerName, keyIDHash).SetToCurrentTime() +} + +func RecordInvalidKeyIDFromStatus(providerName, errCode string) { + InvalidKeyIDFromStatusTotal.WithLabelValues(providerName, errCode).Inc() +} + func RecordArrival(transformationType string, start time.Time) { switch transformationType { case FromStorageLabel: @@ -104,3 +254,51 @@ func RecordArrival(transformationType string, start time.Time) { func RecordDekCacheFillPercent(percent float64) { dekCacheFillPercent.Set(percent) } + +// RecordKMSOperationLatency records the latency of KMS operation. +func RecordKMSOperationLatency(providerName, methodName string, duration time.Duration, err error) { + KMSOperationsLatencyMetric.WithLabelValues(providerName, methodName, getErrorCode(err)).Observe(duration.Seconds()) +} + +type gRPCError interface { + GRPCStatus() *status.Status +} + +func getErrorCode(err error) string { + if err == nil { + return codes.OK.String() + } + + // handle errors wrapped with fmt.Errorf and similar + var s gRPCError + if errors.As(err, &s) { + return s.GRPCStatus().Code().String() + } + + // This is not gRPC error. The operation must have failed before gRPC + // method was called, otherwise we would get gRPC error. + return "unknown-non-grpc" +} + +func getHash(data string) string { + h := hashPool.Get().(hash.Hash) + h.Reset() + h.Write([]byte(data)) + result := fmt.Sprintf("sha256:%x", h.Sum(nil)) + hashPool.Put(h) + return result +} + +func addLabelToCache(c *lru.Cache, transformationType, providerName, keyID string) string { + keyIDHash := "" + // only get hash if the keyID is not empty + if len(keyID) > 0 { + keyIDHash = getHash(keyID) + } + c.Add(metricLabels{ + transformationType: transformationType, + providerName: providerName, + keyIDHash: keyIDHash, + }, nil) // value is irrelevant, this is a set and not a map + return keyIDHash +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go b/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go index 63ab526af..c8fd2f4c0 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/metrics.go @@ -51,7 +51,7 @@ var ( Buckets: metrics.ExponentialBuckets(5e-6, 2, 25), StabilityLevel: metrics.ALPHA, }, - []string{"transformation_type"}, + []string{"transformation_type", "transformer_prefix"}, ) transformerOperationsTotal = metrics.NewCounterVec( @@ -111,12 +111,11 @@ func RegisterMetrics() { // RecordTransformation records latencies and count of TransformFromStorage and TransformToStorage operations. // Note that transformation_failures_total metric is deprecated, use transformation_operations_total instead. -func RecordTransformation(transformationType, transformerPrefix string, start time.Time, err error) { +func RecordTransformation(transformationType, transformerPrefix string, elapsed time.Duration, err error) { transformerOperationsTotal.WithLabelValues(transformationType, transformerPrefix, status.Code(err).String()).Inc() - switch { - case err == nil: - transformerLatencies.WithLabelValues(transformationType).Observe(sinceInSeconds(start)) + if err == nil { + transformerLatencies.WithLabelValues(transformationType, transformerPrefix).Observe(elapsed.Seconds()) } } diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go b/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go index 8e5bf94c9..a6a4aa184 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go +++ b/vendor/k8s.io/apiserver/pkg/storage/value/transformer.go @@ -100,9 +100,9 @@ func (t *prefixTransformers) TransformFromStorage(ctx context.Context, data []by continue } if len(transformer.Prefix) == 0 { - RecordTransformation("from_storage", "identity", start, err) + RecordTransformation("from_storage", "identity", time.Since(start), err) } else { - RecordTransformation("from_storage", string(transformer.Prefix), start, err) + RecordTransformation("from_storage", string(transformer.Prefix), time.Since(start), err) } // It is valid to have overlapping prefixes when the same encryption provider @@ -146,7 +146,7 @@ func (t *prefixTransformers) TransformFromStorage(ctx context.Context, data []by if err := errors.Reduce(errors.NewAggregate(errs)); err != nil { return nil, false, err } - RecordTransformation("from_storage", "unknown", start, t.err) + RecordTransformation("from_storage", "unknown", time.Since(start), t.err) return nil, false, t.err } @@ -155,7 +155,7 @@ func (t *prefixTransformers) TransformToStorage(ctx context.Context, data []byte start := time.Now() transformer := t.transformers[0] result, err := transformer.Transformer.TransformToStorage(ctx, data, dataCtx) - RecordTransformation("to_storage", string(transformer.Prefix), start, err) + RecordTransformation("to_storage", string(transformer.Prefix), time.Since(start), err) if err != nil { return nil, err } diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go index 5718dd9e8..2048a6ef6 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller.go @@ -1026,7 +1026,7 @@ func (cfgCtlr *configController) startRequest(ctx context.Context, rd RequestDig noteFn(selectedFlowSchema, plState.pl, flowDistinguisher) workEstimate := workEstimator() - startWaitingTime = time.Now() + startWaitingTime = cfgCtlr.clock.Now() klog.V(7).Infof("startRequest(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, numQueues=%d", rd, selectedFlowSchema.Name, selectedFlowSchema.Spec.DistinguisherMethod, plName, numQueues) req, idle := plState.queues.StartRequest(ctx, &workEstimate, hashValue, flowDistinguisher, selectedFlowSchema.Name, rd.RequestInfo, rd.User, queueNoteFn) if idle { diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go index 91c49a4be..0b9bc02f9 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_controller_debug.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "net/http" + "sort" "strconv" "strings" "text/tabwriter" @@ -50,16 +51,30 @@ func (cfgCtlr *configController) dumpPriorityLevels(w http.ResponseWriter, r *ht defer cfgCtlr.lock.Unlock() tabWriter := tabwriter.NewWriter(w, 8, 0, 1, ' ', 0) columnHeaders := []string{ - "PriorityLevelName", // 1 - "ActiveQueues", // 2 - "IsIdle", // 3 - "IsQuiescing", // 4 - "WaitingRequests", // 5 - "ExecutingRequests", // 6 + "PriorityLevelName", // 1 + "ActiveQueues", // 2 + "IsIdle", // 3 + "IsQuiescing", // 4 + "WaitingRequests", // 5 + "ExecutingRequests", // 6 + "DispatchedRequests", // 7 + "RejectedRequests", // 8 + "TimedoutRequests", // 9 + "CancelledRequests", // 10 } tabPrint(tabWriter, rowForHeaders(columnHeaders)) endLine(tabWriter) - for _, plState := range cfgCtlr.priorityLevelStates { + plNames := make([]string, 0, len(cfgCtlr.priorityLevelStates)) + for plName := range cfgCtlr.priorityLevelStates { + plNames = append(plNames, plName) + } + sort.Strings(plNames) + for i := range plNames { + plState, ok := cfgCtlr.priorityLevelStates[plNames[i]] + if !ok { + continue + } + if plState.queues == nil { tabPrint(tabWriter, row( plState.pl.Name, // 1 @@ -68,6 +83,10 @@ func (cfgCtlr *configController) dumpPriorityLevels(w http.ResponseWriter, r *ht "", // 4 "", // 5 "", // 6 + "", // 7 + "", // 8 + "", // 9 + "", // 10 )) endLine(tabWriter) continue @@ -81,12 +100,16 @@ func (cfgCtlr *configController) dumpPriorityLevels(w http.ResponseWriter, r *ht } tabPrint(tabWriter, rowForPriorityLevel( - plState.pl.Name, // 1 - activeQueueNum, // 2 - plState.queues.IsIdle(), // 3 - plState.quiescing, // 4 - queueSetDigest.Waiting, // 5 - queueSetDigest.Executing, // 6 + plState.pl.Name, // 1 + activeQueueNum, // 2 + plState.queues.IsIdle(), // 3 + plState.quiescing, // 4 + queueSetDigest.Waiting, // 5 + queueSetDigest.Executing, // 6 + queueSetDigest.Dispatched, // 7 + queueSetDigest.Rejected, // 8 + queueSetDigest.Timedout, // 9 + queueSetDigest.Cancelled, // 10 )) endLine(tabWriter) } @@ -236,7 +259,8 @@ func rowForHeaders(headers []string) string { return row(headers...) } -func rowForPriorityLevel(plName string, activeQueues int, isIdle, isQuiescing bool, waitingRequests, executingRequests int) string { +func rowForPriorityLevel(plName string, activeQueues int, isIdle, isQuiescing bool, waitingRequests, executingRequests int, + dispatchedReqeusts, rejectedRequests, timedoutRequests, cancelledRequests int) string { return row( plName, strconv.Itoa(activeQueues), @@ -244,6 +268,10 @@ func rowForPriorityLevel(plName string, activeQueues int, isIdle, isQuiescing bo strconv.FormatBool(isQuiescing), strconv.Itoa(waitingRequests), strconv.Itoa(executingRequests), + strconv.Itoa(dispatchedReqeusts), + strconv.Itoa(rejectedRequests), + strconv.Itoa(timedoutRequests), + strconv.Itoa(cancelledRequests), ) } diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go index 037ac0db1..2929048ec 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/apf_filter.go @@ -21,6 +21,7 @@ import ( "strconv" "time" + endpointsrequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/server/httplog" "k8s.io/apiserver/pkg/server/mux" fq "k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing" @@ -161,7 +162,7 @@ func (cfgCtlr *configController) Handle(ctx context.Context, requestDigest Reque queued := startWaitingTime != time.Time{} if req == nil { if queued { - metrics.ObserveWaitingDuration(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime)) + observeQueueWaitTime(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), cfgCtlr.clock.Since(startWaitingTime)) } klog.V(7).Infof("Handle(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, isExempt=%v, reject", requestDigest, fs.Name, fs.Spec.DistinguisherMethod, pl.Name, isExempt) return @@ -178,20 +179,26 @@ func (cfgCtlr *configController) Handle(ctx context.Context, requestDigest Reque }() idle = req.Finish(func() { if queued { - metrics.ObserveWaitingDuration(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime)) + observeQueueWaitTime(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), cfgCtlr.clock.Since(startWaitingTime)) } metrics.AddDispatch(ctx, pl.Name, fs.Name) + fqs.OnRequestDispatched(req) executed = true - startExecutionTime := time.Now() + startExecutionTime := cfgCtlr.clock.Now() defer func() { - executionTime := time.Since(startExecutionTime) + executionTime := cfgCtlr.clock.Since(startExecutionTime) httplog.AddKeyValue(ctx, "apf_execution_time", executionTime) metrics.ObserveExecutionDuration(ctx, pl.Name, fs.Name, executionTime) }() execFn() }) if queued && !executed { - metrics.ObserveWaitingDuration(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), time.Since(startWaitingTime)) + observeQueueWaitTime(ctx, pl.Name, fs.Name, strconv.FormatBool(req != nil), cfgCtlr.clock.Since(startWaitingTime)) } panicking = false } + +func observeQueueWaitTime(ctx context.Context, priorityLevelName, flowSchemaName, execute string, waitTime time.Duration) { + metrics.ObserveWaitingDuration(ctx, priorityLevelName, flowSchemaName, execute, waitTime) + endpointsrequest.TrackAPFQueueWaitLatency(ctx, waitTime) +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go index 436039071..904f4fce2 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/conc_alloc.go @@ -108,11 +108,12 @@ const epsilon = 0.0000001 // if possible otherwise returns an error saying why it is impossible. // `allocs` sums to `requiredSum`. // For each J in [0, len(classes)): -// (1) `classes[J].lowerBound <= allocs[J] <= classes[J].upperBound` and -// (2) exactly one of the following is true: -// (2a) `allocs[J] == fairProp * classes[J].target`, -// (2b) `allocs[J] == classes[J].lowerBound && classes[J].lowerBound > fairProp * classes[J].target`, or -// (2c) `allocs[J] == classes[J].upperBound && classes[J].upperBound < fairProp * classes[J].target`. +// 1. `classes[J].lowerBound <= allocs[J] <= classes[J].upperBound` and +// 2. exactly one of the following is true: +// 2a. `allocs[J] == fairProp * classes[J].target`, +// 2b. `allocs[J] == classes[J].lowerBound && classes[J].lowerBound > fairProp * classes[J].target`, or +// 2c. `allocs[J] == classes[J].upperBound && classes[J].upperBound < fairProp * classes[J].target`. +// // Each allocProblemItem is required to have `target >= lowerBound >= 0` and `upperBound >= lowerBound`. // A target smaller than MinTarget is treated as if it were MinTarget. func computeConcurrencyAllocation(requiredSum int, classes []allocProblemItem) ([]float64, float64, error) { diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go index 439d48c45..f2945b613 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/debug/dump.go @@ -30,6 +30,10 @@ type QueueSetDump struct { Executing int SeatsInUse int SeatsWaiting int + Dispatched int + Rejected int + Timedout int + Cancelled int } // QueueDump is an instant dump of one queue in a queue-set. diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go index 9106a033e..11c15ccb7 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/fairqueuing/queueset/queueset.go @@ -148,6 +148,22 @@ type queueSet struct { // enqueues is the number of requests that have ever been enqueued enqueues int + + // totRequestsDispatched is the total number of requests of this + // queueSet that have been processed. + totRequestsDispatched int + + // totRequestsRejected is the total number of requests of this + // queueSet that have been rejected. + totRequestsRejected int + + // totRequestsTimedout is the total number of requests of this + // queueSet that have been timeouted. + totRequestsTimedout int + + // totRequestsCancelled is the total number of requests of this + // queueSet that have been cancelled. + totRequestsCancelled int } // NewQueueSetFactory creates a new QueueSetFactory object @@ -304,6 +320,7 @@ func (qs *queueSet) StartRequest(ctx context.Context, workEstimate *fqrequest.Wo if !qs.canAccommodateSeatsLocked(workEstimate.MaxSeats()) { klog.V(5).Infof("QS(%s): rejecting request %q %#+v %#+v because %d seats are asked for, %d seats are in use (%d are executing) and the limit is %d", qs.qCfg.Name, fsName, descr1, descr2, workEstimate, qs.totSeatsInUse, qs.totRequestsExecuting, qs.dCfg.ConcurrencyLimit) + qs.totRequestsRejected++ metrics.AddReject(ctx, qs.qCfg.Name, fsName, "concurrency-limit") return nil, qs.isIdleLocked() } @@ -323,6 +340,7 @@ func (qs *queueSet) StartRequest(ctx context.Context, workEstimate *fqrequest.Wo // concurrency shares and at max queue length already if req == nil { klog.V(5).Infof("QS(%s): rejecting request %q %#+v %#+v due to queue full", qs.qCfg.Name, fsName, descr1, descr2) + qs.totRequestsRejected++ metrics.AddReject(ctx, qs.qCfg.Name, fsName, "queue-full") return nil, qs.isIdleLocked() } @@ -400,6 +418,8 @@ func (req *request) wait() (bool, bool) { switch decisionAny { case decisionReject: klog.V(5).Infof("QS(%s): request %#+v %#+v timed out after being enqueued\n", qs.qCfg.Name, req.descr1, req.descr2) + qs.totRequestsRejected++ + qs.totRequestsTimedout++ metrics.AddReject(req.ctx, qs.qCfg.Name, req.fsName, "time-out") return false, qs.isIdleLocked() case decisionCancel: @@ -418,6 +438,8 @@ func (req *request) wait() (bool, bool) { defer qs.boundNextDispatchLocked(queue) qs.totRequestsWaiting-- qs.totSeatsWaiting -= req.MaxSeats() + qs.totRequestsRejected++ + qs.totRequestsCancelled++ metrics.AddReject(req.ctx, qs.qCfg.Name, req.fsName, "cancelled") metrics.AddRequestsInQueues(req.ctx, qs.qCfg.Name, req.fsName, -1) req.NoteQueued(false) @@ -1038,9 +1060,27 @@ func (qs *queueSet) Dump(includeRequestDetails bool) debug.QueueSetDump { Executing: qs.totRequestsExecuting, SeatsInUse: qs.totSeatsInUse, SeatsWaiting: qs.totSeatsWaiting, + Dispatched: qs.totRequestsDispatched, + Rejected: qs.totRequestsRejected, + Timedout: qs.totRequestsTimedout, + Cancelled: qs.totRequestsCancelled, } for i, q := range qs.queues { d.Queues[i] = q.dumpLocked(includeRequestDetails) } return d } + +func OnRequestDispatched(r fq.Request) { + req, ok := r.(*request) + if !ok { + return + } + + qs := req.qs + if qs != nil { + qs.lock.Lock() + defer qs.lock.Unlock() + qs.totRequestsDispatched++ + } +} diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go index cd32782a4..2275be6aa 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/metrics/timing_ratio_histogram.go @@ -70,6 +70,7 @@ func NewTimingRatioHistogram(opts *TimingRatioHistogramOpts) *TimingRatioHistogr // NewTestableTimingHistogram adds injection of the clock func NewTestableTimingRatioHistogram(nowFunc func() time.Time, opts *TimingRatioHistogramOpts) *TimingRatioHistogram { + //nolint:govet // copylocks: assignment copies lock value to ratioedOpts: k8s.io/component-base/metrics.TimingHistogramOpts contains sync.Once contains sync.Mutex ratioedOpts := opts.TimingHistogramOpts ratioedOpts.InitialValue /= opts.InitialDenominator th := compbasemetrics.NewTestableTimingHistogram(nowFunc, &ratioedOpts) diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go index 75d70a0ad..130746a41 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/request/list_work_estimator.go @@ -147,8 +147,11 @@ func key(requestInfo *apirequest.RequestInfo) string { // staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go func shouldListFromStorage(query url.Values, opts *metav1.ListOptions) bool { resourceVersion := opts.ResourceVersion + match := opts.ResourceVersionMatch pagingEnabled := utilfeature.DefaultFeatureGate.Enabled(features.APIListChunking) hasContinuation := pagingEnabled && len(opts.Continue) > 0 hasLimit := pagingEnabled && opts.Limit > 0 && resourceVersion != "0" - return resourceVersion == "" || hasContinuation || hasLimit || opts.ResourceVersionMatch == metav1.ResourceVersionMatchExact + unsupportedMatch := match != "" && match != metav1.ResourceVersionMatchNotOlderThan + + return resourceVersion == "" || hasContinuation || hasLimit || unsupportedMatch } diff --git a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go index 287b100cf..b7b9c886b 100644 --- a/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go +++ b/vendor/k8s.io/apiserver/pkg/util/flowcontrol/watch_tracker.go @@ -195,9 +195,8 @@ func (w *watchTracker) forgetWatch(identifier *watchIdentifier, index *indexValu // GetInterestedWatchCount implements WatchTracker interface. // // TODO(wojtek-t): As of now, requestInfo for object creation (POST) doesn't -// -// contain the Name field set. Figure out if we can somehow get it for the -// more accurate cost estimation. +// contain the Name field set. Figure out if we can somehow get it for the +// more accurate cost estimation. // // TODO(wojtek-t): Figure out how to approach DELETECOLLECTION calls. func (w *watchTracker) GetInterestedWatchCount(requestInfo *request.RequestInfo) int { diff --git a/vendor/k8s.io/apiserver/pkg/util/openapi/enablement.go b/vendor/k8s.io/apiserver/pkg/util/openapi/enablement.go deleted file mode 100644 index 693821ac0..000000000 --- a/vendor/k8s.io/apiserver/pkg/util/openapi/enablement.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2021 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 openapi - -import ( - "strings" - - genericfeatures "k8s.io/apiserver/pkg/features" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kube-openapi/pkg/common" - "k8s.io/kube-openapi/pkg/schemamutation" - "k8s.io/kube-openapi/pkg/validation/spec" -) - -// enumTypeDescriptionHeader is the header of enum section in schema description. -const enumTypeDescriptionHeader = "Possible enum values:" - -// GetOpenAPIDefinitionsWithoutDisabledFeatures wraps a GetOpenAPIDefinitions to revert -// any change to the schema that was made by disabled features. -func GetOpenAPIDefinitionsWithoutDisabledFeatures(GetOpenAPIDefinitions common.GetOpenAPIDefinitions) common.GetOpenAPIDefinitions { - return func(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { - defs := GetOpenAPIDefinitions(ref) - restoreDefinitions(defs) - return defs - } -} - -// restoreDefinitions restores any changes by disabled features from definition map. -func restoreDefinitions(defs map[string]common.OpenAPIDefinition) { - // revert changes from OpenAPIEnums - if !utilfeature.DefaultFeatureGate.Enabled(genericfeatures.OpenAPIEnums) { - for gvk, def := range defs { - orig := &def.Schema - if ret := pruneEnums(orig); ret != orig { - def.Schema = *ret - defs[gvk] = def - } - } - } -} - -func pruneEnums(schema *spec.Schema) *spec.Schema { - walker := schemamutation.Walker{ - SchemaCallback: func(schema *spec.Schema) *spec.Schema { - orig := schema - clone := func() { - if orig == schema { // if schema has not been mutated yet - schema = new(spec.Schema) - *schema = *orig // make a clone from orig to schema - } - } - if headerIndex := strings.Index(schema.Description, enumTypeDescriptionHeader); headerIndex != -1 { - // remove the enum section from description. - // note that the new lines before the header should be removed too, - // thus the slice range. - clone() - schema.Description = schema.Description[:headerIndex] - } - if len(schema.Enum) != 0 { - // remove the enum field - clone() - schema.Enum = nil - } - return schema - }, - RefCallback: schemamutation.RefCallbackNoop, - } - return walker.WalkSchema(schema) -} diff --git a/vendor/k8s.io/apiserver/pkg/util/openapi/proto.go b/vendor/k8s.io/apiserver/pkg/util/openapi/proto.go deleted file mode 100644 index 162812f14..000000000 --- a/vendor/k8s.io/apiserver/pkg/util/openapi/proto.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2018 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 openapi - -import ( - "encoding/json" - - openapi_v2 "github.com/google/gnostic/openapiv2" - - "k8s.io/kube-openapi/pkg/util/proto" - "k8s.io/kube-openapi/pkg/validation/spec" -) - -// ToProtoModels builds the proto formatted models from OpenAPI spec -func ToProtoModels(openAPISpec *spec.Swagger) (proto.Models, error) { - specBytes, err := json.MarshalIndent(openAPISpec, " ", " ") - if err != nil { - return nil, err - } - - doc, err := openapi_v2.ParseDocument(specBytes) - if err != nil { - return nil, err - } - - models, err := proto.NewOpenAPIData(doc) - if err != nil { - return nil, err - } - - return models, nil -} diff --git a/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go b/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go index 06a74c1cd..45143bf6e 100644 --- a/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go +++ b/vendor/k8s.io/apiserver/pkg/util/webhook/webhook.go @@ -121,7 +121,7 @@ func WithExponentialBackoff(ctx context.Context, retryBackoff wait.Backoff, webh // having a webhook error allows us to track the last actual webhook error for requests that // are later cancelled or time out. var webhookErr error - err := wait.ExponentialBackoffWithContext(ctx, retryBackoff, func() (bool, error) { + err := wait.ExponentialBackoffWithContext(ctx, retryBackoff, func(_ context.Context) (bool, error) { webhookErr = webhookFn() if shouldRetry(webhookErr) { return false, nil diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go new file mode 100644 index 000000000..ea1dc377b --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/matchcondition.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use +// with apply. +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` +} + +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with +// apply. +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value + return b +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go index eba37bafd..faff51a04 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/mutatingwebhook.go @@ -37,6 +37,7 @@ type MutatingWebhookApplyConfiguration struct { TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` ReinvocationPolicy *admissionregistrationv1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // MutatingWebhookApplyConfiguration constructs an declarative configuration of the MutatingWebhook type for use with @@ -139,3 +140,16 @@ func (b *MutatingWebhookApplyConfiguration) WithReinvocationPolicy(value admissi b.ReinvocationPolicy = &value return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *MutatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *MutatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go index d0691de10..613856bac 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1/validatingwebhook.go @@ -36,6 +36,7 @@ type ValidatingWebhookApplyConfiguration struct { SideEffects *admissionregistrationv1.SideEffectClass `json:"sideEffects,omitempty"` TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // ValidatingWebhookApplyConfiguration constructs an declarative configuration of the ValidatingWebhook type for use with @@ -130,3 +131,16 @@ func (b *ValidatingWebhookApplyConfiguration) WithAdmissionReviewVersions(values } return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/admissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/admissionpolicyspec.go deleted file mode 100644 index 4936110fb..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/admissionpolicyspec.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" -) - -// AdmissionPolicySpecApplyConfiguration represents an declarative configuration of the AdmissionPolicySpec type for use -// with apply. -type AdmissionPolicySpecApplyConfiguration struct { - ParamSource *ParamSourceApplyConfiguration `json:"paramSource,omitempty"` - MatchResources *MatchResourcesApplyConfiguration `json:"matchResources,omitempty"` - Validations []ValidationApplyConfiguration `json:"validations,omitempty"` - FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"` -} - -// AdmissionPolicySpecApplyConfiguration constructs an declarative configuration of the AdmissionPolicySpec type for use with -// apply. -func AdmissionPolicySpec() *AdmissionPolicySpecApplyConfiguration { - return &AdmissionPolicySpecApplyConfiguration{} -} - -// WithParamSource sets the ParamSource field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ParamSource field is set to the value of the last call. -func (b *AdmissionPolicySpecApplyConfiguration) WithParamSource(value *ParamSourceApplyConfiguration) *AdmissionPolicySpecApplyConfiguration { - b.ParamSource = value - return b -} - -// WithMatchResources sets the MatchResources field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the MatchResources field is set to the value of the last call. -func (b *AdmissionPolicySpecApplyConfiguration) WithMatchResources(value *MatchResourcesApplyConfiguration) *AdmissionPolicySpecApplyConfiguration { - b.MatchResources = value - return b -} - -// WithValidations adds the given value to the Validations field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Validations field. -func (b *AdmissionPolicySpecApplyConfiguration) WithValidations(values ...*ValidationApplyConfiguration) *AdmissionPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithValidations") - } - b.Validations = append(b.Validations, *values[i]) - } - return b -} - -// WithFailurePolicy sets the FailurePolicy field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the FailurePolicy field is set to the value of the last call. -func (b *AdmissionPolicySpecApplyConfiguration) WithFailurePolicy(value admissionregistrationv1alpha1.FailurePolicyType) *AdmissionPolicySpecApplyConfiguration { - b.FailurePolicy = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go new file mode 100644 index 000000000..023695139 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/auditannotation.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// AuditAnnotationApplyConfiguration represents an declarative configuration of the AuditAnnotation type for use +// with apply. +type AuditAnnotationApplyConfiguration struct { + Key *string `json:"key,omitempty"` + ValueExpression *string `json:"valueExpression,omitempty"` +} + +// AuditAnnotationApplyConfiguration constructs an declarative configuration of the AuditAnnotation type for use with +// apply. +func AuditAnnotation() *AuditAnnotationApplyConfiguration { + return &AuditAnnotationApplyConfiguration{} +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *AuditAnnotationApplyConfiguration) WithKey(value string) *AuditAnnotationApplyConfiguration { + b.Key = &value + return b +} + +// WithValueExpression sets the ValueExpression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ValueExpression field is set to the value of the last call. +func (b *AuditAnnotationApplyConfiguration) WithValueExpression(value string) *AuditAnnotationApplyConfiguration { + b.ValueExpression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go new file mode 100644 index 000000000..f8b511f51 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/expressionwarning.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ExpressionWarningApplyConfiguration represents an declarative configuration of the ExpressionWarning type for use +// with apply. +type ExpressionWarningApplyConfiguration struct { + FieldRef *string `json:"fieldRef,omitempty"` + Warning *string `json:"warning,omitempty"` +} + +// ExpressionWarningApplyConfiguration constructs an declarative configuration of the ExpressionWarning type for use with +// apply. +func ExpressionWarning() *ExpressionWarningApplyConfiguration { + return &ExpressionWarningApplyConfiguration{} +} + +// WithFieldRef sets the FieldRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the FieldRef field is set to the value of the last call. +func (b *ExpressionWarningApplyConfiguration) WithFieldRef(value string) *ExpressionWarningApplyConfiguration { + b.FieldRef = &value + return b +} + +// WithWarning sets the Warning field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Warning field is set to the value of the last call. +func (b *ExpressionWarningApplyConfiguration) WithWarning(value string) *ExpressionWarningApplyConfiguration { + b.Warning = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramsource.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go similarity index 50% rename from vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramsource.go rename to vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go index a7a5a6af8..186c750f9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/paramsource.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/matchcondition.go @@ -18,31 +18,31 @@ limitations under the License. package v1alpha1 -// ParamSourceApplyConfiguration represents an declarative configuration of the ParamSource type for use +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use // with apply. -type ParamSourceApplyConfiguration struct { - APIVersion *string `json:"apiVersion,omitempty"` - Kind *string `json:"kind,omitempty"` +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` } -// ParamSourceApplyConfiguration constructs an declarative configuration of the ParamSource type for use with +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with // apply. -func ParamSource() *ParamSourceApplyConfiguration { - return &ParamSourceApplyConfiguration{} +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} } -// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the APIVersion field is set to the value of the last call. -func (b *ParamSourceApplyConfiguration) WithAPIVersion(value string) *ParamSourceApplyConfiguration { - b.APIVersion = &value +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value return b } -// WithKind sets the Kind field in the declarative configuration to the given value +// WithExpression sets the Expression field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *ParamSourceApplyConfiguration) WithKind(value string) *ParamSourceApplyConfiguration { - b.Kind = &value +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rule.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rule.go deleted file mode 100644 index 313de9d5f..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rule.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "k8s.io/api/admissionregistration/v1alpha1" -) - -// RuleApplyConfiguration represents an declarative configuration of the Rule type for use -// with apply. -type RuleApplyConfiguration struct { - APIGroups []string `json:"apiGroups,omitempty"` - APIVersions []string `json:"apiVersions,omitempty"` - Resources []string `json:"resources,omitempty"` - Scope *v1alpha1.ScopeType `json:"scope,omitempty"` -} - -// RuleApplyConfiguration constructs an declarative configuration of the Rule type for use with -// apply. -func Rule() *RuleApplyConfiguration { - return &RuleApplyConfiguration{} -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleApplyConfiguration) WithAPIGroups(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleApplyConfiguration) WithAPIVersions(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleApplyConfiguration) WithResources(values ...string) *RuleApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleApplyConfiguration) WithScope(value v1alpha1.ScopeType) *RuleApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rulewithoperations.go deleted file mode 100644 index 112f4826b..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/rulewithoperations.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1 "k8s.io/api/admissionregistration/v1" - admissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" -) - -// RuleWithOperationsApplyConfiguration represents an declarative configuration of the RuleWithOperations type for use -// with apply. -type RuleWithOperationsApplyConfiguration struct { - Operations []v1.OperationType `json:"operations,omitempty"` - admissionregistrationv1.RuleApplyConfiguration `json:",inline"` -} - -// RuleWithOperationsApplyConfiguration constructs an declarative configuration of the RuleWithOperations type for use with -// apply. -func RuleWithOperations() *RuleWithOperationsApplyConfiguration { - return &RuleWithOperationsApplyConfiguration{} -} - -// WithOperations adds the given value to the Operations field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Operations field. -func (b *RuleWithOperationsApplyConfiguration) WithOperations(values ...v1.OperationType) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Operations = append(b.Operations, values[i]) - } - return b -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIGroups(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIVersions(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleWithOperationsApplyConfiguration) WithResources(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleWithOperationsApplyConfiguration) WithScope(value v1.ScopeType) *RuleWithOperationsApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go new file mode 100644 index 000000000..42a917071 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/typechecking.go @@ -0,0 +1,44 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// TypeCheckingApplyConfiguration represents an declarative configuration of the TypeChecking type for use +// with apply. +type TypeCheckingApplyConfiguration struct { + ExpressionWarnings []ExpressionWarningApplyConfiguration `json:"expressionWarnings,omitempty"` +} + +// TypeCheckingApplyConfiguration constructs an declarative configuration of the TypeChecking type for use with +// apply. +func TypeChecking() *TypeCheckingApplyConfiguration { + return &TypeCheckingApplyConfiguration{} +} + +// WithExpressionWarnings adds the given value to the ExpressionWarnings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ExpressionWarnings field. +func (b *TypeCheckingApplyConfiguration) WithExpressionWarnings(values ...*ExpressionWarningApplyConfiguration) *TypeCheckingApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithExpressionWarnings") + } + b.ExpressionWarnings = append(b.ExpressionWarnings, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go index 3a23e0c72..c860b85cf 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -32,7 +32,8 @@ import ( type ValidatingAdmissionPolicyApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *ValidatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` + Spec *ValidatingAdmissionPolicySpecApplyConfiguration `json:"spec,omitempty"` + Status *ValidatingAdmissionPolicyStatusApplyConfiguration `json:"status,omitempty"` } // ValidatingAdmissionPolicy constructs an declarative configuration of the ValidatingAdmissionPolicy type for use with @@ -245,3 +246,11 @@ func (b *ValidatingAdmissionPolicyApplyConfiguration) WithSpec(value *Validating b.Spec = value return b } + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyApplyConfiguration) WithStatus(value *ValidatingAdmissionPolicyStatusApplyConfiguration) *ValidatingAdmissionPolicyApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go index f06f65549..c9a4ff7ab 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicybindingspec.go @@ -18,12 +18,17 @@ limitations under the License. package v1alpha1 +import ( + admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" +) + // ValidatingAdmissionPolicyBindingSpecApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicyBindingSpec type for use // with apply. type ValidatingAdmissionPolicyBindingSpecApplyConfiguration struct { - PolicyName *string `json:"policyName,omitempty"` - ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` - MatchResources *MatchResourcesApplyConfiguration `json:"matchResources,omitempty"` + PolicyName *string `json:"policyName,omitempty"` + ParamRef *ParamRefApplyConfiguration `json:"paramRef,omitempty"` + MatchResources *MatchResourcesApplyConfiguration `json:"matchResources,omitempty"` + ValidationActions []admissionregistrationv1alpha1.ValidationAction `json:"validationActions,omitempty"` } // ValidatingAdmissionPolicyBindingSpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicyBindingSpec type for use with @@ -55,3 +60,13 @@ func (b *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) WithMatchResour b.MatchResources = value return b } + +// WithValidationActions adds the given value to the ValidationActions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ValidationActions field. +func (b *ValidatingAdmissionPolicyBindingSpecApplyConfiguration) WithValidationActions(values ...admissionregistrationv1alpha1.ValidationAction) *ValidatingAdmissionPolicyBindingSpecApplyConfiguration { + for i := range values { + b.ValidationActions = append(b.ValidationActions, values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go index cba1e720c..f674b5b1e 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicyspec.go @@ -29,6 +29,8 @@ type ValidatingAdmissionPolicySpecApplyConfiguration struct { MatchConstraints *MatchResourcesApplyConfiguration `json:"matchConstraints,omitempty"` Validations []ValidationApplyConfiguration `json:"validations,omitempty"` FailurePolicy *admissionregistrationv1alpha1.FailurePolicyType `json:"failurePolicy,omitempty"` + AuditAnnotations []AuditAnnotationApplyConfiguration `json:"auditAnnotations,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // ValidatingAdmissionPolicySpecApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicySpec type for use with @@ -73,3 +75,29 @@ func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithFailurePolicy(valu b.FailurePolicy = &value return b } + +// WithAuditAnnotations adds the given value to the AuditAnnotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the AuditAnnotations field. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithAuditAnnotations(values ...*AuditAnnotationApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithAuditAnnotations") + } + b.AuditAnnotations = append(b.AuditAnnotations, *values[i]) + } + return b +} + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingAdmissionPolicySpecApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingAdmissionPolicySpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go new file mode 100644 index 000000000..821184c8a --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validatingadmissionpolicystatus.go @@ -0,0 +1,66 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ValidatingAdmissionPolicyStatusApplyConfiguration represents an declarative configuration of the ValidatingAdmissionPolicyStatus type for use +// with apply. +type ValidatingAdmissionPolicyStatusApplyConfiguration struct { + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + TypeChecking *TypeCheckingApplyConfiguration `json:"typeChecking,omitempty"` + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// ValidatingAdmissionPolicyStatusApplyConfiguration constructs an declarative configuration of the ValidatingAdmissionPolicyStatus type for use with +// apply. +func ValidatingAdmissionPolicyStatus() *ValidatingAdmissionPolicyStatusApplyConfiguration { + return &ValidatingAdmissionPolicyStatusApplyConfiguration{} +} + +// WithObservedGeneration sets the ObservedGeneration field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ObservedGeneration field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithObservedGeneration(value int64) *ValidatingAdmissionPolicyStatusApplyConfiguration { + b.ObservedGeneration = &value + return b +} + +// WithTypeChecking sets the TypeChecking field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TypeChecking field is set to the value of the last call. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithTypeChecking(value *TypeCheckingApplyConfiguration) *ValidatingAdmissionPolicyStatusApplyConfiguration { + b.TypeChecking = value + return b +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ValidatingAdmissionPolicyStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *ValidatingAdmissionPolicyStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go index 43916603b..9a5fc8475 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1/validation.go @@ -25,9 +25,10 @@ import ( // ValidationApplyConfiguration represents an declarative configuration of the Validation type for use // with apply. type ValidationApplyConfiguration struct { - Expression *string `json:"expression,omitempty"` - Message *string `json:"message,omitempty"` - Reason *v1.StatusReason `json:"reason,omitempty"` + Expression *string `json:"expression,omitempty"` + Message *string `json:"message,omitempty"` + Reason *v1.StatusReason `json:"reason,omitempty"` + MessageExpression *string `json:"messageExpression,omitempty"` } // ValidationApplyConfiguration constructs an declarative configuration of the Validation type for use with @@ -59,3 +60,11 @@ func (b *ValidationApplyConfiguration) WithReason(value v1.StatusReason) *Valida b.Reason = &value return b } + +// WithMessageExpression sets the MessageExpression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MessageExpression field is set to the value of the last call. +func (b *ValidationApplyConfiguration) WithMessageExpression(value string) *ValidationApplyConfiguration { + b.MessageExpression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go new file mode 100644 index 000000000..d099b6b6e --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/matchcondition.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1beta1 + +// MatchConditionApplyConfiguration represents an declarative configuration of the MatchCondition type for use +// with apply. +type MatchConditionApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Expression *string `json:"expression,omitempty"` +} + +// MatchConditionApplyConfiguration constructs an declarative configuration of the MatchCondition type for use with +// apply. +func MatchCondition() *MatchConditionApplyConfiguration { + return &MatchConditionApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithName(value string) *MatchConditionApplyConfiguration { + b.Name = &value + return b +} + +// WithExpression sets the Expression field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Expression field is set to the value of the last call. +func (b *MatchConditionApplyConfiguration) WithExpression(value string) *MatchConditionApplyConfiguration { + b.Expression = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go index cc48d3b6f..54845341f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/mutatingwebhook.go @@ -38,6 +38,7 @@ type MutatingWebhookApplyConfiguration struct { TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` ReinvocationPolicy *admissionregistrationv1beta1.ReinvocationPolicyType `json:"reinvocationPolicy,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // MutatingWebhookApplyConfiguration constructs an declarative configuration of the MutatingWebhook type for use with @@ -140,3 +141,16 @@ func (b *MutatingWebhookApplyConfiguration) WithReinvocationPolicy(value admissi b.ReinvocationPolicy = &value return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *MutatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *MutatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go deleted file mode 100644 index 21151b998..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rule.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/admissionregistration/v1beta1" -) - -// RuleApplyConfiguration represents an declarative configuration of the Rule type for use -// with apply. -type RuleApplyConfiguration struct { - APIGroups []string `json:"apiGroups,omitempty"` - APIVersions []string `json:"apiVersions,omitempty"` - Resources []string `json:"resources,omitempty"` - Scope *v1beta1.ScopeType `json:"scope,omitempty"` -} - -// RuleApplyConfiguration constructs an declarative configuration of the Rule type for use with -// apply. -func Rule() *RuleApplyConfiguration { - return &RuleApplyConfiguration{} -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleApplyConfiguration) WithAPIGroups(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleApplyConfiguration) WithAPIVersions(values ...string) *RuleApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleApplyConfiguration) WithResources(values ...string) *RuleApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleApplyConfiguration) WithScope(value v1beta1.ScopeType) *RuleApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go deleted file mode 100644 index 0fd5dd34d..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/rulewithoperations.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1 "k8s.io/api/admissionregistration/v1" - admissionregistrationv1 "k8s.io/client-go/applyconfigurations/admissionregistration/v1" -) - -// RuleWithOperationsApplyConfiguration represents an declarative configuration of the RuleWithOperations type for use -// with apply. -type RuleWithOperationsApplyConfiguration struct { - Operations []v1.OperationType `json:"operations,omitempty"` - admissionregistrationv1.RuleApplyConfiguration `json:",inline"` -} - -// RuleWithOperationsApplyConfiguration constructs an declarative configuration of the RuleWithOperations type for use with -// apply. -func RuleWithOperations() *RuleWithOperationsApplyConfiguration { - return &RuleWithOperationsApplyConfiguration{} -} - -// WithOperations adds the given value to the Operations field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Operations field. -func (b *RuleWithOperationsApplyConfiguration) WithOperations(values ...v1.OperationType) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Operations = append(b.Operations, values[i]) - } - return b -} - -// WithAPIGroups adds the given value to the APIGroups field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIGroups field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIGroups(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIGroups = append(b.APIGroups, values[i]) - } - return b -} - -// WithAPIVersions adds the given value to the APIVersions field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the APIVersions field. -func (b *RuleWithOperationsApplyConfiguration) WithAPIVersions(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.APIVersions = append(b.APIVersions, values[i]) - } - return b -} - -// WithResources adds the given value to the Resources field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Resources field. -func (b *RuleWithOperationsApplyConfiguration) WithResources(values ...string) *RuleWithOperationsApplyConfiguration { - for i := range values { - b.Resources = append(b.Resources, values[i]) - } - return b -} - -// WithScope sets the Scope field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Scope field is set to the value of the last call. -func (b *RuleWithOperationsApplyConfiguration) WithScope(value v1.ScopeType) *RuleWithOperationsApplyConfiguration { - b.Scope = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go index 84479b5db..8c5c341ba 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go +++ b/vendor/k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1/validatingwebhook.go @@ -37,6 +37,7 @@ type ValidatingWebhookApplyConfiguration struct { SideEffects *admissionregistrationv1beta1.SideEffectClass `json:"sideEffects,omitempty"` TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"` AdmissionReviewVersions []string `json:"admissionReviewVersions,omitempty"` + MatchConditions []MatchConditionApplyConfiguration `json:"matchConditions,omitempty"` } // ValidatingWebhookApplyConfiguration constructs an declarative configuration of the ValidatingWebhook type for use with @@ -131,3 +132,16 @@ func (b *ValidatingWebhookApplyConfiguration) WithAdmissionReviewVersions(values } return b } + +// WithMatchConditions adds the given value to the MatchConditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the MatchConditions field. +func (b *ValidatingWebhookApplyConfiguration) WithMatchConditions(values ...*MatchConditionApplyConfiguration) *ValidatingWebhookApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMatchConditions") + } + b.MatchConditions = append(b.MatchConditions, *values[i]) + } + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go b/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go deleted file mode 100644 index 86601cc48..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/autoscaling/v2/podresourcemetricsource.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v2 - -import ( - v1 "k8s.io/api/core/v1" -) - -// PodResourceMetricSourceApplyConfiguration represents an declarative configuration of the PodResourceMetricSource type for use -// with apply. -type PodResourceMetricSourceApplyConfiguration struct { - Name *v1.ResourceName `json:"name,omitempty"` - Target *MetricTargetApplyConfiguration `json:"target,omitempty"` -} - -// PodResourceMetricSourceApplyConfiguration constructs an declarative configuration of the PodResourceMetricSource type for use with -// apply. -func PodResourceMetricSource() *PodResourceMetricSourceApplyConfiguration { - return &PodResourceMetricSourceApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *PodResourceMetricSourceApplyConfiguration) WithName(value v1.ResourceName) *PodResourceMetricSourceApplyConfiguration { - b.Name = &value - return b -} - -// WithTarget sets the Target field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Target field is set to the value of the last call. -func (b *PodResourceMetricSourceApplyConfiguration) WithTarget(value *MetricTargetApplyConfiguration) *PodResourceMetricSourceApplyConfiguration { - b.Target = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podscheduling.go b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go similarity index 64% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podscheduling.go rename to vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go index 44890c2d9..788d2a07d 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podscheduling.go +++ b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundle.go @@ -19,7 +19,7 @@ limitations under the License. package v1alpha1 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -27,66 +27,63 @@ import ( v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) -// PodSchedulingApplyConfiguration represents an declarative configuration of the PodScheduling type for use +// ClusterTrustBundleApplyConfiguration represents an declarative configuration of the ClusterTrustBundle type for use // with apply. -type PodSchedulingApplyConfiguration struct { +type ClusterTrustBundleApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *PodSchedulingSpecApplyConfiguration `json:"spec,omitempty"` - Status *PodSchedulingStatusApplyConfiguration `json:"status,omitempty"` + Spec *ClusterTrustBundleSpecApplyConfiguration `json:"spec,omitempty"` } -// PodScheduling constructs an declarative configuration of the PodScheduling type for use with +// ClusterTrustBundle constructs an declarative configuration of the ClusterTrustBundle type for use with // apply. -func PodScheduling(name, namespace string) *PodSchedulingApplyConfiguration { - b := &PodSchedulingApplyConfiguration{} +func ClusterTrustBundle(name string) *ClusterTrustBundleApplyConfiguration { + b := &ClusterTrustBundleApplyConfiguration{} b.WithName(name) - b.WithNamespace(namespace) - b.WithKind("PodScheduling") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithKind("ClusterTrustBundle") + b.WithAPIVersion("certificates.k8s.io/v1alpha1") return b } -// ExtractPodScheduling extracts the applied configuration owned by fieldManager from -// podScheduling. If no managedFields are found in podScheduling for fieldManager, a -// PodSchedulingApplyConfiguration is returned with only the Name, Namespace (if applicable), +// ExtractClusterTrustBundle extracts the applied configuration owned by fieldManager from +// clusterTrustBundle. If no managedFields are found in clusterTrustBundle for fieldManager, a +// ClusterTrustBundleApplyConfiguration is returned with only the Name, Namespace (if applicable), // APIVersion and Kind populated. It is possible that no managed fields were found for because other // field managers have taken ownership of all the fields previously owned by fieldManager, or because // the fieldManager never owned fields any fields. -// podScheduling must be a unmodified PodScheduling API object that was retrieved from the Kubernetes API. -// ExtractPodScheduling provides a way to perform a extract/modify-in-place/apply workflow. +// clusterTrustBundle must be a unmodified ClusterTrustBundle API object that was retrieved from the Kubernetes API. +// ExtractClusterTrustBundle provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractPodScheduling(podScheduling *resourcev1alpha1.PodScheduling, fieldManager string) (*PodSchedulingApplyConfiguration, error) { - return extractPodScheduling(podScheduling, fieldManager, "") +func ExtractClusterTrustBundle(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string) (*ClusterTrustBundleApplyConfiguration, error) { + return extractClusterTrustBundle(clusterTrustBundle, fieldManager, "") } -// ExtractPodSchedulingStatus is the same as ExtractPodScheduling except +// ExtractClusterTrustBundleStatus is the same as ExtractClusterTrustBundle except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractPodSchedulingStatus(podScheduling *resourcev1alpha1.PodScheduling, fieldManager string) (*PodSchedulingApplyConfiguration, error) { - return extractPodScheduling(podScheduling, fieldManager, "status") +func ExtractClusterTrustBundleStatus(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string) (*ClusterTrustBundleApplyConfiguration, error) { + return extractClusterTrustBundle(clusterTrustBundle, fieldManager, "status") } -func extractPodScheduling(podScheduling *resourcev1alpha1.PodScheduling, fieldManager string, subresource string) (*PodSchedulingApplyConfiguration, error) { - b := &PodSchedulingApplyConfiguration{} - err := managedfields.ExtractInto(podScheduling, internal.Parser().Type("io.k8s.api.resource.v1alpha1.PodScheduling"), fieldManager, b, subresource) +func extractClusterTrustBundle(clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundle, fieldManager string, subresource string) (*ClusterTrustBundleApplyConfiguration, error) { + b := &ClusterTrustBundleApplyConfiguration{} + err := managedfields.ExtractInto(clusterTrustBundle, internal.Parser().Type("io.k8s.api.certificates.v1alpha1.ClusterTrustBundle"), fieldManager, b, subresource) if err != nil { return nil, err } - b.WithName(podScheduling.Name) - b.WithNamespace(podScheduling.Namespace) + b.WithName(clusterTrustBundle.Name) - b.WithKind("PodScheduling") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithKind("ClusterTrustBundle") + b.WithAPIVersion("certificates.k8s.io/v1alpha1") return b, nil } // WithKind sets the Kind field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithKind(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithKind(value string) *ClusterTrustBundleApplyConfiguration { b.Kind = &value return b } @@ -94,7 +91,7 @@ func (b *PodSchedulingApplyConfiguration) WithKind(value string) *PodSchedulingA // WithAPIVersion sets the APIVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithAPIVersion(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithAPIVersion(value string) *ClusterTrustBundleApplyConfiguration { b.APIVersion = &value return b } @@ -102,7 +99,7 @@ func (b *PodSchedulingApplyConfiguration) WithAPIVersion(value string) *PodSched // WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Name field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithName(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithName(value string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Name = &value return b @@ -111,7 +108,7 @@ func (b *PodSchedulingApplyConfiguration) WithName(value string) *PodSchedulingA // WithGenerateName sets the GenerateName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the GenerateName field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithGenerateName(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithGenerateName(value string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.GenerateName = &value return b @@ -120,7 +117,7 @@ func (b *PodSchedulingApplyConfiguration) WithGenerateName(value string) *PodSch // WithNamespace sets the Namespace field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Namespace field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithNamespace(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithNamespace(value string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Namespace = &value return b @@ -129,7 +126,7 @@ func (b *PodSchedulingApplyConfiguration) WithNamespace(value string) *PodSchedu // WithUID sets the UID field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the UID field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithUID(value types.UID) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithUID(value types.UID) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.UID = &value return b @@ -138,7 +135,7 @@ func (b *PodSchedulingApplyConfiguration) WithUID(value types.UID) *PodSchedulin // WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithResourceVersion(value string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithResourceVersion(value string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ResourceVersion = &value return b @@ -147,7 +144,7 @@ func (b *PodSchedulingApplyConfiguration) WithResourceVersion(value string) *Pod // WithGeneration sets the Generation field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Generation field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithGeneration(value int64) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithGeneration(value int64) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Generation = &value return b @@ -156,7 +153,7 @@ func (b *PodSchedulingApplyConfiguration) WithGeneration(value int64) *PodSchedu // WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.CreationTimestamp = &value return b @@ -165,7 +162,7 @@ func (b *PodSchedulingApplyConfiguration) WithCreationTimestamp(value metav1.Tim // WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionTimestamp = &value return b @@ -174,7 +171,7 @@ func (b *PodSchedulingApplyConfiguration) WithDeletionTimestamp(value metav1.Tim // WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionGracePeriodSeconds = &value return b @@ -184,7 +181,7 @@ func (b *PodSchedulingApplyConfiguration) WithDeletionGracePeriodSeconds(value i // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Labels field, // overwriting an existing map entries in Labels field with the same key. -func (b *PodSchedulingApplyConfiguration) WithLabels(entries map[string]string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithLabels(entries map[string]string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Labels == nil && len(entries) > 0 { b.Labels = make(map[string]string, len(entries)) @@ -199,7 +196,7 @@ func (b *PodSchedulingApplyConfiguration) WithLabels(entries map[string]string) // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Annotations field, // overwriting an existing map entries in Annotations field with the same key. -func (b *PodSchedulingApplyConfiguration) WithAnnotations(entries map[string]string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Annotations == nil && len(entries) > 0 { b.Annotations = make(map[string]string, len(entries)) @@ -213,7 +210,7 @@ func (b *PodSchedulingApplyConfiguration) WithAnnotations(entries map[string]str // WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *PodSchedulingApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { if values[i] == nil { @@ -227,7 +224,7 @@ func (b *PodSchedulingApplyConfiguration) WithOwnerReferences(values ...*v1.Owne // WithFinalizers adds the given value to the Finalizers field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *PodSchedulingApplyConfiguration) WithFinalizers(values ...string) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithFinalizers(values ...string) *ClusterTrustBundleApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { b.Finalizers = append(b.Finalizers, values[i]) @@ -235,7 +232,7 @@ func (b *PodSchedulingApplyConfiguration) WithFinalizers(values ...string) *PodS return b } -func (b *PodSchedulingApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { +func (b *ClusterTrustBundleApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { if b.ObjectMetaApplyConfiguration == nil { b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} } @@ -244,15 +241,7 @@ func (b *PodSchedulingApplyConfiguration) ensureObjectMetaApplyConfigurationExis // WithSpec sets the Spec field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Spec field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithSpec(value *PodSchedulingSpecApplyConfiguration) *PodSchedulingApplyConfiguration { +func (b *ClusterTrustBundleApplyConfiguration) WithSpec(value *ClusterTrustBundleSpecApplyConfiguration) *ClusterTrustBundleApplyConfiguration { b.Spec = value return b } - -// WithStatus sets the Status field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Status field is set to the value of the last call. -func (b *PodSchedulingApplyConfiguration) WithStatus(value *PodSchedulingStatusApplyConfiguration) *PodSchedulingApplyConfiguration { - b.Status = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go new file mode 100644 index 000000000..d1aea1d6d --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/certificates/v1alpha1/clustertrustbundlespec.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ClusterTrustBundleSpecApplyConfiguration represents an declarative configuration of the ClusterTrustBundleSpec type for use +// with apply. +type ClusterTrustBundleSpecApplyConfiguration struct { + SignerName *string `json:"signerName,omitempty"` + TrustBundle *string `json:"trustBundle,omitempty"` +} + +// ClusterTrustBundleSpecApplyConfiguration constructs an declarative configuration of the ClusterTrustBundleSpec type for use with +// apply. +func ClusterTrustBundleSpec() *ClusterTrustBundleSpecApplyConfiguration { + return &ClusterTrustBundleSpecApplyConfiguration{} +} + +// WithSignerName sets the SignerName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SignerName field is set to the value of the last call. +func (b *ClusterTrustBundleSpecApplyConfiguration) WithSignerName(value string) *ClusterTrustBundleSpecApplyConfiguration { + b.SignerName = &value + return b +} + +// WithTrustBundle sets the TrustBundle field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the TrustBundle field is set to the value of the last call. +func (b *ClusterTrustBundleSpecApplyConfiguration) WithTrustBundle(value string) *ClusterTrustBundleSpecApplyConfiguration { + b.TrustBundle = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go index d3b066d9c..9ada59ee2 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/container.go @@ -25,28 +25,29 @@ import ( // ContainerApplyConfiguration represents an declarative configuration of the Container type for use // with apply. type ContainerApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Image *string `json:"image,omitempty"` - Command []string `json:"command,omitempty"` - Args []string `json:"args,omitempty"` - WorkingDir *string `json:"workingDir,omitempty"` - Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` - EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` - Env []EnvVarApplyConfiguration `json:"env,omitempty"` - Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` - VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` - VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` - LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` - ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` - StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` - Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` - TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` - TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` - ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` - Stdin *bool `json:"stdin,omitempty"` - StdinOnce *bool `json:"stdinOnce,omitempty"` - TTY *bool `json:"tty,omitempty"` + Name *string `json:"name,omitempty"` + Image *string `json:"image,omitempty"` + Command []string `json:"command,omitempty"` + Args []string `json:"args,omitempty"` + WorkingDir *string `json:"workingDir,omitempty"` + Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` + EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` + Env []EnvVarApplyConfiguration `json:"env,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` + ResizePolicy []ContainerResizePolicyApplyConfiguration `json:"resizePolicy,omitempty"` + VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` + VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` + LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` + ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` + StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` + Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` + TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` + TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` + ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` + Stdin *bool `json:"stdin,omitempty"` + StdinOnce *bool `json:"stdinOnce,omitempty"` + TTY *bool `json:"tty,omitempty"` } // ContainerApplyConfiguration constructs an declarative configuration of the Container type for use with @@ -146,6 +147,19 @@ func (b *ContainerApplyConfiguration) WithResources(value *ResourceRequirementsA return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *ContainerApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *ContainerApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go new file mode 100644 index 000000000..bbbcbc9f1 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerresizepolicy.go @@ -0,0 +1,52 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// ContainerResizePolicyApplyConfiguration represents an declarative configuration of the ContainerResizePolicy type for use +// with apply. +type ContainerResizePolicyApplyConfiguration struct { + ResourceName *v1.ResourceName `json:"resourceName,omitempty"` + RestartPolicy *v1.ResourceResizeRestartPolicy `json:"restartPolicy,omitempty"` +} + +// ContainerResizePolicyApplyConfiguration constructs an declarative configuration of the ContainerResizePolicy type for use with +// apply. +func ContainerResizePolicy() *ContainerResizePolicyApplyConfiguration { + return &ContainerResizePolicyApplyConfiguration{} +} + +// WithResourceName sets the ResourceName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceName field is set to the value of the last call. +func (b *ContainerResizePolicyApplyConfiguration) WithResourceName(value v1.ResourceName) *ContainerResizePolicyApplyConfiguration { + b.ResourceName = &value + return b +} + +// WithRestartPolicy sets the RestartPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the RestartPolicy field is set to the value of the last call. +func (b *ContainerResizePolicyApplyConfiguration) WithRestartPolicy(value v1.ResourceResizeRestartPolicy) *ContainerResizePolicyApplyConfiguration { + b.RestartPolicy = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go index 18d2925c1..2b98c4658 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/containerstatus.go @@ -18,18 +18,24 @@ limitations under the License. package v1 +import ( + corev1 "k8s.io/api/core/v1" +) + // ContainerStatusApplyConfiguration represents an declarative configuration of the ContainerStatus type for use // with apply. type ContainerStatusApplyConfiguration struct { - Name *string `json:"name,omitempty"` - State *ContainerStateApplyConfiguration `json:"state,omitempty"` - LastTerminationState *ContainerStateApplyConfiguration `json:"lastState,omitempty"` - Ready *bool `json:"ready,omitempty"` - RestartCount *int32 `json:"restartCount,omitempty"` - Image *string `json:"image,omitempty"` - ImageID *string `json:"imageID,omitempty"` - ContainerID *string `json:"containerID,omitempty"` - Started *bool `json:"started,omitempty"` + Name *string `json:"name,omitempty"` + State *ContainerStateApplyConfiguration `json:"state,omitempty"` + LastTerminationState *ContainerStateApplyConfiguration `json:"lastState,omitempty"` + Ready *bool `json:"ready,omitempty"` + RestartCount *int32 `json:"restartCount,omitempty"` + Image *string `json:"image,omitempty"` + ImageID *string `json:"imageID,omitempty"` + ContainerID *string `json:"containerID,omitempty"` + Started *bool `json:"started,omitempty"` + AllocatedResources *corev1.ResourceList `json:"allocatedResources,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` } // ContainerStatusApplyConfiguration constructs an declarative configuration of the ContainerStatus type for use with @@ -109,3 +115,19 @@ func (b *ContainerStatusApplyConfiguration) WithStarted(value bool) *ContainerSt b.Started = &value return b } + +// WithAllocatedResources sets the AllocatedResources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AllocatedResources field is set to the value of the last call. +func (b *ContainerStatusApplyConfiguration) WithAllocatedResources(value corev1.ResourceList) *ContainerStatusApplyConfiguration { + b.AllocatedResources = &value + return b +} + +// WithResources sets the Resources field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resources field is set to the value of the last call. +func (b *ContainerStatusApplyConfiguration) WithResources(value *ResourceRequirementsApplyConfiguration) *ContainerStatusApplyConfiguration { + b.Resources = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go index 6c24cd419..c51049ba1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainer.go @@ -126,6 +126,19 @@ func (b *EphemeralContainerApplyConfiguration) WithResources(value *ResourceRequ return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *EphemeralContainerApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *EphemeralContainerApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go index 67e658cfa..764b830e0 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/ephemeralcontainercommon.go @@ -25,28 +25,29 @@ import ( // EphemeralContainerCommonApplyConfiguration represents an declarative configuration of the EphemeralContainerCommon type for use // with apply. type EphemeralContainerCommonApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Image *string `json:"image,omitempty"` - Command []string `json:"command,omitempty"` - Args []string `json:"args,omitempty"` - WorkingDir *string `json:"workingDir,omitempty"` - Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` - EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` - Env []EnvVarApplyConfiguration `json:"env,omitempty"` - Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` - VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` - VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` - LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` - ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` - StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` - Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` - TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` - TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` - ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` - Stdin *bool `json:"stdin,omitempty"` - StdinOnce *bool `json:"stdinOnce,omitempty"` - TTY *bool `json:"tty,omitempty"` + Name *string `json:"name,omitempty"` + Image *string `json:"image,omitempty"` + Command []string `json:"command,omitempty"` + Args []string `json:"args,omitempty"` + WorkingDir *string `json:"workingDir,omitempty"` + Ports []ContainerPortApplyConfiguration `json:"ports,omitempty"` + EnvFrom []EnvFromSourceApplyConfiguration `json:"envFrom,omitempty"` + Env []EnvVarApplyConfiguration `json:"env,omitempty"` + Resources *ResourceRequirementsApplyConfiguration `json:"resources,omitempty"` + ResizePolicy []ContainerResizePolicyApplyConfiguration `json:"resizePolicy,omitempty"` + VolumeMounts []VolumeMountApplyConfiguration `json:"volumeMounts,omitempty"` + VolumeDevices []VolumeDeviceApplyConfiguration `json:"volumeDevices,omitempty"` + LivenessProbe *ProbeApplyConfiguration `json:"livenessProbe,omitempty"` + ReadinessProbe *ProbeApplyConfiguration `json:"readinessProbe,omitempty"` + StartupProbe *ProbeApplyConfiguration `json:"startupProbe,omitempty"` + Lifecycle *LifecycleApplyConfiguration `json:"lifecycle,omitempty"` + TerminationMessagePath *string `json:"terminationMessagePath,omitempty"` + TerminationMessagePolicy *corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty"` + ImagePullPolicy *corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + SecurityContext *SecurityContextApplyConfiguration `json:"securityContext,omitempty"` + Stdin *bool `json:"stdin,omitempty"` + StdinOnce *bool `json:"stdinOnce,omitempty"` + TTY *bool `json:"tty,omitempty"` } // EphemeralContainerCommonApplyConfiguration constructs an declarative configuration of the EphemeralContainerCommon type for use with @@ -146,6 +147,19 @@ func (b *EphemeralContainerCommonApplyConfiguration) WithResources(value *Resour return b } +// WithResizePolicy adds the given value to the ResizePolicy field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResizePolicy field. +func (b *EphemeralContainerCommonApplyConfiguration) WithResizePolicy(values ...*ContainerResizePolicyApplyConfiguration) *EphemeralContainerCommonApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResizePolicy") + } + b.ResizePolicy = append(b.ResizePolicy, *values[i]) + } + return b +} + // WithVolumeMounts adds the given value to the VolumeMounts field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the VolumeMounts field. diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go index 7ee5b9955..e9d8e5b28 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/podstatus.go @@ -39,6 +39,7 @@ type PodStatusApplyConfiguration struct { ContainerStatuses []ContainerStatusApplyConfiguration `json:"containerStatuses,omitempty"` QOSClass *v1.PodQOSClass `json:"qosClass,omitempty"` EphemeralContainerStatuses []ContainerStatusApplyConfiguration `json:"ephemeralContainerStatuses,omitempty"` + Resize *v1.PodResizeStatus `json:"resize,omitempty"` } // PodStatusApplyConfiguration constructs an declarative configuration of the PodStatus type for use with @@ -175,3 +176,11 @@ func (b *PodStatusApplyConfiguration) WithEphemeralContainerStatuses(values ...* } return b } + +// WithResize sets the Resize field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resize field is set to the value of the last call. +func (b *PodStatusApplyConfiguration) WithResize(value v1.PodResizeStatus) *PodStatusApplyConfiguration { + b.Resize = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go b/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go index db376b941..493af6fb3 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/core/v1/servicespec.go @@ -35,7 +35,7 @@ type ServiceSpecApplyConfiguration struct { LoadBalancerIP *string `json:"loadBalancerIP,omitempty"` LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty"` ExternalName *string `json:"externalName,omitempty"` - ExternalTrafficPolicy *corev1.ServiceExternalTrafficPolicyType `json:"externalTrafficPolicy,omitempty"` + ExternalTrafficPolicy *corev1.ServiceExternalTrafficPolicy `json:"externalTrafficPolicy,omitempty"` HealthCheckNodePort *int32 `json:"healthCheckNodePort,omitempty"` PublishNotReadyAddresses *bool `json:"publishNotReadyAddresses,omitempty"` SessionAffinityConfig *SessionAffinityConfigApplyConfiguration `json:"sessionAffinityConfig,omitempty"` @@ -43,7 +43,7 @@ type ServiceSpecApplyConfiguration struct { IPFamilyPolicy *corev1.IPFamilyPolicy `json:"ipFamilyPolicy,omitempty"` AllocateLoadBalancerNodePorts *bool `json:"allocateLoadBalancerNodePorts,omitempty"` LoadBalancerClass *string `json:"loadBalancerClass,omitempty"` - InternalTrafficPolicy *corev1.ServiceInternalTrafficPolicyType `json:"internalTrafficPolicy,omitempty"` + InternalTrafficPolicy *corev1.ServiceInternalTrafficPolicy `json:"internalTrafficPolicy,omitempty"` } // ServiceSpecApplyConfiguration constructs an declarative configuration of the ServiceSpec type for use with @@ -152,7 +152,7 @@ func (b *ServiceSpecApplyConfiguration) WithExternalName(value string) *ServiceS // WithExternalTrafficPolicy sets the ExternalTrafficPolicy field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ExternalTrafficPolicy field is set to the value of the last call. -func (b *ServiceSpecApplyConfiguration) WithExternalTrafficPolicy(value corev1.ServiceExternalTrafficPolicyType) *ServiceSpecApplyConfiguration { +func (b *ServiceSpecApplyConfiguration) WithExternalTrafficPolicy(value corev1.ServiceExternalTrafficPolicy) *ServiceSpecApplyConfiguration { b.ExternalTrafficPolicy = &value return b } @@ -218,7 +218,7 @@ func (b *ServiceSpecApplyConfiguration) WithLoadBalancerClass(value string) *Ser // WithInternalTrafficPolicy sets the InternalTrafficPolicy field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the InternalTrafficPolicy field is set to the value of the last call. -func (b *ServiceSpecApplyConfiguration) WithInternalTrafficPolicy(value corev1.ServiceInternalTrafficPolicyType) *ServiceSpecApplyConfiguration { +func (b *ServiceSpecApplyConfiguration) WithInternalTrafficPolicy(value corev1.ServiceInternalTrafficPolicy) *ServiceSpecApplyConfiguration { b.InternalTrafficPolicy = &value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go deleted file mode 100644 index 27b49bf15..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedcsidriver.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedCSIDriverApplyConfiguration represents an declarative configuration of the AllowedCSIDriver type for use -// with apply. -type AllowedCSIDriverApplyConfiguration struct { - Name *string `json:"name,omitempty"` -} - -// AllowedCSIDriverApplyConfiguration constructs an declarative configuration of the AllowedCSIDriver type for use with -// apply. -func AllowedCSIDriver() *AllowedCSIDriverApplyConfiguration { - return &AllowedCSIDriverApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *AllowedCSIDriverApplyConfiguration) WithName(value string) *AllowedCSIDriverApplyConfiguration { - b.Name = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go deleted file mode 100644 index 30c3724cf..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedflexvolume.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedFlexVolumeApplyConfiguration represents an declarative configuration of the AllowedFlexVolume type for use -// with apply. -type AllowedFlexVolumeApplyConfiguration struct { - Driver *string `json:"driver,omitempty"` -} - -// AllowedFlexVolumeApplyConfiguration constructs an declarative configuration of the AllowedFlexVolume type for use with -// apply. -func AllowedFlexVolume() *AllowedFlexVolumeApplyConfiguration { - return &AllowedFlexVolumeApplyConfiguration{} -} - -// WithDriver sets the Driver field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Driver field is set to the value of the last call. -func (b *AllowedFlexVolumeApplyConfiguration) WithDriver(value string) *AllowedFlexVolumeApplyConfiguration { - b.Driver = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go deleted file mode 100644 index 493815d8d..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/allowedhostpath.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// AllowedHostPathApplyConfiguration represents an declarative configuration of the AllowedHostPath type for use -// with apply. -type AllowedHostPathApplyConfiguration struct { - PathPrefix *string `json:"pathPrefix,omitempty"` - ReadOnly *bool `json:"readOnly,omitempty"` -} - -// AllowedHostPathApplyConfiguration constructs an declarative configuration of the AllowedHostPath type for use with -// apply. -func AllowedHostPath() *AllowedHostPathApplyConfiguration { - return &AllowedHostPathApplyConfiguration{} -} - -// WithPathPrefix sets the PathPrefix field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the PathPrefix field is set to the value of the last call. -func (b *AllowedHostPathApplyConfiguration) WithPathPrefix(value string) *AllowedHostPathApplyConfiguration { - b.PathPrefix = &value - return b -} - -// WithReadOnly sets the ReadOnly field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ReadOnly field is set to the value of the last call. -func (b *AllowedHostPathApplyConfiguration) WithReadOnly(value bool) *AllowedHostPathApplyConfiguration { - b.ReadOnly = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go deleted file mode 100644 index c7434a6af..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/fsgroupstrategyoptions.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// FSGroupStrategyOptionsApplyConfiguration represents an declarative configuration of the FSGroupStrategyOptions type for use -// with apply. -type FSGroupStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.FSGroupStrategyType `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// FSGroupStrategyOptionsApplyConfiguration constructs an declarative configuration of the FSGroupStrategyOptions type for use with -// apply. -func FSGroupStrategyOptions() *FSGroupStrategyOptionsApplyConfiguration { - return &FSGroupStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *FSGroupStrategyOptionsApplyConfiguration) WithRule(value v1beta1.FSGroupStrategyType) *FSGroupStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *FSGroupStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *FSGroupStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go deleted file mode 100644 index 7c7968813..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/hostportrange.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// HostPortRangeApplyConfiguration represents an declarative configuration of the HostPortRange type for use -// with apply. -type HostPortRangeApplyConfiguration struct { - Min *int32 `json:"min,omitempty"` - Max *int32 `json:"max,omitempty"` -} - -// HostPortRangeApplyConfiguration constructs an declarative configuration of the HostPortRange type for use with -// apply. -func HostPortRange() *HostPortRangeApplyConfiguration { - return &HostPortRangeApplyConfiguration{} -} - -// WithMin sets the Min field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Min field is set to the value of the last call. -func (b *HostPortRangeApplyConfiguration) WithMin(value int32) *HostPortRangeApplyConfiguration { - b.Min = &value - return b -} - -// WithMax sets the Max field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Max field is set to the value of the last call. -func (b *HostPortRangeApplyConfiguration) WithMax(value int32) *HostPortRangeApplyConfiguration { - b.Max = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go deleted file mode 100644 index af46f7658..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/idrange.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// IDRangeApplyConfiguration represents an declarative configuration of the IDRange type for use -// with apply. -type IDRangeApplyConfiguration struct { - Min *int64 `json:"min,omitempty"` - Max *int64 `json:"max,omitempty"` -} - -// IDRangeApplyConfiguration constructs an declarative configuration of the IDRange type for use with -// apply. -func IDRange() *IDRangeApplyConfiguration { - return &IDRangeApplyConfiguration{} -} - -// WithMin sets the Min field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Min field is set to the value of the last call. -func (b *IDRangeApplyConfiguration) WithMin(value int64) *IDRangeApplyConfiguration { - b.Min = &value - return b -} - -// WithMax sets the Max field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Max field is set to the value of the last call. -func (b *IDRangeApplyConfiguration) WithMax(value int64) *IDRangeApplyConfiguration { - b.Max = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go deleted file mode 100644 index de3949dc9..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicyspec.go +++ /dev/null @@ -1,285 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1 "k8s.io/api/core/v1" - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// PodSecurityPolicySpecApplyConfiguration represents an declarative configuration of the PodSecurityPolicySpec type for use -// with apply. -type PodSecurityPolicySpecApplyConfiguration struct { - Privileged *bool `json:"privileged,omitempty"` - DefaultAddCapabilities []v1.Capability `json:"defaultAddCapabilities,omitempty"` - RequiredDropCapabilities []v1.Capability `json:"requiredDropCapabilities,omitempty"` - AllowedCapabilities []v1.Capability `json:"allowedCapabilities,omitempty"` - Volumes []v1beta1.FSType `json:"volumes,omitempty"` - HostNetwork *bool `json:"hostNetwork,omitempty"` - HostPorts []HostPortRangeApplyConfiguration `json:"hostPorts,omitempty"` - HostPID *bool `json:"hostPID,omitempty"` - HostIPC *bool `json:"hostIPC,omitempty"` - SELinux *SELinuxStrategyOptionsApplyConfiguration `json:"seLinux,omitempty"` - RunAsUser *RunAsUserStrategyOptionsApplyConfiguration `json:"runAsUser,omitempty"` - RunAsGroup *RunAsGroupStrategyOptionsApplyConfiguration `json:"runAsGroup,omitempty"` - SupplementalGroups *SupplementalGroupsStrategyOptionsApplyConfiguration `json:"supplementalGroups,omitempty"` - FSGroup *FSGroupStrategyOptionsApplyConfiguration `json:"fsGroup,omitempty"` - ReadOnlyRootFilesystem *bool `json:"readOnlyRootFilesystem,omitempty"` - DefaultAllowPrivilegeEscalation *bool `json:"defaultAllowPrivilegeEscalation,omitempty"` - AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty"` - AllowedHostPaths []AllowedHostPathApplyConfiguration `json:"allowedHostPaths,omitempty"` - AllowedFlexVolumes []AllowedFlexVolumeApplyConfiguration `json:"allowedFlexVolumes,omitempty"` - AllowedCSIDrivers []AllowedCSIDriverApplyConfiguration `json:"allowedCSIDrivers,omitempty"` - AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty"` - ForbiddenSysctls []string `json:"forbiddenSysctls,omitempty"` - AllowedProcMountTypes []v1.ProcMountType `json:"allowedProcMountTypes,omitempty"` - RuntimeClass *RuntimeClassStrategyOptionsApplyConfiguration `json:"runtimeClass,omitempty"` -} - -// PodSecurityPolicySpecApplyConfiguration constructs an declarative configuration of the PodSecurityPolicySpec type for use with -// apply. -func PodSecurityPolicySpec() *PodSecurityPolicySpecApplyConfiguration { - return &PodSecurityPolicySpecApplyConfiguration{} -} - -// WithPrivileged sets the Privileged field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Privileged field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithPrivileged(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.Privileged = &value - return b -} - -// WithDefaultAddCapabilities adds the given value to the DefaultAddCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the DefaultAddCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithDefaultAddCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.DefaultAddCapabilities = append(b.DefaultAddCapabilities, values[i]) - } - return b -} - -// WithRequiredDropCapabilities adds the given value to the RequiredDropCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the RequiredDropCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRequiredDropCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.RequiredDropCapabilities = append(b.RequiredDropCapabilities, values[i]) - } - return b -} - -// WithAllowedCapabilities adds the given value to the AllowedCapabilities field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedCapabilities field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedCapabilities(values ...v1.Capability) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedCapabilities = append(b.AllowedCapabilities, values[i]) - } - return b -} - -// WithVolumes adds the given value to the Volumes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Volumes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithVolumes(values ...v1beta1.FSType) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.Volumes = append(b.Volumes, values[i]) - } - return b -} - -// WithHostNetwork sets the HostNetwork field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostNetwork field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostNetwork(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostNetwork = &value - return b -} - -// WithHostPorts adds the given value to the HostPorts field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the HostPorts field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostPorts(values ...*HostPortRangeApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithHostPorts") - } - b.HostPorts = append(b.HostPorts, *values[i]) - } - return b -} - -// WithHostPID sets the HostPID field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostPID field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostPID(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostPID = &value - return b -} - -// WithHostIPC sets the HostIPC field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the HostIPC field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithHostIPC(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.HostIPC = &value - return b -} - -// WithSELinux sets the SELinux field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SELinux field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithSELinux(value *SELinuxStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.SELinux = value - return b -} - -// WithRunAsUser sets the RunAsUser field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RunAsUser field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRunAsUser(value *RunAsUserStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RunAsUser = value - return b -} - -// WithRunAsGroup sets the RunAsGroup field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RunAsGroup field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRunAsGroup(value *RunAsGroupStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RunAsGroup = value - return b -} - -// WithSupplementalGroups sets the SupplementalGroups field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SupplementalGroups field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithSupplementalGroups(value *SupplementalGroupsStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.SupplementalGroups = value - return b -} - -// WithFSGroup sets the FSGroup field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the FSGroup field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithFSGroup(value *FSGroupStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.FSGroup = value - return b -} - -// WithReadOnlyRootFilesystem sets the ReadOnlyRootFilesystem field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ReadOnlyRootFilesystem field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithReadOnlyRootFilesystem(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.ReadOnlyRootFilesystem = &value - return b -} - -// WithDefaultAllowPrivilegeEscalation sets the DefaultAllowPrivilegeEscalation field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DefaultAllowPrivilegeEscalation field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithDefaultAllowPrivilegeEscalation(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.DefaultAllowPrivilegeEscalation = &value - return b -} - -// WithAllowPrivilegeEscalation sets the AllowPrivilegeEscalation field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the AllowPrivilegeEscalation field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowPrivilegeEscalation(value bool) *PodSecurityPolicySpecApplyConfiguration { - b.AllowPrivilegeEscalation = &value - return b -} - -// WithAllowedHostPaths adds the given value to the AllowedHostPaths field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedHostPaths field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedHostPaths(values ...*AllowedHostPathApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedHostPaths") - } - b.AllowedHostPaths = append(b.AllowedHostPaths, *values[i]) - } - return b -} - -// WithAllowedFlexVolumes adds the given value to the AllowedFlexVolumes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedFlexVolumes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedFlexVolumes(values ...*AllowedFlexVolumeApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedFlexVolumes") - } - b.AllowedFlexVolumes = append(b.AllowedFlexVolumes, *values[i]) - } - return b -} - -// WithAllowedCSIDrivers adds the given value to the AllowedCSIDrivers field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedCSIDrivers field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedCSIDrivers(values ...*AllowedCSIDriverApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithAllowedCSIDrivers") - } - b.AllowedCSIDrivers = append(b.AllowedCSIDrivers, *values[i]) - } - return b -} - -// WithAllowedUnsafeSysctls adds the given value to the AllowedUnsafeSysctls field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedUnsafeSysctls field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedUnsafeSysctls(values ...string) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedUnsafeSysctls = append(b.AllowedUnsafeSysctls, values[i]) - } - return b -} - -// WithForbiddenSysctls adds the given value to the ForbiddenSysctls field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the ForbiddenSysctls field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithForbiddenSysctls(values ...string) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.ForbiddenSysctls = append(b.ForbiddenSysctls, values[i]) - } - return b -} - -// WithAllowedProcMountTypes adds the given value to the AllowedProcMountTypes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedProcMountTypes field. -func (b *PodSecurityPolicySpecApplyConfiguration) WithAllowedProcMountTypes(values ...v1.ProcMountType) *PodSecurityPolicySpecApplyConfiguration { - for i := range values { - b.AllowedProcMountTypes = append(b.AllowedProcMountTypes, values[i]) - } - return b -} - -// WithRuntimeClass sets the RuntimeClass field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RuntimeClass field is set to the value of the last call. -func (b *PodSecurityPolicySpecApplyConfiguration) WithRuntimeClass(value *RuntimeClassStrategyOptionsApplyConfiguration) *PodSecurityPolicySpecApplyConfiguration { - b.RuntimeClass = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go deleted file mode 100644 index 75e76e85f..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasgroupstrategyoptions.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// RunAsGroupStrategyOptionsApplyConfiguration represents an declarative configuration of the RunAsGroupStrategyOptions type for use -// with apply. -type RunAsGroupStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.RunAsGroupStrategy `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// RunAsGroupStrategyOptionsApplyConfiguration constructs an declarative configuration of the RunAsGroupStrategyOptions type for use with -// apply. -func RunAsGroupStrategyOptions() *RunAsGroupStrategyOptionsApplyConfiguration { - return &RunAsGroupStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *RunAsGroupStrategyOptionsApplyConfiguration) WithRule(value v1beta1.RunAsGroupStrategy) *RunAsGroupStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *RunAsGroupStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *RunAsGroupStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go deleted file mode 100644 index 712c1675a..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runasuserstrategyoptions.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// RunAsUserStrategyOptionsApplyConfiguration represents an declarative configuration of the RunAsUserStrategyOptions type for use -// with apply. -type RunAsUserStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.RunAsUserStrategy `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// RunAsUserStrategyOptionsApplyConfiguration constructs an declarative configuration of the RunAsUserStrategyOptions type for use with -// apply. -func RunAsUserStrategyOptions() *RunAsUserStrategyOptionsApplyConfiguration { - return &RunAsUserStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *RunAsUserStrategyOptionsApplyConfiguration) WithRule(value v1beta1.RunAsUserStrategy) *RunAsUserStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *RunAsUserStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *RunAsUserStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go deleted file mode 100644 index c19a7ce61..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/runtimeclassstrategyoptions.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -// RuntimeClassStrategyOptionsApplyConfiguration represents an declarative configuration of the RuntimeClassStrategyOptions type for use -// with apply. -type RuntimeClassStrategyOptionsApplyConfiguration struct { - AllowedRuntimeClassNames []string `json:"allowedRuntimeClassNames,omitempty"` - DefaultRuntimeClassName *string `json:"defaultRuntimeClassName,omitempty"` -} - -// RuntimeClassStrategyOptionsApplyConfiguration constructs an declarative configuration of the RuntimeClassStrategyOptions type for use with -// apply. -func RuntimeClassStrategyOptions() *RuntimeClassStrategyOptionsApplyConfiguration { - return &RuntimeClassStrategyOptionsApplyConfiguration{} -} - -// WithAllowedRuntimeClassNames adds the given value to the AllowedRuntimeClassNames field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the AllowedRuntimeClassNames field. -func (b *RuntimeClassStrategyOptionsApplyConfiguration) WithAllowedRuntimeClassNames(values ...string) *RuntimeClassStrategyOptionsApplyConfiguration { - for i := range values { - b.AllowedRuntimeClassNames = append(b.AllowedRuntimeClassNames, values[i]) - } - return b -} - -// WithDefaultRuntimeClassName sets the DefaultRuntimeClassName field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the DefaultRuntimeClassName field is set to the value of the last call. -func (b *RuntimeClassStrategyOptionsApplyConfiguration) WithDefaultRuntimeClassName(value string) *RuntimeClassStrategyOptionsApplyConfiguration { - b.DefaultRuntimeClassName = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go deleted file mode 100644 index 265906a73..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/selinuxstrategyoptions.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" - v1 "k8s.io/client-go/applyconfigurations/core/v1" -) - -// SELinuxStrategyOptionsApplyConfiguration represents an declarative configuration of the SELinuxStrategyOptions type for use -// with apply. -type SELinuxStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.SELinuxStrategy `json:"rule,omitempty"` - SELinuxOptions *v1.SELinuxOptionsApplyConfiguration `json:"seLinuxOptions,omitempty"` -} - -// SELinuxStrategyOptionsApplyConfiguration constructs an declarative configuration of the SELinuxStrategyOptions type for use with -// apply. -func SELinuxStrategyOptions() *SELinuxStrategyOptionsApplyConfiguration { - return &SELinuxStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *SELinuxStrategyOptionsApplyConfiguration) WithRule(value v1beta1.SELinuxStrategy) *SELinuxStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithSELinuxOptions sets the SELinuxOptions field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SELinuxOptions field is set to the value of the last call. -func (b *SELinuxStrategyOptionsApplyConfiguration) WithSELinuxOptions(value *v1.SELinuxOptionsApplyConfiguration) *SELinuxStrategyOptionsApplyConfiguration { - b.SELinuxOptions = value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go b/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go deleted file mode 100644 index ec4313812..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/supplementalgroupsstrategyoptions.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" -) - -// SupplementalGroupsStrategyOptionsApplyConfiguration represents an declarative configuration of the SupplementalGroupsStrategyOptions type for use -// with apply. -type SupplementalGroupsStrategyOptionsApplyConfiguration struct { - Rule *v1beta1.SupplementalGroupsStrategyType `json:"rule,omitempty"` - Ranges []IDRangeApplyConfiguration `json:"ranges,omitempty"` -} - -// SupplementalGroupsStrategyOptionsApplyConfiguration constructs an declarative configuration of the SupplementalGroupsStrategyOptions type for use with -// apply. -func SupplementalGroupsStrategyOptions() *SupplementalGroupsStrategyOptionsApplyConfiguration { - return &SupplementalGroupsStrategyOptionsApplyConfiguration{} -} - -// WithRule sets the Rule field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Rule field is set to the value of the last call. -func (b *SupplementalGroupsStrategyOptionsApplyConfiguration) WithRule(value v1beta1.SupplementalGroupsStrategyType) *SupplementalGroupsStrategyOptionsApplyConfiguration { - b.Rule = &value - return b -} - -// WithRanges adds the given value to the Ranges field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Ranges field. -func (b *SupplementalGroupsStrategyOptionsApplyConfiguration) WithRanges(values ...*IDRangeApplyConfiguration) *SupplementalGroupsStrategyOptionsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithRanges") - } - b.Ranges = append(b.Ranges, *values[i]) - } - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go b/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go index 94dd2160d..361b2f4e8 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go +++ b/vendor/k8s.io/client-go/applyconfigurations/internal/internal.go @@ -39,6 +39,17 @@ func Parser() *typed.Parser { var parserOnce sync.Once var parser *typed.Parser var schemaYAML = typed.YAMLObject(`types: +- name: io.k8s.api.admissionregistration.v1.MatchCondition + map: + fields: + - name: expression + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1.MutatingWebhook map: fields: @@ -55,6 +66,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -167,6 +186,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -225,6 +252,39 @@ var schemaYAML = typed.YAMLObject(`types: - name: url type: scalar: string +- name: io.k8s.api.admissionregistration.v1alpha1.AuditAnnotation + map: + fields: + - name: key + type: + scalar: string + default: "" + - name: valueExpression + type: + scalar: string + default: "" +- name: io.k8s.api.admissionregistration.v1alpha1.ExpressionWarning + map: + fields: + - name: fieldRef + type: + scalar: string + default: "" + - name: warning + type: + scalar: string + default: "" +- name: io.k8s.api.admissionregistration.v1alpha1.MatchCondition + map: + fields: + - name: expression + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1alpha1.MatchResources map: fields: @@ -307,6 +367,15 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.TypeChecking + map: + fields: + - name: expressionWarnings + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.ExpressionWarning + elementRelationship: atomic - name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicy map: fields: @@ -324,6 +393,10 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicySpec default: {} + - name: status + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus + default: {} - name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyBinding map: fields: @@ -353,12 +426,32 @@ var schemaYAML = typed.YAMLObject(`types: - name: policyName type: scalar: string + - name: validationActions + type: + list: + elementType: + scalar: string + elementRelationship: associative - name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicySpec map: fields: + - name: auditAnnotations + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.AuditAnnotation + elementRelationship: atomic - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1alpha1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchConstraints type: namedType: io.k8s.api.admissionregistration.v1alpha1.MatchResources @@ -371,6 +464,23 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.admissionregistration.v1alpha1.Validation elementRelationship: atomic +- name: io.k8s.api.admissionregistration.v1alpha1.ValidatingAdmissionPolicyStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type + - name: observedGeneration + type: + scalar: numeric + - name: typeChecking + type: + namedType: io.k8s.api.admissionregistration.v1alpha1.TypeChecking - name: io.k8s.api.admissionregistration.v1alpha1.Validation map: fields: @@ -381,9 +491,23 @@ var schemaYAML = typed.YAMLObject(`types: - name: message type: scalar: string + - name: messageExpression + type: + scalar: string - name: reason type: scalar: string +- name: io.k8s.api.admissionregistration.v1beta1.MatchCondition + map: + fields: + - name: expression + type: + scalar: string + default: "" + - name: name + type: + scalar: string + default: "" - name: io.k8s.api.admissionregistration.v1beta1.MutatingWebhook map: fields: @@ -400,6 +524,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1beta1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -482,6 +614,14 @@ var schemaYAML = typed.YAMLObject(`types: - name: failurePolicy type: scalar: string + - name: matchConditions + type: + list: + elementType: + namedType: io.k8s.api.admissionregistration.v1beta1.MatchCondition + elementRelationship: associative + keys: + - name - name: matchPolicy type: scalar: string @@ -3502,6 +3642,33 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - type +- name: io.k8s.api.certificates.v1alpha1.ClusterTrustBundle + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.certificates.v1alpha1.ClusterTrustBundleSpec + default: {} +- name: io.k8s.api.certificates.v1alpha1.ClusterTrustBundleSpec + map: + fields: + - name: signerName + type: + scalar: string + - name: trustBundle + type: + scalar: string + default: "" - name: io.k8s.api.certificates.v1beta1.CertificateSigningRequest map: fields: @@ -4129,6 +4296,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: readinessProbe type: namedType: io.k8s.api.core.v1.Probe + - name: resizePolicy + type: + list: + elementType: + namedType: io.k8s.api.core.v1.ContainerResizePolicy + elementRelationship: atomic - name: resources type: namedType: io.k8s.api.core.v1.ResourceRequirements @@ -4205,6 +4378,17 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: TCP +- name: io.k8s.api.core.v1.ContainerResizePolicy + map: + fields: + - name: resourceName + type: + scalar: string + default: "" + - name: restartPolicy + type: + scalar: string + default: "" - name: io.k8s.api.core.v1.ContainerState map: fields: @@ -4263,6 +4447,11 @@ var schemaYAML = typed.YAMLObject(`types: - name: io.k8s.api.core.v1.ContainerStatus map: fields: + - name: allocatedResources + type: + map: + elementType: + namedType: io.k8s.apimachinery.pkg.api.resource.Quantity - name: containerID type: scalar: string @@ -4286,6 +4475,9 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: boolean default: false + - name: resources + type: + namedType: io.k8s.api.core.v1.ResourceRequirements - name: restartCount type: scalar: numeric @@ -4521,6 +4713,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: readinessProbe type: namedType: io.k8s.api.core.v1.Probe + - name: resizePolicy + type: + list: + elementType: + namedType: io.k8s.api.core.v1.ContainerResizePolicy + elementRelationship: atomic - name: resources type: namedType: io.k8s.api.core.v1.ResourceRequirements @@ -6185,6 +6383,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: reason type: scalar: string + - name: resize + type: + scalar: string - name: startTime type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Time @@ -7734,29 +7935,6 @@ var schemaYAML = typed.YAMLObject(`types: type: namedType: io.k8s.apimachinery.pkg.apis.meta.v1.MicroTime default: {} -- name: io.k8s.api.extensions.v1beta1.AllowedCSIDriver - map: - fields: - - name: name - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.AllowedFlexVolume - map: - fields: - - name: driver - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.AllowedHostPath - map: - fields: - - name: pathPrefix - type: - scalar: string - - name: readOnly - type: - scalar: boolean - name: io.k8s.api.extensions.v1beta1.DaemonSet map: fields: @@ -7992,18 +8170,6 @@ var schemaYAML = typed.YAMLObject(`types: - name: type type: scalar: string -- name: io.k8s.api.extensions.v1beta1.FSGroupStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - name: io.k8s.api.extensions.v1beta1.HTTPIngressPath map: fields: @@ -8026,28 +8192,6 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: io.k8s.api.extensions.v1beta1.HTTPIngressPath elementRelationship: atomic -- name: io.k8s.api.extensions.v1beta1.HostPortRange - map: - fields: - - name: max - type: - scalar: numeric - default: 0 - - name: min - type: - scalar: numeric - default: 0 -- name: io.k8s.api.extensions.v1beta1.IDRange - map: - fields: - - name: max - type: - scalar: numeric - default: 0 - - name: min - type: - scalar: numeric - default: 0 - name: io.k8s.api.extensions.v1beta1.IPBlock map: fields: @@ -8293,135 +8437,6 @@ var schemaYAML = typed.YAMLObject(`types: elementRelationship: associative keys: - type -- name: io.k8s.api.extensions.v1beta1.PodSecurityPolicy - map: - fields: - - name: apiVersion - type: - scalar: string - - name: kind - type: - scalar: string - - name: metadata - type: - namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta - default: {} - - name: spec - type: - namedType: io.k8s.api.extensions.v1beta1.PodSecurityPolicySpec - default: {} -- name: io.k8s.api.extensions.v1beta1.PodSecurityPolicySpec - map: - fields: - - name: allowPrivilegeEscalation - type: - scalar: boolean - - name: allowedCSIDrivers - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedCSIDriver - elementRelationship: atomic - - name: allowedCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: allowedFlexVolumes - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedFlexVolume - elementRelationship: atomic - - name: allowedHostPaths - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.AllowedHostPath - elementRelationship: atomic - - name: allowedProcMountTypes - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: allowedUnsafeSysctls - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultAddCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultAllowPrivilegeEscalation - type: - scalar: boolean - - name: forbiddenSysctls - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: fsGroup - type: - namedType: io.k8s.api.extensions.v1beta1.FSGroupStrategyOptions - default: {} - - name: hostIPC - type: - scalar: boolean - - name: hostNetwork - type: - scalar: boolean - - name: hostPID - type: - scalar: boolean - - name: hostPorts - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.HostPortRange - elementRelationship: atomic - - name: privileged - type: - scalar: boolean - - name: readOnlyRootFilesystem - type: - scalar: boolean - - name: requiredDropCapabilities - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: runAsGroup - type: - namedType: io.k8s.api.extensions.v1beta1.RunAsGroupStrategyOptions - - name: runAsUser - type: - namedType: io.k8s.api.extensions.v1beta1.RunAsUserStrategyOptions - default: {} - - name: runtimeClass - type: - namedType: io.k8s.api.extensions.v1beta1.RuntimeClassStrategyOptions - - name: seLinux - type: - namedType: io.k8s.api.extensions.v1beta1.SELinuxStrategyOptions - default: {} - - name: supplementalGroups - type: - namedType: io.k8s.api.extensions.v1beta1.SupplementalGroupsStrategyOptions - default: {} - - name: volumes - type: - list: - elementType: - scalar: string - elementRelationship: atomic - name: io.k8s.api.extensions.v1beta1.ReplicaSet map: fields: @@ -8531,66 +8546,6 @@ var schemaYAML = typed.YAMLObject(`types: - name: maxUnavailable type: namedType: io.k8s.apimachinery.pkg.util.intstr.IntOrString -- name: io.k8s.api.extensions.v1beta1.RunAsGroupStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.RunAsUserStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - default: "" -- name: io.k8s.api.extensions.v1beta1.RuntimeClassStrategyOptions - map: - fields: - - name: allowedRuntimeClassNames - type: - list: - elementType: - scalar: string - elementRelationship: atomic - - name: defaultRuntimeClassName - type: - scalar: string -- name: io.k8s.api.extensions.v1beta1.SELinuxStrategyOptions - map: - fields: - - name: rule - type: - scalar: string - default: "" - - name: seLinuxOptions - type: - namedType: io.k8s.api.core.v1.SELinuxOptions -- name: io.k8s.api.extensions.v1beta1.SupplementalGroupsStrategyOptions - map: - fields: - - name: ranges - type: - list: - elementType: - namedType: io.k8s.api.extensions.v1beta1.IDRange - elementRelationship: atomic - - name: rule - type: - scalar: string - name: io.k8s.api.flowcontrol.v1alpha1.FlowDistinguisherMethod map: fields: @@ -10270,6 +10225,47 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: numeric default: 0 +- name: io.k8s.api.networking.v1alpha1.IPAddress + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: io.k8s.api.networking.v1alpha1.IPAddressSpec + default: {} +- name: io.k8s.api.networking.v1alpha1.IPAddressSpec + map: + fields: + - name: parentRef + type: + namedType: io.k8s.api.networking.v1alpha1.ParentReference +- name: io.k8s.api.networking.v1alpha1.ParentReference + map: + fields: + - name: group + type: + scalar: string + - name: name + type: + scalar: string + - name: namespace + type: + scalar: string + - name: resource + type: + scalar: string + - name: uid + type: + scalar: string - name: io.k8s.api.networking.v1beta1.HTTPIngressPath map: fields: @@ -11509,19 +11505,22 @@ var schemaYAML = typed.YAMLObject(`types: - name: namespace type: scalar: string -- name: io.k8s.api.resource.v1alpha1.AllocationResult +- name: io.k8s.api.resource.v1alpha2.AllocationResult map: fields: - name: availableOnNodes type: namedType: io.k8s.api.core.v1.NodeSelector - - name: resourceHandle + - name: resourceHandles type: - scalar: string + list: + elementType: + namedType: io.k8s.api.resource.v1alpha2.ResourceHandle + elementRelationship: atomic - name: shareable type: scalar: boolean -- name: io.k8s.api.resource.v1alpha1.PodScheduling +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContext map: fields: - name: apiVersion @@ -11536,13 +11535,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha1.PodSchedulingSpec + namedType: io.k8s.api.resource.v1alpha2.PodSchedulingContextSpec default: {} - name: status type: - namedType: io.k8s.api.resource.v1alpha1.PodSchedulingStatus + namedType: io.k8s.api.resource.v1alpha2.PodSchedulingContextStatus default: {} -- name: io.k8s.api.resource.v1alpha1.PodSchedulingSpec +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContextSpec map: fields: - name: potentialNodes @@ -11554,18 +11553,18 @@ var schemaYAML = typed.YAMLObject(`types: - name: selectedNode type: scalar: string -- name: io.k8s.api.resource.v1alpha1.PodSchedulingStatus +- name: io.k8s.api.resource.v1alpha2.PodSchedulingContextStatus map: fields: - name: resourceClaims type: list: elementType: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimSchedulingStatus + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSchedulingStatus elementRelationship: associative keys: - name -- name: io.k8s.api.resource.v1alpha1.ResourceClaim +- name: io.k8s.api.resource.v1alpha2.ResourceClaim map: fields: - name: apiVersion @@ -11580,13 +11579,13 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimSpec + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSpec default: {} - name: status type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimStatus + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimStatus default: {} -- name: io.k8s.api.resource.v1alpha1.ResourceClaimConsumerReference +- name: io.k8s.api.resource.v1alpha2.ResourceClaimConsumerReference map: fields: - name: apiGroup @@ -11604,7 +11603,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.resource.v1alpha1.ResourceClaimParametersReference +- name: io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference map: fields: - name: apiGroup @@ -11618,7 +11617,7 @@ var schemaYAML = typed.YAMLObject(`types: type: scalar: string default: "" -- name: io.k8s.api.resource.v1alpha1.ResourceClaimSchedulingStatus +- name: io.k8s.api.resource.v1alpha2.ResourceClaimSchedulingStatus map: fields: - name: name @@ -11630,7 +11629,7 @@ var schemaYAML = typed.YAMLObject(`types: elementType: scalar: string elementRelationship: associative -- name: io.k8s.api.resource.v1alpha1.ResourceClaimSpec +- name: io.k8s.api.resource.v1alpha2.ResourceClaimSpec map: fields: - name: allocationMode @@ -11638,17 +11637,17 @@ var schemaYAML = typed.YAMLObject(`types: scalar: string - name: parametersRef type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimParametersReference + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimParametersReference - name: resourceClassName type: scalar: string default: "" -- name: io.k8s.api.resource.v1alpha1.ResourceClaimStatus +- name: io.k8s.api.resource.v1alpha2.ResourceClaimStatus map: fields: - name: allocation type: - namedType: io.k8s.api.resource.v1alpha1.AllocationResult + namedType: io.k8s.api.resource.v1alpha2.AllocationResult - name: deallocationRequested type: scalar: boolean @@ -11659,11 +11658,11 @@ var schemaYAML = typed.YAMLObject(`types: type: list: elementType: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimConsumerReference + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimConsumerReference elementRelationship: associative keys: - uid -- name: io.k8s.api.resource.v1alpha1.ResourceClaimTemplate +- name: io.k8s.api.resource.v1alpha2.ResourceClaimTemplate map: fields: - name: apiVersion @@ -11678,9 +11677,9 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimTemplateSpec + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimTemplateSpec default: {} -- name: io.k8s.api.resource.v1alpha1.ResourceClaimTemplateSpec +- name: io.k8s.api.resource.v1alpha2.ResourceClaimTemplateSpec map: fields: - name: metadata @@ -11689,9 +11688,9 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: spec type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClaimSpec + namedType: io.k8s.api.resource.v1alpha2.ResourceClaimSpec default: {} -- name: io.k8s.api.resource.v1alpha1.ResourceClass +- name: io.k8s.api.resource.v1alpha2.ResourceClass map: fields: - name: apiVersion @@ -11710,11 +11709,11 @@ var schemaYAML = typed.YAMLObject(`types: default: {} - name: parametersRef type: - namedType: io.k8s.api.resource.v1alpha1.ResourceClassParametersReference + namedType: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference - name: suitableNodes type: namedType: io.k8s.api.core.v1.NodeSelector -- name: io.k8s.api.resource.v1alpha1.ResourceClassParametersReference +- name: io.k8s.api.resource.v1alpha2.ResourceClassParametersReference map: fields: - name: apiGroup @@ -11731,6 +11730,15 @@ var schemaYAML = typed.YAMLObject(`types: - name: namespace type: scalar: string +- name: io.k8s.api.resource.v1alpha2.ResourceHandle + map: + fields: + - name: data + type: + scalar: string + - name: driverName + type: + scalar: string - name: io.k8s.api.scheduling.v1.PriorityClass map: fields: diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/groupversionkind.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/groupversionkind.go deleted file mode 100644 index f400e5164..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/groupversionkind.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1 - -// GroupVersionKindApplyConfiguration represents an declarative configuration of the GroupVersionKind type for use -// with apply. -type GroupVersionKindApplyConfiguration struct { - Group *string `json:"group,omitempty"` - Version *string `json:"version,omitempty"` - Kind *string `json:"kind,omitempty"` -} - -// GroupVersionKindApplyConfiguration constructs an declarative configuration of the GroupVersionKind type for use with -// apply. -func GroupVersionKind() *GroupVersionKindApplyConfiguration { - return &GroupVersionKindApplyConfiguration{} -} - -// WithGroup sets the Group field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Group field is set to the value of the last call. -func (b *GroupVersionKindApplyConfiguration) WithGroup(value string) *GroupVersionKindApplyConfiguration { - b.Group = &value - return b -} - -// WithVersion sets the Version field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Version field is set to the value of the last call. -func (b *GroupVersionKindApplyConfiguration) WithVersion(value string) *GroupVersionKindApplyConfiguration { - b.Version = &value - return b -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *GroupVersionKindApplyConfiguration) WithKind(value string) *GroupVersionKindApplyConfiguration { - b.Kind = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/listmeta.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/listmeta.go deleted file mode 100644 index 5cadee335..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/listmeta.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1 - -// ListMetaApplyConfiguration represents an declarative configuration of the ListMeta type for use -// with apply. -type ListMetaApplyConfiguration struct { - SelfLink *string `json:"selfLink,omitempty"` - ResourceVersion *string `json:"resourceVersion,omitempty"` - Continue *string `json:"continue,omitempty"` - RemainingItemCount *int64 `json:"remainingItemCount,omitempty"` -} - -// ListMetaApplyConfiguration constructs an declarative configuration of the ListMeta type for use with -// apply. -func ListMeta() *ListMetaApplyConfiguration { - return &ListMetaApplyConfiguration{} -} - -// WithSelfLink sets the SelfLink field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SelfLink field is set to the value of the last call. -func (b *ListMetaApplyConfiguration) WithSelfLink(value string) *ListMetaApplyConfiguration { - b.SelfLink = &value - return b -} - -// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *ListMetaApplyConfiguration) WithResourceVersion(value string) *ListMetaApplyConfiguration { - b.ResourceVersion = &value - return b -} - -// WithContinue sets the Continue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Continue field is set to the value of the last call. -func (b *ListMetaApplyConfiguration) WithContinue(value string) *ListMetaApplyConfiguration { - b.Continue = &value - return b -} - -// WithRemainingItemCount sets the RemainingItemCount field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RemainingItemCount field is set to the value of the last call. -func (b *ListMetaApplyConfiguration) WithRemainingItemCount(value int64) *ListMetaApplyConfiguration { - b.RemainingItemCount = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/status.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/status.go deleted file mode 100644 index 7db432089..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/status.go +++ /dev/null @@ -1,142 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// StatusApplyConfiguration represents an declarative configuration of the Status type for use -// with apply. -type StatusApplyConfiguration struct { - TypeMetaApplyConfiguration `json:",inline"` - *ListMetaApplyConfiguration `json:"metadata,omitempty"` - Status *string `json:"status,omitempty"` - Message *string `json:"message,omitempty"` - Reason *metav1.StatusReason `json:"reason,omitempty"` - Details *StatusDetailsApplyConfiguration `json:"details,omitempty"` - Code *int32 `json:"code,omitempty"` -} - -// StatusApplyConfiguration constructs an declarative configuration of the Status type for use with -// apply. -func Status() *StatusApplyConfiguration { - b := &StatusApplyConfiguration{} - b.WithKind("Status") - b.WithAPIVersion("meta.k8s.io/v1") - return b -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithKind(value string) *StatusApplyConfiguration { - b.Kind = &value - return b -} - -// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the APIVersion field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithAPIVersion(value string) *StatusApplyConfiguration { - b.APIVersion = &value - return b -} - -// WithSelfLink sets the SelfLink field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the SelfLink field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithSelfLink(value string) *StatusApplyConfiguration { - b.ensureListMetaApplyConfigurationExists() - b.SelfLink = &value - return b -} - -// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithResourceVersion(value string) *StatusApplyConfiguration { - b.ensureListMetaApplyConfigurationExists() - b.ResourceVersion = &value - return b -} - -// WithContinue sets the Continue field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Continue field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithContinue(value string) *StatusApplyConfiguration { - b.ensureListMetaApplyConfigurationExists() - b.Continue = &value - return b -} - -// WithRemainingItemCount sets the RemainingItemCount field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RemainingItemCount field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithRemainingItemCount(value int64) *StatusApplyConfiguration { - b.ensureListMetaApplyConfigurationExists() - b.RemainingItemCount = &value - return b -} - -func (b *StatusApplyConfiguration) ensureListMetaApplyConfigurationExists() { - if b.ListMetaApplyConfiguration == nil { - b.ListMetaApplyConfiguration = &ListMetaApplyConfiguration{} - } -} - -// WithStatus sets the Status field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Status field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithStatus(value string) *StatusApplyConfiguration { - b.Status = &value - return b -} - -// WithMessage sets the Message field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Message field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithMessage(value string) *StatusApplyConfiguration { - b.Message = &value - return b -} - -// WithReason sets the Reason field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Reason field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithReason(value metav1.StatusReason) *StatusApplyConfiguration { - b.Reason = &value - return b -} - -// WithDetails sets the Details field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Details field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithDetails(value *StatusDetailsApplyConfiguration) *StatusApplyConfiguration { - b.Details = value - return b -} - -// WithCode sets the Code field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Code field is set to the value of the last call. -func (b *StatusApplyConfiguration) WithCode(value int32) *StatusApplyConfiguration { - b.Code = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statuscause.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statuscause.go deleted file mode 100644 index 7f05bca49..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statuscause.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1 - -import ( - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// StatusCauseApplyConfiguration represents an declarative configuration of the StatusCause type for use -// with apply. -type StatusCauseApplyConfiguration struct { - Type *v1.CauseType `json:"reason,omitempty"` - Message *string `json:"message,omitempty"` - Field *string `json:"field,omitempty"` -} - -// StatusCauseApplyConfiguration constructs an declarative configuration of the StatusCause type for use with -// apply. -func StatusCause() *StatusCauseApplyConfiguration { - return &StatusCauseApplyConfiguration{} -} - -// WithType sets the Type field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Type field is set to the value of the last call. -func (b *StatusCauseApplyConfiguration) WithType(value v1.CauseType) *StatusCauseApplyConfiguration { - b.Type = &value - return b -} - -// WithMessage sets the Message field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Message field is set to the value of the last call. -func (b *StatusCauseApplyConfiguration) WithMessage(value string) *StatusCauseApplyConfiguration { - b.Message = &value - return b -} - -// WithField sets the Field field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Field field is set to the value of the last call. -func (b *StatusCauseApplyConfiguration) WithField(value string) *StatusCauseApplyConfiguration { - b.Field = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statusdetails.go b/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statusdetails.go deleted file mode 100644 index a7dbaa1b2..000000000 --- a/vendor/k8s.io/client-go/applyconfigurations/meta/v1/statusdetails.go +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by applyconfiguration-gen. DO NOT EDIT. - -package v1 - -import ( - types "k8s.io/apimachinery/pkg/types" -) - -// StatusDetailsApplyConfiguration represents an declarative configuration of the StatusDetails type for use -// with apply. -type StatusDetailsApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Group *string `json:"group,omitempty"` - Kind *string `json:"kind,omitempty"` - UID *types.UID `json:"uid,omitempty"` - Causes []StatusCauseApplyConfiguration `json:"causes,omitempty"` - RetryAfterSeconds *int32 `json:"retryAfterSeconds,omitempty"` -} - -// StatusDetailsApplyConfiguration constructs an declarative configuration of the StatusDetails type for use with -// apply. -func StatusDetails() *StatusDetailsApplyConfiguration { - return &StatusDetailsApplyConfiguration{} -} - -// WithName sets the Name field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithName(value string) *StatusDetailsApplyConfiguration { - b.Name = &value - return b -} - -// WithGroup sets the Group field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Group field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithGroup(value string) *StatusDetailsApplyConfiguration { - b.Group = &value - return b -} - -// WithKind sets the Kind field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Kind field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithKind(value string) *StatusDetailsApplyConfiguration { - b.Kind = &value - return b -} - -// WithUID sets the UID field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the UID field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithUID(value types.UID) *StatusDetailsApplyConfiguration { - b.UID = &value - return b -} - -// WithCauses adds the given value to the Causes field in the declarative configuration -// and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Causes field. -func (b *StatusDetailsApplyConfiguration) WithCauses(values ...*StatusCauseApplyConfiguration) *StatusDetailsApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithCauses") - } - b.Causes = append(b.Causes, *values[i]) - } - return b -} - -// WithRetryAfterSeconds sets the RetryAfterSeconds field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the RetryAfterSeconds field is set to the value of the last call. -func (b *StatusDetailsApplyConfiguration) WithRetryAfterSeconds(value int32) *StatusDetailsApplyConfiguration { - b.RetryAfterSeconds = &value - return b -} diff --git a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go similarity index 66% rename from vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go rename to vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go index c70906cfa..da6822111 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/extensions/v1beta1/podsecuritypolicy.go +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddress.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1beta1 +package v1alpha1 import ( - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -27,63 +27,63 @@ import ( v1 "k8s.io/client-go/applyconfigurations/meta/v1" ) -// PodSecurityPolicyApplyConfiguration represents an declarative configuration of the PodSecurityPolicy type for use +// IPAddressApplyConfiguration represents an declarative configuration of the IPAddress type for use // with apply. -type PodSecurityPolicyApplyConfiguration struct { +type IPAddressApplyConfiguration struct { v1.TypeMetaApplyConfiguration `json:",inline"` *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` - Spec *PodSecurityPolicySpecApplyConfiguration `json:"spec,omitempty"` + Spec *IPAddressSpecApplyConfiguration `json:"spec,omitempty"` } -// PodSecurityPolicy constructs an declarative configuration of the PodSecurityPolicy type for use with +// IPAddress constructs an declarative configuration of the IPAddress type for use with // apply. -func PodSecurityPolicy(name string) *PodSecurityPolicyApplyConfiguration { - b := &PodSecurityPolicyApplyConfiguration{} +func IPAddress(name string) *IPAddressApplyConfiguration { + b := &IPAddressApplyConfiguration{} b.WithName(name) - b.WithKind("PodSecurityPolicy") - b.WithAPIVersion("extensions/v1beta1") + b.WithKind("IPAddress") + b.WithAPIVersion("networking.k8s.io/v1alpha1") return b } -// ExtractPodSecurityPolicy extracts the applied configuration owned by fieldManager from -// podSecurityPolicy. If no managedFields are found in podSecurityPolicy for fieldManager, a -// PodSecurityPolicyApplyConfiguration is returned with only the Name, Namespace (if applicable), +// ExtractIPAddress extracts the applied configuration owned by fieldManager from +// iPAddress. If no managedFields are found in iPAddress for fieldManager, a +// IPAddressApplyConfiguration is returned with only the Name, Namespace (if applicable), // APIVersion and Kind populated. It is possible that no managed fields were found for because other // field managers have taken ownership of all the fields previously owned by fieldManager, or because // the fieldManager never owned fields any fields. -// podSecurityPolicy must be a unmodified PodSecurityPolicy API object that was retrieved from the Kubernetes API. -// ExtractPodSecurityPolicy provides a way to perform a extract/modify-in-place/apply workflow. +// iPAddress must be a unmodified IPAddress API object that was retrieved from the Kubernetes API. +// ExtractIPAddress provides a way to perform a extract/modify-in-place/apply workflow. // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractPodSecurityPolicy(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string) (*PodSecurityPolicyApplyConfiguration, error) { - return extractPodSecurityPolicy(podSecurityPolicy, fieldManager, "") +func ExtractIPAddress(iPAddress *networkingv1alpha1.IPAddress, fieldManager string) (*IPAddressApplyConfiguration, error) { + return extractIPAddress(iPAddress, fieldManager, "") } -// ExtractPodSecurityPolicyStatus is the same as ExtractPodSecurityPolicy except +// ExtractIPAddressStatus is the same as ExtractIPAddress except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractPodSecurityPolicyStatus(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string) (*PodSecurityPolicyApplyConfiguration, error) { - return extractPodSecurityPolicy(podSecurityPolicy, fieldManager, "status") +func ExtractIPAddressStatus(iPAddress *networkingv1alpha1.IPAddress, fieldManager string) (*IPAddressApplyConfiguration, error) { + return extractIPAddress(iPAddress, fieldManager, "status") } -func extractPodSecurityPolicy(podSecurityPolicy *extensionsv1beta1.PodSecurityPolicy, fieldManager string, subresource string) (*PodSecurityPolicyApplyConfiguration, error) { - b := &PodSecurityPolicyApplyConfiguration{} - err := managedfields.ExtractInto(podSecurityPolicy, internal.Parser().Type("io.k8s.api.extensions.v1beta1.PodSecurityPolicy"), fieldManager, b, subresource) +func extractIPAddress(iPAddress *networkingv1alpha1.IPAddress, fieldManager string, subresource string) (*IPAddressApplyConfiguration, error) { + b := &IPAddressApplyConfiguration{} + err := managedfields.ExtractInto(iPAddress, internal.Parser().Type("io.k8s.api.networking.v1alpha1.IPAddress"), fieldManager, b, subresource) if err != nil { return nil, err } - b.WithName(podSecurityPolicy.Name) + b.WithName(iPAddress.Name) - b.WithKind("PodSecurityPolicy") - b.WithAPIVersion("extensions/v1beta1") + b.WithKind("IPAddress") + b.WithAPIVersion("networking.k8s.io/v1alpha1") return b, nil } // WithKind sets the Kind field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Kind field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithKind(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithKind(value string) *IPAddressApplyConfiguration { b.Kind = &value return b } @@ -91,7 +91,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithKind(value string) *PodSecurit // WithAPIVersion sets the APIVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the APIVersion field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithAPIVersion(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithAPIVersion(value string) *IPAddressApplyConfiguration { b.APIVersion = &value return b } @@ -99,7 +99,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithAPIVersion(value string) *PodS // WithName sets the Name field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Name field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithName(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithName(value string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Name = &value return b @@ -108,7 +108,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithName(value string) *PodSecurit // WithGenerateName sets the GenerateName field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the GenerateName field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithGenerateName(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithGenerateName(value string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.GenerateName = &value return b @@ -117,7 +117,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithGenerateName(value string) *Po // WithNamespace sets the Namespace field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Namespace field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithNamespace(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithNamespace(value string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Namespace = &value return b @@ -126,7 +126,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithNamespace(value string) *PodSe // WithUID sets the UID field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the UID field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithUID(value types.UID) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithUID(value types.UID) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.UID = &value return b @@ -135,7 +135,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithUID(value types.UID) *PodSecur // WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the ResourceVersion field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithResourceVersion(value string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithResourceVersion(value string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.ResourceVersion = &value return b @@ -144,7 +144,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithResourceVersion(value string) // WithGeneration sets the Generation field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Generation field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithGeneration(value int64) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithGeneration(value int64) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.Generation = &value return b @@ -153,7 +153,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithGeneration(value int64) *PodSe // WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreationTimestamp field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithCreationTimestamp(value metav1.Time) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.CreationTimestamp = &value return b @@ -162,7 +162,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithCreationTimestamp(value metav1 // WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionTimestamp field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionTimestamp = &value return b @@ -171,7 +171,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithDeletionTimestamp(value metav1 // WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() b.DeletionGracePeriodSeconds = &value return b @@ -181,7 +181,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithDeletionGracePeriodSeconds(val // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Labels field, // overwriting an existing map entries in Labels field with the same key. -func (b *PodSecurityPolicyApplyConfiguration) WithLabels(entries map[string]string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithLabels(entries map[string]string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Labels == nil && len(entries) > 0 { b.Labels = make(map[string]string, len(entries)) @@ -196,7 +196,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithLabels(entries map[string]stri // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, the entries provided by each call will be put on the Annotations field, // overwriting an existing map entries in Annotations field with the same key. -func (b *PodSecurityPolicyApplyConfiguration) WithAnnotations(entries map[string]string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithAnnotations(entries map[string]string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() if b.Annotations == nil && len(entries) > 0 { b.Annotations = make(map[string]string, len(entries)) @@ -210,7 +210,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithAnnotations(entries map[string // WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the OwnerReferences field. -func (b *PodSecurityPolicyApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { if values[i] == nil { @@ -224,7 +224,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithOwnerReferences(values ...*v1. // WithFinalizers adds the given value to the Finalizers field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Finalizers field. -func (b *PodSecurityPolicyApplyConfiguration) WithFinalizers(values ...string) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithFinalizers(values ...string) *IPAddressApplyConfiguration { b.ensureObjectMetaApplyConfigurationExists() for i := range values { b.Finalizers = append(b.Finalizers, values[i]) @@ -232,7 +232,7 @@ func (b *PodSecurityPolicyApplyConfiguration) WithFinalizers(values ...string) * return b } -func (b *PodSecurityPolicyApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { +func (b *IPAddressApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { if b.ObjectMetaApplyConfiguration == nil { b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} } @@ -241,7 +241,7 @@ func (b *PodSecurityPolicyApplyConfiguration) ensureObjectMetaApplyConfiguration // WithSpec sets the Spec field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Spec field is set to the value of the last call. -func (b *PodSecurityPolicyApplyConfiguration) WithSpec(value *PodSecurityPolicySpecApplyConfiguration) *PodSecurityPolicyApplyConfiguration { +func (b *IPAddressApplyConfiguration) WithSpec(value *IPAddressSpecApplyConfiguration) *IPAddressApplyConfiguration { b.Spec = value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go new file mode 100644 index 000000000..064963d69 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/ipaddressspec.go @@ -0,0 +1,39 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// IPAddressSpecApplyConfiguration represents an declarative configuration of the IPAddressSpec type for use +// with apply. +type IPAddressSpecApplyConfiguration struct { + ParentRef *ParentReferenceApplyConfiguration `json:"parentRef,omitempty"` +} + +// IPAddressSpecApplyConfiguration constructs an declarative configuration of the IPAddressSpec type for use with +// apply. +func IPAddressSpec() *IPAddressSpecApplyConfiguration { + return &IPAddressSpecApplyConfiguration{} +} + +// WithParentRef sets the ParentRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ParentRef field is set to the value of the last call. +func (b *IPAddressSpecApplyConfiguration) WithParentRef(value *ParentReferenceApplyConfiguration) *IPAddressSpecApplyConfiguration { + b.ParentRef = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go new file mode 100644 index 000000000..14b10b19f --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/networking/v1alpha1/parentreference.go @@ -0,0 +1,79 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + types "k8s.io/apimachinery/pkg/types" +) + +// ParentReferenceApplyConfiguration represents an declarative configuration of the ParentReference type for use +// with apply. +type ParentReferenceApplyConfiguration struct { + Group *string `json:"group,omitempty"` + Resource *string `json:"resource,omitempty"` + Namespace *string `json:"namespace,omitempty"` + Name *string `json:"name,omitempty"` + UID *types.UID `json:"uid,omitempty"` +} + +// ParentReferenceApplyConfiguration constructs an declarative configuration of the ParentReference type for use with +// apply. +func ParentReference() *ParentReferenceApplyConfiguration { + return &ParentReferenceApplyConfiguration{} +} + +// WithGroup sets the Group field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Group field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithGroup(value string) *ParentReferenceApplyConfiguration { + b.Group = &value + return b +} + +// WithResource sets the Resource field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resource field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithResource(value string) *ParentReferenceApplyConfiguration { + b.Resource = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithNamespace(value string) *ParentReferenceApplyConfiguration { + b.Namespace = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithName(value string) *ParentReferenceApplyConfiguration { + b.Name = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ParentReferenceApplyConfiguration) WithUID(value types.UID) *ParentReferenceApplyConfiguration { + b.UID = &value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/allocationresult.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go similarity index 76% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/allocationresult.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go index a2ad3adf1..bc6078aa9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/allocationresult.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/allocationresult.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( v1 "k8s.io/client-go/applyconfigurations/core/v1" @@ -25,7 +25,7 @@ import ( // AllocationResultApplyConfiguration represents an declarative configuration of the AllocationResult type for use // with apply. type AllocationResultApplyConfiguration struct { - ResourceHandle *string `json:"resourceHandle,omitempty"` + ResourceHandles []ResourceHandleApplyConfiguration `json:"resourceHandles,omitempty"` AvailableOnNodes *v1.NodeSelectorApplyConfiguration `json:"availableOnNodes,omitempty"` Shareable *bool `json:"shareable,omitempty"` } @@ -36,11 +36,16 @@ func AllocationResult() *AllocationResultApplyConfiguration { return &AllocationResultApplyConfiguration{} } -// WithResourceHandle sets the ResourceHandle field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ResourceHandle field is set to the value of the last call. -func (b *AllocationResultApplyConfiguration) WithResourceHandle(value string) *AllocationResultApplyConfiguration { - b.ResourceHandle = &value +// WithResourceHandles adds the given value to the ResourceHandles field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ResourceHandles field. +func (b *AllocationResultApplyConfiguration) WithResourceHandles(values ...*ResourceHandleApplyConfiguration) *AllocationResultApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithResourceHandles") + } + b.ResourceHandles = append(b.ResourceHandles, *values[i]) + } return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 000000000..1dfb6ff97 --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,258 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + internal "k8s.io/client-go/applyconfigurations/internal" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// PodSchedulingContextApplyConfiguration represents an declarative configuration of the PodSchedulingContext type for use +// with apply. +type PodSchedulingContextApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *PodSchedulingContextSpecApplyConfiguration `json:"spec,omitempty"` + Status *PodSchedulingContextStatusApplyConfiguration `json:"status,omitempty"` +} + +// PodSchedulingContext constructs an declarative configuration of the PodSchedulingContext type for use with +// apply. +func PodSchedulingContext(name, namespace string) *PodSchedulingContextApplyConfiguration { + b := &PodSchedulingContextApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("PodSchedulingContext") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b +} + +// ExtractPodSchedulingContext extracts the applied configuration owned by fieldManager from +// podSchedulingContext. If no managedFields are found in podSchedulingContext for fieldManager, a +// PodSchedulingContextApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// podSchedulingContext must be a unmodified PodSchedulingContext API object that was retrieved from the Kubernetes API. +// ExtractPodSchedulingContext provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractPodSchedulingContext(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string) (*PodSchedulingContextApplyConfiguration, error) { + return extractPodSchedulingContext(podSchedulingContext, fieldManager, "") +} + +// ExtractPodSchedulingContextStatus is the same as ExtractPodSchedulingContext except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractPodSchedulingContextStatus(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string) (*PodSchedulingContextApplyConfiguration, error) { + return extractPodSchedulingContext(podSchedulingContext, fieldManager, "status") +} + +func extractPodSchedulingContext(podSchedulingContext *resourcev1alpha2.PodSchedulingContext, fieldManager string, subresource string) (*PodSchedulingContextApplyConfiguration, error) { + b := &PodSchedulingContextApplyConfiguration{} + err := managedfields.ExtractInto(podSchedulingContext, internal.Parser().Type("io.k8s.api.resource.v1alpha2.PodSchedulingContext"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(podSchedulingContext.Name) + b.WithNamespace(podSchedulingContext.Namespace) + + b.WithKind("PodSchedulingContext") + b.WithAPIVersion("resource.k8s.io/v1alpha2") + return b, nil +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithKind(value string) *PodSchedulingContextApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithAPIVersion(value string) *PodSchedulingContextApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithName(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithGenerateName(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithNamespace(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithUID(value types.UID) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithResourceVersion(value string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithGeneration(value int64) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *PodSchedulingContextApplyConfiguration) WithLabels(entries map[string]string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *PodSchedulingContextApplyConfiguration) WithAnnotations(entries map[string]string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *PodSchedulingContextApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *PodSchedulingContextApplyConfiguration) WithFinalizers(values ...string) *PodSchedulingContextApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *PodSchedulingContextApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithSpec(value *PodSchedulingContextSpecApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *PodSchedulingContextApplyConfiguration) WithStatus(value *PodSchedulingContextStatusApplyConfiguration) *PodSchedulingContextApplyConfiguration { + b.Status = value + return b +} diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go similarity index 67% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingspec.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go index 9fd3c1ee5..c95d3295e 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextspec.go @@ -16,25 +16,25 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -// PodSchedulingSpecApplyConfiguration represents an declarative configuration of the PodSchedulingSpec type for use +// PodSchedulingContextSpecApplyConfiguration represents an declarative configuration of the PodSchedulingContextSpec type for use // with apply. -type PodSchedulingSpecApplyConfiguration struct { +type PodSchedulingContextSpecApplyConfiguration struct { SelectedNode *string `json:"selectedNode,omitempty"` PotentialNodes []string `json:"potentialNodes,omitempty"` } -// PodSchedulingSpecApplyConfiguration constructs an declarative configuration of the PodSchedulingSpec type for use with +// PodSchedulingContextSpecApplyConfiguration constructs an declarative configuration of the PodSchedulingContextSpec type for use with // apply. -func PodSchedulingSpec() *PodSchedulingSpecApplyConfiguration { - return &PodSchedulingSpecApplyConfiguration{} +func PodSchedulingContextSpec() *PodSchedulingContextSpecApplyConfiguration { + return &PodSchedulingContextSpecApplyConfiguration{} } // WithSelectedNode sets the SelectedNode field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the SelectedNode field is set to the value of the last call. -func (b *PodSchedulingSpecApplyConfiguration) WithSelectedNode(value string) *PodSchedulingSpecApplyConfiguration { +func (b *PodSchedulingContextSpecApplyConfiguration) WithSelectedNode(value string) *PodSchedulingContextSpecApplyConfiguration { b.SelectedNode = &value return b } @@ -42,7 +42,7 @@ func (b *PodSchedulingSpecApplyConfiguration) WithSelectedNode(value string) *Po // WithPotentialNodes adds the given value to the PotentialNodes field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the PotentialNodes field. -func (b *PodSchedulingSpecApplyConfiguration) WithPotentialNodes(values ...string) *PodSchedulingSpecApplyConfiguration { +func (b *PodSchedulingContextSpecApplyConfiguration) WithPotentialNodes(values ...string) *PodSchedulingContextSpecApplyConfiguration { for i := range values { b.PotentialNodes = append(b.PotentialNodes, values[i]) } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go similarity index 64% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingstatus.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go index 5744f6c3e..a8b10b9a0 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/podschedulingstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/podschedulingcontextstatus.go @@ -16,24 +16,24 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -// PodSchedulingStatusApplyConfiguration represents an declarative configuration of the PodSchedulingStatus type for use +// PodSchedulingContextStatusApplyConfiguration represents an declarative configuration of the PodSchedulingContextStatus type for use // with apply. -type PodSchedulingStatusApplyConfiguration struct { +type PodSchedulingContextStatusApplyConfiguration struct { ResourceClaims []ResourceClaimSchedulingStatusApplyConfiguration `json:"resourceClaims,omitempty"` } -// PodSchedulingStatusApplyConfiguration constructs an declarative configuration of the PodSchedulingStatus type for use with +// PodSchedulingContextStatusApplyConfiguration constructs an declarative configuration of the PodSchedulingContextStatus type for use with // apply. -func PodSchedulingStatus() *PodSchedulingStatusApplyConfiguration { - return &PodSchedulingStatusApplyConfiguration{} +func PodSchedulingContextStatus() *PodSchedulingContextStatusApplyConfiguration { + return &PodSchedulingContextStatusApplyConfiguration{} } // WithResourceClaims adds the given value to the ResourceClaims field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the ResourceClaims field. -func (b *PodSchedulingStatusApplyConfiguration) WithResourceClaims(values ...*ResourceClaimSchedulingStatusApplyConfiguration) *PodSchedulingStatusApplyConfiguration { +func (b *PodSchedulingContextStatusApplyConfiguration) WithResourceClaims(values ...*ResourceClaimSchedulingStatusApplyConfiguration) *PodSchedulingContextStatusApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithResourceClaims") diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaim.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go similarity index 96% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaim.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go index f94811a9b..6c219f837 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaim.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaim.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -43,7 +43,7 @@ func ResourceClaim(name, namespace string) *ResourceClaimApplyConfiguration { b.WithName(name) b.WithNamespace(namespace) b.WithKind("ResourceClaim") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b } @@ -58,20 +58,20 @@ func ResourceClaim(name, namespace string) *ResourceClaimApplyConfiguration { // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractResourceClaim(resourceClaim *resourcev1alpha1.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { +func ExtractResourceClaim(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { return extractResourceClaim(resourceClaim, fieldManager, "") } // ExtractResourceClaimStatus is the same as ExtractResourceClaim except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractResourceClaimStatus(resourceClaim *resourcev1alpha1.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { +func ExtractResourceClaimStatus(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string) (*ResourceClaimApplyConfiguration, error) { return extractResourceClaim(resourceClaim, fieldManager, "status") } -func extractResourceClaim(resourceClaim *resourcev1alpha1.ResourceClaim, fieldManager string, subresource string) (*ResourceClaimApplyConfiguration, error) { +func extractResourceClaim(resourceClaim *resourcev1alpha2.ResourceClaim, fieldManager string, subresource string) (*ResourceClaimApplyConfiguration, error) { b := &ResourceClaimApplyConfiguration{} - err := managedfields.ExtractInto(resourceClaim, internal.Parser().Type("io.k8s.api.resource.v1alpha1.ResourceClaim"), fieldManager, b, subresource) + err := managedfields.ExtractInto(resourceClaim, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClaim"), fieldManager, b, subresource) if err != nil { return nil, err } @@ -79,7 +79,7 @@ func extractResourceClaim(resourceClaim *resourcev1alpha1.ResourceClaim, fieldMa b.WithNamespace(resourceClaim.Namespace) b.WithKind("ResourceClaim") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b, nil } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimconsumerreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimconsumerreference.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go index 477099cd7..41bb9e9a1 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimconsumerreference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimconsumerreference.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( types "k8s.io/apimachinery/pkg/types" diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimparametersreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimparametersreference.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go index d7b25d75e..27820ede6 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimparametersreference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimparametersreference.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // ResourceClaimParametersReferenceApplyConfiguration represents an declarative configuration of the ResourceClaimParametersReference type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimschedulingstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimschedulingstatus.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go index 35ff34aba..e74679aed 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimschedulingstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimschedulingstatus.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // ResourceClaimSchedulingStatusApplyConfiguration represents an declarative configuration of the ResourceClaimSchedulingStatus type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimspec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go similarity index 93% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimspec.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go index d32619046..0c73e64e9 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimspec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimspec.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" ) // ResourceClaimSpecApplyConfiguration represents an declarative configuration of the ResourceClaimSpec type for use @@ -27,7 +27,7 @@ import ( type ResourceClaimSpecApplyConfiguration struct { ResourceClassName *string `json:"resourceClassName,omitempty"` ParametersRef *ResourceClaimParametersReferenceApplyConfiguration `json:"parametersRef,omitempty"` - AllocationMode *resourcev1alpha1.AllocationMode `json:"allocationMode,omitempty"` + AllocationMode *resourcev1alpha2.AllocationMode `json:"allocationMode,omitempty"` } // ResourceClaimSpecApplyConfiguration constructs an declarative configuration of the ResourceClaimSpec type for use with @@ -55,7 +55,7 @@ func (b *ResourceClaimSpecApplyConfiguration) WithParametersRef(value *ResourceC // WithAllocationMode sets the AllocationMode field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the AllocationMode field is set to the value of the last call. -func (b *ResourceClaimSpecApplyConfiguration) WithAllocationMode(value resourcev1alpha1.AllocationMode) *ResourceClaimSpecApplyConfiguration { +func (b *ResourceClaimSpecApplyConfiguration) WithAllocationMode(value resourcev1alpha2.AllocationMode) *ResourceClaimSpecApplyConfiguration { b.AllocationMode = &value return b } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimstatus.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimstatus.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go index e2283f8b0..c6fa61090 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimstatus.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimstatus.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // ResourceClaimStatusApplyConfiguration represents an declarative configuration of the ResourceClaimStatus type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go similarity index 96% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplate.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go index e3c602cb6..fc2209b8f 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplate.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -42,7 +42,7 @@ func ResourceClaimTemplate(name, namespace string) *ResourceClaimTemplateApplyCo b.WithName(name) b.WithNamespace(namespace) b.WithKind("ResourceClaimTemplate") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b } @@ -57,20 +57,20 @@ func ResourceClaimTemplate(name, namespace string) *ResourceClaimTemplateApplyCo // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { +func ExtractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { return extractResourceClaimTemplate(resourceClaimTemplate, fieldManager, "") } // ExtractResourceClaimTemplateStatus is the same as ExtractResourceClaimTemplate except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractResourceClaimTemplateStatus(resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { +func ExtractResourceClaimTemplateStatus(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string) (*ResourceClaimTemplateApplyConfiguration, error) { return extractResourceClaimTemplate(resourceClaimTemplate, fieldManager, "status") } -func extractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplate, fieldManager string, subresource string) (*ResourceClaimTemplateApplyConfiguration, error) { +func extractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplate, fieldManager string, subresource string) (*ResourceClaimTemplateApplyConfiguration, error) { b := &ResourceClaimTemplateApplyConfiguration{} - err := managedfields.ExtractInto(resourceClaimTemplate, internal.Parser().Type("io.k8s.api.resource.v1alpha1.ResourceClaimTemplate"), fieldManager, b, subresource) + err := managedfields.ExtractInto(resourceClaimTemplate, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClaimTemplate"), fieldManager, b, subresource) if err != nil { return nil, err } @@ -78,7 +78,7 @@ func extractResourceClaimTemplate(resourceClaimTemplate *resourcev1alpha1.Resour b.WithNamespace(resourceClaimTemplate.Namespace) b.WithKind("ResourceClaimTemplate") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b, nil } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplatespec.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplatespec.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go index 88058e066..2f38ea036 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclaimtemplatespec.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclaimtemplatespec.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclass.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go similarity index 96% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclass.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go index 5f980acdb..724c9e88e 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclass.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclass.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" managedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -44,7 +44,7 @@ func ResourceClass(name string) *ResourceClassApplyConfiguration { b := &ResourceClassApplyConfiguration{} b.WithName(name) b.WithKind("ResourceClass") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b } @@ -59,27 +59,27 @@ func ResourceClass(name string) *ResourceClassApplyConfiguration { // Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously // applied if another fieldManager has updated or force applied any of the previously applied fields. // Experimental! -func ExtractResourceClass(resourceClass *resourcev1alpha1.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { +func ExtractResourceClass(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { return extractResourceClass(resourceClass, fieldManager, "") } // ExtractResourceClassStatus is the same as ExtractResourceClass except // that it extracts the status subresource applied configuration. // Experimental! -func ExtractResourceClassStatus(resourceClass *resourcev1alpha1.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { +func ExtractResourceClassStatus(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string) (*ResourceClassApplyConfiguration, error) { return extractResourceClass(resourceClass, fieldManager, "status") } -func extractResourceClass(resourceClass *resourcev1alpha1.ResourceClass, fieldManager string, subresource string) (*ResourceClassApplyConfiguration, error) { +func extractResourceClass(resourceClass *resourcev1alpha2.ResourceClass, fieldManager string, subresource string) (*ResourceClassApplyConfiguration, error) { b := &ResourceClassApplyConfiguration{} - err := managedfields.ExtractInto(resourceClass, internal.Parser().Type("io.k8s.api.resource.v1alpha1.ResourceClass"), fieldManager, b, subresource) + err := managedfields.ExtractInto(resourceClass, internal.Parser().Type("io.k8s.api.resource.v1alpha2.ResourceClass"), fieldManager, b, subresource) if err != nil { return nil, err } b.WithName(resourceClass.Name) b.WithKind("ResourceClass") - b.WithAPIVersion("resource.k8s.io/v1alpha1") + b.WithAPIVersion("resource.k8s.io/v1alpha2") return b, nil } diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclassparametersreference.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go similarity index 99% rename from vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclassparametersreference.go rename to vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go index b03a9a6da..d67e4d397 100644 --- a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha1/resourceclassparametersreference.go +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourceclassparametersreference.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by applyconfiguration-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 // ResourceClassParametersReferenceApplyConfiguration represents an declarative configuration of the ResourceClassParametersReference type for use // with apply. diff --git a/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go new file mode 100644 index 000000000..028cbaa1a --- /dev/null +++ b/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha2/resourcehandle.go @@ -0,0 +1,48 @@ +/* +Copyright 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha2 + +// ResourceHandleApplyConfiguration represents an declarative configuration of the ResourceHandle type for use +// with apply. +type ResourceHandleApplyConfiguration struct { + DriverName *string `json:"driverName,omitempty"` + Data *string `json:"data,omitempty"` +} + +// ResourceHandleApplyConfiguration constructs an declarative configuration of the ResourceHandle type for use with +// apply. +func ResourceHandle() *ResourceHandleApplyConfiguration { + return &ResourceHandleApplyConfiguration{} +} + +// WithDriverName sets the DriverName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DriverName field is set to the value of the last call. +func (b *ResourceHandleApplyConfiguration) WithDriverName(value string) *ResourceHandleApplyConfiguration { + b.DriverName = &value + return b +} + +// WithData sets the Data field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Data field is set to the value of the last call. +func (b *ResourceHandleApplyConfiguration) WithData(value string) *ResourceHandleApplyConfiguration { + b.Data = &value + return b +} diff --git a/vendor/k8s.io/client-go/discovery/aggregated_discovery.go b/vendor/k8s.io/client-go/discovery/aggregated_discovery.go index 033a4c8fc..7470259dc 100644 --- a/vendor/k8s.io/client-go/discovery/aggregated_discovery.go +++ b/vendor/k8s.io/client-go/discovery/aggregated_discovery.go @@ -24,19 +24,36 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) +// StaleGroupVersionError encasulates failed GroupVersion marked "stale" +// in the returned AggregatedDiscovery format. +type StaleGroupVersionError struct { + gv schema.GroupVersion +} + +func (s StaleGroupVersionError) Error() string { + return fmt.Sprintf("stale GroupVersion discovery: %v", s.gv) +} + // SplitGroupsAndResources transforms "aggregated" discovery top-level structure into // the previous "unaggregated" discovery groups and resources. -func SplitGroupsAndResources(aggregatedGroups apidiscovery.APIGroupDiscoveryList) (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList) { +func SplitGroupsAndResources(aggregatedGroups apidiscovery.APIGroupDiscoveryList) ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error) { // Aggregated group list will contain the entirety of discovery, including - // groups, versions, and resources. + // groups, versions, and resources. GroupVersions marked "stale" are failed. groups := []*metav1.APIGroup{} + failedGVs := map[schema.GroupVersion]error{} resourcesByGV := map[schema.GroupVersion]*metav1.APIResourceList{} for _, aggGroup := range aggregatedGroups.Items { - group, resources := convertAPIGroup(aggGroup) + group, resources, failed := convertAPIGroup(aggGroup) groups = append(groups, group) for gv, resourceList := range resources { resourcesByGV[gv] = resourceList } + for gv, err := range failed { + failedGVs[gv] = err + } } // Transform slice of groups to group list before returning. groupList := &metav1.APIGroupList{} @@ -44,65 +61,94 @@ func SplitGroupsAndResources(aggregatedGroups apidiscovery.APIGroupDiscoveryList for _, group := range groups { groupList.Groups = append(groupList.Groups, *group) } - return groupList, resourcesByGV + return groupList, resourcesByGV, failedGVs } // convertAPIGroup tranforms an "aggregated" APIGroupDiscovery to an "legacy" APIGroup, // also returning the map of APIResourceList for resources within GroupVersions. -func convertAPIGroup(g apidiscovery.APIGroupDiscovery) (*metav1.APIGroup, map[schema.GroupVersion]*metav1.APIResourceList) { +func convertAPIGroup(g apidiscovery.APIGroupDiscovery) ( + *metav1.APIGroup, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error) { // Iterate through versions to convert to group and resources. group := &metav1.APIGroup{} gvResources := map[schema.GroupVersion]*metav1.APIResourceList{} + failedGVs := map[schema.GroupVersion]error{} group.Name = g.ObjectMeta.Name - for i, v := range g.Versions { - version := metav1.GroupVersionForDiscovery{} + for _, v := range g.Versions { gv := schema.GroupVersion{Group: g.Name, Version: v.Version} + if v.Freshness == apidiscovery.DiscoveryFreshnessStale { + failedGVs[gv] = StaleGroupVersionError{gv: gv} + continue + } + version := metav1.GroupVersionForDiscovery{} version.GroupVersion = gv.String() version.Version = v.Version group.Versions = append(group.Versions, version) - if i == 0 { + // PreferredVersion is first non-stale Version + if group.PreferredVersion == (metav1.GroupVersionForDiscovery{}) { group.PreferredVersion = version } resourceList := &metav1.APIResourceList{} resourceList.GroupVersion = gv.String() for _, r := range v.Resources { - resource := convertAPIResource(r) - resourceList.APIResources = append(resourceList.APIResources, resource) + resource, err := convertAPIResource(r) + if err == nil { + resourceList.APIResources = append(resourceList.APIResources, resource) + } // Subresources field in new format get transformed into full APIResources. + // It is possible a partial result with an error was returned to be used + // as the parent resource for the subresource. for _, subresource := range r.Subresources { - sr := convertAPISubresource(resource, subresource) - resourceList.APIResources = append(resourceList.APIResources, sr) + sr, err := convertAPISubresource(resource, subresource) + if err == nil { + resourceList.APIResources = append(resourceList.APIResources, sr) + } } } gvResources[gv] = resourceList } - return group, gvResources + return group, gvResources, failedGVs } -// convertAPIResource tranforms a APIResourceDiscovery to an APIResource. -func convertAPIResource(in apidiscovery.APIResourceDiscovery) metav1.APIResource { - return metav1.APIResource{ +// convertAPIResource tranforms a APIResourceDiscovery to an APIResource. We are +// resilient to missing GVK, since this resource might be the parent resource +// for a subresource. If the parent is missing a GVK, it is not returned in +// discovery, and the subresource MUST have the GVK. +func convertAPIResource(in apidiscovery.APIResourceDiscovery) (metav1.APIResource, error) { + result := metav1.APIResource{ Name: in.Resource, SingularName: in.SingularResource, Namespaced: in.Scope == apidiscovery.ScopeNamespace, - Group: in.ResponseKind.Group, - Version: in.ResponseKind.Version, - Kind: in.ResponseKind.Kind, Verbs: in.Verbs, ShortNames: in.ShortNames, Categories: in.Categories, } + var err error + if in.ResponseKind != nil { + result.Group = in.ResponseKind.Group + result.Version = in.ResponseKind.Version + result.Kind = in.ResponseKind.Kind + } else { + err = fmt.Errorf("discovery resource %s missing GVK", in.Resource) + } + // Can return partial result with error, which can be the parent for a + // subresource. Do not add this result to the returned discovery resources. + return result, err } // convertAPISubresource tranforms a APISubresourceDiscovery to an APIResource. -func convertAPISubresource(parent metav1.APIResource, in apidiscovery.APISubresourceDiscovery) metav1.APIResource { - return metav1.APIResource{ - Name: fmt.Sprintf("%s/%s", parent.Name, in.Subresource), - SingularName: parent.SingularName, - Namespaced: parent.Namespaced, - Group: in.ResponseKind.Group, - Version: in.ResponseKind.Version, - Kind: in.ResponseKind.Kind, - Verbs: in.Verbs, +func convertAPISubresource(parent metav1.APIResource, in apidiscovery.APISubresourceDiscovery) (metav1.APIResource, error) { + result := metav1.APIResource{} + if in.ResponseKind == nil { + return result, fmt.Errorf("subresource %s/%s missing GVK", parent.Name, in.Subresource) } + result.Name = fmt.Sprintf("%s/%s", parent.Name, in.Subresource) + result.SingularName = parent.SingularName + result.Namespaced = parent.Namespaced + result.Group = in.ResponseKind.Group + result.Version = in.ResponseKind.Version + result.Kind = in.ResponseKind.Kind + result.Verbs = in.Verbs + return result, nil } diff --git a/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go b/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go index 0a4101847..9143ce00a 100644 --- a/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go +++ b/vendor/k8s.io/client-go/discovery/cached/memory/memcache.go @@ -33,6 +33,7 @@ import ( "k8s.io/client-go/openapi" cachedopenapi "k8s.io/client-go/openapi/cached" restclient "k8s.io/client-go/rest" + "k8s.io/klog/v2" ) type cacheEntry struct { @@ -61,6 +62,15 @@ var ( ErrCacheNotFound = errors.New("not found") ) +// Server returning empty ResourceList for Group/Version. +type emptyResponseError struct { + gv string +} + +func (e *emptyResponseError) Error() string { + return fmt.Sprintf("received empty response for: %s", e.gv) +} + var _ discovery.CachedDiscoveryInterface = &memCacheClient{} // isTransientConnectionError checks whether given error is "Connection refused" or @@ -103,7 +113,13 @@ func (d *memCacheClient) ServerResourcesForGroupVersion(groupVersion string) (*m if cachedVal.err != nil && isTransientError(cachedVal.err) { r, err := d.serverResourcesForGroupVersion(groupVersion) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", groupVersion, err)) + // Don't log "empty response" as an error; it is a common response for metrics. + if _, emptyErr := err.(*emptyResponseError); emptyErr { + // Log at same verbosity as disk cache. + klog.V(3).Infof("%v", err) + } else { + utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", groupVersion, err)) + } } cachedVal = &cacheEntry{r, err} d.groupToServerResources[groupVersion] = cachedVal @@ -120,32 +136,38 @@ func (d *memCacheClient) ServerGroupsAndResources() ([]*metav1.APIGroup, []*meta // GroupsAndMaybeResources returns the list of APIGroups, and possibly the map of group/version // to resources. The returned groups will never be nil, but the resources map can be nil // if there are no cached resources. -func (d *memCacheClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { +func (d *memCacheClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, map[schema.GroupVersion]error, error) { d.lock.Lock() defer d.lock.Unlock() if !d.cacheValid { if err := d.refreshLocked(); err != nil { - return nil, nil, err + return nil, nil, nil, err } } // Build the resourceList from the cache? var resourcesMap map[schema.GroupVersion]*metav1.APIResourceList + var failedGVs map[schema.GroupVersion]error if d.receivedAggregatedDiscovery && len(d.groupToServerResources) > 0 { resourcesMap = map[schema.GroupVersion]*metav1.APIResourceList{} + failedGVs = map[schema.GroupVersion]error{} for gv, cacheEntry := range d.groupToServerResources { groupVersion, err := schema.ParseGroupVersion(gv) if err != nil { - return nil, nil, fmt.Errorf("failed to parse group version (%v): %v", gv, err) + return nil, nil, nil, fmt.Errorf("failed to parse group version (%v): %v", gv, err) + } + if cacheEntry.err != nil { + failedGVs[groupVersion] = cacheEntry.err + } else { + resourcesMap[groupVersion] = cacheEntry.resourceList } - resourcesMap[groupVersion] = cacheEntry.resourceList } } - return d.groupList, resourcesMap, nil + return d.groupList, resourcesMap, failedGVs, nil } func (d *memCacheClient) ServerGroups() (*metav1.APIGroupList, error) { - groups, _, err := d.GroupsAndMaybeResources() + groups, _, _, err := d.GroupsAndMaybeResources() if err != nil { return nil, err } @@ -219,7 +241,8 @@ func (d *memCacheClient) refreshLocked() error { if ad, ok := d.delegate.(discovery.AggregatedDiscoveryInterface); ok { var resources map[schema.GroupVersion]*metav1.APIResourceList - gl, resources, err = ad.GroupsAndMaybeResources() + var failedGVs map[schema.GroupVersion]error + gl, resources, failedGVs, err = ad.GroupsAndMaybeResources() if resources != nil && err == nil { // Cache the resources. d.groupToServerResources = map[string]*cacheEntry{} @@ -227,6 +250,10 @@ func (d *memCacheClient) refreshLocked() error { for gv, resources := range resources { d.groupToServerResources[gv.String()] = &cacheEntry{resources, nil} } + // Cache GroupVersion discovery errors + for gv, err := range failedGVs { + d.groupToServerResources[gv.String()] = &cacheEntry{nil, err} + } d.receivedAggregatedDiscovery = true d.cacheValid = true return nil @@ -252,7 +279,13 @@ func (d *memCacheClient) refreshLocked() error { r, err := d.serverResourcesForGroupVersion(gv) if err != nil { - utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", gv, err)) + // Don't log "empty response" as an error; it is a common response for metrics. + if _, emptyErr := err.(*emptyResponseError); emptyErr { + // Log at same verbosity as disk cache. + klog.V(3).Infof("%v", err) + } else { + utilruntime.HandleError(fmt.Errorf("couldn't get resource list for %v: %v", gv, err)) + } } resultLock.Lock() @@ -274,7 +307,7 @@ func (d *memCacheClient) serverResourcesForGroupVersion(groupVersion string) (*m return r, err } if len(r.APIResources) == 0 { - return r, fmt.Errorf("Got empty response for: %v", groupVersion) + return r, &emptyResponseError{gv: groupVersion} } return r, nil } diff --git a/vendor/k8s.io/client-go/discovery/discovery_client.go b/vendor/k8s.io/client-go/discovery/discovery_client.go index 43906190f..1253fa1f4 100644 --- a/vendor/k8s.io/client-go/discovery/discovery_client.go +++ b/vendor/k8s.io/client-go/discovery/discovery_client.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "mime" "net/http" "net/url" "sort" @@ -58,8 +59,9 @@ const ( defaultBurst = 300 AcceptV1 = runtime.ContentTypeJSON - // Aggregated discovery content-type (currently v2beta1). NOTE: Currently, we are assuming the order - // for "g", "v", and "as" from the server. We can only compare this string if we can make that assumption. + // Aggregated discovery content-type (v2beta1). NOTE: content-type parameters + // MUST be ordered (g, v, as) for server in "Accept" header (BUT we are resilient + // to ordering when comparing returned values in "Content-Type" header). AcceptV2Beta1 = runtime.ContentTypeJSON + ";" + "g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList" // Prioritize aggregated discovery by placing first in the order of discovery accept types. acceptDiscoveryFormats = AcceptV2Beta1 + "," + AcceptV1 @@ -86,7 +88,7 @@ type DiscoveryInterface interface { type AggregatedDiscoveryInterface interface { DiscoveryInterface - GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) + GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, map[schema.GroupVersion]error, error) } // CachedDiscoveryInterface is a DiscoveryInterface with cache invalidation and freshness. @@ -186,18 +188,23 @@ func apiVersionsToAPIGroup(apiVersions *metav1.APIVersions) (apiGroup metav1.API // and resources from /api and /apis (either aggregated or not). Legacy groups // must be ordered first. The server will either return both endpoints (/api, /apis) // as aggregated discovery format or legacy format. For safety, resources will only -// be returned if both endpoints returned resources. -func (d *DiscoveryClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { +// be returned if both endpoints returned resources. Returned "failedGVs" can be +// empty, but will only be nil in the case an error is returned. +func (d *DiscoveryClient) GroupsAndMaybeResources() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { // Legacy group ordered first (there is only one -- core/v1 group). Returned groups must // be non-nil, but it could be empty. Returned resources, apiResources map could be nil. - groups, resources, err := d.downloadLegacy() + groups, resources, failedGVs, err := d.downloadLegacy() if err != nil { - return nil, nil, err + return nil, nil, nil, err } // Discovery groups and (possibly) resources downloaded from /apis. - apiGroups, apiResources, aerr := d.downloadAPIs() + apiGroups, apiResources, failedApisGVs, aerr := d.downloadAPIs() if aerr != nil { - return nil, nil, aerr + return nil, nil, nil, aerr } // Merge apis groups into the legacy groups. for _, group := range apiGroups.Groups { @@ -211,14 +218,23 @@ func (d *DiscoveryClient) GroupsAndMaybeResources() (*metav1.APIGroupList, map[s } else if resources != nil { resources = nil } - return groups, resources, err + // Merge failed GroupVersions from /api and /apis + for gv, err := range failedApisGVs { + failedGVs[gv] = err + } + return groups, resources, failedGVs, err } // downloadLegacy returns the discovery groups and possibly resources // for the legacy v1 GVR at /api, or an error if one occurred. It is // possible for the resource map to be nil if the server returned -// the unaggregated discovery. -func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { +// the unaggregated discovery. Returned "failedGVs" can be empty, but +// will only be nil in the case of a returned error. +func (d *DiscoveryClient) downloadLegacy() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { accept := acceptDiscoveryFormats if d.UseLegacyDiscovery { accept = AcceptV1 @@ -230,48 +246,55 @@ func (d *DiscoveryClient) downloadLegacy() (*metav1.APIGroupList, map[schema.Gro Do(context.TODO()). ContentType(&responseContentType). Raw() - // Special error handling for 403 or 404 to be compatible with older v1.0 servers. - // Return empty group list to be merged with /apis. - if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) { - return nil, nil, err - } - if err != nil && (errors.IsNotFound(err) || errors.IsForbidden(err)) { - return &metav1.APIGroupList{}, nil, nil + apiGroupList := &metav1.APIGroupList{} + failedGVs := map[schema.GroupVersion]error{} + if err != nil { + // Tolerate 404, since aggregated api servers can return it. + if errors.IsNotFound(err) { + // Return empty structures and no error. + emptyGVMap := map[schema.GroupVersion]*metav1.APIResourceList{} + return apiGroupList, emptyGVMap, failedGVs, nil + } else { + return nil, nil, nil, err + } } - apiGroupList := &metav1.APIGroupList{} var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList // Switch on content-type server responded with: aggregated or unaggregated. - switch responseContentType { - case AcceptV1: + switch { + case isV2Beta1ContentType(responseContentType): + var aggregatedDiscovery apidiscovery.APIGroupDiscoveryList + err = json.Unmarshal(body, &aggregatedDiscovery) + if err != nil { + return nil, nil, nil, err + } + apiGroupList, resourcesByGV, failedGVs = SplitGroupsAndResources(aggregatedDiscovery) + default: + // Default is unaggregated discovery v1. var v metav1.APIVersions err = json.Unmarshal(body, &v) if err != nil { - return nil, nil, err + return nil, nil, nil, err } apiGroup := metav1.APIGroup{} if len(v.Versions) != 0 { apiGroup = apiVersionsToAPIGroup(&v) } apiGroupList.Groups = []metav1.APIGroup{apiGroup} - case AcceptV2Beta1: - var aggregatedDiscovery apidiscovery.APIGroupDiscoveryList - err = json.Unmarshal(body, &aggregatedDiscovery) - if err != nil { - return nil, nil, err - } - apiGroupList, resourcesByGV = SplitGroupsAndResources(aggregatedDiscovery) - default: - return nil, nil, fmt.Errorf("Unknown discovery response content-type: %s", responseContentType) } - return apiGroupList, resourcesByGV, nil + return apiGroupList, resourcesByGV, failedGVs, nil } // downloadAPIs returns the discovery groups and (if aggregated format) the // discovery resources. The returned groups will always exist, but the -// resources map may be nil. -func (d *DiscoveryClient) downloadAPIs() (*metav1.APIGroupList, map[schema.GroupVersion]*metav1.APIResourceList, error) { +// resources map may be nil. Returned "failedGVs" can be empty, but will +// only be nil in the case of a returned error. +func (d *DiscoveryClient) downloadAPIs() ( + *metav1.APIGroupList, + map[schema.GroupVersion]*metav1.APIResourceList, + map[schema.GroupVersion]error, + error) { accept := acceptDiscoveryFormats if d.UseLegacyDiscovery { accept = AcceptV1 @@ -283,42 +306,59 @@ func (d *DiscoveryClient) downloadAPIs() (*metav1.APIGroupList, map[schema.Group Do(context.TODO()). ContentType(&responseContentType). Raw() - // Special error handling for 403 or 404 to be compatible with older v1.0 servers. - // Return empty group list to be merged with /api. - if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) { - return nil, nil, err - } - if err != nil && (errors.IsNotFound(err) || errors.IsForbidden(err)) { - return &metav1.APIGroupList{}, nil, nil + if err != nil { + return nil, nil, nil, err } apiGroupList := &metav1.APIGroupList{} + failedGVs := map[schema.GroupVersion]error{} var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList // Switch on content-type server responded with: aggregated or unaggregated. - switch responseContentType { - case AcceptV1: - err = json.Unmarshal(body, apiGroupList) - if err != nil { - return nil, nil, err - } - case AcceptV2Beta1: + switch { + case isV2Beta1ContentType(responseContentType): var aggregatedDiscovery apidiscovery.APIGroupDiscoveryList err = json.Unmarshal(body, &aggregatedDiscovery) if err != nil { - return nil, nil, err + return nil, nil, nil, err } - apiGroupList, resourcesByGV = SplitGroupsAndResources(aggregatedDiscovery) + apiGroupList, resourcesByGV, failedGVs = SplitGroupsAndResources(aggregatedDiscovery) default: - return nil, nil, fmt.Errorf("Unknown discovery response content-type: %s", responseContentType) + // Default is unaggregated discovery v1. + err = json.Unmarshal(body, apiGroupList) + if err != nil { + return nil, nil, nil, err + } } - return apiGroupList, resourcesByGV, nil + return apiGroupList, resourcesByGV, failedGVs, nil +} + +// isV2Beta1ContentType checks of the content-type string is both +// "application/json" and contains the v2beta1 content-type params. +// NOTE: This function is resilient to the ordering of the +// content-type parameters, as well as parameters added by +// intermediaries such as proxies or gateways. Examples: +// +// "application/json; g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList" = true +// "application/json; as=APIGroupDiscoveryList;v=v2beta1;g=apidiscovery.k8s.io" = true +// "application/json; as=APIGroupDiscoveryList;v=v2beta1;g=apidiscovery.k8s.io;charset=utf-8" = true +// "application/json" = false +// "application/json; charset=UTF-8" = false +func isV2Beta1ContentType(contentType string) bool { + base, params, err := mime.ParseMediaType(contentType) + if err != nil { + return false + } + return runtime.ContentTypeJSON == base && + params["g"] == "apidiscovery.k8s.io" && + params["v"] == "v2beta1" && + params["as"] == "APIGroupDiscoveryList" } // ServerGroups returns the supported groups, with information like supported versions and the // preferred version. func (d *DiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) { - groups, _, err := d.GroupsAndMaybeResources() + groups, _, _, err := d.GroupsAndMaybeResources() if err != nil { return nil, err } @@ -341,8 +381,10 @@ func (d *DiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (r } err = d.restClient.Get().AbsPath(url.String()).Do(context.TODO()).Into(resources) if err != nil { - // ignore 403 or 404 error to be compatible with an v1.0 server. - if groupVersion == "v1" && (errors.IsNotFound(err) || errors.IsForbidden(err)) { + // Tolerate core/v1 not found response by returning empty resource list; + // this probably should not happen. But we should verify all callers are + // not depending on this toleration before removal. + if groupVersion == "v1" && errors.IsNotFound(err) { return resources, nil } return nil, err @@ -383,13 +425,14 @@ func IsGroupDiscoveryFailedError(err error) bool { func ServerGroupsAndResources(d DiscoveryInterface) ([]*metav1.APIGroup, []*metav1.APIResourceList, error) { var sgs *metav1.APIGroupList var resources []*metav1.APIResourceList + var failedGVs map[schema.GroupVersion]error var err error // If the passed discovery object implements the wider AggregatedDiscoveryInterface, // then attempt to retrieve aggregated discovery with both groups and the resources. if ad, ok := d.(AggregatedDiscoveryInterface); ok { var resourcesByGV map[schema.GroupVersion]*metav1.APIResourceList - sgs, resourcesByGV, err = ad.GroupsAndMaybeResources() + sgs, resourcesByGV, failedGVs, err = ad.GroupsAndMaybeResources() for _, resourceList := range resourcesByGV { resources = append(resources, resourceList) } @@ -404,8 +447,15 @@ func ServerGroupsAndResources(d DiscoveryInterface) ([]*metav1.APIGroup, []*meta for i := range sgs.Groups { resultGroups = append(resultGroups, &sgs.Groups[i]) } + // resources is non-nil if aggregated discovery succeeded. if resources != nil { - return resultGroups, resources, nil + // Any stale Group/Versions returned by aggregated discovery + // must be surfaced to the caller as failed Group/Versions. + var ferr error + if len(failedGVs) > 0 { + ferr = &ErrGroupDiscoveryFailed{Groups: failedGVs} + } + return resultGroups, resources, ferr } groupVersionResources, failedGroups := fetchGroupVersionResources(d, sgs) @@ -436,16 +486,18 @@ func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList, var err error // If the passed discovery object implements the wider AggregatedDiscoveryInterface, - // then it is attempt to retrieve both the groups and the resources. + // then it is attempt to retrieve both the groups and the resources. "failedGroups" + // are Group/Versions returned as stale in AggregatedDiscovery format. ad, ok := d.(AggregatedDiscoveryInterface) if ok { - serverGroupList, groupVersionResources, err = ad.GroupsAndMaybeResources() + serverGroupList, groupVersionResources, failedGroups, err = ad.GroupsAndMaybeResources() } else { serverGroupList, err = d.ServerGroups() } if err != nil { return nil, err } + // Non-aggregated discovery must fetch resources from Groups. if groupVersionResources == nil { groupVersionResources, failedGroups = fetchGroupVersionResources(d, serverGroupList) } diff --git a/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go b/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go index 40878b400..62d01339d 100644 --- a/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go +++ b/vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go @@ -61,6 +61,12 @@ type dynamicSharedInformerFactory struct { // This allows Start() to be called multiple times safely. startedInformers map[schema.GroupVersionResource]bool tweakListOptions TweakListOptionsFunc + + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool } var _ DynamicSharedInformerFactory = &dynamicSharedInformerFactory{} @@ -86,9 +92,21 @@ func (f *dynamicSharedInformerFactory) Start(stopCh <-chan struct{}) { f.lock.Lock() defer f.lock.Unlock() + if f.shuttingDown { + return + } + for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - go informer.Informer().Run(stopCh) + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer.Informer() + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() f.startedInformers[informerType] = true } } @@ -116,11 +134,20 @@ func (f *dynamicSharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) return res } +func (f *dynamicSharedInformerFactory) Shutdown() { + // Will return immediately if there is nothing to wait for. + defer f.wg.Wait() + + f.lock.Lock() + defer f.lock.Unlock() + f.shuttingDown = true +} + // NewFilteredDynamicInformer constructs a new informer for a dynamic type. func NewFilteredDynamicInformer(client dynamic.Interface, gvr schema.GroupVersionResource, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions TweakListOptionsFunc) informers.GenericInformer { return &dynamicInformer{ gvr: gvr, - informer: cache.NewSharedIndexInformer( + informer: cache.NewSharedIndexInformerWithOptions( &cache.ListWatch{ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { @@ -136,8 +163,11 @@ func NewFilteredDynamicInformer(client dynamic.Interface, gvr schema.GroupVersio }, }, &unstructured.Unstructured{}, - resyncPeriod, - indexers, + cache.SharedIndexInformerOptions{ + ResyncPeriod: resyncPeriod, + Indexers: indexers, + ObjectDescription: gvr.String(), + }, ), } } diff --git a/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go b/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go index 083977c30..0419ef4f8 100644 --- a/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go +++ b/vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go @@ -24,9 +24,28 @@ import ( // DynamicSharedInformerFactory provides access to a shared informer and lister for dynamic client type DynamicSharedInformerFactory interface { + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. Start(stopCh <-chan struct{}) + + // ForResource gives generic access to a shared informer of the matching type. ForResource(gvr schema.GroupVersionResource) informers.GenericInformer + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. WaitForCacheSync(stopCh <-chan struct{}) map[schema.GroupVersionResource]bool + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() } // TweakListOptionsFunc defines the signature of a helper function diff --git a/vendor/k8s.io/client-go/informers/certificates/interface.go b/vendor/k8s.io/client-go/informers/certificates/interface.go index e38d01177..39a4e2911 100644 --- a/vendor/k8s.io/client-go/informers/certificates/interface.go +++ b/vendor/k8s.io/client-go/informers/certificates/interface.go @@ -20,6 +20,7 @@ package certificates import ( v1 "k8s.io/client-go/informers/certificates/v1" + v1alpha1 "k8s.io/client-go/informers/certificates/v1alpha1" v1beta1 "k8s.io/client-go/informers/certificates/v1beta1" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" ) @@ -28,6 +29,8 @@ import ( type Interface interface { // V1 provides access to shared informers for resources in V1. V1() v1.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface // V1beta1 provides access to shared informers for resources in V1beta1. V1beta1() v1beta1.Interface } @@ -48,6 +51,11 @@ func (g *group) V1() v1.Interface { return v1.New(g.factory, g.namespace, g.tweakListOptions) } +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} + // V1beta1 returns a new v1beta1.Interface. func (g *group) V1beta1() v1beta1.Interface { return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/podscheduling.go b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go similarity index 52% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/podscheduling.go rename to vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go index 87b4c34e1..e8b341587 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/podscheduling.go +++ b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/clustertrustbundle.go @@ -22,69 +22,68 @@ import ( "context" time "time" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1alpha1 "k8s.io/client-go/listers/resource/v1alpha1" + v1alpha1 "k8s.io/client-go/listers/certificates/v1alpha1" cache "k8s.io/client-go/tools/cache" ) -// PodSchedulingInformer provides access to a shared informer and lister for -// PodSchedulings. -type PodSchedulingInformer interface { +// ClusterTrustBundleInformer provides access to a shared informer and lister for +// ClusterTrustBundles. +type ClusterTrustBundleInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.PodSchedulingLister + Lister() v1alpha1.ClusterTrustBundleLister } -type podSchedulingInformer struct { +type clusterTrustBundleInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string } -// NewPodSchedulingInformer constructs a new informer for PodScheduling type. +// NewClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewPodSchedulingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodSchedulingInformer(client, namespace, resyncPeriod, indexers, nil) +func NewClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, indexers, nil) } -// NewFilteredPodSchedulingInformer constructs a new informer for PodScheduling type. +// NewFilteredClusterTrustBundleInformer constructs a new informer for ClusterTrustBundle type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewFilteredPodSchedulingInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredClusterTrustBundleInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { return cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().PodSchedulings(namespace).List(context.TODO(), options) + return client.CertificatesV1alpha1().ClusterTrustBundles().List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().PodSchedulings(namespace).Watch(context.TODO(), options) + return client.CertificatesV1alpha1().ClusterTrustBundles().Watch(context.TODO(), options) }, }, - &resourcev1alpha1.PodScheduling{}, + &certificatesv1alpha1.ClusterTrustBundle{}, resyncPeriod, indexers, ) } -func (f *podSchedulingInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodSchedulingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +func (f *clusterTrustBundleInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterTrustBundleInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } -func (f *podSchedulingInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha1.PodScheduling{}, f.defaultInformer) +func (f *clusterTrustBundleInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&certificatesv1alpha1.ClusterTrustBundle{}, f.defaultInformer) } -func (f *podSchedulingInformer) Lister() v1alpha1.PodSchedulingLister { - return v1alpha1.NewPodSchedulingLister(f.Informer().GetIndexer()) +func (f *clusterTrustBundleInformer) Lister() v1alpha1.ClusterTrustBundleLister { + return v1alpha1.NewClusterTrustBundleLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go new file mode 100644 index 000000000..40ce8f42d --- /dev/null +++ b/vendor/k8s.io/client-go/informers/certificates/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterTrustBundles returns a ClusterTrustBundleInformer. + ClusterTrustBundles() ClusterTrustBundleInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterTrustBundles returns a ClusterTrustBundleInformer. +func (v *version) ClusterTrustBundles() ClusterTrustBundleInformer { + return &clusterTrustBundleInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/doc.go b/vendor/k8s.io/client-go/informers/doc.go new file mode 100644 index 000000000..231bffb69 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/doc.go @@ -0,0 +1,18 @@ +/* +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 informers provides generated informers for Kubernetes APIs. +package informers diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go b/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go index 6f0bea7e8..600741e3a 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go +++ b/vendor/k8s.io/client-go/informers/extensions/v1beta1/interface.go @@ -32,8 +32,6 @@ type Interface interface { Ingresses() IngressInformer // NetworkPolicies returns a NetworkPolicyInformer. NetworkPolicies() NetworkPolicyInformer - // PodSecurityPolicies returns a PodSecurityPolicyInformer. - PodSecurityPolicies() PodSecurityPolicyInformer // ReplicaSets returns a ReplicaSetInformer. ReplicaSets() ReplicaSetInformer } @@ -69,11 +67,6 @@ func (v *version) NetworkPolicies() NetworkPolicyInformer { return &networkPolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } -// PodSecurityPolicies returns a PodSecurityPolicyInformer. -func (v *version) PodSecurityPolicies() PodSecurityPolicyInformer { - return &podSecurityPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - // ReplicaSets returns a ReplicaSetInformer. func (v *version) ReplicaSets() ReplicaSetInformer { return &replicaSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/vendor/k8s.io/client-go/informers/generic.go b/vendor/k8s.io/client-go/informers/generic.go index 59505bdda..2b63a8028 100644 --- a/vendor/k8s.io/client-go/informers/generic.go +++ b/vendor/k8s.io/client-go/informers/generic.go @@ -35,6 +35,7 @@ import ( batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" certificatesv1beta1 "k8s.io/api/certificates/v1beta1" coordinationv1 "k8s.io/api/coordination/v1" coordinationv1beta1 "k8s.io/api/coordination/v1beta1" @@ -59,7 +60,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" schedulingv1 "k8s.io/api/scheduling/v1" schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" @@ -176,6 +177,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case certificatesv1.SchemeGroupVersion.WithResource("certificatesigningrequests"): return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1().CertificateSigningRequests().Informer()}, nil + // Group=certificates.k8s.io, Version=v1alpha1 + case certificatesv1alpha1.SchemeGroupVersion.WithResource("clustertrustbundles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1alpha1().ClusterTrustBundles().Informer()}, nil + // Group=certificates.k8s.io, Version=v1beta1 case certificatesv1beta1.SchemeGroupVersion.WithResource("certificatesigningrequests"): return &genericInformer{resource: resource.GroupResource(), informer: f.Certificates().V1beta1().CertificateSigningRequests().Informer()}, nil @@ -247,8 +252,6 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().Ingresses().Informer()}, nil case extensionsv1beta1.SchemeGroupVersion.WithResource("networkpolicies"): return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().NetworkPolicies().Informer()}, nil - case extensionsv1beta1.SchemeGroupVersion.WithResource("podsecuritypolicies"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().PodSecurityPolicies().Informer()}, nil case extensionsv1beta1.SchemeGroupVersion.WithResource("replicasets"): return &genericInformer{resource: resource.GroupResource(), informer: f.Extensions().V1beta1().ReplicaSets().Informer()}, nil @@ -291,6 +294,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=networking.k8s.io, Version=v1alpha1 case networkingv1alpha1.SchemeGroupVersion.WithResource("clustercidrs"): return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha1().ClusterCIDRs().Informer()}, nil + case networkingv1alpha1.SchemeGroupVersion.WithResource("ipaddresses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha1().IPAddresses().Informer()}, nil // Group=networking.k8s.io, Version=v1beta1 case networkingv1beta1.SchemeGroupVersion.WithResource("ingresses"): @@ -350,15 +355,15 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case rbacv1beta1.SchemeGroupVersion.WithResource("rolebindings"): return &genericInformer{resource: resource.GroupResource(), informer: f.Rbac().V1beta1().RoleBindings().Informer()}, nil - // Group=resource.k8s.io, Version=v1alpha1 - case resourcev1alpha1.SchemeGroupVersion.WithResource("podschedulings"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha1().PodSchedulings().Informer()}, nil - case resourcev1alpha1.SchemeGroupVersion.WithResource("resourceclaims"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha1().ResourceClaims().Informer()}, nil - case resourcev1alpha1.SchemeGroupVersion.WithResource("resourceclaimtemplates"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha1().ResourceClaimTemplates().Informer()}, nil - case resourcev1alpha1.SchemeGroupVersion.WithResource("resourceclasses"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha1().ResourceClasses().Informer()}, nil + // Group=resource.k8s.io, Version=v1alpha2 + case v1alpha2.SchemeGroupVersion.WithResource("podschedulingcontexts"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().PodSchedulingContexts().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclaims"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaims().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclaimtemplates"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClaimTemplates().Informer()}, nil + case v1alpha2.SchemeGroupVersion.WithResource("resourceclasses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Resource().V1alpha2().ResourceClasses().Informer()}, nil // Group=scheduling.k8s.io, Version=v1 case schedulingv1.SchemeGroupVersion.WithResource("priorityclasses"): diff --git a/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go index c51b74880..07e7d208c 100644 --- a/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go +++ b/vendor/k8s.io/client-go/informers/networking/v1alpha1/interface.go @@ -26,6 +26,8 @@ import ( type Interface interface { // ClusterCIDRs returns a ClusterCIDRInformer. ClusterCIDRs() ClusterCIDRInformer + // IPAddresses returns a IPAddressInformer. + IPAddresses() IPAddressInformer } type version struct { @@ -43,3 +45,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (v *version) ClusterCIDRs() ClusterCIDRInformer { return &clusterCIDRInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } + +// IPAddresses returns a IPAddressInformer. +func (v *version) IPAddresses() IPAddressInformer { + return &iPAddressInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/vendor/k8s.io/client-go/informers/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go similarity index 50% rename from vendor/k8s.io/client-go/informers/extensions/v1beta1/podsecuritypolicy.go rename to vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go index 11be2751c..a1083dbf0 100644 --- a/vendor/k8s.io/client-go/informers/extensions/v1beta1/podsecuritypolicy.go +++ b/vendor/k8s.io/client-go/informers/networking/v1alpha1/ipaddress.go @@ -16,74 +16,74 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1beta1 +package v1alpha1 import ( "context" time "time" - extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + networkingv1alpha1 "k8s.io/api/networking/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1beta1 "k8s.io/client-go/listers/extensions/v1beta1" + v1alpha1 "k8s.io/client-go/listers/networking/v1alpha1" cache "k8s.io/client-go/tools/cache" ) -// PodSecurityPolicyInformer provides access to a shared informer and lister for -// PodSecurityPolicies. -type PodSecurityPolicyInformer interface { +// IPAddressInformer provides access to a shared informer and lister for +// IPAddresses. +type IPAddressInformer interface { Informer() cache.SharedIndexInformer - Lister() v1beta1.PodSecurityPolicyLister + Lister() v1alpha1.IPAddressLister } -type podSecurityPolicyInformer struct { +type iPAddressInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc } -// NewPodSecurityPolicyInformer constructs a new informer for PodSecurityPolicy type. +// NewIPAddressInformer constructs a new informer for IPAddress type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewPodSecurityPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredPodSecurityPolicyInformer(client, resyncPeriod, indexers, nil) +func NewIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIPAddressInformer(client, resyncPeriod, indexers, nil) } -// NewFilteredPodSecurityPolicyInformer constructs a new informer for PodSecurityPolicy type. +// NewFilteredIPAddressInformer constructs a new informer for IPAddress type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewFilteredPodSecurityPolicyInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredIPAddressInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { return cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ExtensionsV1beta1().PodSecurityPolicies().List(context.TODO(), options) + return client.NetworkingV1alpha1().IPAddresses().List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ExtensionsV1beta1().PodSecurityPolicies().Watch(context.TODO(), options) + return client.NetworkingV1alpha1().IPAddresses().Watch(context.TODO(), options) }, }, - &extensionsv1beta1.PodSecurityPolicy{}, + &networkingv1alpha1.IPAddress{}, resyncPeriod, indexers, ) } -func (f *podSecurityPolicyInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredPodSecurityPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +func (f *iPAddressInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIPAddressInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } -func (f *podSecurityPolicyInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&extensionsv1beta1.PodSecurityPolicy{}, f.defaultInformer) +func (f *iPAddressInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&networkingv1alpha1.IPAddress{}, f.defaultInformer) } -func (f *podSecurityPolicyInformer) Lister() v1beta1.PodSecurityPolicyLister { - return v1beta1.NewPodSecurityPolicyLister(f.Informer().GetIndexer()) +func (f *iPAddressInformer) Lister() v1alpha1.IPAddressLister { + return v1alpha1.NewIPAddressLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/informers/resource/interface.go b/vendor/k8s.io/client-go/informers/resource/interface.go index 6cf95b0d4..3fcce8ae9 100644 --- a/vendor/k8s.io/client-go/informers/resource/interface.go +++ b/vendor/k8s.io/client-go/informers/resource/interface.go @@ -20,13 +20,13 @@ package resource import ( internalinterfaces "k8s.io/client-go/informers/internalinterfaces" - v1alpha1 "k8s.io/client-go/informers/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/informers/resource/v1alpha2" ) // Interface provides access to each of this group's versions. type Interface interface { - // V1alpha1 provides access to shared informers for resources in V1alpha1. - V1alpha1() v1alpha1.Interface + // V1alpha2 provides access to shared informers for resources in V1alpha2. + V1alpha2() v1alpha2.Interface } type group struct { @@ -40,7 +40,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// V1alpha1 returns a new v1alpha1.Interface. -func (g *group) V1alpha1() v1alpha1.Interface { - return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +// V1alpha2 returns a new v1alpha2.Interface. +func (g *group) V1alpha2() v1alpha2.Interface { + return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions) } diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/interface.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go similarity index 84% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/interface.go rename to vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go index 4449dfa65..23f817c62 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/interface.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/interface.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( internalinterfaces "k8s.io/client-go/informers/internalinterfaces" @@ -24,8 +24,8 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { - // PodSchedulings returns a PodSchedulingInformer. - PodSchedulings() PodSchedulingInformer + // PodSchedulingContexts returns a PodSchedulingContextInformer. + PodSchedulingContexts() PodSchedulingContextInformer // ResourceClaims returns a ResourceClaimInformer. ResourceClaims() ResourceClaimInformer // ResourceClaimTemplates returns a ResourceClaimTemplateInformer. @@ -45,9 +45,9 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// PodSchedulings returns a PodSchedulingInformer. -func (v *version) PodSchedulings() PodSchedulingInformer { - return &podSchedulingInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +// PodSchedulingContexts returns a PodSchedulingContextInformer. +func (v *version) PodSchedulingContexts() PodSchedulingContextInformer { + return &podSchedulingContextInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } // ResourceClaims returns a ResourceClaimInformer. diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 000000000..b4aabb376 --- /dev/null +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,90 @@ +/* +Copyright 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + time "time" + + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + internalinterfaces "k8s.io/client-go/informers/internalinterfaces" + kubernetes "k8s.io/client-go/kubernetes" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" + cache "k8s.io/client-go/tools/cache" +) + +// PodSchedulingContextInformer provides access to a shared informer and lister for +// PodSchedulingContexts. +type PodSchedulingContextInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha2.PodSchedulingContextLister +} + +type podSchedulingContextInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPodSchedulingContextInformer constructs a new informer for PodSchedulingContext type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPodSchedulingContextInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPodSchedulingContextInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPodSchedulingContextInformer constructs a new informer for PodSchedulingContext type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPodSchedulingContextInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().PodSchedulingContexts(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ResourceV1alpha2().PodSchedulingContexts(namespace).Watch(context.TODO(), options) + }, + }, + &resourcev1alpha2.PodSchedulingContext{}, + resyncPeriod, + indexers, + ) +} + +func (f *podSchedulingContextInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPodSchedulingContextInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *podSchedulingContextInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&resourcev1alpha2.PodSchedulingContext{}, f.defaultInformer) +} + +func (f *podSchedulingContextInformer) Lister() v1alpha2.PodSchedulingContextLister { + return v1alpha2.NewPodSchedulingContextLister(f.Informer().GetIndexer()) +} diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaim.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go similarity index 85% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaim.go rename to vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go index 10150c020..3af936891 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaim.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaim.go @@ -16,19 +16,19 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" time "time" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1alpha1 "k8s.io/client-go/listers/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" cache "k8s.io/client-go/tools/cache" ) @@ -36,7 +36,7 @@ import ( // ResourceClaims. type ResourceClaimInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.ResourceClaimLister + Lister() v1alpha2.ResourceClaimLister } type resourceClaimInformer struct { @@ -62,16 +62,16 @@ func NewFilteredResourceClaimInformer(client kubernetes.Interface, namespace str if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClaims(namespace).List(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClaims(namespace).List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClaims(namespace).Watch(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClaims(namespace).Watch(context.TODO(), options) }, }, - &resourcev1alpha1.ResourceClaim{}, + &resourcev1alpha2.ResourceClaim{}, resyncPeriod, indexers, ) @@ -82,9 +82,9 @@ func (f *resourceClaimInformer) defaultInformer(client kubernetes.Interface, res } func (f *resourceClaimInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha1.ResourceClaim{}, f.defaultInformer) + return f.factory.InformerFor(&resourcev1alpha2.ResourceClaim{}, f.defaultInformer) } -func (f *resourceClaimInformer) Lister() v1alpha1.ResourceClaimLister { - return v1alpha1.NewResourceClaimLister(f.Informer().GetIndexer()) +func (f *resourceClaimInformer) Lister() v1alpha2.ResourceClaimLister { + return v1alpha2.NewResourceClaimLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go similarity index 86% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaimtemplate.go rename to vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go index cdffa49db..13f4ad835 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclaimtemplate.go @@ -16,19 +16,19 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" time "time" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1alpha1 "k8s.io/client-go/listers/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" cache "k8s.io/client-go/tools/cache" ) @@ -36,7 +36,7 @@ import ( // ResourceClaimTemplates. type ResourceClaimTemplateInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.ResourceClaimTemplateLister + Lister() v1alpha2.ResourceClaimTemplateLister } type resourceClaimTemplateInformer struct { @@ -62,16 +62,16 @@ func NewFilteredResourceClaimTemplateInformer(client kubernetes.Interface, names if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClaimTemplates(namespace).List(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClaimTemplates(namespace).List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClaimTemplates(namespace).Watch(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClaimTemplates(namespace).Watch(context.TODO(), options) }, }, - &resourcev1alpha1.ResourceClaimTemplate{}, + &resourcev1alpha2.ResourceClaimTemplate{}, resyncPeriod, indexers, ) @@ -82,9 +82,9 @@ func (f *resourceClaimTemplateInformer) defaultInformer(client kubernetes.Interf } func (f *resourceClaimTemplateInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha1.ResourceClaimTemplate{}, f.defaultInformer) + return f.factory.InformerFor(&resourcev1alpha2.ResourceClaimTemplate{}, f.defaultInformer) } -func (f *resourceClaimTemplateInformer) Lister() v1alpha1.ResourceClaimTemplateLister { - return v1alpha1.NewResourceClaimTemplateLister(f.Informer().GetIndexer()) +func (f *resourceClaimTemplateInformer) Lister() v1alpha2.ResourceClaimTemplateLister { + return v1alpha2.NewResourceClaimTemplateLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclass.go b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go similarity index 85% rename from vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclass.go rename to vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go index e6faa5d02..cb76d78fe 100644 --- a/vendor/k8s.io/client-go/informers/resource/v1alpha1/resourceclass.go +++ b/vendor/k8s.io/client-go/informers/resource/v1alpha2/resourceclass.go @@ -16,19 +16,19 @@ limitations under the License. // Code generated by informer-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" time "time" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" internalinterfaces "k8s.io/client-go/informers/internalinterfaces" kubernetes "k8s.io/client-go/kubernetes" - v1alpha1 "k8s.io/client-go/listers/resource/v1alpha1" + v1alpha2 "k8s.io/client-go/listers/resource/v1alpha2" cache "k8s.io/client-go/tools/cache" ) @@ -36,7 +36,7 @@ import ( // ResourceClasses. type ResourceClassInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.ResourceClassLister + Lister() v1alpha2.ResourceClassLister } type resourceClassInformer struct { @@ -61,16 +61,16 @@ func NewFilteredResourceClassInformer(client kubernetes.Interface, resyncPeriod if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClasses().List(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClasses().List(context.TODO(), options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ResourceV1alpha1().ResourceClasses().Watch(context.TODO(), options) + return client.ResourceV1alpha2().ResourceClasses().Watch(context.TODO(), options) }, }, - &resourcev1alpha1.ResourceClass{}, + &resourcev1alpha2.ResourceClass{}, resyncPeriod, indexers, ) @@ -81,9 +81,9 @@ func (f *resourceClassInformer) defaultInformer(client kubernetes.Interface, res } func (f *resourceClassInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&resourcev1alpha1.ResourceClass{}, f.defaultInformer) + return f.factory.InformerFor(&resourcev1alpha2.ResourceClass{}, f.defaultInformer) } -func (f *resourceClassInformer) Lister() v1alpha1.ResourceClassLister { - return v1alpha1.NewResourceClassLister(f.Informer().GetIndexer()) +func (f *resourceClassInformer) Lister() v1alpha2.ResourceClassLister { + return v1alpha2.NewResourceClassLister(f.Informer().GetIndexer()) } diff --git a/vendor/k8s.io/client-go/kubernetes/clientset.go b/vendor/k8s.io/client-go/kubernetes/clientset.go index 9eecbb2a8..6345f2fb6 100644 --- a/vendor/k8s.io/client-go/kubernetes/clientset.go +++ b/vendor/k8s.io/client-go/kubernetes/clientset.go @@ -42,6 +42,7 @@ import ( batchv1 "k8s.io/client-go/kubernetes/typed/batch/v1" batchv1beta1 "k8s.io/client-go/kubernetes/typed/batch/v1beta1" certificatesv1 "k8s.io/client-go/kubernetes/typed/certificates/v1" + certificatesv1alpha1 "k8s.io/client-go/kubernetes/typed/certificates/v1alpha1" certificatesv1beta1 "k8s.io/client-go/kubernetes/typed/certificates/v1beta1" coordinationv1 "k8s.io/client-go/kubernetes/typed/coordination/v1" coordinationv1beta1 "k8s.io/client-go/kubernetes/typed/coordination/v1beta1" @@ -66,7 +67,7 @@ import ( rbacv1 "k8s.io/client-go/kubernetes/typed/rbac/v1" rbacv1alpha1 "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1" rbacv1beta1 "k8s.io/client-go/kubernetes/typed/rbac/v1beta1" - resourcev1alpha1 "k8s.io/client-go/kubernetes/typed/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/kubernetes/typed/resource/v1alpha2" schedulingv1 "k8s.io/client-go/kubernetes/typed/scheduling/v1" schedulingv1alpha1 "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/client-go/kubernetes/typed/scheduling/v1beta1" @@ -99,6 +100,7 @@ type Interface interface { BatchV1beta1() batchv1beta1.BatchV1beta1Interface CertificatesV1() certificatesv1.CertificatesV1Interface CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta1Interface + CertificatesV1alpha1() certificatesv1alpha1.CertificatesV1alpha1Interface CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface CoordinationV1() coordinationv1.CoordinationV1Interface CoreV1() corev1.CoreV1Interface @@ -122,7 +124,7 @@ type Interface interface { RbacV1() rbacv1.RbacV1Interface RbacV1beta1() rbacv1beta1.RbacV1beta1Interface RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface - ResourceV1alpha1() resourcev1alpha1.ResourceV1alpha1Interface + ResourceV1alpha2() resourcev1alpha2.ResourceV1alpha2Interface SchedulingV1alpha1() schedulingv1alpha1.SchedulingV1alpha1Interface SchedulingV1beta1() schedulingv1beta1.SchedulingV1beta1Interface SchedulingV1() schedulingv1.SchedulingV1Interface @@ -154,6 +156,7 @@ type Clientset struct { batchV1beta1 *batchv1beta1.BatchV1beta1Client certificatesV1 *certificatesv1.CertificatesV1Client certificatesV1beta1 *certificatesv1beta1.CertificatesV1beta1Client + certificatesV1alpha1 *certificatesv1alpha1.CertificatesV1alpha1Client coordinationV1beta1 *coordinationv1beta1.CoordinationV1beta1Client coordinationV1 *coordinationv1.CoordinationV1Client coreV1 *corev1.CoreV1Client @@ -177,7 +180,7 @@ type Clientset struct { rbacV1 *rbacv1.RbacV1Client rbacV1beta1 *rbacv1beta1.RbacV1beta1Client rbacV1alpha1 *rbacv1alpha1.RbacV1alpha1Client - resourceV1alpha1 *resourcev1alpha1.ResourceV1alpha1Client + resourceV1alpha2 *resourcev1alpha2.ResourceV1alpha2Client schedulingV1alpha1 *schedulingv1alpha1.SchedulingV1alpha1Client schedulingV1beta1 *schedulingv1beta1.SchedulingV1beta1Client schedulingV1 *schedulingv1.SchedulingV1Client @@ -286,6 +289,11 @@ func (c *Clientset) CertificatesV1beta1() certificatesv1beta1.CertificatesV1beta return c.certificatesV1beta1 } +// CertificatesV1alpha1 retrieves the CertificatesV1alpha1Client +func (c *Clientset) CertificatesV1alpha1() certificatesv1alpha1.CertificatesV1alpha1Interface { + return c.certificatesV1alpha1 +} + // CoordinationV1beta1 retrieves the CoordinationV1beta1Client func (c *Clientset) CoordinationV1beta1() coordinationv1beta1.CoordinationV1beta1Interface { return c.coordinationV1beta1 @@ -401,9 +409,9 @@ func (c *Clientset) RbacV1alpha1() rbacv1alpha1.RbacV1alpha1Interface { return c.rbacV1alpha1 } -// ResourceV1alpha1 retrieves the ResourceV1alpha1Client -func (c *Clientset) ResourceV1alpha1() resourcev1alpha1.ResourceV1alpha1Interface { - return c.resourceV1alpha1 +// ResourceV1alpha2 retrieves the ResourceV1alpha2Client +func (c *Clientset) ResourceV1alpha2() resourcev1alpha2.ResourceV1alpha2Interface { + return c.resourceV1alpha2 } // SchedulingV1alpha1 retrieves the SchedulingV1alpha1Client @@ -560,6 +568,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.certificatesV1alpha1, err = certificatesv1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.coordinationV1beta1, err = coordinationv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -652,7 +664,7 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } - cs.resourceV1alpha1, err = resourcev1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + cs.resourceV1alpha2, err = resourcev1alpha2.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err } @@ -721,6 +733,7 @@ func New(c rest.Interface) *Clientset { cs.batchV1beta1 = batchv1beta1.New(c) cs.certificatesV1 = certificatesv1.New(c) cs.certificatesV1beta1 = certificatesv1beta1.New(c) + cs.certificatesV1alpha1 = certificatesv1alpha1.New(c) cs.coordinationV1beta1 = coordinationv1beta1.New(c) cs.coordinationV1 = coordinationv1.New(c) cs.coreV1 = corev1.New(c) @@ -744,7 +757,7 @@ func New(c rest.Interface) *Clientset { cs.rbacV1 = rbacv1.New(c) cs.rbacV1beta1 = rbacv1beta1.New(c) cs.rbacV1alpha1 = rbacv1alpha1.New(c) - cs.resourceV1alpha1 = resourcev1alpha1.New(c) + cs.resourceV1alpha2 = resourcev1alpha2.New(c) cs.schedulingV1alpha1 = schedulingv1alpha1.New(c) cs.schedulingV1beta1 = schedulingv1beta1.New(c) cs.schedulingV1 = schedulingv1.New(c) diff --git a/vendor/k8s.io/client-go/kubernetes/doc.go b/vendor/k8s.io/client-go/kubernetes/doc.go index b272334ad..9cef4242f 100644 --- a/vendor/k8s.io/client-go/kubernetes/doc.go +++ b/vendor/k8s.io/client-go/kubernetes/doc.go @@ -1,5 +1,5 @@ /* -Copyright The Kubernetes Authors. +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. @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - -// This package has the automatically generated clientset. +// Package kubernetes holds packages which implement a clientset for Kubernetes +// APIs. package kubernetes diff --git a/vendor/k8s.io/client-go/kubernetes/scheme/register.go b/vendor/k8s.io/client-go/kubernetes/scheme/register.go index e43780529..64d3ce2a7 100644 --- a/vendor/k8s.io/client-go/kubernetes/scheme/register.go +++ b/vendor/k8s.io/client-go/kubernetes/scheme/register.go @@ -38,6 +38,7 @@ import ( batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" certificatesv1 "k8s.io/api/certificates/v1" + certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1" certificatesv1beta1 "k8s.io/api/certificates/v1beta1" coordinationv1 "k8s.io/api/coordination/v1" coordinationv1beta1 "k8s.io/api/coordination/v1beta1" @@ -62,7 +63,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" rbacv1alpha1 "k8s.io/api/rbac/v1alpha1" rbacv1beta1 "k8s.io/api/rbac/v1beta1" - resourcev1alpha1 "k8s.io/api/resource/v1alpha1" + resourcev1alpha2 "k8s.io/api/resource/v1alpha2" schedulingv1 "k8s.io/api/scheduling/v1" schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1" schedulingv1beta1 "k8s.io/api/scheduling/v1beta1" @@ -100,6 +101,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ batchv1beta1.AddToScheme, certificatesv1.AddToScheme, certificatesv1beta1.AddToScheme, + certificatesv1alpha1.AddToScheme, coordinationv1beta1.AddToScheme, coordinationv1.AddToScheme, corev1.AddToScheme, @@ -123,7 +125,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ rbacv1.AddToScheme, rbacv1beta1.AddToScheme, rbacv1alpha1.AddToScheme, - resourcev1alpha1.AddToScheme, + resourcev1alpha2.AddToScheme, schedulingv1alpha1.AddToScheme, schedulingv1beta1.AddToScheme, schedulingv1.AddToScheme, diff --git a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go index ba827f3c9..1d994b5ab 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1/validatingadmissionpolicy.go @@ -43,6 +43,7 @@ type ValidatingAdmissionPoliciesGetter interface { type ValidatingAdmissionPolicyInterface interface { Create(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.CreateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) Update(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) + UpdateStatus(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ValidatingAdmissionPolicy, error) @@ -50,6 +51,7 @@ type ValidatingAdmissionPolicyInterface interface { Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ValidatingAdmissionPolicy, err error) Apply(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) + ApplyStatus(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) ValidatingAdmissionPolicyExpansion } @@ -132,6 +134,21 @@ func (c *validatingAdmissionPolicies) Update(ctx context.Context, validatingAdmi return } +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *validatingAdmissionPolicies) UpdateStatus(ctx context.Context, validatingAdmissionPolicy *v1alpha1.ValidatingAdmissionPolicy, opts v1.UpdateOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Put(). + Resource("validatingadmissionpolicies"). + Name(validatingAdmissionPolicy.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(validatingAdmissionPolicy). + Do(ctx). + Into(result) + return +} + // Delete takes name of the validatingAdmissionPolicy and deletes it. Returns an error if one occurs. func (c *validatingAdmissionPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { return c.client.Delete(). @@ -195,3 +212,32 @@ func (c *validatingAdmissionPolicies) Apply(ctx context.Context, validatingAdmis Into(result) return } + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *validatingAdmissionPolicies) ApplyStatus(ctx context.Context, validatingAdmissionPolicy *admissionregistrationv1alpha1.ValidatingAdmissionPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ValidatingAdmissionPolicy, err error) { + if validatingAdmissionPolicy == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(validatingAdmissionPolicy) + if err != nil { + return nil, err + } + + name := validatingAdmissionPolicy.Name + if name == nil { + return nil, fmt.Errorf("validatingAdmissionPolicy.Name must be provided to Apply") + } + + result = &v1alpha1.ValidatingAdmissionPolicy{} + err = c.client.Patch(types.ApplyPatchType). + Resource("validatingadmissionpolicies"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go index 218cb60c3..7823729e0 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/authentication_client.go @@ -28,6 +28,7 @@ import ( type AuthenticationV1beta1Interface interface { RESTClient() rest.Interface + SelfSubjectReviewsGetter TokenReviewsGetter } @@ -36,6 +37,10 @@ type AuthenticationV1beta1Client struct { restClient rest.Interface } +func (c *AuthenticationV1beta1Client) SelfSubjectReviews() SelfSubjectReviewInterface { + return newSelfSubjectReviews(c) +} + func (c *AuthenticationV1beta1Client) TokenReviews() TokenReviewInterface { return newTokenReviews(c) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go index 60bf15ab9..527a458d7 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/generated_expansion.go @@ -18,4 +18,6 @@ limitations under the License. package v1beta1 +type SelfSubjectReviewExpansion interface{} + type TokenReviewExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go new file mode 100644 index 000000000..9d54826a3 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1/selfsubjectreview.go @@ -0,0 +1,64 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + + v1beta1 "k8s.io/api/authentication/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// SelfSubjectReviewsGetter has a method to return a SelfSubjectReviewInterface. +// A group's client should implement this interface. +type SelfSubjectReviewsGetter interface { + SelfSubjectReviews() SelfSubjectReviewInterface +} + +// SelfSubjectReviewInterface has methods to work with SelfSubjectReview resources. +type SelfSubjectReviewInterface interface { + Create(ctx context.Context, selfSubjectReview *v1beta1.SelfSubjectReview, opts v1.CreateOptions) (*v1beta1.SelfSubjectReview, error) + SelfSubjectReviewExpansion +} + +// selfSubjectReviews implements SelfSubjectReviewInterface +type selfSubjectReviews struct { + client rest.Interface +} + +// newSelfSubjectReviews returns a SelfSubjectReviews +func newSelfSubjectReviews(c *AuthenticationV1beta1Client) *selfSubjectReviews { + return &selfSubjectReviews{ + client: c.RESTClient(), + } +} + +// Create takes the representation of a selfSubjectReview and creates it. Returns the server's representation of the selfSubjectReview, and an error, if there is any. +func (c *selfSubjectReviews) Create(ctx context.Context, selfSubjectReview *v1beta1.SelfSubjectReview, opts v1.CreateOptions) (result *v1beta1.SelfSubjectReview, err error) { + result = &v1beta1.SelfSubjectReview{} + err = c.client.Post(). + Resource("selfsubjectreviews"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(selfSubjectReview). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go new file mode 100644 index 000000000..a9050af94 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/certificates_client.go @@ -0,0 +1,107 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "net/http" + + v1alpha1 "k8s.io/api/certificates/v1alpha1" + "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +type CertificatesV1alpha1Interface interface { + RESTClient() rest.Interface + ClusterTrustBundlesGetter +} + +// CertificatesV1alpha1Client is used to interact with features provided by the certificates.k8s.io group. +type CertificatesV1alpha1Client struct { + restClient rest.Interface +} + +func (c *CertificatesV1alpha1Client) ClusterTrustBundles() ClusterTrustBundleInterface { + return newClusterTrustBundles(c) +} + +// NewForConfig creates a new CertificatesV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*CertificatesV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new CertificatesV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*CertificatesV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &CertificatesV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new CertificatesV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *CertificatesV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new CertificatesV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *CertificatesV1alpha1Client { + return &CertificatesV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *CertificatesV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go new file mode 100644 index 000000000..970fb15e6 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/clustertrustbundle.go @@ -0,0 +1,197 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/certificates/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + certificatesv1alpha1 "k8s.io/client-go/applyconfigurations/certificates/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// ClusterTrustBundlesGetter has a method to return a ClusterTrustBundleInterface. +// A group's client should implement this interface. +type ClusterTrustBundlesGetter interface { + ClusterTrustBundles() ClusterTrustBundleInterface +} + +// ClusterTrustBundleInterface has methods to work with ClusterTrustBundle resources. +type ClusterTrustBundleInterface interface { + Create(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.CreateOptions) (*v1alpha1.ClusterTrustBundle, error) + Update(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.UpdateOptions) (*v1alpha1.ClusterTrustBundle, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ClusterTrustBundle, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterTrustBundleList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterTrustBundle, err error) + Apply(ctx context.Context, clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundleApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterTrustBundle, err error) + ClusterTrustBundleExpansion +} + +// clusterTrustBundles implements ClusterTrustBundleInterface +type clusterTrustBundles struct { + client rest.Interface +} + +// newClusterTrustBundles returns a ClusterTrustBundles +func newClusterTrustBundles(c *CertificatesV1alpha1Client) *clusterTrustBundles { + return &clusterTrustBundles{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterTrustBundle, and returns the corresponding clusterTrustBundle object, and an error if there is any. +func (c *clusterTrustBundles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Get(). + Resource("clustertrustbundles"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterTrustBundles that match those selectors. +func (c *clusterTrustBundles) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterTrustBundleList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ClusterTrustBundleList{} + err = c.client.Get(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterTrustBundles. +func (c *clusterTrustBundles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a clusterTrustBundle and creates it. Returns the server's representation of the clusterTrustBundle, and an error, if there is any. +func (c *clusterTrustBundles) Create(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.CreateOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Post(). + Resource("clustertrustbundles"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterTrustBundle). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a clusterTrustBundle and updates it. Returns the server's representation of the clusterTrustBundle, and an error, if there is any. +func (c *clusterTrustBundles) Update(ctx context.Context, clusterTrustBundle *v1alpha1.ClusterTrustBundle, opts v1.UpdateOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Put(). + Resource("clustertrustbundles"). + Name(clusterTrustBundle.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterTrustBundle). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the clusterTrustBundle and deletes it. Returns an error if one occurs. +func (c *clusterTrustBundles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("clustertrustbundles"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterTrustBundles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clustertrustbundles"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched clusterTrustBundle. +func (c *clusterTrustBundles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterTrustBundle, err error) { + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Patch(pt). + Resource("clustertrustbundles"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied clusterTrustBundle. +func (c *clusterTrustBundles) Apply(ctx context.Context, clusterTrustBundle *certificatesv1alpha1.ClusterTrustBundleApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ClusterTrustBundle, err error) { + if clusterTrustBundle == nil { + return nil, fmt.Errorf("clusterTrustBundle provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(clusterTrustBundle) + if err != nil { + return nil, err + } + name := clusterTrustBundle.Name + if name == nil { + return nil, fmt.Errorf("clusterTrustBundle.Name must be provided to Apply") + } + result = &v1alpha1.ClusterTrustBundle{} + err = c.client.Patch(types.ApplyPatchType). + Resource("clustertrustbundles"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/doc.go similarity index 100% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/doc.go rename to vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/doc.go diff --git a/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go new file mode 100644 index 000000000..43cc534b3 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type ClusterTrustBundleExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go index 464fff911..562f8d5e4 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/events/v1beta1/event_expansion.go @@ -82,8 +82,7 @@ func (e *events) UpdateWithEventNamespace(event *v1beta1.Event) (*v1beta1.Event, // It returns the copy of the event that the server returns, or an error. // The namespace and name of the target event is deduced from the event. // The namespace must either match this event client's namespace, or this event client must -// -// have been created with the "" namespace. +// have been created with the "" namespace. func (e *events) PatchWithEventNamespace(event *v1beta1.Event, data []byte) (*v1beta1.Event, error) { if e.ns != "" && event.Namespace != e.ns { return nil, fmt.Errorf("can't patch an event with namespace '%v' in namespace '%v'", event.Namespace, e.ns) diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go index 827b514df..4725d2cd1 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/extensions_client.go @@ -32,7 +32,6 @@ type ExtensionsV1beta1Interface interface { DeploymentsGetter IngressesGetter NetworkPoliciesGetter - PodSecurityPoliciesGetter ReplicaSetsGetter } @@ -57,10 +56,6 @@ func (c *ExtensionsV1beta1Client) NetworkPolicies(namespace string) NetworkPolic return newNetworkPolicies(c, namespace) } -func (c *ExtensionsV1beta1Client) PodSecurityPolicies() PodSecurityPolicyInterface { - return newPodSecurityPolicies(c) -} - func (c *ExtensionsV1beta1Client) ReplicaSets(namespace string) ReplicaSetInterface { return newReplicaSets(c, namespace) } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go index 41d28f041..67fcf4992 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/generated_expansion.go @@ -24,6 +24,4 @@ type IngressExpansion interface{} type NetworkPolicyExpansion interface{} -type PodSecurityPolicyExpansion interface{} - type ReplicaSetExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go deleted file mode 100644 index 3f38c3133..000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1/podsecuritypolicy.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1beta1 - -import ( - "context" - json "encoding/json" - "fmt" - "time" - - v1beta1 "k8s.io/api/extensions/v1beta1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - extensionsv1beta1 "k8s.io/client-go/applyconfigurations/extensions/v1beta1" - scheme "k8s.io/client-go/kubernetes/scheme" - rest "k8s.io/client-go/rest" -) - -// PodSecurityPoliciesGetter has a method to return a PodSecurityPolicyInterface. -// A group's client should implement this interface. -type PodSecurityPoliciesGetter interface { - PodSecurityPolicies() PodSecurityPolicyInterface -} - -// PodSecurityPolicyInterface has methods to work with PodSecurityPolicy resources. -type PodSecurityPolicyInterface interface { - Create(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.CreateOptions) (*v1beta1.PodSecurityPolicy, error) - Update(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.UpdateOptions) (*v1beta1.PodSecurityPolicy, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.PodSecurityPolicy, error) - List(ctx context.Context, opts v1.ListOptions) (*v1beta1.PodSecurityPolicyList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.PodSecurityPolicy, err error) - Apply(ctx context.Context, podSecurityPolicy *extensionsv1beta1.PodSecurityPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.PodSecurityPolicy, err error) - PodSecurityPolicyExpansion -} - -// podSecurityPolicies implements PodSecurityPolicyInterface -type podSecurityPolicies struct { - client rest.Interface -} - -// newPodSecurityPolicies returns a PodSecurityPolicies -func newPodSecurityPolicies(c *ExtensionsV1beta1Client) *podSecurityPolicies { - return &podSecurityPolicies{ - client: c.RESTClient(), - } -} - -// Get takes name of the podSecurityPolicy, and returns the corresponding podSecurityPolicy object, and an error if there is any. -func (c *podSecurityPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Get(). - Resource("podsecuritypolicies"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of PodSecurityPolicies that match those selectors. -func (c *podSecurityPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.PodSecurityPolicyList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1beta1.PodSecurityPolicyList{} - err = c.client.Get(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested podSecurityPolicies. -func (c *podSecurityPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a podSecurityPolicy and creates it. Returns the server's representation of the podSecurityPolicy, and an error, if there is any. -func (c *podSecurityPolicies) Create(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.CreateOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Post(). - Resource("podsecuritypolicies"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podSecurityPolicy). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a podSecurityPolicy and updates it. Returns the server's representation of the podSecurityPolicy, and an error, if there is any. -func (c *podSecurityPolicies) Update(ctx context.Context, podSecurityPolicy *v1beta1.PodSecurityPolicy, opts v1.UpdateOptions) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Put(). - Resource("podsecuritypolicies"). - Name(podSecurityPolicy.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podSecurityPolicy). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the podSecurityPolicy and deletes it. Returns an error if one occurs. -func (c *podSecurityPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Resource("podsecuritypolicies"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *podSecurityPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Resource("podsecuritypolicies"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched podSecurityPolicy. -func (c *podSecurityPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.PodSecurityPolicy, err error) { - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Patch(pt). - Resource("podsecuritypolicies"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied podSecurityPolicy. -func (c *podSecurityPolicies) Apply(ctx context.Context, podSecurityPolicy *extensionsv1beta1.PodSecurityPolicyApplyConfiguration, opts v1.ApplyOptions) (result *v1beta1.PodSecurityPolicy, err error) { - if podSecurityPolicy == nil { - return nil, fmt.Errorf("podSecurityPolicy provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := json.Marshal(podSecurityPolicy) - if err != nil { - return nil, err - } - name := podSecurityPolicy.Name - if name == nil { - return nil, fmt.Errorf("podSecurityPolicy.Name must be provided to Apply") - } - result = &v1beta1.PodSecurityPolicy{} - err = c.client.Patch(types.ApplyPatchType). - Resource("podsecuritypolicies"). - Name(*name). - VersionedParams(&patchOpts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go index ab41abb7d..9c2979d6c 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/generated_expansion.go @@ -19,3 +19,5 @@ limitations under the License. package v1alpha1 type ClusterCIDRExpansion interface{} + +type IPAddressExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go new file mode 100644 index 000000000..fff193d68 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/ipaddress.go @@ -0,0 +1,197 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha1 "k8s.io/api/networking/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + networkingv1alpha1 "k8s.io/client-go/applyconfigurations/networking/v1alpha1" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// IPAddressesGetter has a method to return a IPAddressInterface. +// A group's client should implement this interface. +type IPAddressesGetter interface { + IPAddresses() IPAddressInterface +} + +// IPAddressInterface has methods to work with IPAddress resources. +type IPAddressInterface interface { + Create(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.CreateOptions) (*v1alpha1.IPAddress, error) + Update(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.UpdateOptions) (*v1alpha1.IPAddress, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.IPAddress, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.IPAddressList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPAddress, err error) + Apply(ctx context.Context, iPAddress *networkingv1alpha1.IPAddressApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.IPAddress, err error) + IPAddressExpansion +} + +// iPAddresses implements IPAddressInterface +type iPAddresses struct { + client rest.Interface +} + +// newIPAddresses returns a IPAddresses +func newIPAddresses(c *NetworkingV1alpha1Client) *iPAddresses { + return &iPAddresses{ + client: c.RESTClient(), + } +} + +// Get takes name of the iPAddress, and returns the corresponding iPAddress object, and an error if there is any. +func (c *iPAddresses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Get(). + Resource("ipaddresses"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of IPAddresses that match those selectors. +func (c *iPAddresses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.IPAddressList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.IPAddressList{} + err = c.client.Get(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested iPAddresses. +func (c *iPAddresses) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a iPAddress and creates it. Returns the server's representation of the iPAddress, and an error, if there is any. +func (c *iPAddresses) Create(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.CreateOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Post(). + Resource("ipaddresses"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(iPAddress). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a iPAddress and updates it. Returns the server's representation of the iPAddress, and an error, if there is any. +func (c *iPAddresses) Update(ctx context.Context, iPAddress *v1alpha1.IPAddress, opts v1.UpdateOptions) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Put(). + Resource("ipaddresses"). + Name(iPAddress.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(iPAddress). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the iPAddress and deletes it. Returns an error if one occurs. +func (c *iPAddresses) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("ipaddresses"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *iPAddresses) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("ipaddresses"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched iPAddress. +func (c *iPAddresses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.IPAddress, err error) { + result = &v1alpha1.IPAddress{} + err = c.client.Patch(pt). + Resource("ipaddresses"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied iPAddress. +func (c *iPAddresses) Apply(ctx context.Context, iPAddress *networkingv1alpha1.IPAddressApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.IPAddress, err error) { + if iPAddress == nil { + return nil, fmt.Errorf("iPAddress provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(iPAddress) + if err != nil { + return nil, err + } + name := iPAddress.Name + if name == nil { + return nil, fmt.Errorf("iPAddress.Name must be provided to Apply") + } + result = &v1alpha1.IPAddress{} + err = c.client.Patch(types.ApplyPatchType). + Resource("ipaddresses"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go index ccb593316..884c846f5 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/networking/v1alpha1/networking_client.go @@ -29,6 +29,7 @@ import ( type NetworkingV1alpha1Interface interface { RESTClient() rest.Interface ClusterCIDRsGetter + IPAddressesGetter } // NetworkingV1alpha1Client is used to interact with features provided by the networking.k8s.io group. @@ -40,6 +41,10 @@ func (c *NetworkingV1alpha1Client) ClusterCIDRs() ClusterCIDRInterface { return newClusterCIDRs(c) } +func (c *NetworkingV1alpha1Client) IPAddresses() IPAddressInterface { + return newIPAddresses(c) +} + // NewForConfig creates a new NetworkingV1alpha1Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/podscheduling.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/podscheduling.go deleted file mode 100644 index e163a8456..000000000 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/podscheduling.go +++ /dev/null @@ -1,256 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - "context" - json "encoding/json" - "fmt" - "time" - - v1alpha1 "k8s.io/api/resource/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" - scheme "k8s.io/client-go/kubernetes/scheme" - rest "k8s.io/client-go/rest" -) - -// PodSchedulingsGetter has a method to return a PodSchedulingInterface. -// A group's client should implement this interface. -type PodSchedulingsGetter interface { - PodSchedulings(namespace string) PodSchedulingInterface -} - -// PodSchedulingInterface has methods to work with PodScheduling resources. -type PodSchedulingInterface interface { - Create(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.CreateOptions) (*v1alpha1.PodScheduling, error) - Update(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (*v1alpha1.PodScheduling, error) - UpdateStatus(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (*v1alpha1.PodScheduling, error) - Delete(ctx context.Context, name string, opts v1.DeleteOptions) error - DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.PodScheduling, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.PodSchedulingList, error) - Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.PodScheduling, err error) - Apply(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) - ApplyStatus(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) - PodSchedulingExpansion -} - -// podSchedulings implements PodSchedulingInterface -type podSchedulings struct { - client rest.Interface - ns string -} - -// newPodSchedulings returns a PodSchedulings -func newPodSchedulings(c *ResourceV1alpha1Client, namespace string) *podSchedulings { - return &podSchedulings{ - client: c.RESTClient(), - ns: namespace, - } -} - -// Get takes name of the podScheduling, and returns the corresponding podScheduling object, and an error if there is any. -func (c *podSchedulings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Get(). - Namespace(c.ns). - Resource("podschedulings"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(ctx). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of PodSchedulings that match those selectors. -func (c *podSchedulings) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.PodSchedulingList, err error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - result = &v1alpha1.PodSchedulingList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("podschedulings"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Do(ctx). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested podSchedulings. -func (c *podSchedulings) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - var timeout time.Duration - if opts.TimeoutSeconds != nil { - timeout = time.Duration(*opts.TimeoutSeconds) * time.Second - } - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("podschedulings"). - VersionedParams(&opts, scheme.ParameterCodec). - Timeout(timeout). - Watch(ctx) -} - -// Create takes the representation of a podScheduling and creates it. Returns the server's representation of the podScheduling, and an error, if there is any. -func (c *podSchedulings) Create(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.CreateOptions) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Post(). - Namespace(c.ns). - Resource("podschedulings"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podScheduling). - Do(ctx). - Into(result) - return -} - -// Update takes the representation of a podScheduling and updates it. Returns the server's representation of the podScheduling, and an error, if there is any. -func (c *podSchedulings) Update(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Put(). - Namespace(c.ns). - Resource("podschedulings"). - Name(podScheduling.Name). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podScheduling). - Do(ctx). - Into(result) - return -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *podSchedulings) UpdateStatus(ctx context.Context, podScheduling *v1alpha1.PodScheduling, opts v1.UpdateOptions) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Put(). - Namespace(c.ns). - Resource("podschedulings"). - Name(podScheduling.Name). - SubResource("status"). - VersionedParams(&opts, scheme.ParameterCodec). - Body(podScheduling). - Do(ctx). - Into(result) - return -} - -// Delete takes name of the podScheduling and deletes it. Returns an error if one occurs. -func (c *podSchedulings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("podschedulings"). - Name(name). - Body(&opts). - Do(ctx). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *podSchedulings) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - var timeout time.Duration - if listOpts.TimeoutSeconds != nil { - timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second - } - return c.client.Delete(). - Namespace(c.ns). - Resource("podschedulings"). - VersionedParams(&listOpts, scheme.ParameterCodec). - Timeout(timeout). - Body(&opts). - Do(ctx). - Error() -} - -// Patch applies the patch and returns the patched podScheduling. -func (c *podSchedulings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.PodScheduling, err error) { - result = &v1alpha1.PodScheduling{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("podschedulings"). - Name(name). - SubResource(subresources...). - VersionedParams(&opts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} - -// Apply takes the given apply declarative configuration, applies it and returns the applied podScheduling. -func (c *podSchedulings) Apply(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) { - if podScheduling == nil { - return nil, fmt.Errorf("podScheduling provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := json.Marshal(podScheduling) - if err != nil { - return nil, err - } - name := podScheduling.Name - if name == nil { - return nil, fmt.Errorf("podScheduling.Name must be provided to Apply") - } - result = &v1alpha1.PodScheduling{} - err = c.client.Patch(types.ApplyPatchType). - Namespace(c.ns). - Resource("podschedulings"). - Name(*name). - VersionedParams(&patchOpts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} - -// ApplyStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *podSchedulings) ApplyStatus(ctx context.Context, podScheduling *resourcev1alpha1.PodSchedulingApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.PodScheduling, err error) { - if podScheduling == nil { - return nil, fmt.Errorf("podScheduling provided to Apply must not be nil") - } - patchOpts := opts.ToPatchOptions() - data, err := json.Marshal(podScheduling) - if err != nil { - return nil, err - } - - name := podScheduling.Name - if name == nil { - return nil, fmt.Errorf("podScheduling.Name must be provided to Apply") - } - - result = &v1alpha1.PodScheduling{} - err = c.client.Patch(types.ApplyPatchType). - Namespace(c.ns). - Resource("podschedulings"). - Name(*name). - SubResource("status"). - VersionedParams(&patchOpts, scheme.ParameterCodec). - Body(data). - Do(ctx). - Into(result) - return -} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go new file mode 100644 index 000000000..baaf2d985 --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha2 diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/generated_expansion.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go similarity index 92% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/generated_expansion.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go index df88c2f93..2c02e9ce7 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/generated_expansion.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/generated_expansion.go @@ -16,9 +16,9 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -type PodSchedulingExpansion interface{} +type PodSchedulingContextExpansion interface{} type ResourceClaimExpansion interface{} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 000000000..72e81a29e --- /dev/null +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,256 @@ +/* +Copyright 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1alpha2 "k8s.io/api/resource/v1alpha2" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" + scheme "k8s.io/client-go/kubernetes/scheme" + rest "k8s.io/client-go/rest" +) + +// PodSchedulingContextsGetter has a method to return a PodSchedulingContextInterface. +// A group's client should implement this interface. +type PodSchedulingContextsGetter interface { + PodSchedulingContexts(namespace string) PodSchedulingContextInterface +} + +// PodSchedulingContextInterface has methods to work with PodSchedulingContext resources. +type PodSchedulingContextInterface interface { + Create(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.CreateOptions) (*v1alpha2.PodSchedulingContext, error) + Update(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (*v1alpha2.PodSchedulingContext, error) + UpdateStatus(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (*v1alpha2.PodSchedulingContext, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.PodSchedulingContext, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.PodSchedulingContextList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.PodSchedulingContext, err error) + Apply(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) + ApplyStatus(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) + PodSchedulingContextExpansion +} + +// podSchedulingContexts implements PodSchedulingContextInterface +type podSchedulingContexts struct { + client rest.Interface + ns string +} + +// newPodSchedulingContexts returns a PodSchedulingContexts +func newPodSchedulingContexts(c *ResourceV1alpha2Client, namespace string) *podSchedulingContexts { + return &podSchedulingContexts{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the podSchedulingContext, and returns the corresponding podSchedulingContext object, and an error if there is any. +func (c *podSchedulingContexts) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of PodSchedulingContexts that match those selectors. +func (c *podSchedulingContexts) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.PodSchedulingContextList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha2.PodSchedulingContextList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested podSchedulingContexts. +func (c *podSchedulingContexts) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a podSchedulingContext and creates it. Returns the server's representation of the podSchedulingContext, and an error, if there is any. +func (c *podSchedulingContexts) Create(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.CreateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Post(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a podSchedulingContext and updates it. Returns the server's representation of the podSchedulingContext, and an error, if there is any. +func (c *podSchedulingContexts) Update(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Put(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(podSchedulingContext.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *podSchedulingContexts) UpdateStatus(ctx context.Context, podSchedulingContext *v1alpha2.PodSchedulingContext, opts v1.UpdateOptions) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Put(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(podSchedulingContext.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(podSchedulingContext). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the podSchedulingContext and deletes it. Returns an error if one occurs. +func (c *podSchedulingContexts) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *podSchedulingContexts) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("podschedulingcontexts"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched podSchedulingContext. +func (c *podSchedulingContexts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.PodSchedulingContext, err error) { + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied podSchedulingContext. +func (c *podSchedulingContexts) Apply(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) { + if podSchedulingContext == nil { + return nil, fmt.Errorf("podSchedulingContext provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(podSchedulingContext) + if err != nil { + return nil, err + } + name := podSchedulingContext.Name + if name == nil { + return nil, fmt.Errorf("podSchedulingContext.Name must be provided to Apply") + } + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *podSchedulingContexts) ApplyStatus(ctx context.Context, podSchedulingContext *resourcev1alpha2.PodSchedulingContextApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.PodSchedulingContext, err error) { + if podSchedulingContext == nil { + return nil, fmt.Errorf("podSchedulingContext provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(podSchedulingContext) + if err != nil { + return nil, err + } + + name := podSchedulingContext.Name + if name == nil { + return nil, fmt.Errorf("podSchedulingContext.Name must be provided to Apply") + } + + result = &v1alpha2.PodSchedulingContext{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("podschedulingcontexts"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resource_client.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go similarity index 66% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resource_client.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go index 2355bf7cc..d5795fd62 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resource_client.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resource_client.go @@ -16,49 +16,49 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "net/http" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) -type ResourceV1alpha1Interface interface { +type ResourceV1alpha2Interface interface { RESTClient() rest.Interface - PodSchedulingsGetter + PodSchedulingContextsGetter ResourceClaimsGetter ResourceClaimTemplatesGetter ResourceClassesGetter } -// ResourceV1alpha1Client is used to interact with features provided by the resource.k8s.io group. -type ResourceV1alpha1Client struct { +// ResourceV1alpha2Client is used to interact with features provided by the resource.k8s.io group. +type ResourceV1alpha2Client struct { restClient rest.Interface } -func (c *ResourceV1alpha1Client) PodSchedulings(namespace string) PodSchedulingInterface { - return newPodSchedulings(c, namespace) +func (c *ResourceV1alpha2Client) PodSchedulingContexts(namespace string) PodSchedulingContextInterface { + return newPodSchedulingContexts(c, namespace) } -func (c *ResourceV1alpha1Client) ResourceClaims(namespace string) ResourceClaimInterface { +func (c *ResourceV1alpha2Client) ResourceClaims(namespace string) ResourceClaimInterface { return newResourceClaims(c, namespace) } -func (c *ResourceV1alpha1Client) ResourceClaimTemplates(namespace string) ResourceClaimTemplateInterface { +func (c *ResourceV1alpha2Client) ResourceClaimTemplates(namespace string) ResourceClaimTemplateInterface { return newResourceClaimTemplates(c, namespace) } -func (c *ResourceV1alpha1Client) ResourceClasses() ResourceClassInterface { +func (c *ResourceV1alpha2Client) ResourceClasses() ResourceClassInterface { return newResourceClasses(c) } -// NewForConfig creates a new ResourceV1alpha1Client for the given config. +// NewForConfig creates a new ResourceV1alpha2Client for the given config. // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), // where httpClient was generated with rest.HTTPClientFor(c). -func NewForConfig(c *rest.Config) (*ResourceV1alpha1Client, error) { +func NewForConfig(c *rest.Config) (*ResourceV1alpha2Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err @@ -70,9 +70,9 @@ func NewForConfig(c *rest.Config) (*ResourceV1alpha1Client, error) { return NewForConfigAndClient(&config, httpClient) } -// NewForConfigAndClient creates a new ResourceV1alpha1Client for the given config and http client. +// NewForConfigAndClient creates a new ResourceV1alpha2Client for the given config and http client. // Note the http client provided takes precedence over the configured transport values. -func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ResourceV1alpha1Client, error) { +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ResourceV1alpha2Client, error) { config := *c if err := setConfigDefaults(&config); err != nil { return nil, err @@ -81,12 +81,12 @@ func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ResourceV1alpha1Cli if err != nil { return nil, err } - return &ResourceV1alpha1Client{client}, nil + return &ResourceV1alpha2Client{client}, nil } -// NewForConfigOrDie creates a new ResourceV1alpha1Client for the given config and +// NewForConfigOrDie creates a new ResourceV1alpha2Client for the given config and // panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *ResourceV1alpha1Client { +func NewForConfigOrDie(c *rest.Config) *ResourceV1alpha2Client { client, err := NewForConfig(c) if err != nil { panic(err) @@ -94,13 +94,13 @@ func NewForConfigOrDie(c *rest.Config) *ResourceV1alpha1Client { return client } -// New creates a new ResourceV1alpha1Client for the given RESTClient. -func New(c rest.Interface) *ResourceV1alpha1Client { - return &ResourceV1alpha1Client{c} +// New creates a new ResourceV1alpha2Client for the given RESTClient. +func New(c rest.Interface) *ResourceV1alpha2Client { + return &ResourceV1alpha2Client{c} } func setConfigDefaults(config *rest.Config) error { - gv := v1alpha1.SchemeGroupVersion + gv := v1alpha2.SchemeGroupVersion config.GroupVersion = &gv config.APIPath = "/apis" config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() @@ -114,7 +114,7 @@ func setConfigDefaults(config *rest.Config) error { // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. -func (c *ResourceV1alpha1Client) RESTClient() rest.Interface { +func (c *ResourceV1alpha2Client) RESTClient() rest.Interface { if c == nil { return nil } diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaim.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go similarity index 79% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaim.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go index cd2d0c782..cfb27c9db 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaim.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaim.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" @@ -24,11 +24,11 @@ import ( "fmt" "time" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" scheme "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) @@ -41,17 +41,17 @@ type ResourceClaimsGetter interface { // ResourceClaimInterface has methods to work with ResourceClaim resources. type ResourceClaimInterface interface { - Create(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.CreateOptions) (*v1alpha1.ResourceClaim, error) - Update(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (*v1alpha1.ResourceClaim, error) - UpdateStatus(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (*v1alpha1.ResourceClaim, error) + Create(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.CreateOptions) (*v1alpha2.ResourceClaim, error) + Update(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (*v1alpha2.ResourceClaim, error) + UpdateStatus(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (*v1alpha2.ResourceClaim, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ResourceClaim, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ResourceClaimList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClaim, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClaimList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaim, err error) - Apply(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) - ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaim, err error) + Apply(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) + ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) ResourceClaimExpansion } @@ -62,7 +62,7 @@ type resourceClaims struct { } // newResourceClaims returns a ResourceClaims -func newResourceClaims(c *ResourceV1alpha1Client, namespace string) *resourceClaims { +func newResourceClaims(c *ResourceV1alpha2Client, namespace string) *resourceClaims { return &resourceClaims{ client: c.RESTClient(), ns: namespace, @@ -70,8 +70,8 @@ func newResourceClaims(c *ResourceV1alpha1Client, namespace string) *resourceCla } // Get takes name of the resourceClaim, and returns the corresponding resourceClaim object, and an error if there is any. -func (c *resourceClaims) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Get(). Namespace(c.ns). Resource("resourceclaims"). @@ -83,12 +83,12 @@ func (c *resourceClaims) Get(ctx context.Context, name string, options v1.GetOpt } // List takes label and field selectors, and returns the list of ResourceClaims that match those selectors. -func (c *resourceClaims) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClaimList, err error) { +func (c *resourceClaims) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimList, err error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second } - result = &v1alpha1.ResourceClaimList{} + result = &v1alpha2.ResourceClaimList{} err = c.client.Get(). Namespace(c.ns). Resource("resourceclaims"). @@ -115,8 +115,8 @@ func (c *resourceClaims) Watch(ctx context.Context, opts v1.ListOptions) (watch. } // Create takes the representation of a resourceClaim and creates it. Returns the server's representation of the resourceClaim, and an error, if there is any. -func (c *resourceClaims) Create(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.CreateOptions) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) Create(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.CreateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Post(). Namespace(c.ns). Resource("resourceclaims"). @@ -128,8 +128,8 @@ func (c *resourceClaims) Create(ctx context.Context, resourceClaim *v1alpha1.Res } // Update takes the representation of a resourceClaim and updates it. Returns the server's representation of the resourceClaim, and an error, if there is any. -func (c *resourceClaims) Update(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) Update(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Put(). Namespace(c.ns). Resource("resourceclaims"). @@ -143,8 +143,8 @@ func (c *resourceClaims) Update(ctx context.Context, resourceClaim *v1alpha1.Res // UpdateStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *resourceClaims) UpdateStatus(ctx context.Context, resourceClaim *v1alpha1.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) UpdateStatus(ctx context.Context, resourceClaim *v1alpha2.ResourceClaim, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Put(). Namespace(c.ns). Resource("resourceclaims"). @@ -185,8 +185,8 @@ func (c *resourceClaims) DeleteCollection(ctx context.Context, opts v1.DeleteOpt } // Patch applies the patch and returns the patched resourceClaim. -func (c *resourceClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaim, err error) { - result = &v1alpha1.ResourceClaim{} +func (c *resourceClaims) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaim, err error) { + result = &v1alpha2.ResourceClaim{} err = c.client.Patch(pt). Namespace(c.ns). Resource("resourceclaims"). @@ -200,7 +200,7 @@ func (c *resourceClaims) Patch(ctx context.Context, name string, pt types.PatchT } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaim. -func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) { if resourceClaim == nil { return nil, fmt.Errorf("resourceClaim provided to Apply must not be nil") } @@ -213,7 +213,7 @@ func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alp if name == nil { return nil, fmt.Errorf("resourceClaim.Name must be provided to Apply") } - result = &v1alpha1.ResourceClaim{} + result = &v1alpha2.ResourceClaim{} err = c.client.Patch(types.ApplyPatchType). Namespace(c.ns). Resource("resourceclaims"). @@ -227,7 +227,7 @@ func (c *resourceClaims) Apply(ctx context.Context, resourceClaim *resourcev1alp // ApplyStatus was generated because the type contains a Status member. // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). -func (c *resourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha1.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaim, err error) { +func (c *resourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourcev1alpha2.ResourceClaimApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaim, err error) { if resourceClaim == nil { return nil, fmt.Errorf("resourceClaim provided to Apply must not be nil") } @@ -242,7 +242,7 @@ func (c *resourceClaims) ApplyStatus(ctx context.Context, resourceClaim *resourc return nil, fmt.Errorf("resourceClaim.Name must be provided to Apply") } - result = &v1alpha1.ResourceClaim{} + result = &v1alpha2.ResourceClaim{} err = c.client.Patch(types.ApplyPatchType). Namespace(c.ns). Resource("resourceclaims"). diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go similarity index 80% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaimtemplate.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go index b6cc3d96e..3f4e32006 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclaimtemplate.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" @@ -24,11 +24,11 @@ import ( "fmt" "time" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" scheme "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) @@ -41,15 +41,15 @@ type ResourceClaimTemplatesGetter interface { // ResourceClaimTemplateInterface has methods to work with ResourceClaimTemplate resources. type ResourceClaimTemplateInterface interface { - Create(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.CreateOptions) (*v1alpha1.ResourceClaimTemplate, error) - Update(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.UpdateOptions) (*v1alpha1.ResourceClaimTemplate, error) + Create(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.CreateOptions) (*v1alpha2.ResourceClaimTemplate, error) + Update(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.UpdateOptions) (*v1alpha2.ResourceClaimTemplate, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ResourceClaimTemplate, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ResourceClaimTemplateList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClaimTemplate, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClaimTemplateList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaimTemplate, err error) - Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaimTemplate, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimTemplate, err error) + Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimTemplate, err error) ResourceClaimTemplateExpansion } @@ -60,7 +60,7 @@ type resourceClaimTemplates struct { } // newResourceClaimTemplates returns a ResourceClaimTemplates -func newResourceClaimTemplates(c *ResourceV1alpha1Client, namespace string) *resourceClaimTemplates { +func newResourceClaimTemplates(c *ResourceV1alpha2Client, namespace string) *resourceClaimTemplates { return &resourceClaimTemplates{ client: c.RESTClient(), ns: namespace, @@ -68,8 +68,8 @@ func newResourceClaimTemplates(c *ResourceV1alpha1Client, namespace string) *res } // Get takes name of the resourceClaimTemplate, and returns the corresponding resourceClaimTemplate object, and an error if there is any. -func (c *resourceClaimTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { - result = &v1alpha1.ResourceClaimTemplate{} +func (c *resourceClaimTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Get(). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -81,12 +81,12 @@ func (c *resourceClaimTemplates) Get(ctx context.Context, name string, options v } // List takes label and field selectors, and returns the list of ResourceClaimTemplates that match those selectors. -func (c *resourceClaimTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClaimTemplateList, err error) { +func (c *resourceClaimTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClaimTemplateList, err error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second } - result = &v1alpha1.ResourceClaimTemplateList{} + result = &v1alpha2.ResourceClaimTemplateList{} err = c.client.Get(). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -113,8 +113,8 @@ func (c *resourceClaimTemplates) Watch(ctx context.Context, opts v1.ListOptions) } // Create takes the representation of a resourceClaimTemplate and creates it. Returns the server's representation of the resourceClaimTemplate, and an error, if there is any. -func (c *resourceClaimTemplates) Create(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.CreateOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { - result = &v1alpha1.ResourceClaimTemplate{} +func (c *resourceClaimTemplates) Create(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.CreateOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Post(). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -126,8 +126,8 @@ func (c *resourceClaimTemplates) Create(ctx context.Context, resourceClaimTempla } // Update takes the representation of a resourceClaimTemplate and updates it. Returns the server's representation of the resourceClaimTemplate, and an error, if there is any. -func (c *resourceClaimTemplates) Update(ctx context.Context, resourceClaimTemplate *v1alpha1.ResourceClaimTemplate, opts v1.UpdateOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { - result = &v1alpha1.ResourceClaimTemplate{} +func (c *resourceClaimTemplates) Update(ctx context.Context, resourceClaimTemplate *v1alpha2.ResourceClaimTemplate, opts v1.UpdateOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Put(). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -167,8 +167,8 @@ func (c *resourceClaimTemplates) DeleteCollection(ctx context.Context, opts v1.D } // Patch applies the patch and returns the patched resourceClaimTemplate. -func (c *resourceClaimTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClaimTemplate, err error) { - result = &v1alpha1.ResourceClaimTemplate{} +func (c *resourceClaimTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClaimTemplate, err error) { + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Patch(pt). Namespace(c.ns). Resource("resourceclaimtemplates"). @@ -182,7 +182,7 @@ func (c *resourceClaimTemplates) Patch(ctx context.Context, name string, pt type } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClaimTemplate. -func (c *resourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha1.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClaimTemplate, err error) { +func (c *resourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplate *resourcev1alpha2.ResourceClaimTemplateApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClaimTemplate, err error) { if resourceClaimTemplate == nil { return nil, fmt.Errorf("resourceClaimTemplate provided to Apply must not be nil") } @@ -195,7 +195,7 @@ func (c *resourceClaimTemplates) Apply(ctx context.Context, resourceClaimTemplat if name == nil { return nil, fmt.Errorf("resourceClaimTemplate.Name must be provided to Apply") } - result = &v1alpha1.ResourceClaimTemplate{} + result = &v1alpha2.ResourceClaimTemplate{} err = c.client.Patch(types.ApplyPatchType). Namespace(c.ns). Resource("resourceclaimtemplates"). diff --git a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclass.go b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go similarity index 80% rename from vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclass.go rename to vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go index 9c8b45463..95a4ac566 100644 --- a/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha1/resourceclass.go +++ b/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha2/resourceclass.go @@ -16,7 +16,7 @@ limitations under the License. // Code generated by client-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( "context" @@ -24,11 +24,11 @@ import ( "fmt" "time" - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" - resourcev1alpha1 "k8s.io/client-go/applyconfigurations/resource/v1alpha1" + resourcev1alpha2 "k8s.io/client-go/applyconfigurations/resource/v1alpha2" scheme "k8s.io/client-go/kubernetes/scheme" rest "k8s.io/client-go/rest" ) @@ -41,15 +41,15 @@ type ResourceClassesGetter interface { // ResourceClassInterface has methods to work with ResourceClass resources. type ResourceClassInterface interface { - Create(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.CreateOptions) (*v1alpha1.ResourceClass, error) - Update(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.UpdateOptions) (*v1alpha1.ResourceClass, error) + Create(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.CreateOptions) (*v1alpha2.ResourceClass, error) + Update(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.UpdateOptions) (*v1alpha2.ResourceClass, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error - Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ResourceClass, error) - List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ResourceClassList, error) + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha2.ResourceClass, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha2.ResourceClassList, error) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClass, err error) - Apply(ctx context.Context, resourceClass *resourcev1alpha1.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClass, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClass, err error) + Apply(ctx context.Context, resourceClass *resourcev1alpha2.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClass, err error) ResourceClassExpansion } @@ -59,15 +59,15 @@ type resourceClasses struct { } // newResourceClasses returns a ResourceClasses -func newResourceClasses(c *ResourceV1alpha1Client) *resourceClasses { +func newResourceClasses(c *ResourceV1alpha2Client) *resourceClasses { return &resourceClasses{ client: c.RESTClient(), } } // Get takes name of the resourceClass, and returns the corresponding resourceClass object, and an error if there is any. -func (c *resourceClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ResourceClass, err error) { - result = &v1alpha1.ResourceClass{} +func (c *resourceClasses) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} err = c.client.Get(). Resource("resourceclasses"). Name(name). @@ -78,12 +78,12 @@ func (c *resourceClasses) Get(ctx context.Context, name string, options v1.GetOp } // List takes label and field selectors, and returns the list of ResourceClasses that match those selectors. -func (c *resourceClasses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ResourceClassList, err error) { +func (c *resourceClasses) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha2.ResourceClassList, err error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second } - result = &v1alpha1.ResourceClassList{} + result = &v1alpha2.ResourceClassList{} err = c.client.Get(). Resource("resourceclasses"). VersionedParams(&opts, scheme.ParameterCodec). @@ -108,8 +108,8 @@ func (c *resourceClasses) Watch(ctx context.Context, opts v1.ListOptions) (watch } // Create takes the representation of a resourceClass and creates it. Returns the server's representation of the resourceClass, and an error, if there is any. -func (c *resourceClasses) Create(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.CreateOptions) (result *v1alpha1.ResourceClass, err error) { - result = &v1alpha1.ResourceClass{} +func (c *resourceClasses) Create(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.CreateOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} err = c.client.Post(). Resource("resourceclasses"). VersionedParams(&opts, scheme.ParameterCodec). @@ -120,8 +120,8 @@ func (c *resourceClasses) Create(ctx context.Context, resourceClass *v1alpha1.Re } // Update takes the representation of a resourceClass and updates it. Returns the server's representation of the resourceClass, and an error, if there is any. -func (c *resourceClasses) Update(ctx context.Context, resourceClass *v1alpha1.ResourceClass, opts v1.UpdateOptions) (result *v1alpha1.ResourceClass, err error) { - result = &v1alpha1.ResourceClass{} +func (c *resourceClasses) Update(ctx context.Context, resourceClass *v1alpha2.ResourceClass, opts v1.UpdateOptions) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} err = c.client.Put(). Resource("resourceclasses"). Name(resourceClass.Name). @@ -158,8 +158,8 @@ func (c *resourceClasses) DeleteCollection(ctx context.Context, opts v1.DeleteOp } // Patch applies the patch and returns the patched resourceClass. -func (c *resourceClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ResourceClass, err error) { - result = &v1alpha1.ResourceClass{} +func (c *resourceClasses) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha2.ResourceClass, err error) { + result = &v1alpha2.ResourceClass{} err = c.client.Patch(pt). Resource("resourceclasses"). Name(name). @@ -172,7 +172,7 @@ func (c *resourceClasses) Patch(ctx context.Context, name string, pt types.Patch } // Apply takes the given apply declarative configuration, applies it and returns the applied resourceClass. -func (c *resourceClasses) Apply(ctx context.Context, resourceClass *resourcev1alpha1.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha1.ResourceClass, err error) { +func (c *resourceClasses) Apply(ctx context.Context, resourceClass *resourcev1alpha2.ResourceClassApplyConfiguration, opts v1.ApplyOptions) (result *v1alpha2.ResourceClass, err error) { if resourceClass == nil { return nil, fmt.Errorf("resourceClass provided to Apply must not be nil") } @@ -185,7 +185,7 @@ func (c *resourceClasses) Apply(ctx context.Context, resourceClass *resourcev1al if name == nil { return nil, fmt.Errorf("resourceClass.Name must be provided to Apply") } - result = &v1alpha1.ResourceClass{} + result = &v1alpha2.ResourceClass{} err = c.client.Patch(types.ApplyPatchType). Resource("resourceclasses"). Name(*name). diff --git a/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go new file mode 100644 index 000000000..b8049a761 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/clustertrustbundle.go @@ -0,0 +1,68 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/certificates/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterTrustBundleLister helps list ClusterTrustBundles. +// All objects returned here must be treated as read-only. +type ClusterTrustBundleLister interface { + // List lists all ClusterTrustBundles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ClusterTrustBundle, err error) + // Get retrieves the ClusterTrustBundle from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ClusterTrustBundle, error) + ClusterTrustBundleListerExpansion +} + +// clusterTrustBundleLister implements the ClusterTrustBundleLister interface. +type clusterTrustBundleLister struct { + indexer cache.Indexer +} + +// NewClusterTrustBundleLister returns a new ClusterTrustBundleLister. +func NewClusterTrustBundleLister(indexer cache.Indexer) ClusterTrustBundleLister { + return &clusterTrustBundleLister{indexer: indexer} +} + +// List lists all ClusterTrustBundles in the indexer. +func (s *clusterTrustBundleLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterTrustBundle, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterTrustBundle)) + }) + return ret, err +} + +// Get retrieves the ClusterTrustBundle from the index for a given name. +func (s *clusterTrustBundleLister) Get(name string) (*v1alpha1.ClusterTrustBundle, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clustertrustbundle"), name) + } + return obj.(*v1alpha1.ClusterTrustBundle), nil +} diff --git a/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go new file mode 100644 index 000000000..d77258cb2 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/certificates/v1alpha1/expansion_generated.go @@ -0,0 +1,23 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// ClusterTrustBundleListerExpansion allows custom methods to be added to +// ClusterTrustBundleLister. +type ClusterTrustBundleListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go index 5599219d9..4c65dbf76 100644 --- a/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/extensions/v1beta1/expansion_generated.go @@ -41,7 +41,3 @@ type NetworkPolicyListerExpansion interface{} // NetworkPolicyNamespaceListerExpansion allows custom methods to be added to // NetworkPolicyNamespaceLister. type NetworkPolicyNamespaceListerExpansion interface{} - -// PodSecurityPolicyListerExpansion allows custom methods to be added to -// PodSecurityPolicyLister. -type PodSecurityPolicyListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go b/vendor/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go deleted file mode 100644 index 5f6a8c036..000000000 --- a/vendor/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v1beta1 - -import ( - v1beta1 "k8s.io/api/extensions/v1beta1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// PodSecurityPolicyLister helps list PodSecurityPolicies. -// All objects returned here must be treated as read-only. -type PodSecurityPolicyLister interface { - // List lists all PodSecurityPolicies in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1beta1.PodSecurityPolicy, err error) - // Get retrieves the PodSecurityPolicy from the index for a given name. - // Objects returned here must be treated as read-only. - Get(name string) (*v1beta1.PodSecurityPolicy, error) - PodSecurityPolicyListerExpansion -} - -// podSecurityPolicyLister implements the PodSecurityPolicyLister interface. -type podSecurityPolicyLister struct { - indexer cache.Indexer -} - -// NewPodSecurityPolicyLister returns a new PodSecurityPolicyLister. -func NewPodSecurityPolicyLister(indexer cache.Indexer) PodSecurityPolicyLister { - return &podSecurityPolicyLister{indexer: indexer} -} - -// List lists all PodSecurityPolicies in the indexer. -func (s *podSecurityPolicyLister) List(selector labels.Selector) (ret []*v1beta1.PodSecurityPolicy, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1beta1.PodSecurityPolicy)) - }) - return ret, err -} - -// Get retrieves the PodSecurityPolicy from the index for a given name. -func (s *podSecurityPolicyLister) Get(name string) (*v1beta1.PodSecurityPolicy, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1beta1.Resource("podsecuritypolicy"), name) - } - return obj.(*v1beta1.PodSecurityPolicy), nil -} diff --git a/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go index cdc328231..d57b71b00 100644 --- a/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/networking/v1alpha1/expansion_generated.go @@ -21,3 +21,7 @@ package v1alpha1 // ClusterCIDRListerExpansion allows custom methods to be added to // ClusterCIDRLister. type ClusterCIDRListerExpansion interface{} + +// IPAddressListerExpansion allows custom methods to be added to +// IPAddressLister. +type IPAddressListerExpansion interface{} diff --git a/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go b/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go new file mode 100644 index 000000000..b3dfe2797 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/networking/v1alpha1/ipaddress.go @@ -0,0 +1,68 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "k8s.io/api/networking/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IPAddressLister helps list IPAddresses. +// All objects returned here must be treated as read-only. +type IPAddressLister interface { + // List lists all IPAddresses in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.IPAddress, err error) + // Get retrieves the IPAddress from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.IPAddress, error) + IPAddressListerExpansion +} + +// iPAddressLister implements the IPAddressLister interface. +type iPAddressLister struct { + indexer cache.Indexer +} + +// NewIPAddressLister returns a new IPAddressLister. +func NewIPAddressLister(indexer cache.Indexer) IPAddressLister { + return &iPAddressLister{indexer: indexer} +} + +// List lists all IPAddresses in the indexer. +func (s *iPAddressLister) List(selector labels.Selector) (ret []*v1alpha1.IPAddress, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.IPAddress)) + }) + return ret, err +} + +// Get retrieves the IPAddress from the index for a given name. +func (s *iPAddressLister) Get(name string) (*v1alpha1.IPAddress, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("ipaddress"), name) + } + return obj.(*v1alpha1.IPAddress), nil +} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/podscheduling.go b/vendor/k8s.io/client-go/listers/resource/v1alpha1/podscheduling.go deleted file mode 100644 index fe4371371..000000000 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/podscheduling.go +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright 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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "k8s.io/api/resource/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// PodSchedulingLister helps list PodSchedulings. -// All objects returned here must be treated as read-only. -type PodSchedulingLister interface { - // List lists all PodSchedulings in the indexer. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.PodScheduling, err error) - // PodSchedulings returns an object that can list and get PodSchedulings. - PodSchedulings(namespace string) PodSchedulingNamespaceLister - PodSchedulingListerExpansion -} - -// podSchedulingLister implements the PodSchedulingLister interface. -type podSchedulingLister struct { - indexer cache.Indexer -} - -// NewPodSchedulingLister returns a new PodSchedulingLister. -func NewPodSchedulingLister(indexer cache.Indexer) PodSchedulingLister { - return &podSchedulingLister{indexer: indexer} -} - -// List lists all PodSchedulings in the indexer. -func (s *podSchedulingLister) List(selector labels.Selector) (ret []*v1alpha1.PodScheduling, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.PodScheduling)) - }) - return ret, err -} - -// PodSchedulings returns an object that can list and get PodSchedulings. -func (s *podSchedulingLister) PodSchedulings(namespace string) PodSchedulingNamespaceLister { - return podSchedulingNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// PodSchedulingNamespaceLister helps list and get PodSchedulings. -// All objects returned here must be treated as read-only. -type PodSchedulingNamespaceLister interface { - // List lists all PodSchedulings in the indexer for a given namespace. - // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.PodScheduling, err error) - // Get retrieves the PodScheduling from the indexer for a given namespace and name. - // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.PodScheduling, error) - PodSchedulingNamespaceListerExpansion -} - -// podSchedulingNamespaceLister implements the PodSchedulingNamespaceLister -// interface. -type podSchedulingNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all PodSchedulings in the indexer for a given namespace. -func (s podSchedulingNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.PodScheduling, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.PodScheduling)) - }) - return ret, err -} - -// Get retrieves the PodScheduling from the indexer for a given namespace and name. -func (s podSchedulingNamespaceLister) Get(name string) (*v1alpha1.PodScheduling, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("podscheduling"), name) - } - return obj.(*v1alpha1.PodScheduling), nil -} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/expansion_generated.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go similarity index 79% rename from vendor/k8s.io/client-go/listers/resource/v1alpha1/expansion_generated.go rename to vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go index 94885e784..3b16e4429 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/expansion_generated.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/expansion_generated.go @@ -16,15 +16,15 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 -// PodSchedulingListerExpansion allows custom methods to be added to -// PodSchedulingLister. -type PodSchedulingListerExpansion interface{} +// PodSchedulingContextListerExpansion allows custom methods to be added to +// PodSchedulingContextLister. +type PodSchedulingContextListerExpansion interface{} -// PodSchedulingNamespaceListerExpansion allows custom methods to be added to -// PodSchedulingNamespaceLister. -type PodSchedulingNamespaceListerExpansion interface{} +// PodSchedulingContextNamespaceListerExpansion allows custom methods to be added to +// PodSchedulingContextNamespaceLister. +type PodSchedulingContextNamespaceListerExpansion interface{} // ResourceClaimListerExpansion allows custom methods to be added to // ResourceClaimLister. diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go new file mode 100644 index 000000000..c50b3f889 --- /dev/null +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/podschedulingcontext.go @@ -0,0 +1,99 @@ +/* +Copyright 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1alpha2 "k8s.io/api/resource/v1alpha2" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PodSchedulingContextLister helps list PodSchedulingContexts. +// All objects returned here must be treated as read-only. +type PodSchedulingContextLister interface { + // List lists all PodSchedulingContexts in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) + // PodSchedulingContexts returns an object that can list and get PodSchedulingContexts. + PodSchedulingContexts(namespace string) PodSchedulingContextNamespaceLister + PodSchedulingContextListerExpansion +} + +// podSchedulingContextLister implements the PodSchedulingContextLister interface. +type podSchedulingContextLister struct { + indexer cache.Indexer +} + +// NewPodSchedulingContextLister returns a new PodSchedulingContextLister. +func NewPodSchedulingContextLister(indexer cache.Indexer) PodSchedulingContextLister { + return &podSchedulingContextLister{indexer: indexer} +} + +// List lists all PodSchedulingContexts in the indexer. +func (s *podSchedulingContextLister) List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.PodSchedulingContext)) + }) + return ret, err +} + +// PodSchedulingContexts returns an object that can list and get PodSchedulingContexts. +func (s *podSchedulingContextLister) PodSchedulingContexts(namespace string) PodSchedulingContextNamespaceLister { + return podSchedulingContextNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PodSchedulingContextNamespaceLister helps list and get PodSchedulingContexts. +// All objects returned here must be treated as read-only. +type PodSchedulingContextNamespaceLister interface { + // List lists all PodSchedulingContexts in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) + // Get retrieves the PodSchedulingContext from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha2.PodSchedulingContext, error) + PodSchedulingContextNamespaceListerExpansion +} + +// podSchedulingContextNamespaceLister implements the PodSchedulingContextNamespaceLister +// interface. +type podSchedulingContextNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PodSchedulingContexts in the indexer for a given namespace. +func (s podSchedulingContextNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.PodSchedulingContext, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha2.PodSchedulingContext)) + }) + return ret, err +} + +// Get retrieves the PodSchedulingContext from the indexer for a given namespace and name. +func (s podSchedulingContextNamespaceLister) Get(name string) (*v1alpha2.PodSchedulingContext, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha2.Resource("podschedulingcontext"), name) + } + return obj.(*v1alpha2.PodSchedulingContext), nil +} diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaim.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go similarity index 84% rename from vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaim.go rename to vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go index 05d5e0cfa..273f16af3 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaim.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaim.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" @@ -30,7 +30,7 @@ import ( type ResourceClaimLister interface { // List lists all ResourceClaims in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClaim, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) // ResourceClaims returns an object that can list and get ResourceClaims. ResourceClaims(namespace string) ResourceClaimNamespaceLister ResourceClaimListerExpansion @@ -47,9 +47,9 @@ func NewResourceClaimLister(indexer cache.Indexer) ResourceClaimLister { } // List lists all ResourceClaims in the indexer. -func (s *resourceClaimLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClaim, err error) { +func (s *resourceClaimLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) { err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClaim)) + ret = append(ret, m.(*v1alpha2.ResourceClaim)) }) return ret, err } @@ -64,10 +64,10 @@ func (s *resourceClaimLister) ResourceClaims(namespace string) ResourceClaimName type ResourceClaimNamespaceLister interface { // List lists all ResourceClaims in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClaim, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) // Get retrieves the ResourceClaim from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.ResourceClaim, error) + Get(name string) (*v1alpha2.ResourceClaim, error) ResourceClaimNamespaceListerExpansion } @@ -79,21 +79,21 @@ type resourceClaimNamespaceLister struct { } // List lists all ResourceClaims in the indexer for a given namespace. -func (s resourceClaimNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClaim, err error) { +func (s resourceClaimNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaim, err error) { err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClaim)) + ret = append(ret, m.(*v1alpha2.ResourceClaim)) }) return ret, err } // Get retrieves the ResourceClaim from the indexer for a given namespace and name. -func (s resourceClaimNamespaceLister) Get(name string) (*v1alpha1.ResourceClaim, error) { +func (s resourceClaimNamespaceLister) Get(name string) (*v1alpha2.ResourceClaim, error) { obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) if err != nil { return nil, err } if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("resourceclaim"), name) + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclaim"), name) } - return obj.(*v1alpha1.ResourceClaim), nil + return obj.(*v1alpha2.ResourceClaim), nil } diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaimtemplate.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go similarity index 84% rename from vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaimtemplate.go rename to vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go index 97acddc7a..91a488b17 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclaimtemplate.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclaimtemplate.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" @@ -30,7 +30,7 @@ import ( type ResourceClaimTemplateLister interface { // List lists all ResourceClaimTemplates in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClaimTemplate, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) // ResourceClaimTemplates returns an object that can list and get ResourceClaimTemplates. ResourceClaimTemplates(namespace string) ResourceClaimTemplateNamespaceLister ResourceClaimTemplateListerExpansion @@ -47,9 +47,9 @@ func NewResourceClaimTemplateLister(indexer cache.Indexer) ResourceClaimTemplate } // List lists all ResourceClaimTemplates in the indexer. -func (s *resourceClaimTemplateLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClaimTemplate, err error) { +func (s *resourceClaimTemplateLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) { err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClaimTemplate)) + ret = append(ret, m.(*v1alpha2.ResourceClaimTemplate)) }) return ret, err } @@ -64,10 +64,10 @@ func (s *resourceClaimTemplateLister) ResourceClaimTemplates(namespace string) R type ResourceClaimTemplateNamespaceLister interface { // List lists all ResourceClaimTemplates in the indexer for a given namespace. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClaimTemplate, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) // Get retrieves the ResourceClaimTemplate from the indexer for a given namespace and name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.ResourceClaimTemplate, error) + Get(name string) (*v1alpha2.ResourceClaimTemplate, error) ResourceClaimTemplateNamespaceListerExpansion } @@ -79,21 +79,21 @@ type resourceClaimTemplateNamespaceLister struct { } // List lists all ResourceClaimTemplates in the indexer for a given namespace. -func (s resourceClaimTemplateNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClaimTemplate, err error) { +func (s resourceClaimTemplateNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClaimTemplate, err error) { err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClaimTemplate)) + ret = append(ret, m.(*v1alpha2.ResourceClaimTemplate)) }) return ret, err } // Get retrieves the ResourceClaimTemplate from the indexer for a given namespace and name. -func (s resourceClaimTemplateNamespaceLister) Get(name string) (*v1alpha1.ResourceClaimTemplate, error) { +func (s resourceClaimTemplateNamespaceLister) Get(name string) (*v1alpha2.ResourceClaimTemplate, error) { obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) if err != nil { return nil, err } if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("resourceclaimtemplate"), name) + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclaimtemplate"), name) } - return obj.(*v1alpha1.ResourceClaimTemplate), nil + return obj.(*v1alpha2.ResourceClaimTemplate), nil } diff --git a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclass.go b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go similarity index 81% rename from vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclass.go rename to vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go index 8d4dbf4d0..eeb2fc337 100644 --- a/vendor/k8s.io/client-go/listers/resource/v1alpha1/resourceclass.go +++ b/vendor/k8s.io/client-go/listers/resource/v1alpha2/resourceclass.go @@ -16,10 +16,10 @@ limitations under the License. // Code generated by lister-gen. DO NOT EDIT. -package v1alpha1 +package v1alpha2 import ( - v1alpha1 "k8s.io/api/resource/v1alpha1" + v1alpha2 "k8s.io/api/resource/v1alpha2" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" @@ -30,10 +30,10 @@ import ( type ResourceClassLister interface { // List lists all ResourceClasses in the indexer. // Objects returned here must be treated as read-only. - List(selector labels.Selector) (ret []*v1alpha1.ResourceClass, err error) + List(selector labels.Selector) (ret []*v1alpha2.ResourceClass, err error) // Get retrieves the ResourceClass from the index for a given name. // Objects returned here must be treated as read-only. - Get(name string) (*v1alpha1.ResourceClass, error) + Get(name string) (*v1alpha2.ResourceClass, error) ResourceClassListerExpansion } @@ -48,21 +48,21 @@ func NewResourceClassLister(indexer cache.Indexer) ResourceClassLister { } // List lists all ResourceClasses in the indexer. -func (s *resourceClassLister) List(selector labels.Selector) (ret []*v1alpha1.ResourceClass, err error) { +func (s *resourceClassLister) List(selector labels.Selector) (ret []*v1alpha2.ResourceClass, err error) { err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.ResourceClass)) + ret = append(ret, m.(*v1alpha2.ResourceClass)) }) return ret, err } // Get retrieves the ResourceClass from the index for a given name. -func (s *resourceClassLister) Get(name string) (*v1alpha1.ResourceClass, error) { +func (s *resourceClassLister) Get(name string) (*v1alpha2.ResourceClass, error) { obj, exists, err := s.indexer.GetByKey(name) if err != nil { return nil, err } if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("resourceclass"), name) + return nil, errors.NewNotFound(v1alpha2.Resource("resourceclass"), name) } - return obj.(*v1alpha1.ResourceClass), nil + return obj.(*v1alpha2.ResourceClass), nil } diff --git a/vendor/k8s.io/client-go/openapi/OWNERS b/vendor/k8s.io/client-go/openapi/OWNERS new file mode 100644 index 000000000..e61009424 --- /dev/null +++ b/vendor/k8s.io/client-go/openapi/OWNERS @@ -0,0 +1,4 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - apelisse diff --git a/vendor/k8s.io/client-go/openapi/client.go b/vendor/k8s.io/client-go/openapi/client.go index 7b58762ac..6a4305718 100644 --- a/vendor/k8s.io/client-go/openapi/client.go +++ b/vendor/k8s.io/client-go/openapi/client.go @@ -19,6 +19,7 @@ package openapi import ( "context" "encoding/json" + "strings" "k8s.io/client-go/rest" "k8s.io/kube-openapi/pkg/handler3" @@ -58,7 +59,11 @@ func (c *client) Paths() (map[string]GroupVersion, error) { // Create GroupVersions for each element of the result result := map[string]GroupVersion{} for k, v := range discoMap.Paths { - result[k] = newGroupVersion(c, v) + // If the server returned a URL rooted at /openapi/v3, preserve any additional client-side prefix. + // If the server returned a URL not rooted at /openapi/v3, treat it as an actual server-relative URL. + // See https://github.com/kubernetes/kubernetes/issues/117463 for details + useClientPrefix := strings.HasPrefix(v.ServerRelativeURL, "/openapi/v3") + result[k] = newGroupVersion(c, v, useClientPrefix) } return result, nil } diff --git a/vendor/k8s.io/client-go/openapi/groupversion.go b/vendor/k8s.io/client-go/openapi/groupversion.go index 32133a29b..601dcbe3c 100644 --- a/vendor/k8s.io/client-go/openapi/groupversion.go +++ b/vendor/k8s.io/client-go/openapi/groupversion.go @@ -18,6 +18,7 @@ package openapi import ( "context" + "net/url" "k8s.io/kube-openapi/pkg/handler3" ) @@ -29,18 +30,41 @@ type GroupVersion interface { } type groupversion struct { - client *client - item handler3.OpenAPIV3DiscoveryGroupVersion + client *client + item handler3.OpenAPIV3DiscoveryGroupVersion + useClientPrefix bool } -func newGroupVersion(client *client, item handler3.OpenAPIV3DiscoveryGroupVersion) *groupversion { - return &groupversion{client: client, item: item} +func newGroupVersion(client *client, item handler3.OpenAPIV3DiscoveryGroupVersion, useClientPrefix bool) *groupversion { + return &groupversion{client: client, item: item, useClientPrefix: useClientPrefix} } func (g *groupversion) Schema(contentType string) ([]byte, error) { - return g.client.restClient.Get(). - RequestURI(g.item.ServerRelativeURL). - SetHeader("Accept", contentType). - Do(context.TODO()). - Raw() + if !g.useClientPrefix { + return g.client.restClient.Get(). + RequestURI(g.item.ServerRelativeURL). + SetHeader("Accept", contentType). + Do(context.TODO()). + Raw() + } + + locator, err := url.Parse(g.item.ServerRelativeURL) + if err != nil { + return nil, err + } + + path := g.client.restClient.Get(). + AbsPath(locator.Path). + SetHeader("Accept", contentType) + + // Other than root endpoints(openapiv3/apis), resources have hash query parameter to support etags. + // However, absPath does not support handling query parameters internally, + // so that hash query parameter is added manually + for k, value := range locator.Query() { + for _, v := range value { + path.Param(k, v) + } + } + + return path.Do(context.TODO()).Raw() } diff --git a/vendor/k8s.io/client-go/pkg/version/base.go b/vendor/k8s.io/client-go/pkg/version/base.go index 51e34dda3..676d51d32 100644 --- a/vendor/k8s.io/client-go/pkg/version/base.go +++ b/vendor/k8s.io/client-go/pkg/version/base.go @@ -43,7 +43,8 @@ var ( gitMinor string = "" // minor version, numeric possibly followed by "+" // semantic version, derived by build scripts (see - // https://git.k8s.io/community/contributors/design-proposals/release/versioning.md + // https://github.com/kubernetes/sig-release/blob/master/release-engineering/versioning.md#kubernetes-release-versioning + // https://kubernetes.io/releases/version-skew-policy/ // for a detailed discussion of this field) // // TODO: This field is still called "gitVersion" for legacy diff --git a/vendor/k8s.io/client-go/rest/client.go b/vendor/k8s.io/client-go/rest/client.go index 2cf821bcd..60df7e568 100644 --- a/vendor/k8s.io/client-go/rest/client.go +++ b/vendor/k8s.io/client-go/rest/client.go @@ -52,8 +52,7 @@ type Interface interface { // ClientContentConfig controls how RESTClient communicates with the server. // // TODO: ContentConfig will be updated to accept a Negotiator instead of a -// -// NegotiatedSerializer and NegotiatedSerializer will be removed. +// NegotiatedSerializer and NegotiatedSerializer will be removed. type ClientContentConfig struct { // AcceptContentTypes specifies the types the client will accept and is optional. // If not set, ContentType will be used to define the Accept header diff --git a/vendor/k8s.io/client-go/rest/request.go b/vendor/k8s.io/client-go/rest/request.go index 96e725692..bb6fb4dec 100644 --- a/vendor/k8s.io/client-go/rest/request.go +++ b/vendor/k8s.io/client-go/rest/request.go @@ -481,7 +481,13 @@ func (r *Request) Body(obj interface{}) *Request { return r } -// URL returns the current working URL. +// Error returns any error encountered constructing the request, if any. +func (r *Request) Error() error { + return r.err +} + +// URL returns the current working URL. Check the result of Error() to ensure +// that the returned URL is valid. func (r *Request) URL() *url.URL { p := r.pathPrefix if r.namespaceSet && len(r.namespace) > 0 { @@ -726,7 +732,6 @@ func (r *Request) Watch(ctx context.Context) (watch.Interface, error) { } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) retry.After(ctx, r, resp, err) if err == nil && resp.StatusCode == http.StatusOK { return r.newStreamWatcher(resp) @@ -786,22 +791,36 @@ func (r *Request) newStreamWatcher(resp *http.Response) (watch.Interface, error) ), nil } -// updateURLMetrics is a convenience function for pushing metrics. -// It also handles corner cases for incomplete/invalid request data. -func updateURLMetrics(ctx context.Context, req *Request, resp *http.Response, err error) { - url := "none" +// updateRequestResultMetric increments the RequestResult metric counter, +// it should be called with the (response, err) tuple from the final +// reply from the server. +func updateRequestResultMetric(ctx context.Context, req *Request, resp *http.Response, err error) { + code, host := sanitize(req, resp, err) + metrics.RequestResult.Increment(ctx, code, req.verb, host) +} + +// updateRequestRetryMetric increments the RequestRetry metric counter, +// it should be called with the (response, err) tuple for each retry +// except for the final attempt. +func updateRequestRetryMetric(ctx context.Context, req *Request, resp *http.Response, err error) { + code, host := sanitize(req, resp, err) + metrics.RequestRetry.IncrementRetry(ctx, code, req.verb, host) +} + +func sanitize(req *Request, resp *http.Response, err error) (string, string) { + host := "none" if req.c.base != nil { - url = req.c.base.Host + host = req.c.base.Host } // Errors can be arbitrary strings. Unbound label cardinality is not suitable for a metric // system so we just report them as ``. - if err != nil { - metrics.RequestResult.Increment(ctx, "", req.verb, url) - } else { - // Metrics for failure codes - metrics.RequestResult.Increment(ctx, strconv.Itoa(resp.StatusCode), req.verb, url) + code := "" + if resp != nil { + code = strconv.Itoa(resp.StatusCode) } + + return code, host } // Stream formats and executes the request, and offers streaming of the response. @@ -834,7 +853,6 @@ func (r *Request) Stream(ctx context.Context) (io.ReadCloser, error) { return nil, err } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) retry.After(ctx, r, resp, err) if err != nil { // we only retry on an HTTP response with 'Retry-After' header @@ -979,7 +997,6 @@ func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Resp return err } resp, err := client.Do(req) - updateURLMetrics(ctx, r, resp, err) // The value -1 or a value of 0 with a non-nil Body indicates that the length is unknown. // https://pkg.go.dev/net/http#Request if req.ContentLength >= 0 && !(req.Body != nil && req.ContentLength == 0) { diff --git a/vendor/k8s.io/client-go/rest/with_retry.go b/vendor/k8s.io/client-go/rest/with_retry.go index 207060a5c..eaaadc6a4 100644 --- a/vendor/k8s.io/client-go/rest/with_retry.go +++ b/vendor/k8s.io/client-go/rest/with_retry.go @@ -242,8 +242,20 @@ func (r *withRetry) After(ctx context.Context, request *Request, resp *http.Resp // parameters calculated from the (response, err) tuple from // attempt N-1, so r.retryAfter is outdated and should not be // referred to here. + isRetry := r.retryAfter != nil r.retryAfter = nil + // the client finishes a single request after N attempts (1..N) + // - all attempts (1..N) are counted to the rest_client_requests_total + // metric (current behavior). + // - every attempt after the first (2..N) are counted to the + // rest_client_request_retries_total metric. + updateRequestResultMetric(ctx, request, resp, err) + if isRetry { + // this is attempt 2 or later + updateRequestRetryMetric(ctx, request, resp, err) + } + if request.c.base != nil { if err != nil { request.backoff.UpdateBackoff(request.URL(), err, 0) @@ -346,8 +358,12 @@ func retryAfterResponse() *http.Response { } func retryAfterResponseWithDelay(delay string) *http.Response { + return retryAfterResponseWithCodeAndDelay(http.StatusInternalServerError, delay) +} + +func retryAfterResponseWithCodeAndDelay(code int, delay string) *http.Response { return &http.Response{ - StatusCode: http.StatusInternalServerError, + StatusCode: code, Header: http.Header{"Retry-After": []string{delay}}, } } diff --git a/vendor/k8s.io/client-go/tools/cache/controller.go b/vendor/k8s.io/client-go/tools/cache/controller.go index 0762da3be..f437f2861 100644 --- a/vendor/k8s.io/client-go/tools/cache/controller.go +++ b/vendor/k8s.io/client-go/tools/cache/controller.go @@ -18,6 +18,7 @@ package cache import ( "errors" + "os" "sync" "time" @@ -50,11 +51,12 @@ type Config struct { Process ProcessFunc // ObjectType is an example object of the type this controller is - // expected to handle. Only the type needs to be right, except - // that when that is `unstructured.Unstructured` the object's - // `"apiVersion"` and `"kind"` must also be right. + // expected to handle. ObjectType runtime.Object + // ObjectDescription is the description to use when logging type-specific information about this controller. + ObjectDescription string + // FullResyncPeriod is the period at which ShouldResync is considered. FullResyncPeriod time.Duration @@ -84,7 +86,7 @@ type Config struct { type ShouldResyncFunc func() bool // ProcessFunc processes a single object. -type ProcessFunc func(obj interface{}) error +type ProcessFunc func(obj interface{}, isInInitialList bool) error // `*controller` implements Controller type controller struct { @@ -131,18 +133,24 @@ func (c *controller) Run(stopCh <-chan struct{}) { <-stopCh c.config.Queue.Close() }() - r := NewReflector( + r := NewReflectorWithOptions( c.config.ListerWatcher, c.config.ObjectType, c.config.Queue, - c.config.FullResyncPeriod, + ReflectorOptions{ + ResyncPeriod: c.config.FullResyncPeriod, + TypeDescription: c.config.ObjectDescription, + Clock: c.clock, + }, ) r.ShouldResync = c.config.ShouldResync r.WatchListPageSize = c.config.WatchListPageSize - r.clock = c.clock if c.config.WatchErrorHandler != nil { r.watchErrorHandler = c.config.WatchErrorHandler } + if s := os.Getenv("ENABLE_CLIENT_GO_WATCH_LIST_ALPHA"); len(s) > 0 { + r.UseWatchList = true + } c.reflectorMutex.Lock() c.reflector = r @@ -211,7 +219,7 @@ func (c *controller) processLoop() { // happen if the watch is closed and misses the delete event and we don't // notice the deletion until the subsequent re-list. type ResourceEventHandler interface { - OnAdd(obj interface{}) + OnAdd(obj interface{}, isInInitialList bool) OnUpdate(oldObj, newObj interface{}) OnDelete(obj interface{}) } @@ -220,6 +228,9 @@ type ResourceEventHandler interface { // as few of the notification functions as you want while still implementing // ResourceEventHandler. This adapter does not remove the prohibition against // modifying the objects. +// +// See ResourceEventHandlerDetailedFuncs if your use needs to propagate +// HasSynced. type ResourceEventHandlerFuncs struct { AddFunc func(obj interface{}) UpdateFunc func(oldObj, newObj interface{}) @@ -227,7 +238,7 @@ type ResourceEventHandlerFuncs struct { } // OnAdd calls AddFunc if it's not nil. -func (r ResourceEventHandlerFuncs) OnAdd(obj interface{}) { +func (r ResourceEventHandlerFuncs) OnAdd(obj interface{}, isInInitialList bool) { if r.AddFunc != nil { r.AddFunc(obj) } @@ -247,6 +258,36 @@ func (r ResourceEventHandlerFuncs) OnDelete(obj interface{}) { } } +// ResourceEventHandlerDetailedFuncs is exactly like ResourceEventHandlerFuncs +// except its AddFunc accepts the isInInitialList parameter, for propagating +// HasSynced. +type ResourceEventHandlerDetailedFuncs struct { + AddFunc func(obj interface{}, isInInitialList bool) + UpdateFunc func(oldObj, newObj interface{}) + DeleteFunc func(obj interface{}) +} + +// OnAdd calls AddFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnAdd(obj interface{}, isInInitialList bool) { + if r.AddFunc != nil { + r.AddFunc(obj, isInInitialList) + } +} + +// OnUpdate calls UpdateFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnUpdate(oldObj, newObj interface{}) { + if r.UpdateFunc != nil { + r.UpdateFunc(oldObj, newObj) + } +} + +// OnDelete calls DeleteFunc if it's not nil. +func (r ResourceEventHandlerDetailedFuncs) OnDelete(obj interface{}) { + if r.DeleteFunc != nil { + r.DeleteFunc(obj) + } +} + // FilteringResourceEventHandler applies the provided filter to all events coming // in, ensuring the appropriate nested handler method is invoked. An object // that starts passing the filter after an update is considered an add, and an @@ -258,11 +299,11 @@ type FilteringResourceEventHandler struct { } // OnAdd calls the nested handler only if the filter succeeds -func (r FilteringResourceEventHandler) OnAdd(obj interface{}) { +func (r FilteringResourceEventHandler) OnAdd(obj interface{}, isInInitialList bool) { if !r.FilterFunc(obj) { return } - r.Handler.OnAdd(obj) + r.Handler.OnAdd(obj, isInInitialList) } // OnUpdate ensures the proper handler is called depending on whether the filter matches @@ -273,7 +314,7 @@ func (r FilteringResourceEventHandler) OnUpdate(oldObj, newObj interface{}) { case newer && older: r.Handler.OnUpdate(oldObj, newObj) case newer && !older: - r.Handler.OnAdd(newObj) + r.Handler.OnAdd(newObj, false) case !newer && older: r.Handler.OnDelete(oldObj) default: @@ -353,17 +394,6 @@ func NewIndexerInformer( return clientState, newInformer(lw, objType, resyncPeriod, h, clientState, nil) } -// TransformFunc allows for transforming an object before it will be processed -// and put into the controller cache and before the corresponding handlers will -// be called on it. -// TransformFunc (similarly to ResourceEventHandler functions) should be able -// to correctly handle the tombstone of type cache.DeletedFinalStateUnknown -// -// The most common usage pattern is to clean-up some parts of the object to -// reduce component memory usage if a given component doesn't care about them. -// given controller doesn't care for them -type TransformFunc func(interface{}) (interface{}, error) - // NewTransformingInformer returns a Store and a controller for populating // the store while also providing event notifications. You should only used // the returned Store for Get/List operations; Add/Modify/Deletes will cause @@ -411,19 +441,12 @@ func processDeltas( // Object which receives event notifications from the given deltas handler ResourceEventHandler, clientState Store, - transformer TransformFunc, deltas Deltas, + isInInitialList bool, ) error { // from oldest to newest for _, d := range deltas { obj := d.Object - if transformer != nil { - var err error - obj, err = transformer(obj) - if err != nil { - return err - } - } switch d.Type { case Sync, Replaced, Added, Updated: @@ -436,7 +459,7 @@ func processDeltas( if err := clientState.Add(obj); err != nil { return err } - handler.OnAdd(obj) + handler.OnAdd(obj, isInInitialList) } case Deleted: if err := clientState.Delete(obj); err != nil { @@ -475,6 +498,7 @@ func newInformer( fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{ KnownObjects: clientState, EmitDeltaTypeReplaced: true, + Transformer: transformer, }) cfg := &Config{ @@ -484,9 +508,9 @@ func newInformer( FullResyncPeriod: resyncPeriod, RetryOnError: false, - Process: func(obj interface{}) error { + Process: func(obj interface{}, isInInitialList bool) error { if deltas, ok := obj.(Deltas); ok { - return processDeltas(h, clientState, transformer, deltas) + return processDeltas(h, clientState, deltas, isInInitialList) } return errors.New("object given as Process argument is not Deltas") }, diff --git a/vendor/k8s.io/client-go/tools/cache/delta_fifo.go b/vendor/k8s.io/client-go/tools/cache/delta_fifo.go index 0c13a41f0..7160bb1ee 100644 --- a/vendor/k8s.io/client-go/tools/cache/delta_fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/delta_fifo.go @@ -51,6 +51,10 @@ type DeltaFIFOOptions struct { // When true, `Replaced` events will be sent for items passed to a Replace() call. // When false, `Sync` events will be sent instead. EmitDeltaTypeReplaced bool + + // If set, will be called for objects before enqueueing them. Please + // see the comment on TransformFunc for details. + Transformer TransformFunc } // DeltaFIFO is like FIFO, but differs in two ways. One is that the @@ -129,8 +133,32 @@ type DeltaFIFO struct { // emitDeltaTypeReplaced is whether to emit the Replaced or Sync // DeltaType when Replace() is called (to preserve backwards compat). emitDeltaTypeReplaced bool + + // Called with every object if non-nil. + transformer TransformFunc } +// TransformFunc allows for transforming an object before it will be processed. +// TransformFunc (similarly to ResourceEventHandler functions) should be able +// to correctly handle the tombstone of type cache.DeletedFinalStateUnknown. +// +// New in v1.27: In such cases, the contained object will already have gone +// through the transform object separately (when it was added / updated prior +// to the delete), so the TransformFunc can likely safely ignore such objects +// (i.e., just return the input object). +// +// The most common usage pattern is to clean-up some parts of the object to +// reduce component memory usage if a given component doesn't care about them. +// +// New in v1.27: unless the object is a DeletedFinalStateUnknown, TransformFunc +// sees the object before any other actor, and it is now safe to mutate the +// object in place instead of making a copy. +// +// Note that TransformFunc is called while inserting objects into the +// notification queue and is therefore extremely performance sensitive; please +// do not do anything that will take a long time. +type TransformFunc func(interface{}) (interface{}, error) + // DeltaType is the type of a change (addition, deletion, etc) type DeltaType string @@ -227,6 +255,7 @@ func NewDeltaFIFOWithOptions(opts DeltaFIFOOptions) *DeltaFIFO { knownObjects: opts.KnownObjects, emitDeltaTypeReplaced: opts.EmitDeltaTypeReplaced, + transformer: opts.Transformer, } f.cond.L = &f.lock return f @@ -271,6 +300,10 @@ func (f *DeltaFIFO) KeyOf(obj interface{}) (string, error) { func (f *DeltaFIFO) HasSynced() bool { f.lock.Lock() defer f.lock.Unlock() + return f.hasSynced_locked() +} + +func (f *DeltaFIFO) hasSynced_locked() bool { return f.populated && f.initialPopulationCount == 0 } @@ -411,6 +444,21 @@ func (f *DeltaFIFO) queueActionLocked(actionType DeltaType, obj interface{}) err if err != nil { return KeyError{obj, err} } + + // Every object comes through this code path once, so this is a good + // place to call the transform func. If obj is a + // DeletedFinalStateUnknown tombstone, then the containted inner object + // will already have gone through the transformer, but we document that + // this can happen. In cases involving Replace(), such an object can + // come through multiple times. + if f.transformer != nil { + var err error + obj, err = f.transformer(obj) + if err != nil { + return err + } + } + oldDeltas := f.items[id] newDeltas := append(oldDeltas, Delta{actionType, obj}) newDeltas = dedupDeltas(newDeltas) @@ -526,6 +574,7 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { f.cond.Wait() } + isInInitialList := !f.hasSynced_locked() id := f.queue[0] f.queue = f.queue[1:] depth := len(f.queue) @@ -551,7 +600,7 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { utiltrace.Field{Key: "Reason", Value: "slow event handlers blocking the queue"}) defer trace.LogIfLong(100 * time.Millisecond) } - err := process(item) + err := process(item, isInInitialList) if e, ok := err.(ErrRequeue); ok { f.addIfNotPresent(id, item) err = e.Err @@ -566,12 +615,11 @@ func (f *DeltaFIFO) Pop(process PopProcessFunc) (interface{}, error) { // using the Sync or Replace DeltaType and then (2) it does some deletions. // In particular: for every pre-existing key K that is not the key of // an object in `list` there is the effect of -// `Delete(DeletedFinalStateUnknown{K, O})` where O is current object -// of K. If `f.knownObjects == nil` then the pre-existing keys are -// those in `f.items` and the current object of K is the `.Newest()` -// of the Deltas associated with K. Otherwise the pre-existing keys -// are those listed by `f.knownObjects` and the current object of K is -// what `f.knownObjects.GetByKey(K)` returns. +// `Delete(DeletedFinalStateUnknown{K, O})` where O is the latest known +// object of K. The pre-existing keys are those in the union set of the keys in +// `f.items` and `f.knownObjects` (if not nil). The last known object for key K is +// the one present in the last delta in `f.items`. If there is no delta for K +// in `f.items`, it is the object in `f.knownObjects` func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { f.lock.Lock() defer f.lock.Unlock() @@ -595,56 +643,54 @@ func (f *DeltaFIFO) Replace(list []interface{}, _ string) error { } } - if f.knownObjects == nil { - // Do deletion detection against our own list. - queuedDeletions := 0 - for k, oldItem := range f.items { + // Do deletion detection against objects in the queue + queuedDeletions := 0 + for k, oldItem := range f.items { + if keys.Has(k) { + continue + } + // Delete pre-existing items not in the new list. + // This could happen if watch deletion event was missed while + // disconnected from apiserver. + var deletedObj interface{} + if n := oldItem.Newest(); n != nil { + deletedObj = n.Object + + // if the previous object is a DeletedFinalStateUnknown, we have to extract the actual Object + if d, ok := deletedObj.(DeletedFinalStateUnknown); ok { + deletedObj = d.Obj + } + } + queuedDeletions++ + if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { + return err + } + } + + if f.knownObjects != nil { + // Detect deletions for objects not present in the queue, but present in KnownObjects + knownKeys := f.knownObjects.ListKeys() + for _, k := range knownKeys { if keys.Has(k) { continue } - // Delete pre-existing items not in the new list. - // This could happen if watch deletion event was missed while - // disconnected from apiserver. - var deletedObj interface{} - if n := oldItem.Newest(); n != nil { - deletedObj = n.Object + if len(f.items[k]) > 0 { + continue + } + + deletedObj, exists, err := f.knownObjects.GetByKey(k) + if err != nil { + deletedObj = nil + klog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k) + } else if !exists { + deletedObj = nil + klog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k) } queuedDeletions++ if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { return err } } - - if !f.populated { - f.populated = true - // While there shouldn't be any queued deletions in the initial - // population of the queue, it's better to be on the safe side. - f.initialPopulationCount = keys.Len() + queuedDeletions - } - - return nil - } - - // Detect deletions not already in the queue. - knownKeys := f.knownObjects.ListKeys() - queuedDeletions := 0 - for _, k := range knownKeys { - if keys.Has(k) { - continue - } - - deletedObj, exists, err := f.knownObjects.GetByKey(k) - if err != nil { - deletedObj = nil - klog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k) - } else if !exists { - deletedObj = nil - klog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k) - } - queuedDeletions++ - if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { - return err - } } if !f.populated { diff --git a/vendor/k8s.io/client-go/tools/cache/fifo.go b/vendor/k8s.io/client-go/tools/cache/fifo.go index 8f3313783..dd13c4ea7 100644 --- a/vendor/k8s.io/client-go/tools/cache/fifo.go +++ b/vendor/k8s.io/client-go/tools/cache/fifo.go @@ -25,7 +25,7 @@ import ( // PopProcessFunc is passed to Pop() method of Queue interface. // It is supposed to process the accumulator popped from the queue. -type PopProcessFunc func(interface{}) error +type PopProcessFunc func(obj interface{}, isInInitialList bool) error // ErrRequeue may be returned by a PopProcessFunc to safely requeue // the current item. The value of Err will be returned from Pop. @@ -82,9 +82,12 @@ type Queue interface { // Pop is helper function for popping from Queue. // WARNING: Do NOT use this function in non-test code to avoid races // unless you really really really really know what you are doing. +// +// NOTE: This function is deprecated and may be removed in the future without +// additional warning. func Pop(queue Queue) interface{} { var result interface{} - queue.Pop(func(obj interface{}) error { + queue.Pop(func(obj interface{}, isInInitialList bool) error { result = obj return nil }) @@ -149,6 +152,10 @@ func (f *FIFO) Close() { func (f *FIFO) HasSynced() bool { f.lock.Lock() defer f.lock.Unlock() + return f.hasSynced_locked() +} + +func (f *FIFO) hasSynced_locked() bool { return f.populated && f.initialPopulationCount == 0 } @@ -287,6 +294,7 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) { f.cond.Wait() } + isInInitialList := !f.hasSynced_locked() id := f.queue[0] f.queue = f.queue[1:] if f.initialPopulationCount > 0 { @@ -298,7 +306,7 @@ func (f *FIFO) Pop(process PopProcessFunc) (interface{}, error) { continue } delete(f.items, id) - err := process(item) + err := process(item, isInInitialList) if e, ok := err.(ErrRequeue); ok { f.addIfNotPresent(id, item) err = e.Err diff --git a/vendor/k8s.io/client-go/tools/cache/reflector.go b/vendor/k8s.io/client-go/tools/cache/reflector.go index 9cd476be8..2b335c104 100644 --- a/vendor/k8s.io/client-go/tools/cache/reflector.go +++ b/vendor/k8s.io/client-go/tools/cache/reflector.go @@ -23,6 +23,7 @@ import ( "io" "math/rand" "reflect" + "strings" "sync" "time" @@ -40,6 +41,7 @@ import ( "k8s.io/client-go/tools/pager" "k8s.io/klog/v2" "k8s.io/utils/clock" + "k8s.io/utils/pointer" "k8s.io/utils/trace" ) @@ -49,12 +51,11 @@ const defaultExpectedTypeName = "" type Reflector struct { // name identifies this reflector. By default it will be a file:line if possible. name string - // The name of the type we expect to place in the store. The name // will be the stringification of expectedGVK if provided, and the // stringification of expectedType otherwise. It is for display // only, and should not be used for parsing or comparison. - expectedTypeName string + typeDescription string // An example object of the type we expect to place in the store. // Only the type needs to be right, except that when that is // `unstructured.Unstructured` the object's `"apiVersion"` and @@ -66,17 +67,11 @@ type Reflector struct { store Store // listerWatcher is used to perform lists and watches. listerWatcher ListerWatcher - // backoff manages backoff of ListWatch backoffManager wait.BackoffManager // initConnBackoffManager manages backoff the initial connection with the Watch call of ListAndWatch. initConnBackoffManager wait.BackoffManager - // MaxInternalErrorRetryDuration defines how long we should retry internal errors returned by watch. - MaxInternalErrorRetryDuration time.Duration - - resyncPeriod time.Duration - // ShouldResync is invoked periodically and whenever it returns `true` the Store's Resync operation is invoked - ShouldResync func() bool + resyncPeriod time.Duration // clock allows tests to manipulate time clock clock.Clock // paginatedResult defines whether pagination should be forced for list calls. @@ -91,6 +86,8 @@ type Reflector struct { isLastSyncResourceVersionUnavailable bool // lastSyncResourceVersionMutex guards read/write access to lastSyncResourceVersion lastSyncResourceVersionMutex sync.RWMutex + // Called whenever the ListAndWatch drops the connection with an error. + watchErrorHandler WatchErrorHandler // WatchListPageSize is the requested chunk size of initial and resync watch lists. // If unset, for consistent reads (RV="") or reads that opt-into arbitrarily old data // (RV="0") it will default to pager.PageSize, for the rest (RV != "" && RV != "0") @@ -99,8 +96,19 @@ type Reflector struct { // etcd, which is significantly less efficient and may lead to serious performance and // scalability problems. WatchListPageSize int64 - // Called whenever the ListAndWatch drops the connection with an error. - watchErrorHandler WatchErrorHandler + // ShouldResync is invoked periodically and whenever it returns `true` the Store's Resync operation is invoked + ShouldResync func() bool + // MaxInternalErrorRetryDuration defines how long we should retry internal errors returned by watch. + MaxInternalErrorRetryDuration time.Duration + // UseWatchList if turned on instructs the reflector to open a stream to bring data from the API server. + // Streaming has the primary advantage of using fewer server's resources to fetch data. + // + // The old behaviour establishes a LIST request which gets data in chunks. + // Paginated list is less efficient and depending on the actual size of objects + // might result in an increased memory consumption of the APIServer. + // + // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list#design-details + UseWatchList bool } // ResourceVersionUpdater is an interface that allows store implementation to @@ -131,13 +139,13 @@ func DefaultWatchErrorHandler(r *Reflector, err error) { // Don't set LastSyncResourceVersionUnavailable - LIST call with ResourceVersion=RV already // has a semantic that it returns data at least as fresh as provided RV. // So first try to LIST with setting RV to resource version of last observed object. - klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.expectedTypeName, err) + klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.typeDescription, err) case err == io.EOF: // watch closed normally case err == io.ErrUnexpectedEOF: - klog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.expectedTypeName, err) + klog.V(1).Infof("%s: Watch for %v closed with unexpected EOF: %v", r.name, r.typeDescription, err) default: - utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.expectedTypeName, err)) + utilruntime.HandleError(fmt.Errorf("%s: Failed to watch %v: %v", r.name, r.typeDescription, err)) } } @@ -155,7 +163,40 @@ func NewNamespaceKeyedIndexerAndReflector(lw ListerWatcher, expectedType interfa return indexer, reflector } -// NewReflector creates a new Reflector object which will keep the +// NewReflector creates a new Reflector with its name defaulted to the closest source_file.go:line in the call stack +// that is outside this package. See NewReflectorWithOptions for further information. +func NewReflector(lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { + return NewReflectorWithOptions(lw, expectedType, store, ReflectorOptions{ResyncPeriod: resyncPeriod}) +} + +// NewNamedReflector creates a new Reflector with the specified name. See NewReflectorWithOptions for further +// information. +func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { + return NewReflectorWithOptions(lw, expectedType, store, ReflectorOptions{Name: name, ResyncPeriod: resyncPeriod}) +} + +// ReflectorOptions configures a Reflector. +type ReflectorOptions struct { + // Name is the Reflector's name. If unset/unspecified, the name defaults to the closest source_file.go:line + // in the call stack that is outside this package. + Name string + + // TypeDescription is the Reflector's type description. If unset/unspecified, the type description is defaulted + // using the following rules: if the expectedType passed to NewReflectorWithOptions was nil, the type description is + // "". If the expectedType is an instance of *unstructured.Unstructured and its apiVersion and kind fields + // are set, the type description is the string encoding of those. Otherwise, the type description is set to the + // go type of expectedType.. + TypeDescription string + + // ResyncPeriod is the Reflector's resync period. If unset/unspecified, the resync period defaults to 0 + // (do not resync). + ResyncPeriod time.Duration + + // Clock allows tests to control time. If unset defaults to clock.RealClock{} + Clock clock.Clock +} + +// NewReflectorWithOptions creates a new Reflector object which will keep the // given store up to date with the server's contents for the given // resource. Reflector promises to only put things in the store that // have the type of expectedType, unless expectedType is nil. If @@ -165,49 +206,74 @@ func NewNamespaceKeyedIndexerAndReflector(lw ListerWatcher, expectedType interfa // "yes". This enables you to use reflectors to periodically process // everything as well as incrementally processing the things that // change. -func NewReflector(lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { - return NewNamedReflector(naming.GetNameFromCallsite(internalPackages...), lw, expectedType, store, resyncPeriod) -} - -// NewNamedReflector same as NewReflector, but with a specified name for logging -func NewNamedReflector(name string, lw ListerWatcher, expectedType interface{}, store Store, resyncPeriod time.Duration) *Reflector { - realClock := &clock.RealClock{} +func NewReflectorWithOptions(lw ListerWatcher, expectedType interface{}, store Store, options ReflectorOptions) *Reflector { + reflectorClock := options.Clock + if reflectorClock == nil { + reflectorClock = clock.RealClock{} + } r := &Reflector{ - name: name, - listerWatcher: lw, - store: store, + name: options.Name, + resyncPeriod: options.ResyncPeriod, + typeDescription: options.TypeDescription, + listerWatcher: lw, + store: store, // We used to make the call every 1sec (1 QPS), the goal here is to achieve ~98% traffic reduction when // API server is not healthy. With these parameters, backoff will stop at [30,60) sec interval which is // 0.22 QPS. If we don't backoff for 2min, assume API server is healthy and we reset the backoff. - backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, realClock), - initConnBackoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, realClock), - resyncPeriod: resyncPeriod, - clock: realClock, + backoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock), + initConnBackoffManager: wait.NewExponentialBackoffManager(800*time.Millisecond, 30*time.Second, 2*time.Minute, 2.0, 1.0, reflectorClock), + clock: reflectorClock, watchErrorHandler: WatchErrorHandler(DefaultWatchErrorHandler), + expectedType: reflect.TypeOf(expectedType), } - r.setExpectedType(expectedType) + + if r.name == "" { + r.name = naming.GetNameFromCallsite(internalPackages...) + } + + if r.typeDescription == "" { + r.typeDescription = getTypeDescriptionFromObject(expectedType) + } + + if r.expectedGVK == nil { + r.expectedGVK = getExpectedGVKFromObject(expectedType) + } + return r } -func (r *Reflector) setExpectedType(expectedType interface{}) { - r.expectedType = reflect.TypeOf(expectedType) - if r.expectedType == nil { - r.expectedTypeName = defaultExpectedTypeName - return +func getTypeDescriptionFromObject(expectedType interface{}) string { + if expectedType == nil { + return defaultExpectedTypeName } - r.expectedTypeName = r.expectedType.String() + reflectDescription := reflect.TypeOf(expectedType).String() - if obj, ok := expectedType.(*unstructured.Unstructured); ok { - // Use gvk to check that watch event objects are of the desired type. - gvk := obj.GroupVersionKind() - if gvk.Empty() { - klog.V(4).Infof("Reflector from %s configured with expectedType of *unstructured.Unstructured with empty GroupVersionKind.", r.name) - return - } - r.expectedGVK = &gvk - r.expectedTypeName = gvk.String() + obj, ok := expectedType.(*unstructured.Unstructured) + if !ok { + return reflectDescription } + + gvk := obj.GroupVersionKind() + if gvk.Empty() { + return reflectDescription + } + + return gvk.String() +} + +func getExpectedGVKFromObject(expectedType interface{}) *schema.GroupVersionKind { + obj, ok := expectedType.(*unstructured.Unstructured) + if !ok { + return nil + } + + gvk := obj.GroupVersionKind() + if gvk.Empty() { + return nil + } + + return &gvk } // internalPackages are packages that ignored when creating a default reflector name. These packages are in the common @@ -218,13 +284,13 @@ var internalPackages = []string{"client-go/tools/cache/"} // objects and subsequent deltas. // Run will exit when stopCh is closed. func (r *Reflector) Run(stopCh <-chan struct{}) { - klog.V(3).Infof("Starting reflector %s (%s) from %s", r.expectedTypeName, r.resyncPeriod, r.name) + klog.V(3).Infof("Starting reflector %s (%s) from %s", r.typeDescription, r.resyncPeriod, r.name) wait.BackoffUntil(func() { if err := r.ListAndWatch(stopCh); err != nil { r.watchErrorHandler(r, err) } }, r.backoffManager, true, stopCh) - klog.V(3).Infof("Stopping reflector %s (%s) from %s", r.expectedTypeName, r.resyncPeriod, r.name) + klog.V(3).Infof("Stopping reflector %s (%s) from %s", r.typeDescription, r.resyncPeriod, r.name) } var ( @@ -254,42 +320,75 @@ func (r *Reflector) resyncChan() (<-chan time.Time, func() bool) { // and then use the resource version to watch. // It returns error if ListAndWatch didn't even try to initialize watch. func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { - klog.V(3).Infof("Listing and watching %v from %s", r.expectedTypeName, r.name) + klog.V(3).Infof("Listing and watching %v from %s", r.typeDescription, r.name) + var err error + var w watch.Interface + fallbackToList := !r.UseWatchList - err := r.list(stopCh) - if err != nil { - return err + if r.UseWatchList { + w, err = r.watchList(stopCh) + if w == nil && err == nil { + // stopCh was closed + return nil + } + if err != nil { + if !apierrors.IsInvalid(err) { + return err + } + klog.Warning("the watch-list feature is not supported by the server, falling back to the previous LIST/WATCH semantic") + fallbackToList = true + // Ensure that we won't accidentally pass some garbage down the watch. + w = nil + } + } + + if fallbackToList { + err = r.list(stopCh) + if err != nil { + return err + } } resyncerrc := make(chan error, 1) cancelCh := make(chan struct{}) defer close(cancelCh) - go func() { - resyncCh, cleanup := r.resyncChan() - defer func() { - cleanup() // Call the last one written into cleanup - }() - for { - select { - case <-resyncCh: - case <-stopCh: - return - case <-cancelCh: - return - } - if r.ShouldResync == nil || r.ShouldResync() { - klog.V(4).Infof("%s: forcing resync", r.name) - if err := r.store.Resync(); err != nil { - resyncerrc <- err - return - } - } - cleanup() - resyncCh, cleanup = r.resyncChan() - } - }() + go r.startResync(stopCh, cancelCh, resyncerrc) + return r.watch(w, stopCh, resyncerrc) +} +// startResync periodically calls r.store.Resync() method. +// Note that this method is blocking and should be +// called in a separate goroutine. +func (r *Reflector) startResync(stopCh <-chan struct{}, cancelCh <-chan struct{}, resyncerrc chan error) { + resyncCh, cleanup := r.resyncChan() + defer func() { + cleanup() // Call the last one written into cleanup + }() + for { + select { + case <-resyncCh: + case <-stopCh: + return + case <-cancelCh: + return + } + if r.ShouldResync == nil || r.ShouldResync() { + klog.V(4).Infof("%s: forcing resync", r.name) + if err := r.store.Resync(); err != nil { + resyncerrc <- err + return + } + } + cleanup() + resyncCh, cleanup = r.resyncChan() + } +} + +// watch simply starts a watch request with the server. +func (r *Reflector) watch(w watch.Interface, stopCh <-chan struct{}, resyncerrc chan error) error { + var err error retry := NewRetryWithDeadline(r.MaxInternalErrorRetryDuration, time.Minute, apierrors.IsInternalError, r.clock) + for { // give the stopCh a chance to stop the loop, even in case of continue statements further down on errors select { @@ -298,35 +397,41 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { default: } - timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) - options := metav1.ListOptions{ - ResourceVersion: r.LastSyncResourceVersion(), - // We want to avoid situations of hanging watchers. Stop any watchers that do not - // receive any events within the timeout window. - TimeoutSeconds: &timeoutSeconds, - // To reduce load on kube-apiserver on watch restarts, you may enable watch bookmarks. - // Reflector doesn't assume bookmarks are returned at all (if the server do not support - // watch bookmarks, it will ignore this field). - AllowWatchBookmarks: true, - } - // start the clock before sending the request, since some proxies won't flush headers until after the first watch event is sent start := r.clock.Now() - w, err := r.listerWatcher.Watch(options) - if err != nil { - // If this is "connection refused" error, it means that most likely apiserver is not responsive. - // It doesn't make sense to re-list all objects because most likely we will be able to restart - // watch where we ended. - // If that's the case begin exponentially backing off and resend watch request. - // Do the same for "429" errors. - if utilnet.IsConnectionRefused(err) || apierrors.IsTooManyRequests(err) { - <-r.initConnBackoffManager.Backoff().C() - continue + + if w == nil { + timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + options := metav1.ListOptions{ + ResourceVersion: r.LastSyncResourceVersion(), + // We want to avoid situations of hanging watchers. Stop any watchers that do not + // receive any events within the timeout window. + TimeoutSeconds: &timeoutSeconds, + // To reduce load on kube-apiserver on watch restarts, you may enable watch bookmarks. + // Reflector doesn't assume bookmarks are returned at all (if the server do not support + // watch bookmarks, it will ignore this field). + AllowWatchBookmarks: true, + } + + w, err = r.listerWatcher.Watch(options) + if err != nil { + if canRetry := isWatchErrorRetriable(err); canRetry { + klog.V(4).Infof("%s: watch of %v returned %v - backing off", r.name, r.typeDescription, err) + select { + case <-stopCh: + return nil + case <-r.initConnBackoffManager.Backoff().C(): + continue + } + } + return err } - return err } - err = watchHandler(start, w, r.store, r.expectedType, r.expectedGVK, r.name, r.expectedTypeName, r.setLastSyncResourceVersion, r.clock, resyncerrc, stopCh) + err = watchHandler(start, w, r.store, r.expectedType, r.expectedGVK, r.name, r.typeDescription, r.setLastSyncResourceVersion, nil, r.clock, resyncerrc, stopCh) + // Ensure that watch will not be reused across iterations. + w.Stop() + w = nil retry.After(err) if err != nil { if err != errorStopRequested { @@ -335,16 +440,20 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error { // Don't set LastSyncResourceVersionUnavailable - LIST call with ResourceVersion=RV already // has a semantic that it returns data at least as fresh as provided RV. // So first try to LIST with setting RV to resource version of last observed object. - klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.expectedTypeName, err) + klog.V(4).Infof("%s: watch of %v closed with: %v", r.name, r.typeDescription, err) case apierrors.IsTooManyRequests(err): - klog.V(2).Infof("%s: watch of %v returned 429 - backing off", r.name, r.expectedTypeName) - <-r.initConnBackoffManager.Backoff().C() - continue + klog.V(2).Infof("%s: watch of %v returned 429 - backing off", r.name, r.typeDescription) + select { + case <-stopCh: + return nil + case <-r.initConnBackoffManager.Backoff().C(): + continue + } case apierrors.IsInternalError(err) && retry.ShouldRetry(): - klog.V(2).Infof("%s: retrying watch of %v internal error: %v", r.name, r.expectedTypeName, err) + klog.V(2).Infof("%s: retrying watch of %v internal error: %v", r.name, r.typeDescription, err) continue default: - klog.Warningf("%s: watch of %v ended with: %v", r.name, r.expectedTypeName, err) + klog.Warningf("%s: watch of %v ended with: %v", r.name, r.typeDescription, err) } } return nil @@ -421,8 +530,8 @@ func (r *Reflector) list(stopCh <-chan struct{}) error { } initTrace.Step("Objects listed", trace.Field{Key: "error", Value: err}) if err != nil { - klog.Warningf("%s: failed to list %v: %v", r.name, r.expectedTypeName, err) - return fmt.Errorf("failed to list %v: %w", r.expectedTypeName, err) + klog.Warningf("%s: failed to list %v: %v", r.name, r.typeDescription, err) + return fmt.Errorf("failed to list %v: %w", r.typeDescription, err) } // We check if the list was paginated and if so set the paginatedResult based on that. @@ -460,6 +569,114 @@ func (r *Reflector) list(stopCh <-chan struct{}) error { return nil } +// watchList establishes a stream to get a consistent snapshot of data +// from the server as described in https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list#proposal +// +// case 1: start at Most Recent (RV="", ResourceVersionMatch=ResourceVersionMatchNotOlderThan) +// Establishes a consistent stream with the server. +// That means the returned data is consistent, as if, served directly from etcd via a quorum read. +// It begins with synthetic "Added" events of all resources up to the most recent ResourceVersion. +// It ends with a synthetic "Bookmark" event containing the most recent ResourceVersion. +// After receiving a "Bookmark" event the reflector is considered to be synchronized. +// It replaces its internal store with the collected items and +// reuses the current watch requests for getting further events. +// +// case 2: start at Exact (RV>"0", ResourceVersionMatch=ResourceVersionMatchNotOlderThan) +// Establishes a stream with the server at the provided resource version. +// To establish the initial state the server begins with synthetic "Added" events. +// It ends with a synthetic "Bookmark" event containing the provided or newer resource version. +// After receiving a "Bookmark" event the reflector is considered to be synchronized. +// It replaces its internal store with the collected items and +// reuses the current watch requests for getting further events. +func (r *Reflector) watchList(stopCh <-chan struct{}) (watch.Interface, error) { + var w watch.Interface + var err error + var temporaryStore Store + var resourceVersion string + // TODO(#115478): see if this function could be turned + // into a method and see if error handling + // could be unified with the r.watch method + isErrorRetriableWithSideEffectsFn := func(err error) bool { + if canRetry := isWatchErrorRetriable(err); canRetry { + klog.V(2).Infof("%s: watch-list of %v returned %v - backing off", r.name, r.typeDescription, err) + <-r.initConnBackoffManager.Backoff().C() + return true + } + if isExpiredError(err) || isTooLargeResourceVersionError(err) { + // we tried to re-establish a watch request but the provided RV + // has either expired or it is greater than the server knows about. + // In that case we reset the RV and + // try to get a consistent snapshot from the watch cache (case 1) + r.setIsLastSyncResourceVersionUnavailable(true) + return true + } + return false + } + + initTrace := trace.New("Reflector WatchList", trace.Field{Key: "name", Value: r.name}) + defer initTrace.LogIfLong(10 * time.Second) + for { + select { + case <-stopCh: + return nil, nil + default: + } + + resourceVersion = "" + lastKnownRV := r.rewatchResourceVersion() + temporaryStore = NewStore(DeletionHandlingMetaNamespaceKeyFunc) + // TODO(#115478): large "list", slow clients, slow network, p&f + // might slow down streaming and eventually fail. + // maybe in such a case we should retry with an increased timeout? + timeoutSeconds := int64(minWatchTimeout.Seconds() * (rand.Float64() + 1.0)) + options := metav1.ListOptions{ + ResourceVersion: lastKnownRV, + AllowWatchBookmarks: true, + SendInitialEvents: pointer.Bool(true), + ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, + TimeoutSeconds: &timeoutSeconds, + } + start := r.clock.Now() + + w, err = r.listerWatcher.Watch(options) + if err != nil { + if isErrorRetriableWithSideEffectsFn(err) { + continue + } + return nil, err + } + bookmarkReceived := pointer.Bool(false) + err = watchHandler(start, w, temporaryStore, r.expectedType, r.expectedGVK, r.name, r.typeDescription, + func(rv string) { resourceVersion = rv }, + bookmarkReceived, + r.clock, make(chan error), stopCh) + if err != nil { + w.Stop() // stop and retry with clean state + if err == errorStopRequested { + return nil, nil + } + if isErrorRetriableWithSideEffectsFn(err) { + continue + } + return nil, err + } + if *bookmarkReceived { + break + } + } + // We successfully got initial state from watch-list confirmed by the + // "k8s.io/initial-events-end" bookmark. + initTrace.Step("Objects streamed", trace.Field{Key: "count", Value: len(temporaryStore.List())}) + r.setIsLastSyncResourceVersionUnavailable(false) + if err = r.store.Replace(temporaryStore.List(), resourceVersion); err != nil { + return nil, fmt.Errorf("unable to sync watch-list result: %v", err) + } + initTrace.Step("SyncWith done") + r.setLastSyncResourceVersion(resourceVersion) + + return w, nil +} + // syncWith replaces the store's items with the given list. func (r *Reflector) syncWith(items []runtime.Object, resourceVersion string) error { found := make([]interface{}, 0, len(items)) @@ -478,15 +695,17 @@ func watchHandler(start time.Time, name string, expectedTypeName string, setLastSyncResourceVersion func(string), + exitOnInitialEventsEndBookmark *bool, clock clock.Clock, errc chan error, stopCh <-chan struct{}, ) error { eventCount := 0 - - // Stopping the watcher should be idempotent and if we return from this function there's no way - // we're coming back in with the same watch interface. - defer w.Stop() + if exitOnInitialEventsEndBookmark != nil { + // set it to false just in case somebody + // made it positive + *exitOnInitialEventsEndBookmark = false + } loop: for { @@ -541,6 +760,11 @@ loop: } case watch.Bookmark: // A `Bookmark` means watch has synced here, just update the resourceVersion + if _, ok := meta.GetAnnotations()["k8s.io/initial-events-end"]; ok { + if exitOnInitialEventsEndBookmark != nil { + *exitOnInitialEventsEndBookmark = true + } + } default: utilruntime.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", name, event)) } @@ -549,6 +773,11 @@ loop: rvu.UpdateResourceVersion(resourceVersion) } eventCount++ + if exitOnInitialEventsEndBookmark != nil && *exitOnInitialEventsEndBookmark { + watchDuration := clock.Since(start) + klog.V(4).Infof("exiting %v Watch because received the bookmark that marks the end of initial events stream, total %v items received in %v", name, eventCount, watchDuration) + return nil + } } } @@ -597,6 +826,18 @@ func (r *Reflector) relistResourceVersion() string { return r.lastSyncResourceVersion } +// rewatchResourceVersion determines the resource version the reflector should start streaming from. +func (r *Reflector) rewatchResourceVersion() string { + r.lastSyncResourceVersionMutex.RLock() + defer r.lastSyncResourceVersionMutex.RUnlock() + if r.isLastSyncResourceVersionUnavailable { + // initial stream should return data at the most recent resource version. + // the returned data must be consistent i.e. as if served from etcd via a quorum read + return "" + } + return r.lastSyncResourceVersion +} + // setIsLastSyncResourceVersionUnavailable sets if the last list or watch request with lastSyncResourceVersion returned // "expired" or "too large resource version" error. func (r *Reflector) setIsLastSyncResourceVersionUnavailable(isUnavailable bool) { @@ -635,5 +876,25 @@ func isTooLargeResourceVersionError(err error) bool { return true } } + + // Matches the message returned by api server before 1.17.0 + if strings.Contains(apierr.Status().Message, "Too large resource version") { + return true + } + + return false +} + +// isWatchErrorRetriable determines if it is safe to retry +// a watch error retrieved from the server. +func isWatchErrorRetriable(err error) bool { + // If this is "connection refused" error, it means that most likely apiserver is not responsive. + // It doesn't make sense to re-list all objects because most likely we will be able to restart + // watch where we ended. + // If that's the case begin exponentially backing off and resend watch request. + // Do the same for "429" errors. + if utilnet.IsConnectionRefused(err) || apierrors.IsTooManyRequests(err) { + return true + } return false } diff --git a/vendor/k8s.io/client-go/tools/cache/shared_informer.go b/vendor/k8s.io/client-go/tools/cache/shared_informer.go index f5c7316a1..a889fdbc3 100644 --- a/vendor/k8s.io/client-go/tools/cache/shared_informer.go +++ b/vendor/k8s.io/client-go/tools/cache/shared_informer.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache/synctrack" "k8s.io/utils/buffer" "k8s.io/utils/clock" @@ -132,11 +133,13 @@ import ( // state, except that its ResourceVersion is replaced with a // ResourceVersion in which the object is actually absent. type SharedInformer interface { - // AddEventHandler adds an event handler to the shared informer using the shared informer's resync - // period. Events to a single handler are delivered sequentially, but there is no coordination - // between different handlers. - // It returns a registration handle for the handler that can be used to remove - // the handler again. + // AddEventHandler adds an event handler to the shared informer using + // the shared informer's resync period. Events to a single handler are + // delivered sequentially, but there is no coordination between + // different handlers. + // It returns a registration handle for the handler that can be used to + // remove the handler again, or to tell if the handler is synced (has + // seen every item in the initial list). AddEventHandler(handler ResourceEventHandler) (ResourceEventHandlerRegistration, error) // AddEventHandlerWithResyncPeriod adds an event handler to the // shared informer with the requested resync period; zero means @@ -169,6 +172,10 @@ type SharedInformer interface { // HasSynced returns true if the shared informer's store has been // informed by at least one full LIST of the authoritative state // of the informer's object collection. This is unrelated to "resync". + // + // Note that this doesn't tell you if an individual handler is synced!! + // For that, please call HasSynced on the handle returned by + // AddEventHandler. HasSynced() bool // LastSyncResourceVersion is the resource version observed when last synced with the underlying // store. The value returned is not synchronized with access to the underlying store and is not @@ -198,10 +205,7 @@ type SharedInformer interface { // // Must be set before starting the informer. // - // Note: Since the object given to the handler may be already shared with - // other goroutines, it is advisable to copy the object being - // transform before mutating it at all and returning the copy to prevent - // data races. + // Please see the comment on TransformFunc for more details. SetTransform(handler TransformFunc) error // IsStopped reports whether the informer has already been stopped. @@ -213,7 +217,14 @@ type SharedInformer interface { // Opaque interface representing the registration of ResourceEventHandler for // a SharedInformer. Must be supplied back to the same SharedInformer's // `RemoveEventHandler` to unregister the handlers. -type ResourceEventHandlerRegistration interface{} +// +// Also used to tell if the handler is synced (has had all items in the initial +// list delivered). +type ResourceEventHandlerRegistration interface { + // HasSynced reports if both the parent has synced and all pre-sync + // events have been delivered. + HasSynced() bool +} // SharedIndexInformer provides add and get Indexers ability based on SharedInformer. type SharedIndexInformer interface { @@ -223,14 +234,26 @@ type SharedIndexInformer interface { GetIndexer() Indexer } -// NewSharedInformer creates a new instance for the listwatcher. +// NewSharedInformer creates a new instance for the ListerWatcher. See NewSharedIndexInformerWithOptions for full details. func NewSharedInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration) SharedInformer { return NewSharedIndexInformer(lw, exampleObject, defaultEventHandlerResyncPeriod, Indexers{}) } -// NewSharedIndexInformer creates a new instance for the listwatcher. -// The created informer will not do resyncs if the given -// defaultEventHandlerResyncPeriod is zero. Otherwise: for each +// NewSharedIndexInformer creates a new instance for the ListerWatcher and specified Indexers. See +// NewSharedIndexInformerWithOptions for full details. +func NewSharedIndexInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration, indexers Indexers) SharedIndexInformer { + return NewSharedIndexInformerWithOptions( + lw, + exampleObject, + SharedIndexInformerOptions{ + ResyncPeriod: defaultEventHandlerResyncPeriod, + Indexers: indexers, + }, + ) +} + +// NewSharedIndexInformerWithOptions creates a new instance for the ListerWatcher. +// The created informer will not do resyncs if options.ResyncPeriod is zero. Otherwise: for each // handler that with a non-zero requested resync period, whether added // before or after the informer starts, the nominal resync period is // the requested resync period rounded up to a multiple of the @@ -238,21 +261,36 @@ func NewSharedInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEv // checking period is established when the informer starts running, // and is the maximum of (a) the minimum of the resync periods // requested before the informer starts and the -// defaultEventHandlerResyncPeriod given here and (b) the constant +// options.ResyncPeriod given here and (b) the constant // `minimumResyncPeriod` defined in this file. -func NewSharedIndexInformer(lw ListerWatcher, exampleObject runtime.Object, defaultEventHandlerResyncPeriod time.Duration, indexers Indexers) SharedIndexInformer { +func NewSharedIndexInformerWithOptions(lw ListerWatcher, exampleObject runtime.Object, options SharedIndexInformerOptions) SharedIndexInformer { realClock := &clock.RealClock{} - sharedIndexInformer := &sharedIndexInformer{ + + return &sharedIndexInformer{ + indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, options.Indexers), processor: &sharedProcessor{clock: realClock}, - indexer: NewIndexer(DeletionHandlingMetaNamespaceKeyFunc, indexers), listerWatcher: lw, objectType: exampleObject, - resyncCheckPeriod: defaultEventHandlerResyncPeriod, - defaultEventHandlerResyncPeriod: defaultEventHandlerResyncPeriod, - cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", exampleObject)), + objectDescription: options.ObjectDescription, + resyncCheckPeriod: options.ResyncPeriod, + defaultEventHandlerResyncPeriod: options.ResyncPeriod, clock: realClock, + cacheMutationDetector: NewCacheMutationDetector(fmt.Sprintf("%T", exampleObject)), } - return sharedIndexInformer +} + +// SharedIndexInformerOptions configures a sharedIndexInformer. +type SharedIndexInformerOptions struct { + // ResyncPeriod is the default event handler resync period and resync check + // period. If unset/unspecified, these are defaulted to 0 (do not resync). + ResyncPeriod time.Duration + + // Indexers is the sharedIndexInformer's indexers. If unset/unspecified, no indexers are configured. + Indexers Indexers + + // ObjectDescription is the sharedIndexInformer's object description. This is passed through to the + // underlying Reflector's type description. + ObjectDescription string } // InformerSynced is a function that can be used to determine if an informer has synced. This is useful for determining if caches have synced. @@ -326,12 +364,13 @@ type sharedIndexInformer struct { listerWatcher ListerWatcher - // objectType is an example object of the type this informer is - // expected to handle. Only the type needs to be right, except - // that when that is `unstructured.Unstructured` the object's - // `"apiVersion"` and `"kind"` must also be right. + // objectType is an example object of the type this informer is expected to handle. If set, an event + // with an object with a mismatching type is dropped instead of being delivered to listeners. objectType runtime.Object + // objectDescription is the description of this informer's objects. This typically defaults to + objectDescription string + // resyncCheckPeriod is how often we want the reflector's resync timer to fire so it can call // shouldResync to check if any of our listeners need a resync. resyncCheckPeriod time.Duration @@ -381,7 +420,8 @@ type updateNotification struct { } type addNotification struct { - newObj interface{} + newObj interface{} + isInInitialList bool } type deleteNotification struct { @@ -422,15 +462,17 @@ func (s *sharedIndexInformer) Run(stopCh <-chan struct{}) { fifo := NewDeltaFIFOWithOptions(DeltaFIFOOptions{ KnownObjects: s.indexer, EmitDeltaTypeReplaced: true, + Transformer: s.transform, }) cfg := &Config{ - Queue: fifo, - ListerWatcher: s.listerWatcher, - ObjectType: s.objectType, - FullResyncPeriod: s.resyncCheckPeriod, - RetryOnError: false, - ShouldResync: s.processor.shouldResync, + Queue: fifo, + ListerWatcher: s.listerWatcher, + ObjectType: s.objectType, + ObjectDescription: s.objectDescription, + FullResyncPeriod: s.resyncCheckPeriod, + RetryOnError: false, + ShouldResync: s.processor.shouldResync, Process: s.HandleDeltas, WatchErrorHandler: s.watchErrorHandler, @@ -559,7 +601,7 @@ func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEv } } - listener := newProcessListener(handler, resyncPeriod, determineResyncPeriod(resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize) + listener := newProcessListener(handler, resyncPeriod, determineResyncPeriod(resyncPeriod, s.resyncCheckPeriod), s.clock.Now(), initialBufferSize, s.HasSynced) if !s.started { return s.processor.addListener(listener), nil @@ -575,27 +617,35 @@ func (s *sharedIndexInformer) AddEventHandlerWithResyncPeriod(handler ResourceEv handle := s.processor.addListener(listener) for _, item := range s.indexer.List() { - listener.add(addNotification{newObj: item}) + // Note that we enqueue these notifications with the lock held + // and before returning the handle. That means there is never a + // chance for anyone to call the handle's HasSynced method in a + // state when it would falsely return true (i.e., when the + // shared informer is synced but it has not observed an Add + // with isInitialList being true, nor when the thread + // processing notifications somehow goes faster than this + // thread adding them and the counter is temporarily zero). + listener.add(addNotification{newObj: item, isInInitialList: true}) } return handle, nil } -func (s *sharedIndexInformer) HandleDeltas(obj interface{}) error { +func (s *sharedIndexInformer) HandleDeltas(obj interface{}, isInInitialList bool) error { s.blockDeltas.Lock() defer s.blockDeltas.Unlock() if deltas, ok := obj.(Deltas); ok { - return processDeltas(s, s.indexer, s.transform, deltas) + return processDeltas(s, s.indexer, deltas, isInInitialList) } return errors.New("object given as Process argument is not Deltas") } // Conforms to ResourceEventHandler -func (s *sharedIndexInformer) OnAdd(obj interface{}) { +func (s *sharedIndexInformer) OnAdd(obj interface{}, isInInitialList bool) { // Invocation of this function is locked under s.blockDeltas, so it is // save to distribute the notification s.cacheMutationDetector.AddObject(obj) - s.processor.distribute(addNotification{newObj: obj}, false) + s.processor.distribute(addNotification{newObj: obj, isInInitialList: isInInitialList}, false) } // Conforms to ResourceEventHandler @@ -817,6 +867,8 @@ type processorListener struct { handler ResourceEventHandler + syncTracker *synctrack.SingleFileTracker + // pendingNotifications is an unbounded ring buffer that holds all notifications not yet distributed. // There is one per listener, but a failing/stalled listener will have infinite pendingNotifications // added until we OOM. @@ -847,11 +899,18 @@ type processorListener struct { resyncLock sync.Mutex } -func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, resyncPeriod time.Duration, now time.Time, bufferSize int) *processorListener { +// HasSynced returns true if the source informer has synced, and all +// corresponding events have been delivered. +func (p *processorListener) HasSynced() bool { + return p.syncTracker.HasSynced() +} + +func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, resyncPeriod time.Duration, now time.Time, bufferSize int, hasSynced func() bool) *processorListener { ret := &processorListener{ nextCh: make(chan interface{}), addCh: make(chan interface{}), handler: handler, + syncTracker: &synctrack.SingleFileTracker{UpstreamHasSynced: hasSynced}, pendingNotifications: *buffer.NewRingGrowing(bufferSize), requestedResyncPeriod: requestedResyncPeriod, resyncPeriod: resyncPeriod, @@ -863,6 +922,9 @@ func newProcessListener(handler ResourceEventHandler, requestedResyncPeriod, res } func (p *processorListener) add(notification interface{}) { + if a, ok := notification.(addNotification); ok && a.isInInitialList { + p.syncTracker.Start() + } p.addCh <- notification } @@ -908,7 +970,10 @@ func (p *processorListener) run() { case updateNotification: p.handler.OnUpdate(notification.oldObj, notification.newObj) case addNotification: - p.handler.OnAdd(notification.newObj) + p.handler.OnAdd(notification.newObj, notification.isInInitialList) + if notification.isInInitialList { + p.syncTracker.Finished() + } case deleteNotification: p.handler.OnDelete(notification.oldObj) default: diff --git a/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go b/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go new file mode 100644 index 000000000..ce51da9af --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/synctrack/lazy.go @@ -0,0 +1,83 @@ +/* +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 synctrack + +import ( + "sync" + "sync/atomic" +) + +// Lazy defers the computation of `Evaluate` to when it is necessary. It is +// possible that Evaluate will be called in parallel from multiple goroutines. +type Lazy[T any] struct { + Evaluate func() (T, error) + + cache atomic.Pointer[cacheEntry[T]] +} + +type cacheEntry[T any] struct { + eval func() (T, error) + lock sync.RWMutex + result *T +} + +func (e *cacheEntry[T]) get() (T, error) { + if cur := func() *T { + e.lock.RLock() + defer e.lock.RUnlock() + return e.result + }(); cur != nil { + return *cur, nil + } + + e.lock.Lock() + defer e.lock.Unlock() + if e.result != nil { + return *e.result, nil + } + r, err := e.eval() + if err == nil { + e.result = &r + } + return r, err +} + +func (z *Lazy[T]) newCacheEntry() *cacheEntry[T] { + return &cacheEntry[T]{eval: z.Evaluate} +} + +// Notify should be called when something has changed necessitating a new call +// to Evaluate. +func (z *Lazy[T]) Notify() { z.cache.Swap(z.newCacheEntry()) } + +// Get should be called to get the current result of a call to Evaluate. If the +// current cached value is stale (due to a call to Notify), then Evaluate will +// be called synchronously. If subsequent calls to Get happen (without another +// Notify), they will all wait for the same return value. +// +// Error returns are not cached and will cause multiple calls to evaluate! +func (z *Lazy[T]) Get() (T, error) { + e := z.cache.Load() + if e == nil { + // Since we don't force a constructor, nil is a possible value. + // If multiple Gets race to set this, the swap makes sure only + // one wins. + z.cache.CompareAndSwap(nil, z.newCacheEntry()) + e = z.cache.Load() + } + return e.get() +} diff --git a/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go b/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go new file mode 100644 index 000000000..3fa2beb6b --- /dev/null +++ b/vendor/k8s.io/client-go/tools/cache/synctrack/synctrack.go @@ -0,0 +1,120 @@ +/* +Copyright 2022 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 synctrack contains utilities for helping controllers track whether +// they are "synced" or not, that is, whether they have processed all items +// from the informer's initial list. +package synctrack + +import ( + "sync" + "sync/atomic" + + "k8s.io/apimachinery/pkg/util/sets" +) + +// AsyncTracker helps propagate HasSynced in the face of multiple worker threads. +type AsyncTracker[T comparable] struct { + UpstreamHasSynced func() bool + + lock sync.Mutex + waiting sets.Set[T] +} + +// Start should be called prior to processing each key which is part of the +// initial list. +func (t *AsyncTracker[T]) Start(key T) { + t.lock.Lock() + defer t.lock.Unlock() + if t.waiting == nil { + t.waiting = sets.New[T](key) + } else { + t.waiting.Insert(key) + } +} + +// Finished should be called when finished processing a key which was part of +// the initial list. Since keys are tracked individually, nothing bad happens +// if you call Finished without a corresponding call to Start. This makes it +// easier to use this in combination with e.g. queues which don't make it easy +// to plumb through the isInInitialList boolean. +func (t *AsyncTracker[T]) Finished(key T) { + t.lock.Lock() + defer t.lock.Unlock() + if t.waiting != nil { + t.waiting.Delete(key) + } +} + +// HasSynced returns true if the source is synced and every key present in the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *AsyncTracker[T]) HasSynced() bool { + // Call UpstreamHasSynced first: it might take a lock, which might take + // a significant amount of time, and we can't hold our lock while + // waiting on that or a user is likely to get a deadlock. + if !t.UpstreamHasSynced() { + return false + } + t.lock.Lock() + defer t.lock.Unlock() + return t.waiting.Len() == 0 +} + +// SingleFileTracker helps propagate HasSynced when events are processed in +// order (i.e. via a queue). +type SingleFileTracker struct { + // Important: count is used with atomic operations so it must be 64-bit + // aligned, otherwise atomic operations will panic. Having it at the top of + // the struct will guarantee that, even on 32-bit arches. + // See https://pkg.go.dev/sync/atomic#pkg-note-BUG for more information. + count int64 + + UpstreamHasSynced func() bool +} + +// Start should be called prior to processing each key which is part of the +// initial list. +func (t *SingleFileTracker) Start() { + atomic.AddInt64(&t.count, 1) +} + +// Finished should be called when finished processing a key which was part of +// the initial list. You must never call Finished() before (or without) its +// corresponding Start(), that is a logic error that could cause HasSynced to +// return a wrong value. To help you notice this should it happen, Finished() +// will panic if the internal counter goes negative. +func (t *SingleFileTracker) Finished() { + result := atomic.AddInt64(&t.count, -1) + if result < 0 { + panic("synctrack: negative counter; this logic error means HasSynced may return incorrect value") + } +} + +// HasSynced returns true if the source is synced and every key present in the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *SingleFileTracker) HasSynced() bool { + // Call UpstreamHasSynced first: it might take a lock, which might take + // a significant amount of time, and we don't want to then act on a + // stale count value. + if !t.UpstreamHasSynced() { + return false + } + return atomic.LoadInt64(&t.count) <= 0 +} diff --git a/vendor/k8s.io/client-go/tools/events/event_broadcaster.go b/vendor/k8s.io/client-go/tools/events/event_broadcaster.go index 951965e95..e3000bf6e 100644 --- a/vendor/k8s.io/client-go/tools/events/event_broadcaster.go +++ b/vendor/k8s.io/client-go/tools/events/event_broadcaster.go @@ -56,9 +56,11 @@ var defaultSleepDuration = 10 * time.Second // TODO: validate impact of copying and investigate hashing type eventKey struct { + eventType string action string reason string reportingController string + reportingInstance string regarding corev1.ObjectReference related corev1.ObjectReference } @@ -181,22 +183,24 @@ func (e *eventBroadcasterImpl) recordToSink(event *eventsv1.Event, clock clock.C return nil } isomorphicEvent.Series = &eventsv1.EventSeries{ - Count: 1, + Count: 2, LastObservedTime: metav1.MicroTime{Time: clock.Now()}, } - return isomorphicEvent + // Make a copy of the Event to make sure that recording it + // doesn't mess with the object stored in cache. + return isomorphicEvent.DeepCopy() } e.eventCache[eventKey] = eventCopy - return eventCopy + // Make a copy of the Event to make sure that recording it doesn't + // mess with the object stored in cache. + return eventCopy.DeepCopy() }() if evToRecord != nil { - recordedEvent := e.attemptRecording(evToRecord) - if recordedEvent != nil { - recordedEventKey := getKey(recordedEvent) - e.mu.Lock() - defer e.mu.Unlock() - e.eventCache[recordedEventKey] = recordedEvent - } + // TODO: Add a metric counting the number of recording attempts + e.attemptRecording(evToRecord) + // We don't want the new recorded Event to be reflected in the + // client's cache because server-side mutations could mess with the + // aggregation mechanism used by the client. } }() } @@ -248,6 +252,14 @@ func recordEvent(sink EventSink, event *eventsv1.Event) (*eventsv1.Event, bool) return nil, false case *errors.StatusError: if errors.IsAlreadyExists(err) { + // If we tried to create an Event from an EventSerie, it means that + // the original Patch request failed because the Event we were + // trying to patch didn't exist. If the creation failed because the + // Event now exists, it is safe to retry. This occurs when a new + // Event is emitted twice in a very short period of time. + if isEventSeries { + return nil, true + } klog.V(5).Infof("Server rejected event '%#v': '%v' (will not retry!)", event, err) } else { klog.Errorf("Server rejected event '%#v': '%v' (will not retry!)", event, err) @@ -279,9 +291,11 @@ func createPatchBytesForSeries(event *eventsv1.Event) ([]byte, error) { func getKey(event *eventsv1.Event) eventKey { key := eventKey{ + eventType: event.Type, action: event.Action, reason: event.Reason, reportingController: event.ReportingController, + reportingInstance: event.ReportingInstance, regarding: event.Regarding, } if event.Related != nil { diff --git a/vendor/k8s.io/client-go/tools/events/event_recorder.go b/vendor/k8s.io/client-go/tools/events/event_recorder.go index 132843742..17d053271 100644 --- a/vendor/k8s.io/client-go/tools/events/event_recorder.go +++ b/vendor/k8s.io/client-go/tools/events/event_recorder.go @@ -41,7 +41,7 @@ type recorderImpl struct { } func (recorder *recorderImpl) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...interface{}) { - timestamp := metav1.MicroTime{time.Now()} + timestamp := metav1.MicroTime{Time: time.Now()} message := fmt.Sprintf(note, args...) refRegarding, err := reference.GetReference(recorder.scheme, regarding) if err != nil { diff --git a/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go b/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go index c64ba9b26..940e71617 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/leaderelection.go @@ -64,9 +64,8 @@ import ( "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" rl "k8s.io/client-go/tools/leaderelection/resourcelock" - "k8s.io/utils/clock" - "k8s.io/klog/v2" + "k8s.io/utils/clock" ) const ( @@ -199,9 +198,7 @@ type LeaderElector struct { // stopped holding the leader lease func (le *LeaderElector) Run(ctx context.Context) { defer runtime.HandleCrash() - defer func() { - le.config.Callbacks.OnStoppedLeading() - }() + defer le.config.Callbacks.OnStoppedLeading() if !le.acquire(ctx) { return // ctx signalled done @@ -263,6 +260,7 @@ func (le *LeaderElector) acquire(ctx context.Context) bool { // renew loops calling tryAcquireOrRenew and returns immediately when tryAcquireOrRenew fails or ctx signals done. func (le *LeaderElector) renew(ctx context.Context) { + defer le.config.Lock.RecordEvent("stopped leading") ctx, cancel := context.WithCancel(ctx) defer cancel() wait.Until(func() { @@ -278,7 +276,6 @@ func (le *LeaderElector) renew(ctx context.Context) { klog.V(5).Infof("successfully renewed lease %v", desc) return } - le.config.Lock.RecordEvent("stopped leading") le.metrics.leaderOff(le.config.Name) klog.Infof("failed to renew lease %v: %v", desc, err) cancel() @@ -295,7 +292,7 @@ func (le *LeaderElector) release() bool { if !le.IsLeader() { return true } - now := metav1.Now() + now := metav1.NewTime(le.clock.Now()) leaderElectionRecord := rl.LeaderElectionRecord{ LeaderTransitions: le.observedRecord.LeaderTransitions, LeaseDurationSeconds: 1, @@ -315,7 +312,7 @@ func (le *LeaderElector) release() bool { // else it tries to renew the lease if it has already been acquired. Returns true // on success else returns false. func (le *LeaderElector) tryAcquireOrRenew(ctx context.Context) bool { - now := metav1.Now() + now := metav1.NewTime(le.clock.Now()) leaderElectionRecord := rl.LeaderElectionRecord{ HolderIdentity: le.config.Lock.Identity(), LeaseDurationSeconds: int(le.config.LeaseDuration / time.Second), @@ -347,7 +344,7 @@ func (le *LeaderElector) tryAcquireOrRenew(ctx context.Context) bool { le.observedRawRecord = oldLeaderElectionRawRecord } if len(oldLeaderElectionRecord.HolderIdentity) > 0 && - le.observedTime.Add(le.config.LeaseDuration).After(now.Time) && + le.observedTime.Add(time.Second*time.Duration(oldLeaderElectionRecord.LeaseDurationSeconds)).After(now.Time) && !le.IsLeader() { klog.V(4).Infof("lock is held by %v and has not yet expired", oldLeaderElectionRecord.HolderIdentity) return false diff --git a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/interface.go b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/interface.go index c6e23bda1..05b5b2023 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/interface.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/interface.go @@ -68,7 +68,7 @@ const ( // name: '*' // namespace: kube-system EndpointsLeasesResourceLock = "endpointsleases" - // When using EndpointsLeasesResourceLock, you need to ensure that + // When using ConfigMapsLeasesResourceLock, you need to ensure that // API Priority & Fairness is configured with non-default flow-schema // that will catch the necessary operations on leader-election related // configmap objects. diff --git a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go index 185ef0e50..8a9d7d60f 100644 --- a/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go +++ b/vendor/k8s.io/client-go/tools/leaderelection/resourcelock/leaselock.go @@ -117,10 +117,10 @@ func LeaseSpecToLeaderElectionRecord(spec *coordinationv1.LeaseSpec) *LeaderElec r.LeaderTransitions = int(*spec.LeaseTransitions) } if spec.AcquireTime != nil { - r.AcquireTime = metav1.Time{spec.AcquireTime.Time} + r.AcquireTime = metav1.Time{Time: spec.AcquireTime.Time} } if spec.RenewTime != nil { - r.RenewTime = metav1.Time{spec.RenewTime.Time} + r.RenewTime = metav1.Time{Time: spec.RenewTime.Time} } return &r @@ -132,8 +132,8 @@ func LeaderElectionRecordToLeaseSpec(ler *LeaderElectionRecord) coordinationv1.L return coordinationv1.LeaseSpec{ HolderIdentity: &ler.HolderIdentity, LeaseDurationSeconds: &leaseDurationSeconds, - AcquireTime: &metav1.MicroTime{ler.AcquireTime.Time}, - RenewTime: &metav1.MicroTime{ler.RenewTime.Time}, + AcquireTime: &metav1.MicroTime{Time: ler.AcquireTime.Time}, + RenewTime: &metav1.MicroTime{Time: ler.RenewTime.Time}, LeaseTransitions: &leaseTransitions, } } diff --git a/vendor/k8s.io/client-go/tools/metrics/metrics.go b/vendor/k8s.io/client-go/tools/metrics/metrics.go index 6c684c7fa..f36430dc3 100644 --- a/vendor/k8s.io/client-go/tools/metrics/metrics.go +++ b/vendor/k8s.io/client-go/tools/metrics/metrics.go @@ -58,6 +58,12 @@ type CallsMetric interface { Increment(exitCode int, callStatus string) } +// RetryMetric counts the number of retries sent to the server +// partitioned by code, method, and host. +type RetryMetric interface { + IncrementRetry(ctx context.Context, code string, method string, host string) +} + var ( // ClientCertExpiry is the expiry time of a client certificate ClientCertExpiry ExpiryMetric = noopExpiry{} @@ -76,6 +82,9 @@ var ( // ExecPluginCalls is the number of calls made to an exec plugin, partitioned by // exit code and call status. ExecPluginCalls CallsMetric = noopCalls{} + // RequestRetry is the retry metric that tracks the number of + // retries sent to the server. + RequestRetry RetryMetric = noopRetry{} ) // RegisterOpts contains all the metrics to register. Metrics may be nil. @@ -88,6 +97,7 @@ type RegisterOpts struct { RateLimiterLatency LatencyMetric RequestResult ResultMetric ExecPluginCalls CallsMetric + RequestRetry RetryMetric } // Register registers metrics for the rest client to use. This can @@ -118,6 +128,9 @@ func Register(opts RegisterOpts) { if opts.ExecPluginCalls != nil { ExecPluginCalls = opts.ExecPluginCalls } + if opts.RequestRetry != nil { + RequestRetry = opts.RequestRetry + } }) } @@ -144,3 +157,7 @@ func (noopResult) Increment(context.Context, string, string, string) {} type noopCalls struct{} func (noopCalls) Increment(int, string) {} + +type noopRetry struct{} + +func (noopRetry) IncrementRetry(context.Context, string, string, string) {} diff --git a/vendor/k8s.io/client-go/tools/portforward/portforward.go b/vendor/k8s.io/client-go/tools/portforward/portforward.go index 6b5e3076c..b581043f6 100644 --- a/vendor/k8s.io/client-go/tools/portforward/portforward.go +++ b/vendor/k8s.io/client-go/tools/portforward/portforward.go @@ -37,6 +37,8 @@ import ( // TODO move to API machinery and re-unify with kubelet/server/portfoward const PortForwardProtocolV1Name = "portforward.k8s.io" +var ErrLostConnectionToPod = errors.New("lost connection to pod") + // PortForwarder knows how to listen for local connections and forward them to // a remote pod via an upgraded HTTP request. type PortForwarder struct { @@ -230,7 +232,7 @@ func (pf *PortForwarder) forward() error { select { case <-pf.stopChan: case <-pf.streamConn.CloseChan(): - runtime.HandleError(errors.New("lost connection to pod")) + return ErrLostConnectionToPod } return nil diff --git a/vendor/k8s.io/client-go/tools/record/event.go b/vendor/k8s.io/client-go/tools/record/event.go index 998bf8dfb..4899b362d 100644 --- a/vendor/k8s.io/client-go/tools/record/event.go +++ b/vendor/k8s.io/client-go/tools/record/event.go @@ -17,6 +17,7 @@ limitations under the License. package record import ( + "context" "fmt" "math/rand" "time" @@ -132,7 +133,9 @@ type EventBroadcaster interface { // with the event source set to the given event source. NewRecorder(scheme *runtime.Scheme, source v1.EventSource) EventRecorder - // Shutdown shuts down the broadcaster + // Shutdown shuts down the broadcaster. Once the broadcaster is shut + // down, it will only try to record an event in a sink once before + // giving up on it with an error message. Shutdown() } @@ -157,31 +160,34 @@ func (a *EventRecorderAdapter) Eventf(regarding, _ runtime.Object, eventtype, re // Creates a new event broadcaster. func NewBroadcaster() EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: defaultSleepDuration, - } + return newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), defaultSleepDuration) } func NewBroadcasterForTests(sleepDuration time.Duration) EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: sleepDuration, - } + return newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), sleepDuration) } func NewBroadcasterWithCorrelatorOptions(options CorrelatorOptions) EventBroadcaster { - return &eventBroadcasterImpl{ - Broadcaster: watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), - sleepDuration: defaultSleepDuration, - options: options, + eventBroadcaster := newEventBroadcaster(watch.NewLongQueueBroadcaster(maxQueuedEvents, watch.DropIfChannelFull), defaultSleepDuration) + eventBroadcaster.options = options + return eventBroadcaster +} + +func newEventBroadcaster(broadcaster *watch.Broadcaster, sleepDuration time.Duration) *eventBroadcasterImpl { + eventBroadcaster := &eventBroadcasterImpl{ + Broadcaster: broadcaster, + sleepDuration: sleepDuration, } + eventBroadcaster.cancelationCtx, eventBroadcaster.cancel = context.WithCancel(context.Background()) + return eventBroadcaster } type eventBroadcasterImpl struct { *watch.Broadcaster - sleepDuration time.Duration - options CorrelatorOptions + sleepDuration time.Duration + options CorrelatorOptions + cancelationCtx context.Context + cancel func() } // StartRecordingToSink starts sending events received from the specified eventBroadcaster to the given sink. @@ -191,15 +197,16 @@ func (e *eventBroadcasterImpl) StartRecordingToSink(sink EventSink) watch.Interf eventCorrelator := NewEventCorrelatorWithOptions(e.options) return e.StartEventWatcher( func(event *v1.Event) { - recordToSink(sink, event, eventCorrelator, e.sleepDuration) + e.recordToSink(sink, event, eventCorrelator) }) } func (e *eventBroadcasterImpl) Shutdown() { e.Broadcaster.Shutdown() + e.cancel() } -func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator, sleepDuration time.Duration) { +func (e *eventBroadcasterImpl) recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrelator) { // Make a copy before modification, because there could be multiple listeners. // Events are safe to copy like this. eventCopy := *event @@ -221,12 +228,18 @@ func recordToSink(sink EventSink, event *v1.Event, eventCorrelator *EventCorrela klog.Errorf("Unable to write event '%#v' (retry limit exceeded!)", event) break } + // Randomize the first sleep so that various clients won't all be // synced up if the master goes down. + delay := e.sleepDuration if tries == 1 { - time.Sleep(time.Duration(float64(sleepDuration) * rand.Float64())) - } else { - time.Sleep(sleepDuration) + delay = time.Duration(float64(delay) * rand.Float64()) + } + select { + case <-e.cancelationCtx.Done(): + klog.Errorf("Unable to write event '%#v' (broadcaster is shut down)", event) + return + case <-time.After(delay): } } } diff --git a/vendor/k8s.io/client-go/tools/record/fake.go b/vendor/k8s.io/client-go/tools/record/fake.go index 0b3f344a9..fda4ad8ff 100644 --- a/vendor/k8s.io/client-go/tools/record/fake.go +++ b/vendor/k8s.io/client-go/tools/record/fake.go @@ -41,20 +41,31 @@ func objectString(object runtime.Object, includeObject bool) string { ) } -func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) { - if f.Events != nil { - f.Events <- fmt.Sprintf("%s %s %s%s", eventtype, reason, message, objectString(object, f.IncludeObject)) +func annotationsString(annotations map[string]string) string { + if len(annotations) == 0 { + return "" + } else { + return " " + fmt.Sprint(annotations) } } +func (f *FakeRecorder) writeEvent(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { + if f.Events != nil { + f.Events <- fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...) + + objectString(object, f.IncludeObject) + annotationsString(annotations) + } +} + +func (f *FakeRecorder) Event(object runtime.Object, eventtype, reason, message string) { + f.writeEvent(object, nil, eventtype, reason, "%s", message) +} + func (f *FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { - if f.Events != nil { - f.Events <- fmt.Sprintf(eventtype+" "+reason+" "+messageFmt, args...) + objectString(object, f.IncludeObject) - } + f.writeEvent(object, nil, eventtype, reason, messageFmt, args...) } func (f *FakeRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { - f.Eventf(object, eventtype, reason, messageFmt, args...) + f.writeEvent(object, annotations, eventtype, reason, messageFmt, args...) } // NewFakeRecorder creates new fake event recorder with event channel with diff --git a/vendor/k8s.io/client-go/tools/watch/until.go b/vendor/k8s.io/client-go/tools/watch/until.go index 81d4ff0dd..a2474556b 100644 --- a/vendor/k8s.io/client-go/tools/watch/until.go +++ b/vendor/k8s.io/client-go/tools/watch/until.go @@ -101,8 +101,7 @@ func UntilWithoutRetry(ctx context.Context, watcher watch.Interface, conditions // It guarantees you to see all events and in the order they happened. // Due to this guarantee there is no way it can deal with 'Resource version too old error'. It will fail in this case. // (See `UntilWithSync` if you'd prefer to recover from all the errors including RV too old by re-listing -// -// those items. In normal code you should care about being level driven so you'd not care about not seeing all the edges.) +// those items. In normal code you should care about being level driven so you'd not care about not seeing all the edges.) // // The most frequent usage for Until would be a test where you want to verify exact order of events ("edges"). func Until(ctx context.Context, initialResourceVersion string, watcherClient cache.Watcher, conditions ...ConditionFunc) (*watch.Event, error) { @@ -137,7 +136,7 @@ func UntilWithSync(ctx context.Context, lw cache.ListerWatcher, objType runtime. if precondition != nil { if !cache.WaitForCacheSync(ctx.Done(), informer.HasSynced) { - return nil, fmt.Errorf("UntilWithSync: unable to sync caches: %v", ctx.Err()) + return nil, fmt.Errorf("UntilWithSync: unable to sync caches: %w", ctx.Err()) } done, err := precondition(indexer) diff --git a/vendor/k8s.io/client-go/util/cert/cert.go b/vendor/k8s.io/client-go/util/cert/cert.go index 7196cf890..4be1dfe49 100644 --- a/vendor/k8s.io/client-go/util/cert/cert.go +++ b/vendor/k8s.io/client-go/util/cert/cert.go @@ -191,7 +191,7 @@ func GenerateSelfSignedCertKeyWithFixtures(host string, alternateIPs []net.IP, a if err := os.WriteFile(certFixturePath, certBuffer.Bytes(), 0644); err != nil { return nil, nil, fmt.Errorf("failed to write cert fixture to %s: %v", certFixturePath, err) } - if err := os.WriteFile(keyFixturePath, keyBuffer.Bytes(), 0644); err != nil { + if err := os.WriteFile(keyFixturePath, keyBuffer.Bytes(), 0600); err != nil { return nil, nil, fmt.Errorf("failed to write key fixture to %s: %v", certFixturePath, err) } } diff --git a/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go b/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go index 26eacc2ba..c1df72030 100644 --- a/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/delaying_queue.go @@ -33,38 +33,81 @@ type DelayingInterface interface { AddAfter(item interface{}, duration time.Duration) } +// DelayingQueueConfig specifies optional configurations to customize a DelayingInterface. +type DelayingQueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock optionally allows injecting a real or fake clock for testing purposes. + Clock clock.WithTicker + + // Queue optionally allows injecting custom queue Interface instead of the default one. + Queue Interface +} + // NewDelayingQueue constructs a new workqueue with delayed queuing ability. // NewDelayingQueue does not emit metrics. For use with a MetricsProvider, please use -// NewNamedDelayingQueue instead. +// NewDelayingQueueWithConfig instead and specify a name. func NewDelayingQueue() DelayingInterface { - return NewDelayingQueueWithCustomClock(clock.RealClock{}, "") + return NewDelayingQueueWithConfig(DelayingQueueConfig{}) +} + +// NewDelayingQueueWithConfig constructs a new workqueue with options to +// customize different properties. +func NewDelayingQueueWithConfig(config DelayingQueueConfig) DelayingInterface { + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + + if config.Queue == nil { + config.Queue = NewWithConfig(QueueConfig{ + Name: config.Name, + MetricsProvider: config.MetricsProvider, + Clock: config.Clock, + }) + } + + return newDelayingQueue(config.Clock, config.Queue, config.Name, config.MetricsProvider) } // NewDelayingQueueWithCustomQueue constructs a new workqueue with ability to // inject custom queue Interface instead of the default one +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewDelayingQueueWithCustomQueue(q Interface, name string) DelayingInterface { - return newDelayingQueue(clock.RealClock{}, q, name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: name, + Queue: q, + }) } -// NewNamedDelayingQueue constructs a new named workqueue with delayed queuing ability +// NewNamedDelayingQueue constructs a new named workqueue with delayed queuing ability. +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewNamedDelayingQueue(name string) DelayingInterface { - return NewDelayingQueueWithCustomClock(clock.RealClock{}, name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{Name: name}) } // NewDelayingQueueWithCustomClock constructs a new named workqueue -// with ability to inject real or fake clock for testing purposes +// with ability to inject real or fake clock for testing purposes. +// Deprecated: Use NewDelayingQueueWithConfig instead. func NewDelayingQueueWithCustomClock(clock clock.WithTicker, name string) DelayingInterface { - return newDelayingQueue(clock, NewNamed(name), name) + return NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: name, + Clock: clock, + }) } -func newDelayingQueue(clock clock.WithTicker, q Interface, name string) *delayingType { +func newDelayingQueue(clock clock.WithTicker, q Interface, name string, provider MetricsProvider) *delayingType { ret := &delayingType{ Interface: q, clock: clock, heartbeat: clock.NewTicker(maxWait), stopCh: make(chan struct{}), waitingForAddCh: make(chan *waitFor, 1000), - metrics: newRetryMetrics(name), + metrics: newRetryMetrics(name, provider), } go ret.waitingLoop() diff --git a/vendor/k8s.io/client-go/util/workqueue/metrics.go b/vendor/k8s.io/client-go/util/workqueue/metrics.go index 4b0a69616..f012ccc55 100644 --- a/vendor/k8s.io/client-go/util/workqueue/metrics.go +++ b/vendor/k8s.io/client-go/util/workqueue/metrics.go @@ -244,13 +244,18 @@ func (f *queueMetricsFactory) newQueueMetrics(name string, clock clock.Clock) qu } } -func newRetryMetrics(name string) retryMetrics { +func newRetryMetrics(name string, provider MetricsProvider) retryMetrics { var ret *defaultRetryMetrics if len(name) == 0 { return ret } + + if provider == nil { + provider = globalMetricsFactory.metricsProvider + } + return &defaultRetryMetrics{ - retries: globalMetricsFactory.metricsProvider.NewRetriesMetric(name), + retries: provider.NewRetriesMetric(name), } } diff --git a/vendor/k8s.io/client-go/util/workqueue/queue.go b/vendor/k8s.io/client-go/util/workqueue/queue.go index 6f7063269..380c06455 100644 --- a/vendor/k8s.io/client-go/util/workqueue/queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/queue.go @@ -33,17 +33,60 @@ type Interface interface { ShuttingDown() bool } -// New constructs a new work queue (see the package comment). -func New() *Type { - return NewNamed("") +// QueueConfig specifies optional configurations to customize an Interface. +type QueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock ability to inject real or fake clock for testing purposes. + Clock clock.WithTicker } +// New constructs a new work queue (see the package comment). +func New() *Type { + return NewWithConfig(QueueConfig{ + Name: "", + }) +} + +// NewWithConfig constructs a new workqueue with ability to +// customize different properties. +func NewWithConfig(config QueueConfig) *Type { + return newQueueWithConfig(config, defaultUnfinishedWorkUpdatePeriod) +} + +// NewNamed creates a new named queue. +// Deprecated: Use NewWithConfig instead. func NewNamed(name string) *Type { - rc := clock.RealClock{} + return NewWithConfig(QueueConfig{ + Name: name, + }) +} + +// newQueueWithConfig constructs a new named workqueue +// with the ability to customize different properties for testing purposes +func newQueueWithConfig(config QueueConfig, updatePeriod time.Duration) *Type { + var metricsFactory *queueMetricsFactory + if config.MetricsProvider != nil { + metricsFactory = &queueMetricsFactory{ + metricsProvider: config.MetricsProvider, + } + } else { + metricsFactory = &globalMetricsFactory + } + + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + return newQueue( - rc, - globalMetricsFactory.newQueueMetrics(name, rc), - defaultUnfinishedWorkUpdatePeriod, + config.Clock, + metricsFactory.newQueueMetrics(config.Name, config.Clock), + updatePeriod, ) } diff --git a/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go b/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go index 91cd33f19..3e4016fb0 100644 --- a/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go +++ b/vendor/k8s.io/client-go/util/workqueue/rate_limiting_queue.go @@ -16,6 +16,8 @@ limitations under the License. package workqueue +import "k8s.io/utils/clock" + // RateLimitingInterface is an interface that rate limits items being added to the queue. type RateLimitingInterface interface { DelayingInterface @@ -32,29 +34,68 @@ type RateLimitingInterface interface { NumRequeues(item interface{}) int } +// RateLimitingQueueConfig specifies optional configurations to customize a RateLimitingInterface. + +type RateLimitingQueueConfig struct { + // Name for the queue. If unnamed, the metrics will not be registered. + Name string + + // MetricsProvider optionally allows specifying a metrics provider to use for the queue + // instead of the global provider. + MetricsProvider MetricsProvider + + // Clock optionally allows injecting a real or fake clock for testing purposes. + Clock clock.WithTicker + + // DelayingQueue optionally allows injecting custom delaying queue DelayingInterface instead of the default one. + DelayingQueue DelayingInterface +} + // NewRateLimitingQueue constructs a new workqueue with rateLimited queuing ability // Remember to call Forget! If you don't, you may end up tracking failures forever. // NewRateLimitingQueue does not emit metrics. For use with a MetricsProvider, please use -// NewNamedRateLimitingQueue instead. +// NewRateLimitingQueueWithConfig instead and specify a name. func NewRateLimitingQueue(rateLimiter RateLimiter) RateLimitingInterface { + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{}) +} + +// NewRateLimitingQueueWithConfig constructs a new workqueue with rateLimited queuing ability +// with options to customize different properties. +// Remember to call Forget! If you don't, you may end up tracking failures forever. +func NewRateLimitingQueueWithConfig(rateLimiter RateLimiter, config RateLimitingQueueConfig) RateLimitingInterface { + if config.Clock == nil { + config.Clock = clock.RealClock{} + } + + if config.DelayingQueue == nil { + config.DelayingQueue = NewDelayingQueueWithConfig(DelayingQueueConfig{ + Name: config.Name, + MetricsProvider: config.MetricsProvider, + Clock: config.Clock, + }) + } + return &rateLimitingType{ - DelayingInterface: NewDelayingQueue(), + DelayingInterface: config.DelayingQueue, rateLimiter: rateLimiter, } } +// NewNamedRateLimitingQueue constructs a new named workqueue with rateLimited queuing ability. +// Deprecated: Use NewRateLimitingQueueWithConfig instead. func NewNamedRateLimitingQueue(rateLimiter RateLimiter, name string) RateLimitingInterface { - return &rateLimitingType{ - DelayingInterface: NewNamedDelayingQueue(name), - rateLimiter: rateLimiter, - } + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{ + Name: name, + }) } +// NewRateLimitingQueueWithDelayingInterface constructs a new named workqueue with rateLimited queuing ability +// with the option to inject a custom delaying queue instead of the default one. +// Deprecated: Use NewRateLimitingQueueWithConfig instead. func NewRateLimitingQueueWithDelayingInterface(di DelayingInterface, rateLimiter RateLimiter) RateLimitingInterface { - return &rateLimitingType{ - DelayingInterface: di, - rateLimiter: rateLimiter, - } + return NewRateLimitingQueueWithConfig(rateLimiter, RateLimitingQueueConfig{ + DelayingQueue: di, + }) } // rateLimitingType wraps an Interface and provides rateLimited re-enquing diff --git a/vendor/k8s.io/cloud-provider/app/config/config.go b/vendor/k8s.io/cloud-provider/app/config/config.go index 9e6c03266..20f1d0ef9 100644 --- a/vendor/k8s.io/cloud-provider/app/config/config.go +++ b/vendor/k8s.io/cloud-provider/app/config/config.go @@ -37,6 +37,10 @@ type Config struct { Authentication apiserver.AuthenticationInfo Authorization apiserver.AuthorizationInfo + // WebhookSecureServing is a separate SecureServing configuration from + // healthz, configz, and metrics. + WebhookSecureServing *apiserver.SecureServingInfo + // the general kube client Client *clientset.Clientset diff --git a/vendor/k8s.io/cloud-provider/cloud.go b/vendor/k8s.io/cloud-provider/cloud.go index 44c62ccc0..7e7bf9dfa 100644 --- a/vendor/k8s.io/cloud-provider/cloud.go +++ b/vendor/k8s.io/cloud-provider/cloud.go @@ -218,6 +218,11 @@ type Route struct { Name string // TargetNode is the NodeName of the target instance. TargetNode types.NodeName + // EnableNodeAddresses is a feature gate for TargetNodeAddresses. If false, ignore TargetNodeAddresses. + // Without this, if users haven't updated their cloud-provider, reconcile() will delete and create same route every time. + EnableNodeAddresses bool + // TargetNodeAddresses are the Node IPs of the target Node. + TargetNodeAddresses []v1.NodeAddress // DestinationCIDR is the CIDR format IP range that this routing rule // applies to. DestinationCIDR string diff --git a/vendor/k8s.io/cloud-provider/config/types.go b/vendor/k8s.io/cloud-provider/config/types.go index bcb523e91..133716219 100644 --- a/vendor/k8s.io/cloud-provider/config/types.go +++ b/vendor/k8s.io/cloud-provider/config/types.go @@ -18,6 +18,7 @@ package config import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + nodeconfig "k8s.io/cloud-provider/controllers/node/config" serviceconfig "k8s.io/cloud-provider/controllers/service/config" cmconfig "k8s.io/controller-manager/config" ) @@ -34,12 +35,19 @@ type CloudControllerManagerConfiguration struct { // both in cloud controller manager and kube-controller manager. KubeCloudShared KubeCloudSharedConfiguration + // NodeController holds configuration for node controller + // related features. + NodeController nodeconfig.NodeControllerConfiguration + // ServiceControllerConfiguration holds configuration for ServiceController // related features. ServiceController serviceconfig.ServiceControllerConfiguration // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status NodeStatusUpdateFrequency metav1.Duration + + // Webhook is the configuration for cloud-controller-manager hosted webhooks + Webhook WebhookConfiguration } // KubeCloudSharedConfiguration contains elements shared by both kube-controller manager @@ -84,3 +92,12 @@ type CloudProviderConfiguration struct { // cloudConfigFile is the path to the cloud provider configuration file. CloudConfigFile string } + +type WebhookConfiguration struct { + // Webhooks is the list of webhooks to enable or disable + // '*' means "all enabled by default webhooks" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Webhooks []string +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go index a47cf5338..c7f4760b4 100644 --- a/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/defaults.go @@ -21,6 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + nodeconfigv1alpha1 "k8s.io/cloud-provider/controllers/node/config/v1alpha1" serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" cmconfigv1alpha1 "k8s.io/controller-manager/config/v1alpha1" utilpointer "k8s.io/utils/pointer" @@ -49,6 +50,8 @@ func SetDefaults_CloudControllerManagerConfiguration(obj *CloudControllerManager cmconfigv1alpha1.RecommendedDefaultGenericControllerManagerConfiguration(&obj.Generic) // Use the default RecommendedDefaultServiceControllerConfiguration options serviceconfigv1alpha1.RecommendedDefaultServiceControllerConfiguration(&obj.ServiceController) + // Use the default RecommendedDefaultNodeControllerConfiguration options + nodeconfigv1alpha1.RecommendedDefaultNodeControllerConfiguration(&obj.NodeController) } func SetDefaults_KubeCloudSharedConfiguration(obj *KubeCloudSharedConfiguration) { diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go index 0aed1aa24..53689cadc 100644 --- a/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/types.go @@ -18,12 +18,14 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + nodeconfigv1alpha1 "k8s.io/cloud-provider/controllers/node/config/v1alpha1" serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" cmconfigv1alpha1 "k8s.io/controller-manager/config/v1alpha1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// CloudControllerManagerConfiguration contains elements describing cloud-controller manager. type CloudControllerManagerConfiguration struct { metav1.TypeMeta `json:",inline"` @@ -32,11 +34,16 @@ type CloudControllerManagerConfiguration struct { // KubeCloudSharedConfiguration holds configuration for shared related features // both in cloud controller manager and kube-controller manager. KubeCloudShared KubeCloudSharedConfiguration + // NodeController holds configuration for node controller + // related features. + NodeController nodeconfigv1alpha1.NodeControllerConfiguration // ServiceControllerConfiguration holds configuration for ServiceController // related features. ServiceController serviceconfigv1alpha1.ServiceControllerConfiguration // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status NodeStatusUpdateFrequency metav1.Duration + // Webhook is the configuration for cloud-controller-manager hosted webhooks + Webhook WebhookConfiguration } // KubeCloudSharedConfiguration contains elements shared by both kube-controller manager @@ -81,3 +88,14 @@ type CloudProviderConfiguration struct { // cloudConfigFile is the path to the cloud provider configuration file. CloudConfigFile string } + +// WebhookConfiguration contains configuration related to +// cloud-controller-manager hosted webhooks +type WebhookConfiguration struct { + // Webhooks is the list of webhooks to enable or disable + // '*' means "all enabled by default webhooks" + // 'foo' means "enable 'foo'" + // '-foo' means "disable 'foo'" + // first item for a particular name wins + Webhooks []string +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go index 76acd4d41..cc8d09414 100644 --- a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.conversion.go @@ -22,10 +22,13 @@ limitations under the License. package v1alpha1 import ( + unsafe "unsafe" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" config "k8s.io/cloud-provider/config" + nodeconfigv1alpha1 "k8s.io/cloud-provider/controllers/node/config/v1alpha1" serviceconfigv1alpha1 "k8s.io/cloud-provider/controllers/service/config/v1alpha1" configv1alpha1 "k8s.io/controller-manager/config/v1alpha1" ) @@ -47,6 +50,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*WebhookConfiguration)(nil), (*config.WebhookConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(a.(*WebhookConfiguration), b.(*config.WebhookConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*config.WebhookConfiguration)(nil), (*WebhookConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(a.(*config.WebhookConfiguration), b.(*WebhookConfiguration), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*config.CloudProviderConfiguration)(nil), (*CloudProviderConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_config_CloudProviderConfiguration_To_v1alpha1_CloudProviderConfiguration(a.(*config.CloudProviderConfiguration), b.(*CloudProviderConfiguration), scope) }); err != nil { @@ -77,10 +90,16 @@ func autoConvert_v1alpha1_CloudControllerManagerConfiguration_To_config_CloudCon if err := Convert_v1alpha1_KubeCloudSharedConfiguration_To_config_KubeCloudSharedConfiguration(&in.KubeCloudShared, &out.KubeCloudShared, s); err != nil { return err } + if err := nodeconfigv1alpha1.Convert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(&in.NodeController, &out.NodeController, s); err != nil { + return err + } if err := serviceconfigv1alpha1.Convert_v1alpha1_ServiceControllerConfiguration_To_config_ServiceControllerConfiguration(&in.ServiceController, &out.ServiceController, s); err != nil { return err } out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + if err := Convert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(&in.Webhook, &out.Webhook, s); err != nil { + return err + } return nil } @@ -96,10 +115,16 @@ func autoConvert_config_CloudControllerManagerConfiguration_To_v1alpha1_CloudCon if err := Convert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudSharedConfiguration(&in.KubeCloudShared, &out.KubeCloudShared, s); err != nil { return err } + if err := nodeconfigv1alpha1.Convert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(&in.NodeController, &out.NodeController, s); err != nil { + return err + } if err := serviceconfigv1alpha1.Convert_config_ServiceControllerConfiguration_To_v1alpha1_ServiceControllerConfiguration(&in.ServiceController, &out.ServiceController, s); err != nil { return err } out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + if err := Convert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(&in.Webhook, &out.Webhook, s); err != nil { + return err + } return nil } @@ -159,3 +184,23 @@ func autoConvert_config_KubeCloudSharedConfiguration_To_v1alpha1_KubeCloudShared out.NodeSyncPeriod = in.NodeSyncPeriod return nil } + +func autoConvert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(in *WebhookConfiguration, out *config.WebhookConfiguration, s conversion.Scope) error { + out.Webhooks = *(*[]string)(unsafe.Pointer(&in.Webhooks)) + return nil +} + +// Convert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(in *WebhookConfiguration, out *config.WebhookConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_WebhookConfiguration_To_config_WebhookConfiguration(in, out, s) +} + +func autoConvert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in *config.WebhookConfiguration, out *WebhookConfiguration, s conversion.Scope) error { + out.Webhooks = *(*[]string)(unsafe.Pointer(&in.Webhooks)) + return nil +} + +// Convert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration is an autogenerated conversion function. +func Convert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in *config.WebhookConfiguration, out *WebhookConfiguration, s conversion.Scope) error { + return autoConvert_config_WebhookConfiguration_To_v1alpha1_WebhookConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go index 06eca856e..40a61f147 100644 --- a/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/cloud-provider/config/v1alpha1/zz_generated.deepcopy.go @@ -31,8 +31,10 @@ func (in *CloudControllerManagerConfiguration) DeepCopyInto(out *CloudController out.TypeMeta = in.TypeMeta in.Generic.DeepCopyInto(&out.Generic) in.KubeCloudShared.DeepCopyInto(&out.KubeCloudShared) + out.NodeController = in.NodeController out.ServiceController = in.ServiceController out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + in.Webhook.DeepCopyInto(&out.Webhook) return } @@ -94,3 +96,24 @@ func (in *KubeCloudSharedConfiguration) DeepCopy() *KubeCloudSharedConfiguration in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) { + *out = *in + if in.Webhooks != nil { + in, out := &in.Webhooks, &out.Webhooks + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration. +func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration { + if in == nil { + return nil + } + out := new(WebhookConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go index dc3cc5307..8225daba1 100644 --- a/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go +++ b/vendor/k8s.io/cloud-provider/config/zz_generated.deepcopy.go @@ -31,8 +31,10 @@ func (in *CloudControllerManagerConfiguration) DeepCopyInto(out *CloudController out.TypeMeta = in.TypeMeta in.Generic.DeepCopyInto(&out.Generic) out.KubeCloudShared = in.KubeCloudShared + out.NodeController = in.NodeController out.ServiceController = in.ServiceController out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency + in.Webhook.DeepCopyInto(&out.Webhook) return } @@ -89,3 +91,24 @@ func (in *KubeCloudSharedConfiguration) DeepCopy() *KubeCloudSharedConfiguration in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WebhookConfiguration) DeepCopyInto(out *WebhookConfiguration) { + *out = *in + if in.Webhooks != nil { + in, out := &in.Webhooks, &out.Webhooks + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfiguration. +func (in *WebhookConfiguration) DeepCopy() *WebhookConfiguration { + if in == nil { + return nil + } + out := new(WebhookConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/types.go b/vendor/k8s.io/cloud-provider/controllers/node/config/types.go new file mode 100644 index 000000000..af7c78803 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/types.go @@ -0,0 +1,24 @@ +/* +Copyright 2022 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 config + +// NodeControllerConfiguration contains elements describing NodeController. +type NodeControllerConfiguration struct { + // ConcurrentNodeSyncs is the number of workers + // concurrently synchronizing nodes + ConcurrentNodeSyncs int32 +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/conversion.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/conversion.go new file mode 100644 index 000000000..07dc75d31 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/conversion.go @@ -0,0 +1,39 @@ +/* +Copyright 2022 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/cloud-provider/controllers/node/config" +) + +// Important! The public back-and-forth conversion functions for the types in this generic +// package with ComponentConfig types need to be manually exposed like this in order for +// other packages that reference this package to be able to call these conversion functions +// in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these Convert_* functions +// in autogenerated code as well. + +// Convert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration is an autogenerated conversion function. +func Convert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(in *config.NodeControllerConfiguration, out *NodeControllerConfiguration, s conversion.Scope) error { + return autoConvert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(in, out, s) +} + +// Convert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(in *NodeControllerConfiguration, out *config.NodeControllerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(in, out, s) +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/defaults.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/defaults.go new file mode 100644 index 000000000..5f5ff95ff --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/defaults.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 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 v1alpha1 + +func RecommendedDefaultNodeControllerConfiguration(obj *NodeControllerConfiguration) { + if obj.ConcurrentNodeSyncs == 0 { + obj.ConcurrentNodeSyncs = 1 + } +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/doc.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/doc.go new file mode 100644 index 000000000..eff177166 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2022 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. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/node/config +// +k8s:conversion-gen=k8s.io/cloud-provider/controllers/node/config/v1alpha1 + +package v1alpha1 // import "k8s.io/cloud-provider/controllers/node/config/v1alpha1" diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/register.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/register.go new file mode 100644 index 000000000..a25accd07 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/register.go @@ -0,0 +1,31 @@ +/* +Copyright 2022 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 v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for this API package + SchemeBuilder runtime.SchemeBuilder + // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, + // defaulting and conversion init funcs are registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go new file mode 100644 index 000000000..ca85a557c --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/types.go @@ -0,0 +1,24 @@ +/* +Copyright 2020 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 v1alpha1 + +// NodeControllerConfiguration contains elements describing NodeController. +type NodeControllerConfiguration struct { + // ConcurrentNodeSyncs is the number of workers + // concurrently synchronizing nodes + ConcurrentNodeSyncs int32 +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 000000000..cf3852db2 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,58 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + config "k8s.io/cloud-provider/controllers/node/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddConversionFunc((*config.NodeControllerConfiguration)(nil), (*NodeControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(a.(*config.NodeControllerConfiguration), b.(*NodeControllerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*NodeControllerConfiguration)(nil), (*config.NodeControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(a.(*NodeControllerConfiguration), b.(*config.NodeControllerConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_NodeControllerConfiguration_To_config_NodeControllerConfiguration(in *NodeControllerConfiguration, out *config.NodeControllerConfiguration, s conversion.Scope) error { + out.ConcurrentNodeSyncs = in.ConcurrentNodeSyncs + return nil +} + +func autoConvert_config_NodeControllerConfiguration_To_v1alpha1_NodeControllerConfiguration(in *config.NodeControllerConfiguration, out *NodeControllerConfiguration, s conversion.Scope) error { + out.ConcurrentNodeSyncs = in.ConcurrentNodeSyncs + return nil +} diff --git a/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.deepcopy.go b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000..7e7c1b9fa --- /dev/null +++ b/vendor/k8s.io/cloud-provider/controllers/node/config/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,38 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeControllerConfiguration) DeepCopyInto(out *NodeControllerConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeControllerConfiguration. +func (in *NodeControllerConfiguration) DeepCopy() *NodeControllerConfiguration { + if in == nil { + return nil + } + out := new(NodeControllerConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/cloud-provider/options/nodecontroller.go b/vendor/k8s.io/cloud-provider/options/nodecontroller.go new file mode 100644 index 000000000..4823c437b --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/nodecontroller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 options + +import ( + "fmt" + + "github.com/spf13/pflag" + + nodeconfig "k8s.io/cloud-provider/controllers/node/config" +) + +// NodeControllerOptions holds the ServiceController options. +type NodeControllerOptions struct { + *nodeconfig.NodeControllerConfiguration +} + +// AddFlags adds flags related to ServiceController for controller manager to the specified FlagSet. +func (o *NodeControllerOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + fs.Int32Var(&o.ConcurrentNodeSyncs, "concurrent-node-syncs", o.ConcurrentNodeSyncs, "Number of workers concurrently synchronizing nodes.") +} + +// ApplyTo fills up ServiceController config with options. +func (o *NodeControllerOptions) ApplyTo(cfg *nodeconfig.NodeControllerConfiguration) error { + if o == nil { + return nil + } + + cfg.ConcurrentNodeSyncs = o.ConcurrentNodeSyncs + + return nil +} + +// Validate checks validation of NodeControllerOptions. +func (o *NodeControllerOptions) Validate() []error { + if o == nil { + return nil + } + var errors []error + if o.ConcurrentNodeSyncs <= 0 { + errors = append(errors, fmt.Errorf("concurrent-node-syncs must be a positive number")) + } + return errors +} diff --git a/vendor/k8s.io/cloud-provider/options/options.go b/vendor/k8s.io/cloud-provider/options/options.go index 908c79fc7..35bf1737e 100644 --- a/vendor/k8s.io/cloud-provider/options/options.go +++ b/vendor/k8s.io/cloud-provider/options/options.go @@ -57,20 +57,40 @@ type CloudControllerManagerOptions struct { Generic *cmoptions.GenericControllerManagerConfigurationOptions KubeCloudShared *KubeCloudSharedOptions ServiceController *ServiceControllerOptions + NodeController *NodeControllerOptions SecureServing *apiserveroptions.SecureServingOptionsWithLoopback Authentication *apiserveroptions.DelegatingAuthenticationOptions Authorization *apiserveroptions.DelegatingAuthorizationOptions - Master string - Kubeconfig string + Master string + + WebhookServing *WebhookServingOptions + Webhook *WebhookOptions // NodeStatusUpdateFrequency is the frequency at which the controller updates nodes' status NodeStatusUpdateFrequency metav1.Duration } +// ProviderDefaults are provided by the consumer when calling +// NewCloudControllerManagerOptions(), so that they can customize certain flag +// default values. +type ProviderDefaults struct { + // WebhookBindAddress is the default address. It can be overridden by "--webhook-bind-address". + WebhookBindAddress *net.IP + // WebhookBindPort is the default port. It can be overridden by "--webhook-bind-port". + WebhookBindPort *int +} + // NewCloudControllerManagerOptions creates a new ExternalCMServer with a default config. func NewCloudControllerManagerOptions() (*CloudControllerManagerOptions, error) { + return NewCloudControllerManagerOptionsWithProviderDefaults(ProviderDefaults{}) +} + +// NewCloudControllerManagerOptionsWithProviderDefaults creates a new +// ExternalCMServer with a default config, but allows the cloud provider to +// override a select number of default option values. +func NewCloudControllerManagerOptionsWithProviderDefaults(defaults ProviderDefaults) (*CloudControllerManagerOptions, error) { componentConfig, err := NewDefaultComponentConfig() if err != nil { return nil, err @@ -79,10 +99,15 @@ func NewCloudControllerManagerOptions() (*CloudControllerManagerOptions, error) s := CloudControllerManagerOptions{ Generic: cmoptions.NewGenericControllerManagerConfigurationOptions(&componentConfig.Generic), KubeCloudShared: NewKubeCloudSharedOptions(&componentConfig.KubeCloudShared), + NodeController: &NodeControllerOptions{ + NodeControllerConfiguration: &componentConfig.NodeController, + }, ServiceController: &ServiceControllerOptions{ ServiceControllerConfiguration: &componentConfig.ServiceController, }, SecureServing: apiserveroptions.NewSecureServingOptions().WithLoopback(), + Webhook: NewWebhookOptions(), + WebhookServing: NewWebhookServingOptions(defaults), Authentication: apiserveroptions.NewDelegatingAuthenticationOptions(), Authorization: apiserveroptions.NewDelegatingAuthorizationOptions(), NodeStatusUpdateFrequency: componentConfig.NodeStatusUpdateFrequency, @@ -111,15 +136,23 @@ func NewDefaultComponentConfig() (*ccmconfig.CloudControllerManagerConfiguration if err := ccmconfigscheme.Scheme.Convert(versioned, internal, nil); err != nil { return nil, err } + return internal, nil } // Flags returns flags for a specific CloudController by section name -func (o *CloudControllerManagerOptions) Flags(allControllers, disabledByDefaultControllers []string) cliflag.NamedFlagSets { +func (o *CloudControllerManagerOptions) Flags(allControllers, disabledByDefaultControllers, allWebhooks, disabledByDefaultWebhooks []string) cliflag.NamedFlagSets { fss := cliflag.NamedFlagSets{} o.Generic.AddFlags(&fss, allControllers, disabledByDefaultControllers) o.KubeCloudShared.AddFlags(fss.FlagSet("generic")) + o.NodeController.AddFlags(fss.FlagSet("node controller")) o.ServiceController.AddFlags(fss.FlagSet("service controller")) + if o.Webhook != nil { + o.Webhook.AddFlags(fss.FlagSet("webhook"), allWebhooks, disabledByDefaultWebhooks) + } + if o.WebhookServing != nil { + o.WebhookServing.AddFlags(fss.FlagSet("webhook serving")) + } o.SecureServing.AddFlags(fss.FlagSet("secure serving")) o.Authentication.AddFlags(fss.FlagSet("authentication")) @@ -127,9 +160,8 @@ func (o *CloudControllerManagerOptions) Flags(allControllers, disabledByDefaultC fs := fss.FlagSet("misc") fs.StringVar(&o.Master, "master", o.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig).") - fs.StringVar(&o.Kubeconfig, "kubeconfig", o.Kubeconfig, "Path to kubeconfig file with authorization and master location information.") + fs.StringVar(&o.Generic.ClientConnection.Kubeconfig, "kubeconfig", o.Generic.ClientConnection.Kubeconfig, "Path to kubeconfig file with authorization and master location information (the master location can be overridden by the master flag).") fs.DurationVar(&o.NodeStatusUpdateFrequency.Duration, "node-status-update-frequency", o.NodeStatusUpdateFrequency.Duration, "Specifies how often the controller updates nodes' status.") - utilfeature.DefaultMutableFeatureGate.AddFlag(fss.FlagSet("generic")) return fss @@ -142,7 +174,7 @@ func (o *CloudControllerManagerOptions) ApplyTo(c *config.Config, userAgent stri // Build kubeconfig first to so that if it fails, it doesn't cause leaking // goroutines (started from initializing secure serving - which underneath // creates a queue which in its constructor starts a goroutine). - c.Kubeconfig, err = clientcmd.BuildConfigFromFlags(o.Master, o.Kubeconfig) + c.Kubeconfig, err = clientcmd.BuildConfigFromFlags(o.Master, o.Generic.ClientConnection.Kubeconfig) if err != nil { return err } @@ -161,6 +193,16 @@ func (o *CloudControllerManagerOptions) ApplyTo(c *config.Config, userAgent stri if err = o.ServiceController.ApplyTo(&c.ComponentConfig.ServiceController); err != nil { return err } + if o.Webhook != nil { + if err = o.Webhook.ApplyTo(&c.ComponentConfig.Webhook); err != nil { + return err + } + } + if o.WebhookServing != nil { + if err = o.WebhookServing.ApplyTo(&c.WebhookSecureServing); err != nil { + return err + } + } if err = o.SecureServing.ApplyTo(&c.SecureServing, &c.LoopbackClientConfig); err != nil { return err } @@ -198,12 +240,13 @@ func (o *CloudControllerManagerOptions) ApplyTo(c *config.Config, userAgent stri // sync back to component config // TODO: find more elegant way than syncing back the values. c.ComponentConfig.NodeStatusUpdateFrequency = o.NodeStatusUpdateFrequency + c.ComponentConfig.NodeController.ConcurrentNodeSyncs = o.NodeController.ConcurrentNodeSyncs return nil } // Validate is used to validate config before launching the cloud controller manager -func (o *CloudControllerManagerOptions) Validate(allControllers, disabledByDefaultControllers []string) error { +func (o *CloudControllerManagerOptions) Validate(allControllers, disabledByDefaultControllers, allWebhooks, disabledByDefaultWebhooks []string) error { errors := []error{} errors = append(errors, o.Generic.Validate(allControllers, disabledByDefaultControllers)...) @@ -213,6 +256,16 @@ func (o *CloudControllerManagerOptions) Validate(allControllers, disabledByDefau errors = append(errors, o.Authentication.Validate()...) errors = append(errors, o.Authorization.Validate()...) + if o.Webhook != nil { + errors = append(errors, o.Webhook.Validate(allWebhooks, disabledByDefaultWebhooks)...) + } + if o.WebhookServing != nil { + errors = append(errors, o.WebhookServing.Validate()...) + + if o.WebhookServing.BindPort == o.SecureServing.BindPort { + errors = append(errors, fmt.Errorf("--webhook-secure-port cannot be the same value as --secure-port")) + } + } if len(o.KubeCloudShared.CloudProvider.Name) == 0 { errors = append(errors, fmt.Errorf("--cloud-provider cannot be empty")) } @@ -229,8 +282,8 @@ func resyncPeriod(c *config.Config) func() time.Duration { } // Config return a cloud controller manager config objective -func (o *CloudControllerManagerOptions) Config(allControllers, disabledByDefaultControllers []string) (*config.Config, error) { - if err := o.Validate(allControllers, disabledByDefaultControllers); err != nil { +func (o *CloudControllerManagerOptions) Config(allControllers, disabledByDefaultControllers, allWebhooks, disabledByDefaultWebhooks []string) (*config.Config, error) { + if err := o.Validate(allControllers, disabledByDefaultControllers, allWebhooks, disabledByDefaultWebhooks); err != nil { return nil, err } @@ -238,6 +291,12 @@ func (o *CloudControllerManagerOptions) Config(allControllers, disabledByDefault return nil, fmt.Errorf("error creating self-signed certificates: %v", err) } + if o.WebhookServing != nil { + if err := o.WebhookServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{netutils.ParseIPSloppy("127.0.0.1")}); err != nil { + return nil, fmt.Errorf("error creating self-signed certificates for webhook: %v", err) + } + } + c := &config.Config{} if err := o.ApplyTo(c, CloudControllerManagerUserAgent); err != nil { return nil, err diff --git a/vendor/k8s.io/cloud-provider/options/webhook.go b/vendor/k8s.io/cloud-provider/options/webhook.go new file mode 100644 index 000000000..719a70102 --- /dev/null +++ b/vendor/k8s.io/cloud-provider/options/webhook.go @@ -0,0 +1,206 @@ +/* +Copyright 2022 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 options + +import ( + "context" + "fmt" + "net" + "strconv" + "strings" + + "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/server" + "k8s.io/apiserver/pkg/server/dynamiccertificates" + apiserveroptions "k8s.io/apiserver/pkg/server/options" + "k8s.io/cloud-provider/config" + netutils "k8s.io/utils/net" +) + +const ( + CloudControllerManagerWebhookPort = 10260 +) + +type WebhookOptions struct { + // Webhooks is the list of webhook names that should be enabled or disabled + Webhooks []string +} + +func NewWebhookOptions() *WebhookOptions { + o := &WebhookOptions{} + return o +} + +func (o *WebhookOptions) AddFlags(fs *pflag.FlagSet, allWebhooks, disabledByDefaultWebhooks []string) { + fs.StringSliceVar(&o.Webhooks, "webhooks", o.Webhooks, fmt.Sprintf(""+ + "A list of webhooks to enable. '*' enables all on-by-default webhooks, 'foo' enables the webhook "+ + "named 'foo', '-foo' disables the webhook named 'foo'.\nAll webhooks: %s\nDisabled-by-default webhooks: %s", + strings.Join(allWebhooks, ", "), strings.Join(disabledByDefaultWebhooks, ", "))) +} + +func (o *WebhookOptions) Validate(allWebhooks, disabledByDefaultWebhooks []string) []error { + allErrors := []error{} + + allWebhooksSet := sets.NewString(allWebhooks...) + toValidate := sets.NewString(o.Webhooks...) + toValidate.Insert(disabledByDefaultWebhooks...) + for _, webhook := range toValidate.List() { + if webhook == "*" { + continue + } + webhook = strings.TrimPrefix(webhook, "-") + if !allWebhooksSet.Has(webhook) { + allErrors = append(allErrors, fmt.Errorf("%q is not in the list of known webhooks", webhook)) + } + } + + return allErrors +} + +func (o *WebhookOptions) ApplyTo(cfg *config.WebhookConfiguration) error { + if o == nil { + return nil + } + + cfg.Webhooks = o.Webhooks + + return nil +} + +type WebhookServingOptions struct { + *apiserveroptions.SecureServingOptions +} + +func NewWebhookServingOptions(defaults ProviderDefaults) *WebhookServingOptions { + var ( + bindAddress net.IP + bindPort int + ) + + if defaults.WebhookBindAddress != nil { + bindAddress = *defaults.WebhookBindAddress + } else { + bindAddress = netutils.ParseIPSloppy("0.0.0.0") + } + + if defaults.WebhookBindPort != nil { + bindPort = *defaults.WebhookBindPort + } else { + bindPort = CloudControllerManagerWebhookPort + } + + return &WebhookServingOptions{ + SecureServingOptions: &apiserveroptions.SecureServingOptions{ + BindAddress: bindAddress, + BindPort: bindPort, + ServerCert: apiserveroptions.GeneratableKeyCert{ + CertDirectory: "", + PairName: "cloud-controller-manager-webhook", + }, + }, + } +} + +func (o *WebhookServingOptions) AddFlags(fs *pflag.FlagSet) { + fs.IPVar(&o.BindAddress, "webhook-bind-address", o.BindAddress, ""+ + "The IP address on which to listen for the --webhook-secure-port port. The "+ + "associated interface(s) must be reachable by the rest of the cluster, and by CLI/web "+ + fmt.Sprintf("clients. If set to an unspecified address (0.0.0.0 or ::), all interfaces will be used. If unset, defaults to %v.", o.BindAddress)) + + fs.IntVar(&o.BindPort, "webhook-secure-port", o.BindPort, fmt.Sprintf("Secure port to serve cloud provider webhooks. If unset, defaults to %d.", o.BindPort)) + + fs.StringVar(&o.ServerCert.CertDirectory, "webhook-cert-dir", o.ServerCert.CertDirectory, ""+ + "The directory where the TLS certs are located. "+ + "If --tls-cert-file and --tls-private-key-file are provided, this flag will be ignored.") + + fs.StringVar(&o.ServerCert.CertKey.CertFile, "webhook-tls-cert-file", o.ServerCert.CertKey.CertFile, ""+ + "File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated "+ + "after server cert). If HTTPS serving is enabled, and --tls-cert-file and "+ + "--tls-private-key-file are not provided, a self-signed certificate and key "+ + "are generated for the public address and saved to the directory specified by --cert-dir.") + + fs.StringVar(&o.ServerCert.CertKey.KeyFile, "webhook-tls-private-key-file", o.ServerCert.CertKey.KeyFile, + "File containing the default x509 private key matching --tls-cert-file.") +} + +func (o *WebhookServingOptions) Validate() []error { + allErrors := []error{} + if o.BindPort < 0 || o.BindPort > 65535 { + allErrors = append(allErrors, fmt.Errorf("--webhook-secure-port %v must be between 0 and 65535, inclusive. A value of 0 disables the webhook endpoint entirely.", o.BindPort)) + } + + if (len(o.ServerCert.CertKey.CertFile) != 0 || len(o.ServerCert.CertKey.KeyFile) != 0) && o.ServerCert.GeneratedCert != nil { + allErrors = append(allErrors, fmt.Errorf("cert/key file and in-memory certificate cannot both be set")) + } + + return allErrors +} + +func (o *WebhookServingOptions) ApplyTo(cfg **server.SecureServingInfo) error { + if o == nil { + return nil + } + + if o.BindPort <= 0 { + return nil + } + + var err error + var listener net.Listener + addr := net.JoinHostPort(o.BindAddress.String(), strconv.Itoa(o.BindPort)) + + l := net.ListenConfig{} + + listener, o.BindPort, err = createListener(addr, l) + if err != nil { + return fmt.Errorf("failed to create listener: %v", err) + } + + *cfg = &server.SecureServingInfo{ + Listener: listener, + } + + serverCertFile, serverKeyFile := o.ServerCert.CertKey.CertFile, o.ServerCert.CertKey.KeyFile + if len(serverCertFile) != 0 || len(serverKeyFile) != 0 { + var err error + (*cfg).Cert, err = dynamiccertificates.NewDynamicServingContentFromFiles("serving-cert", serverCertFile, serverKeyFile) + if err != nil { + return err + } + } else if o.ServerCert.GeneratedCert != nil { + (*cfg).Cert = o.ServerCert.GeneratedCert + } + + return nil +} + +func createListener(addr string, config net.ListenConfig) (net.Listener, int, error) { + ln, err := config.Listen(context.TODO(), "tcp", addr) + if err != nil { + return nil, 0, fmt.Errorf("failed to listen on %v: %v", addr, err) + } + + // get port + tcpAddr, ok := ln.Addr().(*net.TCPAddr) + if !ok { + ln.Close() + return nil, 0, fmt.Errorf("invalid listen address: %q", ln.Addr().String()) + } + + return ln, tcpAddr.Port, nil +} diff --git a/vendor/k8s.io/cloud-provider/plugins.go b/vendor/k8s.io/cloud-provider/plugins.go index 5300abdb4..7aa061157 100644 --- a/vendor/k8s.io/cloud-provider/plugins.go +++ b/vendor/k8s.io/cloud-provider/plugins.go @@ -40,7 +40,6 @@ var ( external bool detail string }{ - {"aws", false, "The AWS provider is deprecated and will be removed in a future release. Please use https://github.com/kubernetes/cloud-provider-aws"}, {"azure", false, "The Azure provider is deprecated and will be removed in a future release. Please use https://github.com/kubernetes-sigs/cloud-provider-azure"}, {"gce", false, "The GCE provider is deprecated and will be removed in a future release. Please use https://github.com/kubernetes/cloud-provider-gcp"}, {"vsphere", false, "The vSphere provider is deprecated and will be removed in a future release. Please use https://github.com/kubernetes/cloud-provider-vsphere"}, diff --git a/vendor/k8s.io/component-base/config/types.go b/vendor/k8s.io/component-base/config/types.go index aad605eee..e1b9469d7 100644 --- a/vendor/k8s.io/component-base/config/types.go +++ b/vendor/k8s.io/component-base/config/types.go @@ -74,7 +74,7 @@ type LeaderElectionConfiguration struct { type DebuggingConfiguration struct { // enableProfiling enables profiling via web interface host:port/debug/pprof/ EnableProfiling bool - // enableContentionProfiling enables lock contention profiling, if + // enableContentionProfiling enables block profiling, if // enableProfiling is true. EnableContentionProfiling bool } diff --git a/vendor/k8s.io/component-base/config/v1alpha1/types.go b/vendor/k8s.io/component-base/config/v1alpha1/types.go index c9d05525d..3c5f004f2 100644 --- a/vendor/k8s.io/component-base/config/v1alpha1/types.go +++ b/vendor/k8s.io/component-base/config/v1alpha1/types.go @@ -60,7 +60,7 @@ type LeaderElectionConfiguration struct { type DebuggingConfiguration struct { // enableProfiling enables profiling via web interface host:port/debug/pprof/ EnableProfiling *bool `json:"enableProfiling,omitempty"` - // enableContentionProfiling enables lock contention profiling, if + // enableContentionProfiling enables block profiling, if // enableProfiling is true. EnableContentionProfiling *bool `json:"enableContentionProfiling,omitempty"` } diff --git a/vendor/k8s.io/component-base/logs/api/v1/options.go b/vendor/k8s.io/component-base/logs/api/v1/options.go index 6270b2eb9..a5e11f7d8 100644 --- a/vendor/k8s.io/component-base/logs/api/v1/options.go +++ b/vendor/k8s.io/component-base/logs/api/v1/options.go @@ -19,7 +19,9 @@ package v1 import ( "flag" "fmt" + "io" "math" + "os" "strings" "time" @@ -31,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" cliflag "k8s.io/component-base/cli/flag" "k8s.io/component-base/featuregate" + "k8s.io/component-base/logs/internal/setverbositylevel" "k8s.io/component-base/logs/klogflags" ) @@ -62,18 +65,41 @@ func NewLoggingConfiguration() *LoggingConfiguration { // The optional FeatureGate controls logging features. If nil, the default for // these features is used. func ValidateAndApply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { - return ValidateAndApplyAsField(c, featureGate, nil) + return validateAndApply(c, nil, featureGate, nil) +} + +// ValidateAndApplyWithOptions is a variant of ValidateAndApply which accepts +// additional options beyond those that can be configured through the API. This +// is meant for testing. +func ValidateAndApplyWithOptions(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error { + return validateAndApply(c, options, featureGate, nil) +} + +// +k8s:deepcopy-gen=false + +// LoggingOptions can be used with ValidateAndApplyWithOptions to override +// certain global defaults. +type LoggingOptions struct { + // ErrorStream can be used to override the os.Stderr default. + ErrorStream io.Writer + + // InfoStream can be used to override the os.Stdout default. + InfoStream io.Writer } // ValidateAndApplyAsField is a variant of ValidateAndApply that should be used // when the LoggingConfiguration is embedded in some larger configuration // structure. func ValidateAndApplyAsField(c *LoggingConfiguration, featureGate featuregate.FeatureGate, fldPath *field.Path) error { + return validateAndApply(c, nil, featureGate, fldPath) +} + +func validateAndApply(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate, fldPath *field.Path) error { errs := Validate(c, featureGate, fldPath) if len(errs) > 0 { return errs.ToAggregate() } - return apply(c, featureGate) + return apply(c, options, featureGate) } // Validate can be used to check for invalid settings without applying them. @@ -156,7 +182,7 @@ func featureEnabled(featureGate featuregate.FeatureGate, feature featuregate.Fea return enabled } -func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { +func apply(c *LoggingConfiguration, options *LoggingOptions, featureGate featuregate.FeatureGate) error { contextualLoggingEnabled := contextualLoggingDefault if featureGate != nil { contextualLoggingEnabled = featureGate.Enabled(ContextualLogging) @@ -167,8 +193,19 @@ func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { if format.factory == nil { klog.ClearLogger() } else { - log, flush := format.factory.Create(*c) - klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(flush)) + if options == nil { + options = &LoggingOptions{ + ErrorStream: os.Stderr, + InfoStream: os.Stdout, + } + } + log, control := format.factory.Create(*c, *options) + if control.SetVerbosityLevel != nil { + setverbositylevel.Mutex.Lock() + defer setverbositylevel.Mutex.Unlock() + setverbositylevel.Callbacks = append(setverbositylevel.Callbacks, control.SetVerbosityLevel) + } + klog.SetLoggerWithOptions(log, klog.ContextualLogger(contextualLoggingEnabled), klog.FlushLogger(control.Flush)) } if err := loggingFlags.Lookup("v").Value.Set(VerbosityLevelPflag(&c.Verbosity).String()); err != nil { return fmt.Errorf("internal error while setting klog verbosity: %v", err) @@ -183,6 +220,41 @@ func apply(c *LoggingConfiguration, featureGate featuregate.FeatureGate) error { // AddFlags adds command line flags for the configuration. func AddFlags(c *LoggingConfiguration, fs *pflag.FlagSet) { + addFlags(c, fs) +} + +// AddGoFlags is a variant of AddFlags for a standard FlagSet. +func AddGoFlags(c *LoggingConfiguration, fs *flag.FlagSet) { + addFlags(c, goFlagSet{FlagSet: fs}) +} + +// flagSet is the interface implemented by pflag.FlagSet, with +// just those methods defined which are needed by addFlags. +type flagSet interface { + BoolVar(p *bool, name string, value bool, usage string) + DurationVar(p *time.Duration, name string, value time.Duration, usage string) + StringVar(p *string, name string, value string, usage string) + Var(value pflag.Value, name string, usage string) + VarP(value pflag.Value, name, shorthand, usage string) +} + +// goFlagSet implements flagSet for a stdlib flag.FlagSet. +type goFlagSet struct { + *flag.FlagSet +} + +func (fs goFlagSet) Var(value pflag.Value, name string, usage string) { + fs.FlagSet.Var(value, name, usage) +} + +func (fs goFlagSet) VarP(value pflag.Value, name, shorthand, usage string) { + // Ignore shorthand, it's not needed and not supported. + fs.FlagSet.Var(value, name, usage) +} + +// addFlags can be used with both flag.FlagSet and pflag.FlagSet. The internal +// interface definition avoids duplicating this code. +func addFlags(c *LoggingConfiguration, fs flagSet) { formats := logRegistry.list() fs.StringVar(&c.Format, "logging-format", c.Format, fmt.Sprintf("Sets the log format. Permitted formats: %s.", formats)) // No new log formats should be added after generation is of flag options diff --git a/vendor/k8s.io/component-base/logs/api/v1/registry.go b/vendor/k8s.io/component-base/logs/api/v1/registry.go index 78bc8f885..f8fc1f2ca 100644 --- a/vendor/k8s.io/component-base/logs/api/v1/registry.go +++ b/vendor/k8s.io/component-base/logs/api/v1/registry.go @@ -39,14 +39,29 @@ type logFormat struct { feature featuregate.Feature } +// +k8s:deepcopy-gen=false + +// RuntimeControl provides operations that aren't available through the normal +// Logger or LogSink API. +type RuntimeControl struct { + // Flush ensures that all in-memory data is written. + // May be nil. + Flush func() + + // SetVerbosityLevel changes the level for all Logger instances + // derived from the initial one. May be nil. + // + // The parameter is intentionally a plain uint32 instead of + // VerbosityLevel to enable implementations that don't need to import + // the API (helps avoid circular dependencies). + SetVerbosityLevel func(v uint32) error +} + // LogFormatFactory provides support for a certain additional, // non-default log format. type LogFormatFactory interface { // Create returns a logger with the requested configuration. - // Returning a flush function for the logger is optional. - // If provided, the caller must ensure that it is called - // periodically (if desired) and at program exit. - Create(c LoggingConfiguration) (log logr.Logger, flush func()) + Create(c LoggingConfiguration, o LoggingOptions) (logr.Logger, RuntimeControl) } // RegisterLogFormat registers support for a new logging format. This must be called diff --git a/vendor/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go b/vendor/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go new file mode 100644 index 000000000..c643bae9b --- /dev/null +++ b/vendor/k8s.io/component-base/logs/internal/setverbositylevel/setverbositylevel.go @@ -0,0 +1,34 @@ +/* +Copyright 2022 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 setverbositylevel stores callbacks that will be invoked by logs.GlogLevel. +// +// This is a separate package to avoid a dependency from +// k8s.io/component-base/logs (uses the callbacks) to +// k8s.io/component-base/logs/api/v1 (adds them). Not all users of the logs +// package also use the API. +package setverbositylevel + +import ( + "sync" +) + +var ( + // Mutex controls access to the callbacks. + Mutex sync.Mutex + + Callbacks []func(v uint32) error +) diff --git a/vendor/k8s.io/component-base/logs/logs.go b/vendor/k8s.io/component-base/logs/logs.go index 886c154e4..7fda0f911 100644 --- a/vendor/k8s.io/component-base/logs/logs.go +++ b/vendor/k8s.io/component-base/logs/logs.go @@ -23,10 +23,12 @@ import ( "flag" "fmt" "log" + "strconv" "time" "github.com/spf13/pflag" logsapi "k8s.io/component-base/logs/api/v1" + "k8s.io/component-base/logs/internal/setverbositylevel" "k8s.io/component-base/logs/klogflags" "k8s.io/klog/v2" ) @@ -182,11 +184,26 @@ func NewLogger(prefix string) *log.Logger { return log.New(KlogWriter{}, prefix, 0) } -// GlogSetter is a setter to set glog level. +// GlogSetter modifies the verbosity threshold for the entire program. +// Some components have HTTP-based APIs for invoking this at runtime. func GlogSetter(val string) (string, error) { + v, err := strconv.ParseUint(val, 10, 32) + if err != nil { + return "", err + } + var level klog.Level if err := level.Set(val); err != nil { return "", fmt.Errorf("failed set klog.logging.verbosity %s: %v", val, err) } + + setverbositylevel.Mutex.Lock() + defer setverbositylevel.Mutex.Unlock() + for _, cb := range setverbositylevel.Callbacks { + if err := cb(uint32(v)); err != nil { + return "", err + } + } + return fmt.Sprintf("successfully set klog.logging.verbosity to %s", val), nil } diff --git a/vendor/k8s.io/component-base/metrics/features/kube_features.go b/vendor/k8s.io/component-base/metrics/features/kube_features.go index 3f1713214..3cd6c22af 100644 --- a/vendor/k8s.io/component-base/metrics/features/kube_features.go +++ b/vendor/k8s.io/component-base/metrics/features/kube_features.go @@ -29,7 +29,7 @@ const ( func featureGates() map[featuregate.Feature]featuregate.FeatureSpec { return map[featuregate.Feature]featuregate.FeatureSpec{ - ComponentSLIs: {Default: false, PreRelease: featuregate.Alpha}, + ComponentSLIs: {Default: true, PreRelease: featuregate.Beta}, } } diff --git a/vendor/k8s.io/component-base/metrics/metric.go b/vendor/k8s.io/component-base/metrics/metric.go index 87352e92e..3b22d21ef 100644 --- a/vendor/k8s.io/component-base/metrics/metric.go +++ b/vendor/k8s.io/component-base/metrics/metric.go @@ -97,9 +97,8 @@ func (r *lazyMetric) lazyInit(self kubeCollector, fqName string) { // 2. if the metric is manually disabled via a CLI flag. // // Disclaimer: disabling a metric via a CLI flag has higher precedence than -// -// deprecation and will override show-hidden-metrics for the explicitly -// disabled metric. +// deprecation and will override show-hidden-metrics for the explicitly +// disabled metric. func (r *lazyMetric) preprocessMetric(version semver.Version) { disabledMetricsLock.RLock() defer disabledMetricsLock.RUnlock() diff --git a/vendor/k8s.io/component-base/metrics/testutil/testutil.go b/vendor/k8s.io/component-base/metrics/testutil/testutil.go index 439045989..8587c7522 100644 --- a/vendor/k8s.io/component-base/metrics/testutil/testutil.go +++ b/vendor/k8s.io/component-base/metrics/testutil/testutil.go @@ -67,6 +67,13 @@ func CustomCollectAndCompare(c metrics.StableCollector, expected io.Reader, metr return GatherAndCompare(registry, expected, metricNames...) } +// ScrapeAndCompare calls a remote exporter's endpoint which is expected to return some metrics in +// plain text format. Then it compares it with the results that the `expected` would return. +// If the `metricNames` is not empty it would filter the comparison only to the given metric names. +func ScrapeAndCompare(url string, expected io.Reader, metricNames ...string) error { + return testutil.ScrapeAndCompare(url, expected, metricNames...) +} + // NewFakeKubeRegistry creates a fake `KubeRegistry` that takes the input version as `build in version`. // It should only be used in testing scenario especially for the deprecated metrics. // The input version format should be `major.minor.patch`, e.g. '1.18.0'. diff --git a/vendor/k8s.io/component-base/metrics/value.go b/vendor/k8s.io/component-base/metrics/value.go index b525bb602..4a405048c 100644 --- a/vendor/k8s.io/component-base/metrics/value.go +++ b/vendor/k8s.io/component-base/metrics/value.go @@ -60,8 +60,7 @@ func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues // NewLazyMetricWithTimestamp is a helper of NewMetricWithTimestamp. // // Warning: the Metric 'm' must be the one created by NewLazyConstMetric(), -// -// otherwise, no stability guarantees would be offered. +// otherwise, no stability guarantees would be offered. func NewLazyMetricWithTimestamp(t time.Time, m Metric) Metric { if m == nil { return nil diff --git a/vendor/k8s.io/controller-manager/options/debugging.go b/vendor/k8s.io/controller-manager/options/debugging.go index eafd78a88..063186a50 100644 --- a/vendor/k8s.io/controller-manager/options/debugging.go +++ b/vendor/k8s.io/controller-manager/options/debugging.go @@ -46,7 +46,7 @@ func (o *DebuggingOptions) AddFlags(fs *pflag.FlagSet) { fs.BoolVar(&o.EnableProfiling, "profiling", o.EnableProfiling, "Enable profiling via web interface host:port/debug/pprof/") fs.BoolVar(&o.EnableContentionProfiling, "contention-profiling", o.EnableContentionProfiling, - "Enable lock contention profiling, if profiling is enabled") + "Enable block profiling, if profiling is enabled") } // ApplyTo fills up Debugging config with options. diff --git a/vendor/k8s.io/controller-manager/options/generic.go b/vendor/k8s.io/controller-manager/options/generic.go index bb7e8c7d4..45c086b11 100644 --- a/vendor/k8s.io/controller-manager/options/generic.go +++ b/vendor/k8s.io/controller-manager/options/generic.go @@ -102,6 +102,12 @@ func (o *GenericControllerManagerConfigurationOptions) Validate(allControllers [ errs := []error{} errs = append(errs, o.Debugging.Validate()...) + // TODO: This can be removed when ResourceLock is not available + // Lock the ResourceLock using leases + if o.LeaderElection.LeaderElect && o.LeaderElection.ResourceLock != "leases" { + errs = append(errs, fmt.Errorf(`resourceLock value must be "leases"`)) + } + allControllersSet := sets.NewString(allControllers...) for _, controller := range o.Controllers { if controller == "*" { diff --git a/vendor/k8s.io/controller-manager/pkg/features/kube_features.go b/vendor/k8s.io/controller-manager/pkg/features/kube_features.go index 62d44a09e..8864be325 100644 --- a/vendor/k8s.io/controller-manager/pkg/features/kube_features.go +++ b/vendor/k8s.io/controller-manager/pkg/features/kube_features.go @@ -32,21 +32,26 @@ const ( // of code conflicts because changes are more likely to be scattered // across the file. - // owner: @jiahuif - // alpha: v1.21 - // beta: v1.22 - // GA: v1.24 - // - // Enables Leader Migration for kube-controller-manager and cloud-controller-manager - // copied and sync'ed from k8s.io/kubernetes/pkg/features/kube_features.go - ControllerManagerLeaderMigration featuregate.Feature = "ControllerManagerLeaderMigration" + // owner: @nckturner + // kep: http://kep.k8s.io/2699 + // alpha: v1.27 + // Enable webhook in cloud controller manager + CloudControllerManagerWebhook featuregate.Feature = "CloudControllerManagerWebhook" - // owner: @khenidak - // alpha: v1.15 + // owner: @danwinship + // alpha: v1.27 // - // Enables ipv6 dual stack - // Original copy from k8s.io/kubernetes/pkg/features/kube_features.go - IPv6DualStack featuregate.Feature = "IPv6DualStack" + // Enables dual-stack values in the + // `alpha.kubernetes.io/provided-node-ip` annotation + CloudDualStackNodeIPs featuregate.Feature = "CloudDualStackNodeIPs" + + // owner: @alexanderConstantinescu + // kep: http://kep.k8s.io/3458 + // beta: v1.27 + // + // Enables less load balancer re-configurations by the service controller + // (KCCM) as an effect of changing node state. + StableLoadBalancerNodeSet featuregate.Feature = "StableLoadBalancerNodeSet" ) func SetupCurrentKubernetesSpecificFeatureGates(featuregates featuregate.MutableFeatureGate) error { @@ -56,7 +61,7 @@ func SetupCurrentKubernetesSpecificFeatureGates(featuregates featuregate.Mutable // cloudPublicFeatureGates consists of cloud-specific feature keys. // To add a new feature, define a key for it at k8s.io/api/pkg/features and add it here. var cloudPublicFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ - ControllerManagerLeaderMigration: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26 - - IPv6DualStack: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, + CloudControllerManagerWebhook: {Default: false, PreRelease: featuregate.Alpha}, + CloudDualStackNodeIPs: {Default: false, PreRelease: featuregate.Alpha}, + StableLoadBalancerNodeSet: {Default: true, PreRelease: featuregate.Beta}, } diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go index de8a2c9e0..362893b40 100644 --- a/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/config/default.go @@ -19,8 +19,7 @@ package config import internal "k8s.io/controller-manager/config" // DefaultLeaderMigrationConfiguration returns the default LeaderMigrationConfiguration -// -// that is valid for this release of Kubernetes. +// that is valid for this release of Kubernetes. func DefaultLeaderMigrationConfiguration() *internal.LeaderMigrationConfiguration { return &internal.LeaderMigrationConfiguration{ LeaderName: "cloud-provider-extraction-migration", diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/filter.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/filter.go deleted file mode 100644 index a3e8f2187..000000000 --- a/vendor/k8s.io/controller-manager/pkg/leadermigration/filter.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2021 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 leadermigration - -// FilterResult indicates whether and how the controller manager should start the controller. -type FilterResult int32 - -const ( - // ControllerUnowned indicates that the controller is owned by another controller manager - // and thus should NOT be started by this controller manager. - ControllerUnowned = iota - // ControllerMigrated indicates that the controller manager should start this controller - // with the migration lock. - ControllerMigrated - // ControllerNonMigrated indicates that the controller manager should start this controller - // with the main lock. - ControllerNonMigrated -) - -// FilterFunc takes a name of controller, returning a FilterResult indicating how to start controller. -type FilterFunc func(controllerName string) FilterResult diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/migrator.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/migrator.go deleted file mode 100644 index fdd74a46a..000000000 --- a/vendor/k8s.io/controller-manager/pkg/leadermigration/migrator.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2021 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 leadermigration - -import ( - internal "k8s.io/controller-manager/config" -) - -// LeaderMigrator holds information required by the leader migration process. -type LeaderMigrator struct { - // MigrationReady is closed after the controller manager finishes preparing for the migration lock. - // After this point, the leader migration process will proceed to acquire the migration lock. - MigrationReady chan struct{} - - // FilterFunc returns a FilterResult telling the controller manager what to do with the controller. - FilterFunc FilterFunc -} - -// NewLeaderMigrator creates a LeaderMigrator with given config for the given component. component -// -// indicates which controller manager is requesting this leader migration, and it should be consistent -// with the component field of ControllerLeaderConfiguration. -func NewLeaderMigrator(config *internal.LeaderMigrationConfiguration, component string) *LeaderMigrator { - migratedControllers := make(map[string]bool) - for _, leader := range config.ControllerLeaders { - migratedControllers[leader.Name] = leader.Component == component || leader.Component == "*" - } - return &LeaderMigrator{ - MigrationReady: make(chan struct{}), - FilterFunc: func(controllerName string) FilterResult { - shouldRun, ok := migratedControllers[controllerName] - if ok { - // The controller is included in the migration - if shouldRun { - // If the controller manager should run the controller, - // start it in the migration lock. - return ControllerMigrated - } - // Otherwise, the controller should be started by - // some other controller manager. - return ControllerUnowned - } - // The controller is not included in the migration, - // and should be started in the main lock. - return ControllerNonMigrated - }, - } -} diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go index 5bd078ec7..abbd75e6f 100644 --- a/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go +++ b/vendor/k8s.io/controller-manager/pkg/leadermigration/options/options.go @@ -21,7 +21,6 @@ import ( "github.com/spf13/pflag" "k8s.io/controller-manager/config" - "k8s.io/controller-manager/pkg/leadermigration" migrationconfig "k8s.io/controller-manager/pkg/leadermigration/config" ) @@ -65,9 +64,6 @@ func (o *LeaderMigrationOptions) ApplyTo(cfg *config.GenericControllerManagerCon cfg.LeaderMigrationEnabled = false return nil } - if o.Enabled && !leadermigration.FeatureEnabled() { - return fmt.Errorf("Leader Migration is not enabled through feature gate") - } cfg.LeaderMigrationEnabled = o.Enabled if !cfg.LeaderMigrationEnabled { return nil diff --git a/vendor/k8s.io/controller-manager/pkg/leadermigration/util.go b/vendor/k8s.io/controller-manager/pkg/leadermigration/util.go deleted file mode 100644 index 83eacc0df..000000000 --- a/vendor/k8s.io/controller-manager/pkg/leadermigration/util.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2021 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 leadermigration - -import config "k8s.io/controller-manager/config" - -// Enabled checks whether Leader Migration should be enabled, given the GenericControllerManagerConfiguration. -// It considers the feature gate first, and will always return false if the feature gate is not enabled. -func Enabled(genericConfig *config.GenericControllerManagerConfiguration) bool { - return FeatureEnabled() && genericConfig.LeaderElection.LeaderElect && genericConfig.LeaderMigrationEnabled -} diff --git a/vendor/k8s.io/kms/apis/v1beta1/api.pb.go b/vendor/k8s.io/kms/apis/v1beta1/api.pb.go index 6210014a2..49c4713fb 100644 --- a/vendor/k8s.io/kms/apis/v1beta1/api.pb.go +++ b/vendor/k8s.io/kms/apis/v1beta1/api.pb.go @@ -322,25 +322,27 @@ func init() { func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 286 bytes of a gzipped FileDescriptorProto + // 308 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4f, 0x4b, 0xc3, 0x30, - 0x14, 0x5f, 0x27, 0xae, 0xec, 0x59, 0x5a, 0x08, 0x43, 0x8b, 0x27, 0xcd, 0x65, 0xea, 0xa1, 0x30, - 0xbd, 0x8b, 0x88, 0x9e, 0x44, 0x0f, 0x15, 0xbc, 0x4a, 0x56, 0x1e, 0x1a, 0xb0, 0x69, 0x4c, 0xb3, - 0xca, 0xbe, 0xa8, 0x9f, 0x47, 0x6c, 0x5e, 0x6b, 0x3a, 0x11, 0x77, 0x7c, 0x2f, 0xef, 0xf7, 0xef, - 0xbd, 0xc0, 0x54, 0x68, 0x99, 0x69, 0x53, 0xd9, 0x8a, 0x85, 0xcd, 0x62, 0x89, 0x56, 0x2c, 0xf8, - 0x19, 0xc4, 0x4f, 0x68, 0x6a, 0x59, 0xa9, 0x1c, 0xdf, 0x57, 0x58, 0x5b, 0x96, 0x42, 0xd8, 0xb8, - 0x4e, 0x1a, 0x1c, 0x05, 0x27, 0xd3, 0xbc, 0x2b, 0xf9, 0x07, 0x24, 0xfd, 0x6c, 0xad, 0x2b, 0x55, - 0xe3, 0xdf, 0xc3, 0xec, 0x18, 0x22, 0xb3, 0x52, 0x56, 0x96, 0xf8, 0xac, 0x44, 0x89, 0xe9, 0xb8, - 0x7d, 0xde, 0xa3, 0xde, 0x83, 0x28, 0x91, 0xcd, 0x21, 0xe9, 0x46, 0x3a, 0x92, 0x9d, 0x76, 0x2a, - 0xa6, 0x36, 0xa9, 0xf1, 0x6b, 0x88, 0x6f, 0xb0, 0x30, 0x6b, 0x6d, 0xff, 0x35, 0xc9, 0xf6, 0x61, - 0x52, 0x48, 0xfd, 0x8a, 0xa6, 0x55, 0x8c, 0x72, 0xaa, 0xf8, 0x1c, 0x92, 0x9e, 0x83, 0xcc, 0xcf, - 0x60, 0x57, 0xbf, 0x09, 0xe9, 0x28, 0xa2, 0xdc, 0x15, 0xfc, 0x0a, 0xe2, 0x5b, 0xb5, 0xa5, 0x58, - 0xcf, 0x30, 0xf6, 0x19, 0x4e, 0x21, 0xe9, 0x19, 0x48, 0xea, 0xc7, 0x55, 0xe0, 0xbb, 0x3a, 0xff, - 0x0c, 0x60, 0x76, 0x87, 0xeb, 0x7b, 0xa1, 0xc4, 0x0b, 0x96, 0xa8, 0xec, 0x23, 0x9a, 0x46, 0x16, - 0xc8, 0x2e, 0x21, 0xa4, 0xf4, 0xec, 0x20, 0xa3, 0x63, 0x65, 0xc3, 0x4b, 0x1d, 0xa6, 0xbf, 0x1f, - 0x9c, 0x1c, 0x1f, 0x7d, 0xe3, 0x29, 0xae, 0x87, 0x1f, 0x2e, 0xd1, 0xc3, 0x6f, 0x6c, 0xc6, 0xe1, - 0x29, 0x83, 0x87, 0x1f, 0xee, 0xc5, 0xc3, 0x6f, 0xc4, 0xe5, 0xa3, 0xe5, 0xa4, 0xfd, 0x67, 0x17, - 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x57, 0xc8, 0x65, 0x5a, 0x74, 0x02, 0x00, 0x00, + 0x14, 0x5f, 0x27, 0x6e, 0xec, 0x59, 0x5a, 0x08, 0xc3, 0x55, 0x4f, 0x9a, 0xcb, 0xd4, 0x43, 0xcb, + 0xf4, 0xe2, 0x49, 0x64, 0xe8, 0x49, 0xf4, 0x50, 0xc1, 0x83, 0x17, 0xc9, 0xca, 0x43, 0xc3, 0x6c, + 0x1a, 0x93, 0xac, 0xb2, 0x2f, 0xea, 0xe7, 0x11, 0xdb, 0xb4, 0xa6, 0x13, 0xd1, 0xe3, 0x7b, 0xf9, + 0xfd, 0x79, 0xbf, 0xf7, 0x02, 0x23, 0x26, 0x79, 0x2c, 0x55, 0x61, 0x0a, 0x32, 0x2c, 0x67, 0x0b, + 0x34, 0x6c, 0x46, 0x4f, 0x20, 0x78, 0x40, 0xa5, 0x79, 0x21, 0x52, 0x7c, 0x5b, 0xa1, 0x36, 0x24, + 0x82, 0x61, 0x59, 0x77, 0x22, 0xef, 0xc0, 0x3b, 0x1a, 0xa5, 0x4d, 0x49, 0xdf, 0x21, 0x6c, 0xb1, + 0x5a, 0x16, 0x42, 0xe3, 0xef, 0x60, 0x72, 0x08, 0xbe, 0x5a, 0x09, 0xc3, 0x73, 0x7c, 0x12, 0x2c, + 0xc7, 0xa8, 0x5f, 0x3d, 0xef, 0xd8, 0xde, 0x1d, 0xcb, 0x91, 0x4c, 0x21, 0x6c, 0x20, 0x8d, 0xc8, + 0x56, 0x85, 0x0a, 0x6c, 0xdb, 0xba, 0xd1, 0x39, 0x04, 0x57, 0x98, 0xa9, 0xb5, 0x34, 0x7f, 0x0e, + 0x49, 0x76, 0x61, 0x90, 0x71, 0xf9, 0x82, 0xaa, 0x72, 0xf4, 0x53, 0x5b, 0xd1, 0x29, 0x84, 0xad, + 0x86, 0x1d, 0x7e, 0x0c, 0xdb, 0xf2, 0x95, 0xf1, 0x5a, 0xc2, 0x4f, 0xeb, 0x82, 0x5e, 0x42, 0x70, + 0x2d, 0xfe, 0x69, 0xd6, 0x2a, 0xf4, 0x5d, 0x85, 0x63, 0x08, 0x5b, 0x05, 0x6b, 0xf5, 0x3d, 0x95, + 0xe7, 0x4e, 0x75, 0xfa, 0xe1, 0xc1, 0xf8, 0x06, 0xd7, 0xb7, 0x4c, 0xb0, 0x67, 0xcc, 0x51, 0x98, + 0x7b, 0x54, 0x25, 0xcf, 0x90, 0x5c, 0xc0, 0xd0, 0xa6, 0x27, 0x93, 0xd8, 0x1e, 0x2b, 0xee, 0x5e, + 0x6a, 0x3f, 0xfa, 0xf9, 0x50, 0xdb, 0xd1, 0xde, 0x17, 0xdf, 0xc6, 0x75, 0xf8, 0xdd, 0x25, 0x3a, + 0xfc, 0x8d, 0xcd, 0xd4, 0x7c, 0x9b, 0xc1, 0xe1, 0x77, 0xf7, 0xe2, 0xf0, 0x37, 0xe2, 0xd2, 0xde, + 0x7c, 0xef, 0x71, 0xb2, 0x3c, 0xd7, 0x31, 0x2f, 0x92, 0x65, 0xae, 0x13, 0x26, 0xb9, 0x4e, 0x2c, + 0x78, 0x31, 0xa8, 0xbe, 0xe0, 0xd9, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0x13, 0xcb, 0x8d, 0x9b, + 0x8f, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/vendor/k8s.io/kms/apis/v1beta1/api.proto b/vendor/k8s.io/kms/apis/v1beta1/api.proto index a9b44bf5f..22450edcd 100644 --- a/vendor/k8s.io/kms/apis/v1beta1/api.proto +++ b/vendor/k8s.io/kms/apis/v1beta1/api.proto @@ -14,10 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// To regenerate api.pb.go run hack/update-generated-kms.sh +// To regenerate api.pb.go run `hack/update-codegen.sh protobindings` syntax = "proto3"; package v1beta1; +option go_package = "k8s.io/kms/apis/v1beta1"; // This service defines the public APIs for remote KMS provider. service KeyManagementService { diff --git a/vendor/k8s.io/kms/apis/v2alpha1/api.pb.go b/vendor/k8s.io/kms/apis/v2/api.pb.go similarity index 83% rename from vendor/k8s.io/kms/apis/v2alpha1/api.pb.go rename to vendor/k8s.io/kms/apis/v2/api.pb.go index ab55bd1b3..cb746a64c 100644 --- a/vendor/k8s.io/kms/apis/v2alpha1/api.pb.go +++ b/vendor/k8s.io/kms/apis/v2/api.pb.go @@ -17,7 +17,7 @@ limitations under the License. // Code generated by protoc-gen-gogo. DO NOT EDIT. // source: api.proto -package v2alpha1 +package v2 import ( context "context" @@ -342,45 +342,46 @@ func (m *EncryptResponse) GetAnnotations() map[string][]byte { } func init() { - proto.RegisterType((*StatusRequest)(nil), "v2alpha1.StatusRequest") - proto.RegisterType((*StatusResponse)(nil), "v2alpha1.StatusResponse") - proto.RegisterType((*DecryptRequest)(nil), "v2alpha1.DecryptRequest") - proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.DecryptRequest.AnnotationsEntry") - proto.RegisterType((*DecryptResponse)(nil), "v2alpha1.DecryptResponse") - proto.RegisterType((*EncryptRequest)(nil), "v2alpha1.EncryptRequest") - proto.RegisterType((*EncryptResponse)(nil), "v2alpha1.EncryptResponse") - proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.EncryptResponse.AnnotationsEntry") + proto.RegisterType((*StatusRequest)(nil), "v2.StatusRequest") + proto.RegisterType((*StatusResponse)(nil), "v2.StatusResponse") + proto.RegisterType((*DecryptRequest)(nil), "v2.DecryptRequest") + proto.RegisterMapType((map[string][]byte)(nil), "v2.DecryptRequest.AnnotationsEntry") + proto.RegisterType((*DecryptResponse)(nil), "v2.DecryptResponse") + proto.RegisterType((*EncryptRequest)(nil), "v2.EncryptRequest") + proto.RegisterType((*EncryptResponse)(nil), "v2.EncryptResponse") + proto.RegisterMapType((map[string][]byte)(nil), "v2.EncryptResponse.AnnotationsEntry") } func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } var fileDescriptor_00212fb1f9d3bf1c = []byte{ - // 391 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xcf, 0x4f, 0xe2, 0x40, - 0x14, 0xc7, 0x29, 0x5d, 0x60, 0x79, 0xb0, 0x40, 0x26, 0x6c, 0xb6, 0x4b, 0x36, 0x1b, 0x32, 0x27, - 0x76, 0x0f, 0xdd, 0x2c, 0x5e, 0x8c, 0x89, 0x06, 0x13, 0x39, 0x18, 0xf4, 0x52, 0x8e, 0x1e, 0xcc, - 0x08, 0x2f, 0x76, 0x42, 0x9d, 0xd6, 0x76, 0xda, 0x58, 0xff, 0x50, 0x13, 0xff, 0x01, 0xff, 0x0e, - 0xd3, 0x76, 0xa0, 0x2d, 0x88, 0x9e, 0xbc, 0xcd, 0xfb, 0xd1, 0xef, 0xf7, 0xcd, 0x67, 0x5e, 0xa1, - 0xc9, 0x3c, 0x6e, 0x7a, 0xbe, 0x2b, 0x5d, 0xf2, 0x35, 0x1a, 0x33, 0xc7, 0xb3, 0xd9, 0x7f, 0xda, - 0x85, 0x6f, 0x73, 0xc9, 0x64, 0x18, 0x58, 0x78, 0x1f, 0x62, 0x20, 0xe9, 0x15, 0x74, 0xd6, 0x89, - 0xc0, 0x73, 0x45, 0x80, 0xc4, 0x80, 0x46, 0x84, 0x7e, 0xc0, 0x5d, 0x61, 0x68, 0x43, 0x6d, 0xd4, - 0xb4, 0xd6, 0x61, 0x52, 0xb1, 0x91, 0x39, 0xd2, 0x7e, 0x34, 0xaa, 0x59, 0x45, 0x85, 0xe4, 0x3b, - 0xd4, 0x57, 0x18, 0x5f, 0xf3, 0xa5, 0xa1, 0xa7, 0x85, 0xda, 0x0a, 0xe3, 0xf3, 0x25, 0x7d, 0xd1, - 0xa0, 0x73, 0x86, 0x0b, 0x3f, 0xf6, 0xa4, 0xf2, 0x23, 0xbf, 0x01, 0x16, 0xdc, 0xb3, 0xd1, 0x97, - 0xf8, 0x20, 0x53, 0x83, 0xb6, 0x55, 0xc8, 0x90, 0x1e, 0xe8, 0x21, 0x5f, 0x2a, 0xfd, 0xe4, 0xb8, - 0x47, 0x9b, 0xcc, 0xa0, 0xc5, 0x84, 0x70, 0x25, 0x93, 0xdc, 0x15, 0x81, 0xf1, 0x65, 0xa8, 0x8f, - 0x5a, 0xe3, 0x3f, 0xe6, 0xfa, 0xa6, 0x66, 0xd9, 0xd7, 0x3c, 0xcd, 0x7b, 0xa7, 0x42, 0xfa, 0xb1, - 0x55, 0xfc, 0x7a, 0x70, 0x02, 0xbd, 0xed, 0x86, 0x64, 0x92, 0x15, 0xc6, 0x8a, 0x41, 0x72, 0x24, - 0x7d, 0xa8, 0x45, 0xcc, 0x09, 0x31, 0x9d, 0xae, 0x6d, 0x65, 0xc1, 0x51, 0xf5, 0x50, 0xa3, 0xff, - 0xa0, 0xbb, 0xf1, 0x53, 0x18, 0x7f, 0x41, 0xd3, 0x73, 0x18, 0x17, 0x85, 0x7b, 0xe6, 0x09, 0x3a, - 0x81, 0xce, 0x54, 0x94, 0xc0, 0xbc, 0xdb, 0xbf, 0x8b, 0x85, 0x3e, 0x69, 0xd0, 0xdd, 0x48, 0x28, - 0xcf, 0x8f, 0xe0, 0xe6, 0x28, 0xab, 0x45, 0x94, 0x17, 0x65, 0x94, 0x7a, 0x8a, 0xf2, 0x6f, 0x8e, - 0x72, 0xcb, 0xe6, 0x73, 0x59, 0x8e, 0x9f, 0x35, 0xe8, 0xcf, 0x30, 0xbe, 0x64, 0x82, 0xdd, 0xe2, - 0x1d, 0x0a, 0x39, 0x47, 0x3f, 0xe2, 0x0b, 0x24, 0xc7, 0x50, 0xcf, 0x56, 0x95, 0xfc, 0xc8, 0x67, - 0x2b, 0x6d, 0xf3, 0xc0, 0xd8, 0x2d, 0x64, 0x33, 0xd3, 0x0a, 0x99, 0x40, 0x43, 0xbd, 0x11, 0x31, - 0xf6, 0xad, 0xc9, 0xe0, 0xe7, 0x1b, 0x95, 0xa2, 0x82, 0x42, 0x51, 0x54, 0x28, 0xbf, 0x63, 0x51, - 0x61, 0x8b, 0x1b, 0xad, 0xdc, 0xd4, 0xd3, 0xff, 0xf1, 0xe0, 0x35, 0x00, 0x00, 0xff, 0xff, 0xa7, - 0xdd, 0xa1, 0x79, 0x9c, 0x03, 0x00, 0x00, + // 403 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xcd, 0x6e, 0xda, 0x40, + 0x10, 0xc7, 0xb1, 0x5d, 0x40, 0x0c, 0x14, 0xe8, 0x96, 0x4a, 0x16, 0xaa, 0x2a, 0xb4, 0xed, 0x81, + 0x93, 0xad, 0xba, 0x3d, 0xa0, 0x1e, 0xaa, 0xb6, 0x2a, 0x95, 0xaa, 0xaa, 0x17, 0x73, 0x6b, 0x0f, + 0xd1, 0x06, 0x46, 0x61, 0x65, 0x58, 0x3b, 0xde, 0xb5, 0x15, 0xe7, 0xbd, 0xf2, 0x1e, 0x79, 0x84, + 0x3c, 0x4a, 0x64, 0x7b, 0x01, 0x1b, 0x94, 0xe4, 0x94, 0x9b, 0xe7, 0xf3, 0x3f, 0xf3, 0xdb, 0x31, + 0x74, 0x58, 0xc4, 0x9d, 0x28, 0x0e, 0x55, 0x48, 0xcc, 0xd4, 0xa3, 0x03, 0x78, 0xb9, 0x50, 0x4c, + 0x25, 0xd2, 0xc7, 0xcb, 0x04, 0xa5, 0xa2, 0xff, 0xa1, 0xbf, 0x73, 0xc8, 0x28, 0x14, 0x12, 0x89, + 0x0d, 0xed, 0x14, 0x63, 0xc9, 0x43, 0x61, 0x1b, 0x13, 0x63, 0xda, 0xf1, 0x77, 0x66, 0x1e, 0x59, + 0x23, 0xdb, 0xa8, 0xf5, 0xb5, 0x6d, 0x96, 0x11, 0x6d, 0x92, 0x37, 0xd0, 0x0a, 0x30, 0x3b, 0xe3, + 0x2b, 0xdb, 0x2a, 0x02, 0xcd, 0x00, 0xb3, 0xdf, 0x2b, 0x7a, 0x67, 0x40, 0xff, 0x27, 0x2e, 0xe3, + 0x2c, 0x52, 0x5a, 0x8f, 0xbc, 0x03, 0x58, 0xf2, 0x68, 0x8d, 0xb1, 0xc2, 0x2b, 0x55, 0x08, 0xf4, + 0xfc, 0x8a, 0x87, 0x0c, 0xc1, 0x4a, 0xf8, 0x4a, 0xf7, 0xcf, 0x3f, 0x1f, 0xe8, 0x4d, 0xe6, 0xd0, + 0x65, 0x42, 0x84, 0x8a, 0x29, 0x1e, 0x0a, 0x69, 0xbf, 0x98, 0x58, 0xd3, 0xae, 0xf7, 0xde, 0x49, + 0x3d, 0xa7, 0xae, 0xe8, 0x7c, 0x3f, 0x64, 0xcd, 0x85, 0x8a, 0x33, 0xbf, 0x5a, 0x37, 0xfe, 0x0a, + 0xc3, 0xe3, 0x84, 0x7c, 0x86, 0x00, 0x33, 0xbd, 0x7d, 0xfe, 0x49, 0x46, 0xd0, 0x4c, 0xd9, 0x26, + 0xc1, 0x62, 0xae, 0x9e, 0x5f, 0x1a, 0x5f, 0xcc, 0x99, 0x41, 0x5d, 0x18, 0xec, 0xf5, 0x34, 0xc0, + 0xb7, 0xd0, 0x89, 0x36, 0x8c, 0x8b, 0xca, 0x86, 0x07, 0x07, 0xfd, 0x06, 0xfd, 0xb9, 0xa8, 0x21, + 0x79, 0x34, 0xff, 0x14, 0x08, 0xbd, 0x35, 0x60, 0xb0, 0x6f, 0xa1, 0x35, 0x9f, 0xc2, 0x7a, 0x80, + 0x68, 0x56, 0x21, 0xfe, 0xaa, 0x43, 0xb4, 0x0a, 0x88, 0x1f, 0x72, 0x88, 0x47, 0x02, 0xcf, 0x4b, + 0xd1, 0xbb, 0x31, 0x60, 0xf4, 0x07, 0xb3, 0xbf, 0x4c, 0xb0, 0x0b, 0xdc, 0xa2, 0x50, 0x0b, 0x8c, + 0x53, 0xbe, 0x44, 0xf2, 0x11, 0x5a, 0xe5, 0x79, 0x92, 0x57, 0xf9, 0x54, 0xb5, 0xdb, 0x1d, 0x93, + 0xaa, 0xab, 0x9c, 0x93, 0x36, 0xc8, 0x67, 0x68, 0xeb, 0x17, 0x21, 0xe4, 0xf4, 0x1c, 0xc6, 0xaf, + 0x6b, 0xbe, 0x6a, 0x95, 0x5e, 0xb9, 0xac, 0xaa, 0xbf, 0x51, 0x59, 0x75, 0xc4, 0x84, 0x36, 0x7e, + 0x8c, 0xfe, 0x91, 0x60, 0x26, 0x1d, 0x1e, 0xba, 0xc1, 0x56, 0xba, 0x2c, 0xe2, 0xd2, 0x4d, 0xbd, + 0xf3, 0x56, 0xf1, 0xbf, 0x7d, 0xba, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x5f, 0xf8, 0x49, 0x17, 0x7c, + 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -413,7 +414,7 @@ func NewKeyManagementServiceClient(cc *grpc.ClientConn) KeyManagementServiceClie func (c *keyManagementServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { out := new(StatusResponse) - err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Status", in, out, opts...) + err := c.cc.Invoke(ctx, "/v2.KeyManagementService/Status", in, out, opts...) if err != nil { return nil, err } @@ -422,7 +423,7 @@ func (c *keyManagementServiceClient) Status(ctx context.Context, in *StatusReque func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) { out := new(DecryptResponse) - err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Decrypt", in, out, opts...) + err := c.cc.Invoke(ctx, "/v2.KeyManagementService/Decrypt", in, out, opts...) if err != nil { return nil, err } @@ -431,7 +432,7 @@ func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptReq func (c *keyManagementServiceClient) Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) { out := new(EncryptResponse) - err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Encrypt", in, out, opts...) + err := c.cc.Invoke(ctx, "/v2.KeyManagementService/Encrypt", in, out, opts...) if err != nil { return nil, err } @@ -476,7 +477,7 @@ func _KeyManagementService_Status_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2alpha1.KeyManagementService/Status", + FullMethod: "/v2.KeyManagementService/Status", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(KeyManagementServiceServer).Status(ctx, req.(*StatusRequest)) @@ -494,7 +495,7 @@ func _KeyManagementService_Decrypt_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2alpha1.KeyManagementService/Decrypt", + FullMethod: "/v2.KeyManagementService/Decrypt", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(KeyManagementServiceServer).Decrypt(ctx, req.(*DecryptRequest)) @@ -512,7 +513,7 @@ func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/v2alpha1.KeyManagementService/Encrypt", + FullMethod: "/v2.KeyManagementService/Encrypt", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(KeyManagementServiceServer).Encrypt(ctx, req.(*EncryptRequest)) @@ -521,7 +522,7 @@ func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, } var _KeyManagementService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "v2alpha1.KeyManagementService", + ServiceName: "v2.KeyManagementService", HandlerType: (*KeyManagementServiceServer)(nil), Methods: []grpc.MethodDesc{ { diff --git a/vendor/k8s.io/kms/apis/v2alpha1/api.proto b/vendor/k8s.io/kms/apis/v2/api.proto similarity index 95% rename from vendor/k8s.io/kms/apis/v2alpha1/api.proto rename to vendor/k8s.io/kms/apis/v2/api.proto index 9b960b2ac..09b52126f 100644 --- a/vendor/k8s.io/kms/apis/v2alpha1/api.proto +++ b/vendor/k8s.io/kms/apis/v2/api.proto @@ -14,10 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// To regenerate api.pb.go run hack/update-generated-kms.sh +// To regenerate api.pb.go run `hack/update-codegen.sh protobindings` syntax = "proto3"; -package v2alpha1; +package v2; +option go_package = "k8s.io/kms/apis/v2"; // This service defines the public APIs for remote KMS provider. service KeyManagementService { diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/v2alpha1.go b/vendor/k8s.io/kms/apis/v2/v2.go similarity index 86% rename from vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/v2alpha1.go rename to vendor/k8s.io/kms/apis/v2/v2.go index b8bed64e8..99c4b57cc 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1/v2alpha1.go +++ b/vendor/k8s.io/kms/apis/v2/v2.go @@ -14,5 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package v2alpha1 contains definition of kms-plugin's serialized types. -package v2alpha1 +// Package v2 contains definition of kms-plugin's gRPC service. +package v2 diff --git a/vendor/k8s.io/kms/pkg/service/grpc_service.go b/vendor/k8s.io/kms/pkg/service/grpc_service.go new file mode 100644 index 000000000..fc463e5c4 --- /dev/null +++ b/vendor/k8s.io/kms/pkg/service/grpc_service.go @@ -0,0 +1,141 @@ +/* +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 service + +import ( + "context" + "net" + "time" + + "google.golang.org/grpc" + + "k8s.io/klog/v2" + kmsapi "k8s.io/kms/apis/v2" +) + +// GRPCService is a grpc server that runs the kms v2 alpha1 API. +type GRPCService struct { + addr string + timeout time.Duration + server *grpc.Server + + kmsService Service +} + +var _ kmsapi.KeyManagementServiceServer = (*GRPCService)(nil) + +// NewGRPCService creates an instance of GRPCService. +func NewGRPCService( + address string, + timeout time.Duration, + + kmsService Service, +) *GRPCService { + klog.V(4).InfoS("KMS plugin configured", "address", address, "timeout", timeout) + + return &GRPCService{ + addr: address, + timeout: timeout, + kmsService: kmsService, + } +} + +// ListenAndServe accepts incoming connections on a Unix socket. It is a blocking method. +// Returns non-nil error unless Close or Shutdown is called. +func (s *GRPCService) ListenAndServe() error { + ln, err := net.Listen("unix", s.addr) + if err != nil { + return err + } + defer ln.Close() + + gs := grpc.NewServer( + grpc.ConnectionTimeout(s.timeout), + ) + s.server = gs + + kmsapi.RegisterKeyManagementServiceServer(gs, s) + + klog.V(4).InfoS("kms plugin serving", "address", s.addr) + return gs.Serve(ln) +} + +// Shutdown performs a graceful shutdown. Doesn't accept new connections and +// blocks until all pending RPCs are finished. +func (s *GRPCService) Shutdown() { + klog.V(4).InfoS("kms plugin shutdown", "address", s.addr) + if s.server != nil { + s.server.GracefulStop() + } +} + +// Close stops the server by closing all connections immediately and cancels +// all active RPCs. +func (s *GRPCService) Close() { + klog.V(4).InfoS("kms plugin close", "address", s.addr) + if s.server != nil { + s.server.Stop() + } +} + +// Status sends a status request to specified kms service. +func (s *GRPCService) Status(ctx context.Context, _ *kmsapi.StatusRequest) (*kmsapi.StatusResponse, error) { + res, err := s.kmsService.Status(ctx) + if err != nil { + return nil, err + } + + return &kmsapi.StatusResponse{ + Version: res.Version, + Healthz: res.Healthz, + KeyId: res.KeyID, + }, nil +} + +// Decrypt sends a decryption request to specified kms service. +func (s *GRPCService) Decrypt(ctx context.Context, req *kmsapi.DecryptRequest) (*kmsapi.DecryptResponse, error) { + klog.V(4).InfoS("decrypt request received", "id", req.Uid) + + plaintext, err := s.kmsService.Decrypt(ctx, req.Uid, &DecryptRequest{ + Ciphertext: req.Ciphertext, + KeyID: req.KeyId, + Annotations: req.Annotations, + }) + if err != nil { + return nil, err + } + + return &kmsapi.DecryptResponse{ + Plaintext: plaintext, + }, nil +} + +// Encrypt sends an encryption request to specified kms service. +func (s *GRPCService) Encrypt(ctx context.Context, req *kmsapi.EncryptRequest) (*kmsapi.EncryptResponse, error) { + klog.V(4).InfoS("encrypt request received", "id", req.Uid) + + encRes, err := s.kmsService.Encrypt(ctx, req.Uid, req.Plaintext) + if err != nil { + return nil, err + } + + return &kmsapi.EncryptResponse{ + Ciphertext: encRes.Ciphertext, + KeyId: encRes.KeyID, + Annotations: encRes.Annotations, + }, nil +} diff --git a/vendor/k8s.io/kms/pkg/service/interface.go b/vendor/k8s.io/kms/pkg/service/interface.go new file mode 100644 index 000000000..fad71fa0a --- /dev/null +++ b/vendor/k8s.io/kms/pkg/service/interface.go @@ -0,0 +1,50 @@ +/* +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 service + +import "context" + +// Service allows encrypting and decrypting data using an external Key Management Service. +type Service interface { + // Decrypt a given bytearray to obtain the original data as bytes. + Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) + // Encrypt bytes to a ciphertext. + Encrypt(ctx context.Context, uid string, data []byte) (*EncryptResponse, error) + // Status returns the status of the KMS. + Status(ctx context.Context) (*StatusResponse, error) +} + +// EncryptResponse is the response from the Envelope service when encrypting data. +type EncryptResponse struct { + Ciphertext []byte + KeyID string + Annotations map[string][]byte +} + +// DecryptRequest is the request to the Envelope service when decrypting data. +type DecryptRequest struct { + Ciphertext []byte + KeyID string + Annotations map[string][]byte +} + +// StatusResponse is the response from the Envelope service when getting the status of the service. +type StatusResponse struct { + Version string + Healthz string + KeyID string +} diff --git a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util/util.go b/vendor/k8s.io/kms/pkg/util/util.go similarity index 95% rename from vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util/util.go rename to vendor/k8s.io/kms/pkg/util/util.go index f062370ab..008c6a532 100644 --- a/vendor/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util/util.go +++ b/vendor/k8s.io/kms/pkg/util/util.go @@ -27,7 +27,7 @@ const ( unixProtocol = "unix" ) -// Parse the endpoint to extract schema, host or path. +// ParseEndpoint parses the endpoint to extract schema, host or path. func ParseEndpoint(endpoint string) (string, error) { if len(endpoint) == 0 { return "", fmt.Errorf("remote KMS provider can't use empty string as endpoint") diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/.gitignore b/vendor/k8s.io/kube-openapi/pkg/validation/errors/.gitignore new file mode 100644 index 000000000..dd91ed6a0 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/.gitignore @@ -0,0 +1,2 @@ +secrets.yml +coverage.out diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/LICENSE b/vendor/k8s.io/kube-openapi/pkg/validation/errors/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/LICENSE @@ -0,0 +1,202 @@ + + 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/vendor/k8s.io/kube-openapi/pkg/validation/errors/api.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/api.go new file mode 100644 index 000000000..e0b310044 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/api.go @@ -0,0 +1,46 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 errors + +import ( + "fmt" +) + +// Error represents a error interface all swagger framework errors implement +type Error interface { + error + Code() int32 +} + +type apiError struct { + code int32 + message string +} + +func (a *apiError) Error() string { + return a.message +} + +func (a *apiError) Code() int32 { + return a.code +} + +// New creates a new API error with a code and a message +func New(code int32, message string, args ...interface{}) Error { + if len(args) > 0 { + return &apiError{code, fmt.Sprintf(message, args...)} + } + return &apiError{code, message} +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go new file mode 100644 index 000000000..af01190ce --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/doc.go @@ -0,0 +1,26 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 errors provides an Error interface and several concrete types +implementing this interface to manage API errors and JSON-schema validation +errors. + +A middleware handler ServeError() is provided to serve the errors types +it defines. + +It is used throughout the various go-openapi toolkit libraries +(https://github.com/go-openapi). +*/ +package errors diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/headers.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/headers.go new file mode 100644 index 000000000..3da85c367 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/headers.go @@ -0,0 +1,44 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 errors + +// Validation represents a failure of a precondition +type Validation struct { + code int32 + Name string + In string + Value interface{} + Valid interface{} + message string + Values []interface{} +} + +func (e *Validation) Error() string { + return e.message +} + +// Code the error code +func (e *Validation) Code() int32 { + return e.code +} + +// ValidateName produces an error message name for an aliased property +func (e *Validation) ValidateName(name string) *Validation { + if e.Name == "" && name != "" { + e.Name = name + e.message = name + e.message + } + return e +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/errors/schema.go b/vendor/k8s.io/kube-openapi/pkg/validation/errors/schema.go new file mode 100644 index 000000000..65f133e9e --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/errors/schema.go @@ -0,0 +1,573 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 errors + +import ( + "fmt" + "strings" +) + +const ( + invalidType = "%s is an invalid type name" + typeFail = "%s in %s must be of type %s" + typeFailWithData = "%s in %s must be of type %s: %q" + typeFailWithError = "%s in %s must be of type %s, because: %s" + requiredFail = "%s in %s is required" + tooLongMessage = "%s in %s should be at most %d chars long" + tooShortMessage = "%s in %s should be at least %d chars long" + patternFail = "%s in %s should match '%s'" + enumFail = "%s in %s should be one of %v" + multipleOfFail = "%s in %s should be a multiple of %v" + maxIncFail = "%s in %s should be less than or equal to %v" + maxExcFail = "%s in %s should be less than %v" + minIncFail = "%s in %s should be greater than or equal to %v" + minExcFail = "%s in %s should be greater than %v" + uniqueFail = "%s in %s shouldn't contain duplicates" + maxItemsFail = "%s in %s should have at most %d items" + minItemsFail = "%s in %s should have at least %d items" + typeFailNoIn = "%s must be of type %s" + typeFailWithDataNoIn = "%s must be of type %s: %q" + typeFailWithErrorNoIn = "%s must be of type %s, because: %s" + requiredFailNoIn = "%s is required" + tooLongMessageNoIn = "%s should be at most %d chars long" + tooShortMessageNoIn = "%s should be at least %d chars long" + patternFailNoIn = "%s should match '%s'" + enumFailNoIn = "%s should be one of %v" + multipleOfFailNoIn = "%s should be a multiple of %v" + maxIncFailNoIn = "%s should be less than or equal to %v" + maxExcFailNoIn = "%s should be less than %v" + minIncFailNoIn = "%s should be greater than or equal to %v" + minExcFailNoIn = "%s should be greater than %v" + uniqueFailNoIn = "%s shouldn't contain duplicates" + maxItemsFailNoIn = "%s should have at most %d items" + minItemsFailNoIn = "%s should have at least %d items" + noAdditionalItems = "%s in %s can't have additional items" + noAdditionalItemsNoIn = "%s can't have additional items" + tooFewProperties = "%s in %s should have at least %d properties" + tooFewPropertiesNoIn = "%s should have at least %d properties" + tooManyProperties = "%s in %s should have at most %d properties" + tooManyPropertiesNoIn = "%s should have at most %d properties" + unallowedProperty = "%s.%s in %s is a forbidden property" + unallowedPropertyNoIn = "%s.%s is a forbidden property" + failedAllPatternProps = "%s.%s in %s failed all pattern properties" + failedAllPatternPropsNoIn = "%s.%s failed all pattern properties" + multipleOfMustBePositive = "factor MultipleOf declared for %s must be positive: %v" +) + +// All code responses can be used to differentiate errors for different handling +// by the consuming program +const ( + // CompositeErrorCode remains 422 for backwards-compatibility + // and to separate it from validation errors with cause + CompositeErrorCode = 422 + // InvalidTypeCode is used for any subclass of invalid types + InvalidTypeCode = 600 + iota + RequiredFailCode + TooLongFailCode + TooShortFailCode + PatternFailCode + EnumFailCode + MultipleOfFailCode + MaxFailCode + MinFailCode + UniqueFailCode + MaxItemsFailCode + MinItemsFailCode + NoAdditionalItemsCode + TooFewPropertiesCode + TooManyPropertiesCode + UnallowedPropertyCode + FailedAllPatternPropsCode + MultipleOfMustBePositiveCode +) + +// CompositeError is an error that groups several errors together +type CompositeError struct { + Errors []error + code int32 + message string +} + +// Code for this error +func (c *CompositeError) Code() int32 { + return c.code +} + +func (c *CompositeError) Error() string { + if len(c.Errors) > 0 { + msgs := []string{c.message + ":"} + for _, e := range c.Errors { + msgs = append(msgs, e.Error()) + } + return strings.Join(msgs, "\n") + } + return c.message +} + +// CompositeValidationError an error to wrap a bunch of other errors +func CompositeValidationError(errors ...error) *CompositeError { + return &CompositeError{ + code: CompositeErrorCode, + Errors: append([]error{}, errors...), + message: "validation failure list", + } +} + +// FailedAllPatternProperties an error for when the property doesn't match a pattern +func FailedAllPatternProperties(name, in, key string) *Validation { + msg := fmt.Sprintf(failedAllPatternProps, name, key, in) + if in == "" { + msg = fmt.Sprintf(failedAllPatternPropsNoIn, name, key) + } + return &Validation{ + code: FailedAllPatternPropsCode, + Name: name, + In: in, + Value: key, + message: msg, + } +} + +// PropertyNotAllowed an error for when the property doesn't match a pattern +func PropertyNotAllowed(name, in, key string) *Validation { + msg := fmt.Sprintf(unallowedProperty, name, key, in) + if in == "" { + msg = fmt.Sprintf(unallowedPropertyNoIn, name, key) + } + return &Validation{ + code: UnallowedPropertyCode, + Name: name, + In: in, + Value: key, + message: msg, + } +} + +// TooFewProperties an error for an object with too few properties +func TooFewProperties(name, in string, minProperties, size int64) *Validation { + msg := fmt.Sprintf(tooFewProperties, name, in, minProperties) + if in == "" { + msg = fmt.Sprintf(tooFewPropertiesNoIn, name, minProperties) + } + return &Validation{ + code: TooFewPropertiesCode, + Name: name, + In: in, + Value: size, + Valid: minProperties, + message: msg, + } +} + +// TooManyProperties an error for an object with too many properties +func TooManyProperties(name, in string, maxProperties, size int64) *Validation { + msg := fmt.Sprintf(tooManyProperties, name, in, maxProperties) + if in == "" { + msg = fmt.Sprintf(tooManyPropertiesNoIn, name, maxProperties) + } + return &Validation{ + code: TooManyPropertiesCode, + Name: name, + In: in, + Value: size, + Valid: maxProperties, + message: msg, + } +} + +// AdditionalItemsNotAllowed an error for invalid additional items +func AdditionalItemsNotAllowed(name, in string) *Validation { + msg := fmt.Sprintf(noAdditionalItems, name, in) + if in == "" { + msg = fmt.Sprintf(noAdditionalItemsNoIn, name) + } + return &Validation{ + code: NoAdditionalItemsCode, + Name: name, + In: in, + message: msg, + } +} + +// InvalidCollectionFormat another flavor of invalid type error +func InvalidCollectionFormat(name, in, format string) *Validation { + return &Validation{ + code: InvalidTypeCode, + Name: name, + In: in, + Value: format, + message: fmt.Sprintf("the collection format %q is not supported for the %s param %q", format, in, name), + } +} + +// InvalidTypeName an error for when the type is invalid +func InvalidTypeName(typeName string) *Validation { + return &Validation{ + code: InvalidTypeCode, + Value: typeName, + message: fmt.Sprintf(invalidType, typeName), + } +} + +// InvalidType creates an error for when the type is invalid +func InvalidType(name, in, typeName string, value interface{}) *Validation { + var message string + + if in != "" { + switch value.(type) { + case string: + message = fmt.Sprintf(typeFailWithData, name, in, typeName, value) + case error: + message = fmt.Sprintf(typeFailWithError, name, in, typeName, value) + default: + message = fmt.Sprintf(typeFail, name, in, typeName) + } + } else { + switch value.(type) { + case string: + message = fmt.Sprintf(typeFailWithDataNoIn, name, typeName, value) + case error: + message = fmt.Sprintf(typeFailWithErrorNoIn, name, typeName, value) + default: + message = fmt.Sprintf(typeFailNoIn, name, typeName) + } + } + + return &Validation{ + code: InvalidTypeCode, + Name: name, + In: in, + Value: value, + message: message, + } + +} + +// DuplicateItems error for when an array contains duplicates +func DuplicateItems(name, in string) *Validation { + msg := fmt.Sprintf(uniqueFail, name, in) + if in == "" { + msg = fmt.Sprintf(uniqueFailNoIn, name) + } + return &Validation{ + code: UniqueFailCode, + Name: name, + In: in, + message: msg, + } +} + +// TooManyItems error for when an array contains too many items +func TooManyItems(name, in string, max int64, value interface{}) *Validation { + msg := fmt.Sprintf(maxItemsFail, name, in, max) + if in == "" { + msg = fmt.Sprintf(maxItemsFailNoIn, name, max) + } + + return &Validation{ + code: MaxItemsFailCode, + Name: name, + In: in, + Value: value, + Valid: max, + message: msg, + } +} + +// TooFewItems error for when an array contains too few items +func TooFewItems(name, in string, min int64, value interface{}) *Validation { + msg := fmt.Sprintf(minItemsFail, name, in, min) + if in == "" { + msg = fmt.Sprintf(minItemsFailNoIn, name, min) + } + return &Validation{ + code: MinItemsFailCode, + Name: name, + In: in, + Value: value, + Valid: min, + message: msg, + } +} + +// ExceedsMaximumInt error for when maxinum validation fails +func ExceedsMaximumInt(name, in string, max int64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := maxIncFailNoIn + if exclusive { + m = maxExcFailNoIn + } + message = fmt.Sprintf(m, name, max) + } else { + m := maxIncFail + if exclusive { + m = maxExcFail + } + message = fmt.Sprintf(m, name, in, max) + } + return &Validation{ + code: MaxFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMaximumUint error for when maxinum validation fails +func ExceedsMaximumUint(name, in string, max uint64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := maxIncFailNoIn + if exclusive { + m = maxExcFailNoIn + } + message = fmt.Sprintf(m, name, max) + } else { + m := maxIncFail + if exclusive { + m = maxExcFail + } + message = fmt.Sprintf(m, name, in, max) + } + return &Validation{ + code: MaxFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMaximum error for when maxinum validation fails +func ExceedsMaximum(name, in string, max float64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := maxIncFailNoIn + if exclusive { + m = maxExcFailNoIn + } + message = fmt.Sprintf(m, name, max) + } else { + m := maxIncFail + if exclusive { + m = maxExcFail + } + message = fmt.Sprintf(m, name, in, max) + } + return &Validation{ + code: MaxFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMinimumInt error for when maxinum validation fails +func ExceedsMinimumInt(name, in string, min int64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := minIncFailNoIn + if exclusive { + m = minExcFailNoIn + } + message = fmt.Sprintf(m, name, min) + } else { + m := minIncFail + if exclusive { + m = minExcFail + } + message = fmt.Sprintf(m, name, in, min) + } + return &Validation{ + code: MinFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMinimumUint error for when maxinum validation fails +func ExceedsMinimumUint(name, in string, min uint64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := minIncFailNoIn + if exclusive { + m = minExcFailNoIn + } + message = fmt.Sprintf(m, name, min) + } else { + m := minIncFail + if exclusive { + m = minExcFail + } + message = fmt.Sprintf(m, name, in, min) + } + return &Validation{ + code: MinFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// ExceedsMinimum error for when maxinum validation fails +func ExceedsMinimum(name, in string, min float64, exclusive bool, value interface{}) *Validation { + var message string + if in == "" { + m := minIncFailNoIn + if exclusive { + m = minExcFailNoIn + } + message = fmt.Sprintf(m, name, min) + } else { + m := minIncFail + if exclusive { + m = minExcFail + } + message = fmt.Sprintf(m, name, in, min) + } + return &Validation{ + code: MinFailCode, + Name: name, + In: in, + Value: value, + message: message, + } +} + +// NotMultipleOf error for when multiple of validation fails +func NotMultipleOf(name, in string, multiple, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(multipleOfFailNoIn, name, multiple) + } else { + msg = fmt.Sprintf(multipleOfFail, name, in, multiple) + } + return &Validation{ + code: MultipleOfFailCode, + Name: name, + In: in, + Value: value, + message: msg, + } +} + +// EnumFail error for when an enum validation fails +func EnumFail(name, in string, value interface{}, values []interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(enumFailNoIn, name, values) + } else { + msg = fmt.Sprintf(enumFail, name, in, values) + } + + return &Validation{ + code: EnumFailCode, + Name: name, + In: in, + Value: value, + Values: values, + message: msg, + } +} + +// Required error for when a value is missing +func Required(name, in string) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(requiredFailNoIn, name) + } else { + msg = fmt.Sprintf(requiredFail, name, in) + } + return &Validation{ + code: RequiredFailCode, + Name: name, + In: in, + message: msg, + } +} + +// TooLong error for when a string is too long +func TooLong(name, in string, max int64, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(tooLongMessageNoIn, name, max) + } else { + msg = fmt.Sprintf(tooLongMessage, name, in, max) + } + return &Validation{ + code: TooLongFailCode, + Name: name, + In: in, + Value: value, + Valid: max, + message: msg, + } +} + +// TooShort error for when a string is too short +func TooShort(name, in string, min int64, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(tooShortMessageNoIn, name, min) + } else { + msg = fmt.Sprintf(tooShortMessage, name, in, min) + } + + return &Validation{ + code: TooShortFailCode, + Name: name, + In: in, + Value: value, + Valid: min, + message: msg, + } +} + +// FailedPattern error for when a string fails a regex pattern match +// the pattern that is returned is the ECMA syntax version of the pattern not the golang version. +func FailedPattern(name, in, pattern string, value interface{}) *Validation { + var msg string + if in == "" { + msg = fmt.Sprintf(patternFailNoIn, name, pattern) + } else { + msg = fmt.Sprintf(patternFail, name, in, pattern) + } + + return &Validation{ + code: PatternFailCode, + Name: name, + In: in, + Value: value, + message: msg, + } +} + +// MultipleOfMustBePositive error for when a +// multipleOf factor is negative +func MultipleOfMustBePositive(name, in string, factor interface{}) *Validation { + return &Validation{ + code: MultipleOfMustBePositiveCode, + Name: name, + In: in, + Value: factor, + message: fmt.Sprintf(multipleOfMustBePositive, name, factor), + } +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/.gitignore b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/.gitignore new file mode 100644 index 000000000..dd91ed6a0 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/.gitignore @@ -0,0 +1,2 @@ +secrets.yml +coverage.out diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/LICENSE b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/LICENSE @@ -0,0 +1,202 @@ + + 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/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson.go new file mode 100644 index 000000000..0b6380c8a --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson.go @@ -0,0 +1,103 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 strfmt + +import ( + bsonprim "k8s.io/kube-openapi/pkg/validation/strfmt/bson" +) + +func init() { + var id ObjectId + // register this format in the default registry + Default.Add("bsonobjectid", &id, IsBSONObjectID) +} + +// IsBSONObjectID returns true when the string is a valid BSON.ObjectId +func IsBSONObjectID(str string) bool { + _, err := bsonprim.ObjectIDFromHex(str) + return err == nil +} + +// ObjectId represents a BSON object ID (alias to go.mongodb.org/mongo-driver/bson/primitive.ObjectID) +// +// swagger:strfmt bsonobjectid +type ObjectId bsonprim.ObjectID + +// NewObjectId creates a ObjectId from a Hex String +func NewObjectId(hex string) ObjectId { + oid, err := bsonprim.ObjectIDFromHex(hex) + if err != nil { + panic(err) + } + return ObjectId(oid) +} + +// MarshalText turns this instance into text +func (id ObjectId) MarshalText() ([]byte, error) { + oid := bsonprim.ObjectID(id) + if oid == bsonprim.NilObjectID { + return nil, nil + } + return []byte(oid.Hex()), nil +} + +// UnmarshalText hydrates this instance from text +func (id *ObjectId) UnmarshalText(data []byte) error { // validation is performed later on + if len(data) == 0 { + *id = ObjectId(bsonprim.NilObjectID) + return nil + } + oidstr := string(data) + oid, err := bsonprim.ObjectIDFromHex(oidstr) + if err != nil { + return err + } + *id = ObjectId(oid) + return nil +} + +func (id ObjectId) String() string { + return bsonprim.ObjectID(id).String() +} + +// MarshalJSON returns the ObjectId as JSON +func (id ObjectId) MarshalJSON() ([]byte, error) { + return bsonprim.ObjectID(id).MarshalJSON() +} + +// UnmarshalJSON sets the ObjectId from JSON +func (id *ObjectId) UnmarshalJSON(data []byte) error { + var obj bsonprim.ObjectID + if err := obj.UnmarshalJSON(data); err != nil { + return err + } + *id = ObjectId(obj) + return nil +} + +// DeepCopyInto copies the receiver and writes its value into out. +func (id *ObjectId) DeepCopyInto(out *ObjectId) { + *out = *id +} + +// DeepCopy copies the receiver into a new ObjectId. +func (id *ObjectId) DeepCopy() *ObjectId { + if id == nil { + return nil + } + out := new(ObjectId) + id.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson/objectid.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson/objectid.go new file mode 100644 index 000000000..824534b28 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/bson/objectid.go @@ -0,0 +1,122 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 +// +// Based on gopkg.in/mgo.v2/bson by Gustavo Niemeyer +// See THIRD-PARTY-NOTICES for original license terms. + +package bson + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "fmt" +) + +// ErrInvalidHex indicates that a hex string cannot be converted to an ObjectID. +var ErrInvalidHex = errors.New("the provided hex string is not a valid ObjectID") + +// ObjectID is the BSON ObjectID type. +type ObjectID [12]byte + +// NilObjectID is the zero value for ObjectID. +var NilObjectID ObjectID + +// Hex returns the hex encoding of the ObjectID as a string. +func (id ObjectID) Hex() string { + return hex.EncodeToString(id[:]) +} + +func (id ObjectID) String() string { + return fmt.Sprintf("ObjectID(%q)", id.Hex()) +} + +// IsZero returns true if id is the empty ObjectID. +func (id ObjectID) IsZero() bool { + return bytes.Equal(id[:], NilObjectID[:]) +} + +// ObjectIDFromHex creates a new ObjectID from a hex string. It returns an error if the hex string is not a +// valid ObjectID. +func ObjectIDFromHex(s string) (ObjectID, error) { + b, err := hex.DecodeString(s) + if err != nil { + return NilObjectID, err + } + + if len(b) != 12 { + return NilObjectID, ErrInvalidHex + } + + var oid [12]byte + copy(oid[:], b[:]) + + return oid, nil +} + +// MarshalJSON returns the ObjectID as a string +func (id ObjectID) MarshalJSON() ([]byte, error) { + return json.Marshal(id.Hex()) +} + +// UnmarshalJSON populates the byte slice with the ObjectID. If the byte slice is 24 bytes long, it +// will be populated with the hex representation of the ObjectID. If the byte slice is twelve bytes +// long, it will be populated with the BSON representation of the ObjectID. This method also accepts empty strings and +// decodes them as NilObjectID. For any other inputs, an error will be returned. +func (id *ObjectID) UnmarshalJSON(b []byte) error { + // Ignore "null" to keep parity with the standard library. Decoding a JSON null into a non-pointer ObjectID field + // will leave the field unchanged. For pointer values, encoding/json will set the pointer to nil and will not + // enter the UnmarshalJSON hook. + if string(b) == "null" { + return nil + } + + var err error + switch len(b) { + case 12: + copy(id[:], b) + default: + // Extended JSON + var res interface{} + err := json.Unmarshal(b, &res) + if err != nil { + return err + } + str, ok := res.(string) + if !ok { + m, ok := res.(map[string]interface{}) + if !ok { + return errors.New("not an extended JSON ObjectID") + } + oid, ok := m["$oid"] + if !ok { + return errors.New("not an extended JSON ObjectID") + } + str, ok = oid.(string) + if !ok { + return errors.New("not an extended JSON ObjectID") + } + } + + // An empty string is not a valid ObjectID, but we treat it as a special value that decodes as NilObjectID. + if len(str) == 0 { + copy(id[:], NilObjectID[:]) + return nil + } + + if len(str) != 24 { + return fmt.Errorf("cannot unmarshal into an ObjectID, the length must be 24 but it is %d", len(str)) + } + + _, err = hex.Decode(id[:], []byte(str)) + if err != nil { + return err + } + } + + return err +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/date.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/date.go new file mode 100644 index 000000000..74ce5b6cb --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/date.go @@ -0,0 +1,103 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 strfmt + +import ( + "encoding/json" + "time" +) + +func init() { + d := Date{} + // register this format in the default registry + Default.Add("date", &d, IsDate) +} + +// IsDate returns true when the string is a valid date +func IsDate(str string) bool { + _, err := time.Parse(RFC3339FullDate, str) + return err == nil +} + +const ( + // RFC3339FullDate represents a full-date as specified by RFC3339 + // See: http://goo.gl/xXOvVd + RFC3339FullDate = "2006-01-02" +) + +// Date represents a date from the API +// +// swagger:strfmt date +type Date time.Time + +// String converts this date into a string +func (d Date) String() string { + return time.Time(d).Format(RFC3339FullDate) +} + +// UnmarshalText parses a text representation into a date type +func (d *Date) UnmarshalText(text []byte) error { + if len(text) == 0 { + return nil + } + dd, err := time.Parse(RFC3339FullDate, string(text)) + if err != nil { + return err + } + *d = Date(dd) + return nil +} + +// MarshalText serializes this date type to string +func (d Date) MarshalText() ([]byte, error) { + return []byte(d.String()), nil +} + +// MarshalJSON returns the Date as JSON +func (d Date) MarshalJSON() ([]byte, error) { + return json.Marshal(time.Time(d).Format(RFC3339FullDate)) +} + +// UnmarshalJSON sets the Date from JSON +func (d *Date) UnmarshalJSON(data []byte) error { + if string(data) == jsonNull { + return nil + } + var strdate string + if err := json.Unmarshal(data, &strdate); err != nil { + return err + } + tt, err := time.Parse(RFC3339FullDate, strdate) + if err != nil { + return err + } + *d = Date(tt) + return nil +} + +// DeepCopyInto copies the receiver and writes its value into out. +func (d *Date) DeepCopyInto(out *Date) { + *out = *d +} + +// DeepCopy copies the receiver into a new Date. +func (d *Date) DeepCopy() *Date { + if d == nil { + return nil + } + out := new(Date) + d.DeepCopyInto(out) + return out +} diff --git a/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go new file mode 100644 index 000000000..e85b0f1b4 --- /dev/null +++ b/vendor/k8s.io/kube-openapi/pkg/validation/strfmt/default.go @@ -0,0 +1,1562 @@ +// Copyright 2015 go-swagger maintainers +// +// 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 strfmt + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "net/mail" + "regexp" + "strings" + + "github.com/asaskevich/govalidator" + + netutils "k8s.io/utils/net" +) + +const ( + // HostnamePattern http://json-schema.org/latest/json-schema-validation.html#anchor114 + // A string instance is valid against this attribute if it is a valid + // representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034]. + // http://tools.ietf.org/html/rfc1034#section-3.5 + // ::= any one of the ten digits 0 through 9 + // var digit = /[0-9]/; + // ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case + // var letter = /[a-zA-Z]/; + // ::= | + // var letDig = /[0-9a-zA-Z]/; + // ::= | "-" + // var letDigHyp = /[-0-9a-zA-Z]/; + // ::= | + // var ldhStr = /[-0-9a-zA-Z]+/; + //