diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b8dda9bf..554e34bb 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.29.0" + ".": "0.30.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 3326a8b3..f6bc2e9b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 645 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-bec46ce28212cf90388fa9ba8094b471b922ae78b92e0f5fa80c083cd3017319.yml -openapi_spec_hash: bc1b58805168a142ca35aa5dfab5a03f -config_hash: 7085751e6bd8f3fd13cfebe04bb99fed +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gcore%2Fgcore-2d64161889a53046ca5e593a772328a5290246c3d74f8c07fed1037feae1bdbc.yml +openapi_spec_hash: 2360d25764d74e6972cf600fcd20fd4e +config_hash: e9e5b750687e9071d8b606963f0ffd6d diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b003f43..cb2ed08c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## 0.30.0 (2026-01-22) + +Full Changelog: [v0.29.0...v0.30.0](https://github.com/G-Core/gcore-go/compare/v0.29.0...v0.30.0) + +### ⚠ BREAKING CHANGES + +* **cloud:** use create and update v2 endpoints for security groups +* **cloud:** use v2 endpoint for floating IPs updates + +### Features + +* **api:** aggregated API specs update ([cbbe4ca](https://github.com/G-Core/gcore-go/commit/cbbe4ca8ecc7c17f5032811d36377b614af19637)) +* **api:** aggregated API specs update ([58d174c](https://github.com/G-Core/gcore-go/commit/58d174cb4ee02c819cf74bdd5da372fb42f4115a)) +* **api:** aggregated API specs update ([78a097d](https://github.com/G-Core/gcore-go/commit/78a097d45e77b21e996e7e4d11e02bbf8fdc061e)) +* **cloud:** add polling methods for security groups ([a95ce62](https://github.com/G-Core/gcore-go/commit/a95ce622dd1123f80b4645b29250e36c92b89780)) +* **cloud:** add UpdateAndPoll method for floating IPs ([c71ea15](https://github.com/G-Core/gcore-go/commit/c71ea15b2e53f1a013bf492e1583518c5ee3528a)) +* **cloud:** use create and update v2 endpoints for security groups ([25f9183](https://github.com/G-Core/gcore-go/commit/25f9183d766cf402b7049337778bf78ad6fe32b2)) +* **cloud:** use v2 endpoint for floating IPs updates ([b20c495](https://github.com/G-Core/gcore-go/commit/b20c4950ccceb246b9f73b75d8db9ee8d606d99c)) + + +### Bug Fixes + +* **cloud:** filter options correctly in file share polling methods ([5a0b54e](https://github.com/G-Core/gcore-go/commit/5a0b54ed77f919b80d98d1b9705b87381bcc0851)) +* **cloud:** filter options correctly in floating IP polling methods ([3d9d77f](https://github.com/G-Core/gcore-go/commit/3d9d77fa782194f22fcb32386a8823018f9c6d91)) + ## 0.29.0 (2026-01-16) Full Changelog: [v0.28.0...v0.29.0](https://github.com/G-Core/gcore-go/compare/v0.28.0...v0.29.0) diff --git a/README.md b/README.md index 7e471d3b..eedbc2ba 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Or to pin the version: ```sh -go get -u 'github.com/G-Core/gcore-go@v0.29.0' +go get -u 'github.com/G-Core/gcore-go@v0.30.0' ``` diff --git a/api.md b/api.md index 45ff2716..a6f2aa52 100644 --- a/api.md +++ b/api.md @@ -400,7 +400,7 @@ Response Types: Methods: - client.Cloud.FloatingIPs.New(ctx context.Context, params cloud.FloatingIPNewParams) (\*cloud.TaskIDList, error) -- client.Cloud.FloatingIPs.Update(ctx context.Context, floatingIPID string, params cloud.FloatingIPUpdateParams) (\*cloud.FloatingIP, error) +- client.Cloud.FloatingIPs.Update(ctx context.Context, floatingIPID string, params cloud.FloatingIPUpdateParams) (\*cloud.TaskIDList, error) - client.Cloud.FloatingIPs.List(ctx context.Context, params cloud.FloatingIPListParams) (\*pagination.OffsetPage[cloud.FloatingIPDetailed], error) - client.Cloud.FloatingIPs.Delete(ctx context.Context, floatingIPID string, body cloud.FloatingIPDeleteParams) (\*cloud.TaskIDList, error) - client.Cloud.FloatingIPs.Assign(ctx context.Context, floatingIPID string, params cloud.FloatingIPAssignParams) (\*cloud.FloatingIP, error) @@ -416,8 +416,8 @@ Response Types: Methods: -- client.Cloud.SecurityGroups.New(ctx context.Context, params cloud.SecurityGroupNewParams) (\*cloud.SecurityGroup, error) -- client.Cloud.SecurityGroups.Update(ctx context.Context, groupID string, params cloud.SecurityGroupUpdateParams) (\*cloud.SecurityGroup, error) +- client.Cloud.SecurityGroups.New(ctx context.Context, params cloud.SecurityGroupNewParams) (\*cloud.TaskIDList, error) +- client.Cloud.SecurityGroups.Update(ctx context.Context, groupID string, params cloud.SecurityGroupUpdateParams) (\*cloud.TaskIDList, error) - client.Cloud.SecurityGroups.List(ctx context.Context, params cloud.SecurityGroupListParams) (\*pagination.OffsetPage[cloud.SecurityGroup], error) - client.Cloud.SecurityGroups.Delete(ctx context.Context, groupID string, body cloud.SecurityGroupDeleteParams) error - client.Cloud.SecurityGroups.Copy(ctx context.Context, groupID string, params cloud.SecurityGroupCopyParams) (\*cloud.SecurityGroup, error) diff --git a/cdn/metric.go b/cdn/metric.go index b4475fba..69cd8d8d 100644 --- a/cdn/metric.go +++ b/cdn/metric.go @@ -44,7 +44,7 @@ func (r *MetricService) List(ctx context.Context, body MetricListParams, opts .. type CdnMetrics struct { // If no grouping was requested then "data" holds an array of metric values. If at - // least one field is specified in "`group_by`" then "data" is an object whose + // least one field is specified in "group_by" then "data" is an object whose // properties are groups, which may include other groups; the last group will hold // array of metrics values. Data CdnMetricsDataUnion `json:"data"` diff --git a/cdn/origingroup.go b/cdn/origingroup.go index 93ec4ddd..ee122736 100644 --- a/cdn/origingroup.go +++ b/cdn/origingroup.go @@ -327,8 +327,8 @@ type OriginGroupsAwsSignatureV4Auth struct { // // - Latin letters (A-Z, a-z), numbers (0-9), pluses, slashes, dashes, colons and // underscores. - // - If "`s3_type`": amazon, length should be 40 characters. - // - If "`s3_type`": other, length should be from 16 to 255 characters. + // - If "s3_type": amazon, length should be 40 characters. + // - If "s3_type": other, length should be from 16 to 255 characters. S3SecretAccessKey string `json:"s3_secret_access_key,required"` // Storage type compatible with S3. // @@ -339,11 +339,11 @@ type OriginGroupsAwsSignatureV4Auth struct { S3Type string `json:"s3_type,required"` // S3 storage region. // - // The parameter is required, if "`s3_type`": amazon. + // The parameter is required, if "s3_type": amazon. S3Region string `json:"s3_region"` // S3 storage hostname. // - // The parameter is required, if "`s3_type`": other. + // The parameter is required, if "s3_type": other. S3StorageHostname string `json:"s3_storage_hostname"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { @@ -539,8 +539,8 @@ type OriginGroupNewParamsBodyAwsSignatureV4Auth struct { // // - Latin letters (A-Z, a-z), numbers (0-9), pluses, slashes, dashes, colons and // underscores. - // - If "`s3_type`": amazon, length should be 40 characters. - // - If "`s3_type`": other, length should be from 16 to 255 characters. + // - If "s3_type": amazon, length should be 40 characters. + // - If "s3_type": other, length should be from 16 to 255 characters. S3SecretAccessKey string `json:"s3_secret_access_key,required"` // Storage type compatible with S3. // @@ -551,11 +551,11 @@ type OriginGroupNewParamsBodyAwsSignatureV4Auth struct { S3Type string `json:"s3_type,required"` // S3 storage region. // - // The parameter is required, if "`s3_type`": amazon. + // The parameter is required, if "s3_type": amazon. S3Region param.Opt[string] `json:"s3_region,omitzero"` // S3 storage hostname. // - // The parameter is required, if "`s3_type`": other. + // The parameter is required, if "s3_type": other. S3StorageHostname param.Opt[string] `json:"s3_storage_hostname,omitzero"` paramObj } @@ -744,8 +744,8 @@ type OriginGroupUpdateParamsBodyAwsSignatureV4Auth struct { // // - Latin letters (A-Z, a-z), numbers (0-9), pluses, slashes, dashes, colons and // underscores. - // - If "`s3_type`": amazon, length should be 40 characters. - // - If "`s3_type`": other, length should be from 16 to 255 characters. + // - If "s3_type": amazon, length should be 40 characters. + // - If "s3_type": other, length should be from 16 to 255 characters. S3SecretAccessKey string `json:"s3_secret_access_key,required"` // Storage type compatible with S3. // @@ -756,11 +756,11 @@ type OriginGroupUpdateParamsBodyAwsSignatureV4Auth struct { S3Type string `json:"s3_type,required"` // S3 storage region. // - // The parameter is required, if "`s3_type`": amazon. + // The parameter is required, if "s3_type": amazon. S3Region param.Opt[string] `json:"s3_region,omitzero"` // S3 storage hostname. // - // The parameter is required, if "`s3_type`": other. + // The parameter is required, if "s3_type": other. S3StorageHostname param.Opt[string] `json:"s3_storage_hostname,omitzero"` paramObj } @@ -973,8 +973,8 @@ type OriginGroupReplaceParamsBodyAwsSignatureV4Auth struct { // // - Latin letters (A-Z, a-z), numbers (0-9), pluses, slashes, dashes, colons and // underscores. - // - If "`s3_type`": amazon, length should be 40 characters. - // - If "`s3_type`": other, length should be from 16 to 255 characters. + // - If "s3_type": amazon, length should be 40 characters. + // - If "s3_type": other, length should be from 16 to 255 characters. S3SecretAccessKey string `json:"s3_secret_access_key,required"` // Storage type compatible with S3. // @@ -985,11 +985,11 @@ type OriginGroupReplaceParamsBodyAwsSignatureV4Auth struct { S3Type string `json:"s3_type,required"` // S3 storage region. // - // The parameter is required, if "`s3_type`": amazon. + // The parameter is required, if "s3_type": amazon. S3Region param.Opt[string] `json:"s3_region,omitzero"` // S3 storage hostname. // - // The parameter is required, if "`s3_type`": other. + // The parameter is required, if "s3_type": other. S3StorageHostname param.Opt[string] `json:"s3_storage_hostname,omitzero"` paramObj } diff --git a/cdn/resource.go b/cdn/resource.go index c84d978b..b55d8d42 100644 --- a/cdn/resource.go +++ b/cdn/resource.go @@ -925,11 +925,11 @@ type CdnResourceOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -1688,9 +1688,9 @@ type CdnResourceOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -3392,11 +3392,11 @@ type ResourceNewParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -4094,9 +4094,9 @@ type ResourceNewParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -5728,11 +5728,11 @@ type ResourceUpdateParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -6430,9 +6430,9 @@ type ResourceUpdateParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -7671,14 +7671,14 @@ type ResourcePurgeParamsBodyPurgeByURL struct { // the CDN cache, purge by URL will delete only the first slice (with bytes=0… // .) // 3. "ignoreQueryString" is used. Don’t specify parameters in the purge request. - // 4. "`query_params_blacklist`" is used. Only files with the listed in the option + // 4. "query_params_blacklist" is used. Only files with the listed in the option // parameters will be cached as different objects. Files with other parameters // will be cached as one object. In this case, specify the listed parameters in // the Purge request. Don't specify other parameters. - // 5. "`query_params_whitelist`" is used. Files with listed in the option - // parameters will be cached as one object. Files with other parameters will be - // cached as different objects. In this case, specify other parameters (if any) - // besides the ones listed in the purge request. + // 5. "query_params_whitelist" is used. Files with listed in the option parameters + // will be cached as one object. Files with other parameters will be cached as + // different objects. In this case, specify other parameters (if any) besides + // the ones listed in the purge request. URLs []string `json:"urls,omitzero"` paramObj } @@ -8284,11 +8284,11 @@ type ResourceReplaceParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -8986,9 +8986,9 @@ type ResourceReplaceParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". diff --git a/cdn/resourcerule.go b/cdn/resourcerule.go index 36369c85..a49bd177 100644 --- a/cdn/resourcerule.go +++ b/cdn/resourcerule.go @@ -705,11 +705,11 @@ type CdnResourceRuleOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -1437,9 +1437,9 @@ type CdnResourceRuleOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -2957,11 +2957,11 @@ type ResourceRuleNewParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -3630,9 +3630,9 @@ type ResourceRuleNewParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -5115,11 +5115,11 @@ type ResourceRuleUpdateParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -5788,9 +5788,9 @@ type ResourceRuleUpdateParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -7283,11 +7283,11 @@ type ResourceRuleReplaceParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -7956,9 +7956,9 @@ type ResourceRuleReplaceParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". diff --git a/cdn/ruletemplate.go b/cdn/ruletemplate.go index f4d283b1..cc219ddb 100644 --- a/cdn/ruletemplate.go +++ b/cdn/ruletemplate.go @@ -671,11 +671,11 @@ type RuleTemplateOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -1403,9 +1403,9 @@ type RuleTemplateOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -2896,11 +2896,11 @@ type RuleTemplateNewParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -3569,9 +3569,9 @@ type RuleTemplateNewParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -5041,11 +5041,11 @@ type RuleTemplateUpdateParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -5714,9 +5714,9 @@ type RuleTemplateUpdateParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". @@ -7186,11 +7186,11 @@ type RuleTemplateReplaceParamsOptionsCors struct { // // - **Adds \* as the Access-Control-Allow-Origin header value** - Content will be // uploaded for requests from any domain. `"value": ["*"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value if the + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value if the // origin matches one of the listed domains** - Content will be uploaded only for // requests from the domains specified in the field. // `"value": ["domain.com", "second.dom.com"]` - // - **Adds "$`http_origin`" as the Access-Control-Allow-Origin header value** - + // - **Adds "$http_origin" as the Access-Control-Allow-Origin header value** - // Content will be uploaded for requests from any domain, and the domain from // which the request was sent will be added to the "Access-Control-Allow-Origin" // header in the response. `"value": ["$http_origin"]` @@ -7859,9 +7859,9 @@ type RuleTemplateReplaceParamsOptionsIPAddressACL struct { // // Possible values: // - // - **allow** - Allow access to all IPs except IPs specified in - // "`excepted_values`" field. - // - **deny** - Deny access to all IPs except IPs specified in "`excepted_values`" + // - **allow** - Allow access to all IPs except IPs specified in "excepted_values" + // field. + // - **deny** - Deny access to all IPs except IPs specified in "excepted_values" // field. // // Any of "allow", "deny". diff --git a/cloud/auditlog.go b/cloud/auditlog.go index 2ef44efe..df84a071 100644 --- a/cloud/auditlog.go +++ b/cloud/auditlog.go @@ -374,8 +374,8 @@ type AuditLogListParams struct { RegionID []int64 `query:"region_id,omitzero" json:"-"` // Resource ID. Several options can be specified. ResourceID []string `query:"resource_id,omitzero" json:"-"` - // (DEPRECATED Use '`order_by`' instead) Sorting by timestamp. Oldest first, or - // most recent first + // (DEPRECATED Use 'order_by' instead) Sorting by timestamp. Oldest first, or most + // recent first // // Any of "asc", "desc". Sorting AuditLogListParamsSorting `query:"sorting,omitzero" json:"-"` @@ -404,8 +404,8 @@ const ( AuditLogListParamsOrderByDesc AuditLogListParamsOrderBy = "desc" ) -// (DEPRECATED Use '`order_by`' instead) Sorting by timestamp. Oldest first, or -// most recent first +// (DEPRECATED Use 'order_by' instead) Sorting by timestamp. Oldest first, or most +// recent first type AuditLogListParamsSorting string const ( diff --git a/cloud/baremetalserver.go b/cloud/baremetalserver.go index 0293a88d..2c185b47 100644 --- a/cloud/baremetalserver.go +++ b/cloud/baremetalserver.go @@ -495,12 +495,12 @@ type BaremetalServerNewParams struct { // When only 'password' is provided, it is set as the password for the default user // of the image. For Windows instances, 'username' cannot be specified. Use the // 'password' field to set the password for the 'Admin' user on Windows. Use the - // '`user_data`' field to provide a script to create new users on Windows. The - // password of the Admin user cannot be updated via '`user_data`'. + // 'user_data' field to provide a script to create new users on Windows. The + // password of the Admin user cannot be updated via 'user_data'. Password param.Opt[string] `json:"password,omitzero"` - // String in base64 format. For Linux instances, '`user_data`' is ignored when + // String in base64 format. For Linux instances, 'user_data' is ignored when // 'password' field is provided. For Windows instances, Admin user password is set - // by 'password' field and cannot be updated via '`user_data`'. Examples of the + // by 'password' field and cannot be updated via 'user_data'. Examples of the // `user_data`: https://cloudinit.readthedocs.io/en/latest/topics/examples.html UserData param.Opt[string] `json:"user_data,omitzero"` // For Linux instances, 'username' and 'password' are used to create a new user. @@ -1173,7 +1173,7 @@ type BaremetalServerNewParamsDDOSProfileField struct { BaseField param.Opt[int64] `json:"base_field,omitzero"` // Human-readable name of the DDoS protection field being configured FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. // // Deprecated: deprecated Value param.Opt[string] `json:"value,omitzero"` diff --git a/cloud/billingreservation.go b/cloud/billingreservation.go index 66852d49..49d7d78a 100644 --- a/cloud/billingreservation.go +++ b/cloud/billingreservation.go @@ -200,7 +200,7 @@ func (r *BillingReservations) UnmarshalJSON(data []byte) error { } type BillingReservationListParams struct { - // Metric name for the resource (e.g., 'bm1-hf-`medium_min`') + // Metric name for the resource (e.g., 'bm1-hf-medium_min') MetricName param.Opt[string] `query:"metric_name,omitzero" json:"-"` // Region for reservation RegionID param.Opt[int64] `query:"region_id,omitzero" json:"-"` diff --git a/cloud/cloud.go b/cloud/cloud.go index 72a60262..9c03c7f9 100644 --- a/cloud/cloud.go +++ b/cloud/cloud.go @@ -395,7 +395,7 @@ type DDOSProfileField struct { FieldName string `json:"field_name,required"` // Data type classification of the field (e.g., string, integer, array) FieldType string `json:"field_type,required"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,required"` // Human-readable name of the protection field Name string `json:"name,required"` @@ -403,7 +403,7 @@ type DDOSProfileField struct { Required bool `json:"required,required"` // JSON schema defining validation rules and constraints for the field value ValidationSchema any `json:"validation_schema,required"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value string `json:"value,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { diff --git a/cloud/costreport.go b/cloud/costreport.go index 21e0b9ff..8ca2264b 100644 --- a/cloud/costreport.go +++ b/cloud/costreport.go @@ -58,7 +58,7 @@ func (r *CostReportService) GetAggregated(ctx context.Context, body CostReportGe // Retrieve a detailed cost report totals for a specified month, which includes // both commit and pay-as-you-go (overcommit) prices. Additionally, it provides the -// spent billing units (e.g., hours or GB) for resources. The "`time_to`" parameter +// spent billing units (e.g., hours or GB) for resources. The "time_to" parameter // represents all days in the specified month. // // Data from the past hour may not reflect the full set of statistics. For the most @@ -6033,7 +6033,7 @@ func init() { } type CostReportGetAggregatedParamsTagsCondition struct { - // The name of the tag to filter (e.g., '`os_version`'). + // The name of the tag to filter (e.g., 'os_version'). Key param.Opt[string] `json:"key,omitzero"` // Determines how strictly the tag value must match the specified value. If true, // the tag value must exactly match the given value. If false, a less strict match @@ -7130,7 +7130,7 @@ func init() { } type CostReportGetAggregatedMonthlyParamsTagsCondition struct { - // The name of the tag to filter (e.g., '`os_version`'). + // The name of the tag to filter (e.g., 'os_version'). Key param.Opt[string] `json:"key,omitzero"` // Determines how strictly the tag value must match the specified value. If true, // the tag value must exactly match the given value. If false, a less strict match @@ -8288,7 +8288,7 @@ func init() { } type CostReportGetDetailedParamsTagsCondition struct { - // The name of the tag to filter (e.g., '`os_version`'). + // The name of the tag to filter (e.g., 'os_version'). Key param.Opt[string] `json:"key,omitzero"` // Determines how strictly the tag value must match the specified value. If true, // the tag value must exactly match the given value. If false, a less strict match diff --git a/cloud/fileshare.go b/cloud/fileshare.go index b8720a63..efbee11a 100644 --- a/cloud/fileshare.go +++ b/cloud/fileshare.go @@ -68,13 +68,14 @@ func (r *FileShareService) New(ctx context.Context, params FileShareNewParams, o // NewAndPoll creates a new file share and polls for completion func (r *FileShareService) NewAndPoll(ctx context.Context, params FileShareNewParams, opts ...option.RequestOption) (v *FileShare, err error) { - resource, err := r.New(ctx, params, opts...) + // Exclude WithResponseBodyInto for the action (New returns TaskIDList, must deserialize properly) + actionOpts := requestconfig.ExcludeResponseBodyInto(opts...) + resource, err := r.New(ctx, params, actionOpts...) if err != nil { return } - opts = slices.Concat(r.Options, opts) - precfg, err := requestconfig.PreRequestOptions(opts...) + precfg, err := requestconfig.PreRequestOptions(slices.Concat(r.Options, opts)...) if err != nil { return } @@ -88,7 +89,12 @@ func (r *FileShareService) NewAndPoll(ctx context.Context, params FileShareNewPa return nil, errors.New("expected exactly one task to be created") } taskID := resource.Tasks[0] - task, err := r.tasks.Poll(ctx, taskID, opts...) + // Exclude WithResponseBodyInto and clear request body for Poll (returns Task, must deserialize properly) + pollOpts := slices.Concat( + requestconfig.ExcludeResponseBodyInto(opts...), + []option.RequestOption{requestconfig.WithoutRequestBody()}, + ) + task, err := r.tasks.Poll(ctx, taskID, pollOpts...) if err != nil { return } @@ -98,7 +104,9 @@ func (r *FileShareService) NewAndPoll(ctx context.Context, params FileShareNewPa } resourceID := task.CreatedResources.FileShares[0] - return r.Get(ctx, resourceID, getParams, opts...) + // Clear request body for Get + getOpts := slices.Concat(opts, []option.RequestOption{requestconfig.WithoutRequestBody()}) + return r.Get(ctx, resourceID, getParams, getOpts...) } // Rename file share, update tags or set share specific properties @@ -128,7 +136,9 @@ func (r *FileShareService) Update(ctx context.Context, fileShareID string, param } func (r *FileShareService) UpdateAndPoll(ctx context.Context, fileShareID string, params FileShareUpdateParams, opts ...option.RequestOption) (res *FileShare, err error) { - resource, err := r.Update(ctx, fileShareID, params, opts...) + // Exclude WithResponseBodyInto for the action (Update returns TaskIDList, must deserialize properly) + actionOpts := requestconfig.ExcludeResponseBodyInto(opts...) + resource, err := r.Update(ctx, fileShareID, params, actionOpts...) if err != nil { return } @@ -148,12 +158,19 @@ func (r *FileShareService) UpdateAndPoll(ctx context.Context, fileShareID string return nil, errors.New("expected at least one task to be created") } taskID := resource.Tasks[0] - _, err = r.tasks.Poll(ctx, taskID, opts...) + // Exclude WithResponseBodyInto and clear request body for Poll (returns Task, must deserialize properly) + pollOpts := slices.Concat( + requestconfig.ExcludeResponseBodyInto(opts...), + []option.RequestOption{requestconfig.WithoutRequestBody()}, + ) + _, err = r.tasks.Poll(ctx, taskID, pollOpts...) if err != nil { return nil, err } - return r.Get(ctx, fileShareID, getParams, opts...) + // Clear request body for Get + getOpts := slices.Concat(opts, []option.RequestOption{requestconfig.WithoutRequestBody()}) + return r.Get(ctx, fileShareID, getParams, getOpts...) } // List file shares @@ -222,17 +239,23 @@ func (r *FileShareService) Delete(ctx context.Context, fileShareID string, body // DeleteAndPoll deletes a file share and polls for completion of the first task. Use the [TaskService.Poll] method if you // need to poll for all tasks. func (r *FileShareService) DeleteAndPoll(ctx context.Context, fileShareID string, body FileShareDeleteParams, opts ...option.RequestOption) error { - resource, err := r.Delete(ctx, fileShareID, body, opts...) + // Exclude WithResponseBodyInto for the action (Delete returns TaskIDList, must deserialize properly) + actionOpts := requestconfig.ExcludeResponseBodyInto(opts...) + resource, err := r.Delete(ctx, fileShareID, body, actionOpts...) if err != nil { return err } - opts = slices.Concat(r.Options, opts) if len(resource.Tasks) == 0 { return errors.New("expected at least one task to be created") } taskID := resource.Tasks[0] - _, err = r.tasks.Poll(ctx, taskID, opts...) + // Exclude WithResponseBodyInto and clear request body for Poll (returns Task, must deserialize properly) + pollOpts := slices.Concat( + requestconfig.ExcludeResponseBodyInto(opts...), + []option.RequestOption{requestconfig.WithoutRequestBody()}, + ) + _, err = r.tasks.Poll(ctx, taskID, pollOpts...) return err } @@ -291,7 +314,9 @@ func (r *FileShareService) Resize(ctx context.Context, fileShareID string, param // ResizeAndPoll resizes a file share and polls for completion of the first task. Use the [TaskService.Poll] method if you // need to poll for all tasks. func (r *FileShareService) ResizeAndPoll(ctx context.Context, fileShareID string, params FileShareResizeParams, opts ...option.RequestOption) (v *FileShare, err error) { - resource, err := r.Resize(ctx, fileShareID, params, opts...) + // Exclude WithResponseBodyInto for the action (Resize returns TaskIDList, must deserialize properly) + actionOpts := requestconfig.ExcludeResponseBodyInto(opts...) + resource, err := r.Resize(ctx, fileShareID, params, actionOpts...) if err != nil { return } @@ -311,12 +336,19 @@ func (r *FileShareService) ResizeAndPoll(ctx context.Context, fileShareID string return nil, errors.New("expected at least one task to be created") } taskID := resource.Tasks[0] - _, err = r.tasks.Poll(ctx, taskID, opts...) + // Exclude WithResponseBodyInto and clear request body for Poll (returns Task, must deserialize properly) + pollOpts := slices.Concat( + requestconfig.ExcludeResponseBodyInto(opts...), + []option.RequestOption{requestconfig.WithoutRequestBody()}, + ) + _, err = r.tasks.Poll(ctx, taskID, pollOpts...) if err != nil { return nil, err } - return r.Get(ctx, fileShareID, getParams, opts...) + // Clear request body for Get + getOpts := slices.Concat(opts, []option.RequestOption{requestconfig.WithoutRequestBody()}) + return r.Get(ctx, fileShareID, getParams, getOpts...) } type FileShare struct { @@ -822,20 +854,15 @@ type FileShareUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` diff --git a/cloud/floatingip.go b/cloud/floatingip.go index 28268938..afe6e28c 100644 --- a/cloud/floatingip.go +++ b/cloud/floatingip.go @@ -70,13 +70,14 @@ func (r *FloatingIPService) New(ctx context.Context, params FloatingIPNewParams, // NewAndPoll creates a floating IP and waits for the operation to complete. func (r *FloatingIPService) NewAndPoll(ctx context.Context, params FloatingIPNewParams, opts ...option.RequestOption) (res *FloatingIP, err error) { - resource, err := r.New(ctx, params, opts...) + // Exclude WithResponseBodyInto for the action (New returns TaskIDList, must deserialize properly) + actionOpts := requestconfig.ExcludeResponseBodyInto(opts...) + resource, err := r.New(ctx, params, actionOpts...) if err != nil { return } - opts = slices.Concat(r.Options, opts) - precfg, err := requestconfig.PreRequestOptions(opts...) + precfg, err := requestconfig.PreRequestOptions(slices.Concat(r.Options, opts)...) if err != nil { return } @@ -90,21 +91,70 @@ func (r *FloatingIPService) NewAndPoll(ctx context.Context, params FloatingIPNew return nil, errors.New("expected exactly one task to be created") } taskID := resource.Tasks[0] - task, err := r.tasks.Poll(ctx, taskID, opts...) + // Exclude WithResponseBodyInto and clear request body for Poll (returns Task, must deserialize properly) + pollOpts := slices.Concat( + requestconfig.ExcludeResponseBodyInto(opts...), + []option.RequestOption{requestconfig.WithoutRequestBody()}, + ) + task, err := r.tasks.Poll(ctx, taskID, pollOpts...) if err != nil { return } if !task.JSON.CreatedResources.Valid() || len(task.CreatedResources.Floatingips) != 1 { - return nil, errors.New("expected exactly one network to be created in a task") + return nil, errors.New("expected exactly one floating IP to be created in a task") } resourceID := task.CreatedResources.Floatingips[0] - return r.Get(ctx, resourceID, getParams, opts...) + // Clear request body for Get + getOpts := slices.Concat(opts, []option.RequestOption{requestconfig.WithoutRequestBody()}) + return r.Get(ctx, resourceID, getParams, getOpts...) } -// Update floating IP -func (r *FloatingIPService) Update(ctx context.Context, floatingIPID string, params FloatingIPUpdateParams, opts ...option.RequestOption) (res *FloatingIP, err error) { +// This endpoint updates the association and tags of an existing Floating IP. The +// behavior depends on the current association state and the provided fields: +// +// Parameters: +// +// `port_id`: The unique identifier of the network interface (port) to which the +// Floating IP should be assigned. This ID can be retrieved from the "Get instance" +// or "List network interfaces" endpoints. +// +// `fixed_ip_address`: The private IP address assigned to the network interface. +// This must be one of the IP addresses currently assigned to the specified port. +// You can retrieve available fixed IP addresses from the "Get instance" or "List +// network interfaces" endpoints. +// +// When the Floating IP has no port associated (`port_id` is null): +// +// - Patch with both `port_id` and `fixed_ip_address`: Assign the Floating IP to +// the specified port and the provided `fixed_ip_address`, if that +// `fixed_ip_address` exists on the port and is not yet used by another Floating +// IP. +// - Patch with `port_id` only (`fixed_ip_address` omitted): Assign the Floating IP +// to the specified port using the first available IPv4 fixed IP of that port. +// +// When the Floating IP is already associated with a port: +// +// - Patch with both `port_id` and `fixed_ip_address`: Re-assign the Floating IP to +// the specified port and address if all validations pass. +// - Patch with `port_id` only (`fixed_ip_address` omitted): Re-assign the Floating +// IP to the specified port using the first available IPv4 fixed IP of that port. +// - Patch with `port_id` = null: Unassign the Floating IP from its current port. +// +// Tags: +// +// - You can update tags alongside association changes. Tags are provided as a list +// of key-value pairs. +// +// Idempotency and task creation: +// +// - No worker task is created if the requested state is already actual, i.e., the +// requested `port_id` equals the current `port_id` and/or the requested +// `fixed_ip_address` equals the current `fixed_ip_address`, and the tags already +// match the current tags. In such cases, the endpoint returns an empty tasks +// list. +func (r *FloatingIPService) Update(ctx context.Context, floatingIPID string, params FloatingIPUpdateParams, opts ...option.RequestOption) (res *TaskIDList, err error) { opts = slices.Concat(r.Options, opts) precfg, err := requestconfig.PreRequestOptions(opts...) if err != nil { @@ -124,11 +174,51 @@ func (r *FloatingIPService) Update(ctx context.Context, floatingIPID string, par err = errors.New("missing required floating_ip_id parameter") return } - path := fmt.Sprintf("cloud/v1/floatingips/%v/%v/%s", params.ProjectID.Value, params.RegionID.Value, floatingIPID) + path := fmt.Sprintf("cloud/v2/floatingips/%v/%v/%s", params.ProjectID.Value, params.RegionID.Value, floatingIPID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, params, &res, opts...) return } +// UpdateAndPoll updates a floating IP and polls for completion of the first task. Use the [TaskService.Poll] method if +// you need to poll for all tasks. +func (r *FloatingIPService) UpdateAndPoll(ctx context.Context, floatingIPID string, params FloatingIPUpdateParams, opts ...option.RequestOption) (res *FloatingIP, err error) { + // Exclude WithResponseBodyInto for the action (Update returns TaskIDList, must deserialize properly) + actionOpts := requestconfig.ExcludeResponseBodyInto(opts...) + resource, err := r.Update(ctx, floatingIPID, params, actionOpts...) + if err != nil { + return + } + + opts = slices.Concat(r.Options, opts) + precfg, err := requestconfig.PreRequestOptions(opts...) + if err != nil { + return + } + var getParams FloatingIPGetParams + requestconfig.UseDefaultParam(¶ms.ProjectID, precfg.CloudProjectID) + requestconfig.UseDefaultParam(¶ms.RegionID, precfg.CloudRegionID) + getParams.ProjectID = params.ProjectID + getParams.RegionID = params.RegionID + + if len(resource.Tasks) == 0 { + return nil, errors.New("expected at least one task to be created") + } + taskID := resource.Tasks[0] + // Exclude WithResponseBodyInto and clear request body for Poll (returns Task, must deserialize properly) + pollOpts := slices.Concat( + requestconfig.ExcludeResponseBodyInto(opts...), + []option.RequestOption{requestconfig.WithoutRequestBody()}, + ) + _, err = r.tasks.Poll(ctx, taskID, pollOpts...) + if err != nil { + return nil, err + } + + // Clear request body for Get + getOpts := slices.Concat(opts, []option.RequestOption{requestconfig.WithoutRequestBody()}) + return r.Get(ctx, floatingIPID, getParams, getOpts...) +} + // List floating IPs func (r *FloatingIPService) List(ctx context.Context, params FloatingIPListParams, opts ...option.RequestOption) (res *pagination.OffsetPage[FloatingIPDetailed], err error) { var raw *http.Response @@ -195,7 +285,9 @@ func (r *FloatingIPService) Delete(ctx context.Context, floatingIPID string, bod // DeleteAndPoll deletes a floating IP and polls for completion of the first task. Use the // [TaskService.Poll] method if you need to poll for all tasks. func (r *FloatingIPService) DeleteAndPoll(ctx context.Context, floatingIPID string, body FloatingIPDeleteParams, opts ...option.RequestOption) error { - resource, err := r.Delete(ctx, floatingIPID, body, opts...) + // Exclude WithResponseBodyInto for the action (Delete returns TaskIDList, must deserialize properly) + actionOpts := requestconfig.ExcludeResponseBodyInto(opts...) + resource, err := r.Delete(ctx, floatingIPID, body, actionOpts...) if err != nil { return err } @@ -204,11 +296,21 @@ func (r *FloatingIPService) DeleteAndPoll(ctx context.Context, floatingIPID stri return errors.New("expected at least one task to be created") } taskID := resource.Tasks[0] - _, err = r.tasks.Poll(ctx, taskID, opts...) + // Exclude WithResponseBodyInto and clear request body for Poll (returns Task, must deserialize properly) + pollOpts := slices.Concat( + requestconfig.ExcludeResponseBodyInto(opts...), + []option.RequestOption{requestconfig.WithoutRequestBody()}, + ) + _, err = r.tasks.Poll(ctx, taskID, pollOpts...) return err } // Assign floating IP to instance or loadbalancer +// +// **Deprecated**: Use PATCH +// /v2/floatingips/{`project_id`}/{`region_id`}/{`floating_ip_id`} instead +// +// Deprecated: deprecated func (r *FloatingIPService) Assign(ctx context.Context, floatingIPID string, params FloatingIPAssignParams, opts ...option.RequestOption) (res *FloatingIP, err error) { opts = slices.Concat(r.Options, opts) precfg, err := requestconfig.PreRequestOptions(opts...) @@ -260,7 +362,10 @@ func (r *FloatingIPService) Get(ctx context.Context, floatingIPID string, query return } -// Unassign floating IP +// **Deprecated**: Use PATCH +// /v2/floatingips/{`project_id`}/{`region_id`}/{`floating_ip_id`} instead +// +// Deprecated: deprecated func (r *FloatingIPService) Unassign(ctx context.Context, floatingIPID string, body FloatingIPUnassignParams, opts ...option.RequestOption) (res *FloatingIP, err error) { opts = slices.Concat(r.Options, opts) precfg, err := requestconfig.PreRequestOptions(opts...) @@ -582,6 +687,10 @@ type FloatingIPUpdateParams struct { ProjectID param.Opt[int64] `path:"project_id,omitzero,required" json:"-"` // Region ID RegionID param.Opt[int64] `path:"region_id,omitzero,required" json:"-"` + // Fixed IP address + FixedIPAddress param.Opt[string] `json:"fixed_ip_address,omitzero" format:"ipv4"` + // Port ID + PortID param.Opt[string] `json:"port_id,omitzero" format:"uuid4"` // Update key-value tags using JSON Merge Patch semantics (RFC 7386). Provide // key-value pairs to add or update tags. Set tag values to `null` to remove tags. // Unspecified tags remain unchanged. Read-only tags are always preserved and @@ -592,20 +701,15 @@ type FloatingIPUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` @@ -659,8 +763,10 @@ type FloatingIPDeleteParams struct { } type FloatingIPAssignParams struct { + // Project ID ProjectID param.Opt[int64] `path:"project_id,omitzero,required" json:"-"` - RegionID param.Opt[int64] `path:"region_id,omitzero,required" json:"-"` + // Region ID + RegionID param.Opt[int64] `path:"region_id,omitzero,required" json:"-"` // Port ID PortID string `json:"port_id,required" format:"uuid4"` // Fixed IP address @@ -685,7 +791,9 @@ type FloatingIPGetParams struct { } type FloatingIPUnassignParams struct { + // Project ID ProjectID param.Opt[int64] `path:"project_id,omitzero,required" json:"-"` - RegionID param.Opt[int64] `path:"region_id,omitzero,required" json:"-"` + // Region ID + RegionID param.Opt[int64] `path:"region_id,omitzero,required" json:"-"` paramObj } diff --git a/cloud/floatingip_test.go b/cloud/floatingip_test.go index 9975c608..d72255d8 100644 --- a/cloud/floatingip_test.go +++ b/cloud/floatingip_test.go @@ -60,8 +60,10 @@ func TestFloatingIPUpdateWithOptionalParams(t *testing.T) { context.TODO(), "c64e5db1-5f1f-43ec-a8d9-5090df85b82d", cloud.FloatingIPUpdateParams{ - ProjectID: gcore.Int(1), - RegionID: gcore.Int(1), + ProjectID: gcore.Int(1), + RegionID: gcore.Int(1), + FixedIPAddress: gcore.String("192.168.10.15"), + PortID: gcore.String("ee2402d0-f0cd-4503-9b75-69be1d11c5f1"), Tags: cloud.TagUpdateMap{ "foo": "my-tag-value", }, @@ -149,10 +151,10 @@ func TestFloatingIPAssignWithOptionalParams(t *testing.T) { ) _, err := client.Cloud.FloatingIPs.Assign( context.TODO(), - "floating_ip_id", + "c64e5db1-5f1f-43ec-a8d9-5090df85b82d", cloud.FloatingIPAssignParams{ - ProjectID: gcore.Int(0), - RegionID: gcore.Int(0), + ProjectID: gcore.Int(1), + RegionID: gcore.Int(1), PortID: "ee2402d0-f0cd-4503-9b75-69be1d11c5f1", FixedIPAddress: gcore.String("192.168.10.15"), }, @@ -209,10 +211,10 @@ func TestFloatingIPUnassign(t *testing.T) { ) _, err := client.Cloud.FloatingIPs.Unassign( context.TODO(), - "floating_ip_id", + "c64e5db1-5f1f-43ec-a8d9-5090df85b82d", cloud.FloatingIPUnassignParams{ - ProjectID: gcore.Int(0), - RegionID: gcore.Int(0), + ProjectID: gcore.Int(1), + RegionID: gcore.Int(1), }, ) if err != nil { diff --git a/cloud/gpubaremetalcluster.go b/cloud/gpubaremetalcluster.go index 6005c838..79123dc6 100644 --- a/cloud/gpubaremetalcluster.go +++ b/cloud/gpubaremetalcluster.go @@ -1098,7 +1098,7 @@ func (r *GPUBaremetalClusterNewParamsServersSettingsInterfaceAnySubnetFloatingIP type GPUBaremetalClusterNewParamsServersSettingsCredentials struct { // Used to set the password for the specified 'username' on Linux instances. If // 'username' is not provided, the password is applied to the default user of the - // image. Mutually exclusive with '`user_data`' - only one can be specified. + // image. Mutually exclusive with 'user_data' - only one can be specified. Password param.Opt[string] `json:"password,omitzero" format:"password"` // Specifies the name of the SSH keypair, created via the // [/v1/`ssh_keys` endpoint](/docs/api-reference/cloud/ssh-keys/add-or-generate-ssh-key). @@ -1219,20 +1219,15 @@ type GPUBaremetalClusterActionParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero,required"` diff --git a/cloud/gpubaremetalclusterinterface.go b/cloud/gpubaremetalclusterinterface.go index 917408a5..eb006a49 100644 --- a/cloud/gpubaremetalclusterinterface.go +++ b/cloud/gpubaremetalclusterinterface.go @@ -210,9 +210,9 @@ type GPUBaremetalClusterInterfaceAttachParamsBodyNewInterfaceExternalExtendSchem BaseField param.Opt[int64] `json:"base_field,omitzero"` // Name of DDoS profile field FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,omitzero"` paramObj } @@ -295,9 +295,9 @@ type GPUBaremetalClusterInterfaceAttachParamsBodyNewInterfaceSpecificSubnetSchem BaseField param.Opt[int64] `json:"base_field,omitzero"` // Name of DDoS profile field FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,omitzero"` paramObj } @@ -338,7 +338,7 @@ type GPUBaremetalClusterInterfaceAttachParamsBodyNewInterfaceAnySubnetSchema str InterfaceName param.Opt[string] `json:"interface_name,omitzero"` // Each group will be added to the separate trunk. PortGroup param.Opt[int64] `json:"port_group,omitzero"` - // Must be '`any_subnet`' + // Must be 'any_subnet' Type param.Opt[string] `json:"type,omitzero"` // Advanced DDoS protection. DDOSProfile GPUBaremetalClusterInterfaceAttachParamsBodyNewInterfaceAnySubnetSchemaDDOSProfile `json:"ddos_profile,omitzero"` @@ -391,9 +391,9 @@ type GPUBaremetalClusterInterfaceAttachParamsBodyNewInterfaceAnySubnetSchemaDDOS BaseField param.Opt[int64] `json:"base_field,omitzero"` // Name of DDoS profile field FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,omitzero"` paramObj } @@ -434,7 +434,7 @@ type GPUBaremetalClusterInterfaceAttachParamsBodyNewInterfaceReservedFixedIPSche InterfaceName param.Opt[string] `json:"interface_name,omitzero"` // Each group will be added to the separate trunk. PortGroup param.Opt[int64] `json:"port_group,omitzero"` - // Must be '`reserved_fixed_ip`'. Union tag + // Must be 'reserved_fixed_ip'. Union tag Type param.Opt[string] `json:"type,omitzero"` // Advanced DDoS protection. DDOSProfile GPUBaremetalClusterInterfaceAttachParamsBodyNewInterfaceReservedFixedIPSchemaDDOSProfile `json:"ddos_profile,omitzero"` @@ -477,9 +477,9 @@ type GPUBaremetalClusterInterfaceAttachParamsBodyNewInterfaceReservedFixedIPSche BaseField param.Opt[int64] `json:"base_field,omitzero"` // Name of DDoS profile field FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,omitzero"` paramObj } diff --git a/cloud/gpuvirtualcluster.go b/cloud/gpuvirtualcluster.go index 079d792e..2f18bd9a 100644 --- a/cloud/gpuvirtualcluster.go +++ b/cloud/gpuvirtualcluster.go @@ -1222,7 +1222,7 @@ func init() { type GPUVirtualClusterNewParamsServersSettingsCredentials struct { // Used to set the password for the specified 'username' on Linux instances. If // 'username' is not provided, the password is applied to the default user of the - // image. Mutually exclusive with '`user_data`' - only one can be specified. + // image. Mutually exclusive with 'user_data' - only one can be specified. Password param.Opt[string] `json:"password,omitzero" format:"password"` // Specifies the name of the SSH keypair, created via the // [/v1/`ssh_keys` endpoint](/docs/api-reference/cloud/ssh-keys/add-or-generate-ssh-key). @@ -1480,20 +1480,15 @@ type GPUVirtualClusterActionParamsBodyUpdateTags struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero,required"` diff --git a/cloud/instance.go b/cloud/instance.go index a133dc41..133e4a90 100644 --- a/cloud/instance.go +++ b/cloud/instance.go @@ -708,8 +708,8 @@ type InstanceNewParams struct { // When only 'password' is provided, it is set as the password for the default user // of the image. For Windows instances, 'username' cannot be specified. Use the // 'password' field to set the password for the 'Admin' user on Windows. Use the - // '`user_data`' field to provide a script to create new users on Windows. The - // password of the Admin user cannot be updated via '`user_data`'. + // 'user_data' field to provide a script to create new users on Windows. The + // password of the Admin user cannot be updated via 'user_data'. Password param.Opt[string] `json:"password,omitzero"` // Placement group ID for instance placement policy. // @@ -721,9 +721,9 @@ type InstanceNewParams struct { // - `soft-anti-affinity`: Tries to place instances on different hosts but allows // sharing if needed. ServergroupID param.Opt[string] `json:"servergroup_id,omitzero" format:"uuid4"` - // String in base64 format. For Linux instances, '`user_data`' is ignored when + // String in base64 format. For Linux instances, 'user_data' is ignored when // 'password' field is provided. For Windows instances, Admin user password is set - // by 'password' field and cannot be updated via '`user_data`'. Examples of the + // by 'password' field and cannot be updated via 'user_data'. Examples of the // `user_data`: https://cloudinit.readthedocs.io/en/latest/topics/examples.html UserData param.Opt[string] `json:"user_data,omitzero"` // For Linux instances, 'username' and 'password' are used to create a new user. @@ -1934,20 +1934,15 @@ type InstanceUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` diff --git a/cloud/instanceinterface.go b/cloud/instanceinterface.go index 13562657..c9df1682 100644 --- a/cloud/instanceinterface.go +++ b/cloud/instanceinterface.go @@ -274,9 +274,9 @@ type InstanceInterfaceAttachParamsBodyNewInterfaceExternalExtendSchemaWithDDOSDD BaseField param.Opt[int64] `json:"base_field,omitzero"` // Name of DDoS profile field FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,omitzero"` paramObj } @@ -359,9 +359,9 @@ type InstanceInterfaceAttachParamsBodyNewInterfaceSpecificSubnetSchemaDDOSProfil BaseField param.Opt[int64] `json:"base_field,omitzero"` // Name of DDoS profile field FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,omitzero"` paramObj } @@ -402,7 +402,7 @@ type InstanceInterfaceAttachParamsBodyNewInterfaceAnySubnetSchema struct { InterfaceName param.Opt[string] `json:"interface_name,omitzero"` // Each group will be added to the separate trunk. PortGroup param.Opt[int64] `json:"port_group,omitzero"` - // Must be '`any_subnet`' + // Must be 'any_subnet' Type param.Opt[string] `json:"type,omitzero"` // Advanced DDoS protection. DDOSProfile InstanceInterfaceAttachParamsBodyNewInterfaceAnySubnetSchemaDDOSProfile `json:"ddos_profile,omitzero"` @@ -455,9 +455,9 @@ type InstanceInterfaceAttachParamsBodyNewInterfaceAnySubnetSchemaDDOSProfileFiel BaseField param.Opt[int64] `json:"base_field,omitzero"` // Name of DDoS profile field FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,omitzero"` paramObj } @@ -498,7 +498,7 @@ type InstanceInterfaceAttachParamsBodyNewInterfaceReservedFixedIPSchema struct { InterfaceName param.Opt[string] `json:"interface_name,omitzero"` // Each group will be added to the separate trunk. PortGroup param.Opt[int64] `json:"port_group,omitzero"` - // Must be '`reserved_fixed_ip`'. Union tag + // Must be 'reserved_fixed_ip'. Union tag Type param.Opt[string] `json:"type,omitzero"` // Advanced DDoS protection. DDOSProfile InstanceInterfaceAttachParamsBodyNewInterfaceReservedFixedIPSchemaDDOSProfile `json:"ddos_profile,omitzero"` @@ -541,9 +541,9 @@ type InstanceInterfaceAttachParamsBodyNewInterfaceReservedFixedIPSchemaDDOSProfi BaseField param.Opt[int64] `json:"base_field,omitzero"` // Name of DDoS profile field FieldName param.Opt[string] `json:"field_name,omitzero"` - // Basic type value. Only one of 'value' or '`field_value`' must be specified. + // Basic type value. Only one of 'value' or 'field_value' must be specified. Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified. + // Complex value. Only one of 'value' or 'field_value' must be specified. FieldValue any `json:"field_value,omitzero"` paramObj } diff --git a/cloud/k8scluster.go b/cloud/k8scluster.go index ff0a17d7..d75c348e 100644 --- a/cloud/k8scluster.go +++ b/cloud/k8scluster.go @@ -740,9 +740,9 @@ func (r *K8SClusterDDOSProfile) UnmarshalJSON(data []byte) error { type K8SClusterDDOSProfileField struct { BaseField int64 `json:"base_field,required"` - // Complex value. Only one of 'value' or '`field_value`' must be specified + // Complex value. Only one of 'value' or 'field_value' must be specified FieldValue any `json:"field_value"` - // Basic value. Only one of 'value' or '`field_value`' must be specified + // Basic value. Only one of 'value' or 'field_value' must be specified Value string `json:"value,nullable"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { @@ -1232,9 +1232,9 @@ func (r *K8SClusterNewParamsDDOSProfile) UnmarshalJSON(data []byte) error { // The property BaseField is required. type K8SClusterNewParamsDDOSProfileField struct { BaseField int64 `json:"base_field,required"` - // Basic value. Only one of 'value' or '`field_value`' must be specified + // Basic value. Only one of 'value' or 'field_value' must be specified Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified + // Complex value. Only one of 'value' or 'field_value' must be specified FieldValue any `json:"field_value,omitzero"` paramObj } @@ -1648,9 +1648,9 @@ func (r *K8SClusterUpdateParamsDDOSProfile) UnmarshalJSON(data []byte) error { // The property BaseField is required. type K8SClusterUpdateParamsDDOSProfileField struct { BaseField int64 `json:"base_field,required"` - // Basic value. Only one of 'value' or '`field_value`' must be specified + // Basic value. Only one of 'value' or 'field_value' must be specified Value param.Opt[string] `json:"value,omitzero"` - // Complex value. Only one of 'value' or '`field_value`' must be specified + // Complex value. Only one of 'value' or 'field_value' must be specified FieldValue any `json:"field_value,omitzero"` paramObj } diff --git a/cloud/loadbalancer.go b/cloud/loadbalancer.go index daaca794..6e447ebf 100644 --- a/cloud/loadbalancer.go +++ b/cloud/loadbalancer.go @@ -2120,20 +2120,15 @@ type LoadBalancerUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` diff --git a/cloud/network.go b/cloud/network.go index a9149dbb..a963e7db 100644 --- a/cloud/network.go +++ b/cloud/network.go @@ -288,20 +288,15 @@ type NetworkUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` diff --git a/cloud/networkrouter.go b/cloud/networkrouter.go index d7818476..c0ae60fd 100644 --- a/cloud/networkrouter.go +++ b/cloud/networkrouter.go @@ -102,7 +102,8 @@ func (r *NetworkRouterService) NewAndPoll(ctx context.Context, params NetworkRou return r.Get(ctx, resourceID, getParams, opts...) } -// Update the configuration of an existing router. +// Update the configuration of an existing router. **Deprecated**: Use PATCH +// /v2/routers/{`project_id`}/{`region_id`}/{`router_id`} func (r *NetworkRouterService) Update(ctx context.Context, routerID string, params NetworkRouterUpdateParams, opts ...option.RequestOption) (res *Router, err error) { opts = slices.Concat(r.Options, opts) precfg, err := requestconfig.PreRequestOptions(opts...) @@ -529,6 +530,24 @@ func init() { ) } +func init() { + apijson.RegisterFieldValidator[NetworkRouterNewParamsExternalGatewayInfoRouterExternalDefaultGwSerializer]( + "type", "default", + ) +} + +func init() { + apijson.RegisterFieldValidator[NetworkRouterNewParamsInterface]( + "type", "subnet", + ) +} + +func init() { + apijson.RegisterFieldValidator[NetworkRouterUpdateParamsExternalGatewayInfo]( + "type", "manual", + ) +} + type NetworkRouterNewParamsExternalGatewayInfoRouterExternalDefaultGwSerializer struct { // Is SNAT enabled. Defaults to true. EnableSnat param.Opt[bool] `json:"enable_snat,omitzero"` @@ -547,12 +566,6 @@ func (r *NetworkRouterNewParamsExternalGatewayInfoRouterExternalDefaultGwSeriali return apijson.UnmarshalRoot(data, r) } -func init() { - apijson.RegisterFieldValidator[NetworkRouterNewParamsExternalGatewayInfoRouterExternalDefaultGwSerializer]( - "type", "default", - ) -} - // The property SubnetID is required. type NetworkRouterNewParamsInterface struct { // id of the subnet to attach to. @@ -572,12 +585,6 @@ func (r *NetworkRouterNewParamsInterface) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func init() { - apijson.RegisterFieldValidator[NetworkRouterNewParamsInterface]( - "type", "subnet", - ) -} - // The properties Destination, Nexthop are required. type NetworkRouterNewParamsRoute struct { // CIDR of destination IPv4 subnet. @@ -639,12 +646,6 @@ func (r *NetworkRouterUpdateParamsExternalGatewayInfo) UnmarshalJSON(data []byte return apijson.UnmarshalRoot(data, r) } -func init() { - apijson.RegisterFieldValidator[NetworkRouterUpdateParamsExternalGatewayInfo]( - "type", "manual", - ) -} - // The properties Destination, Nexthop are required. type NetworkRouterUpdateParamsRoute struct { // CIDR of destination IPv4 subnet. diff --git a/cloud/networksubnet.go b/cloud/networksubnet.go index 499a3d61..c71f9917 100644 --- a/cloud/networksubnet.go +++ b/cloud/networksubnet.go @@ -324,20 +324,15 @@ type NetworkSubnetUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` diff --git a/cloud/region.go b/cloud/region.go index 94a32020..effae950 100644 --- a/cloud/region.go +++ b/cloud/region.go @@ -87,7 +87,7 @@ type Region struct { // // Any of "core", "edge". AccessLevel RegionAccessLevel `json:"access_level,required"` - // List of available volume types, 'standard', '`ssd_hiiops`', 'cold']. + // List of available volume types, 'standard', 'ssd_hiiops', 'cold']. AvailableVolumeTypes []string `json:"available_volume_types,required"` // Coordinates of the region Coordinates RegionCoordinates `json:"coordinates,required"` diff --git a/cloud/reservedfixedip.go b/cloud/reservedfixedip.go index c51ed0db..3d153b49 100644 --- a/cloud/reservedfixedip.go +++ b/cloud/reservedfixedip.go @@ -442,7 +442,7 @@ type ReservedFixedIPNewParamsBodyAnySubnet struct { // // Any of "dual", "ipv4", "ipv6". IPFamily InterfaceIPFamily `json:"ip_family,omitzero"` - // Must be '`any_subnet`'. + // Must be 'any_subnet'. // // This field can be elided, and will marshal its zero value as "any_subnet". Type constant.AnySubnet `json:"type,required"` @@ -465,7 +465,7 @@ type ReservedFixedIPNewParamsBodyIPAddress struct { NetworkID string `json:"network_id,required" format:"uuid4"` // If reserved fixed IP is a VIP IsVip param.Opt[bool] `json:"is_vip,omitzero"` - // Must be '`ip_address`'. + // Must be 'ip_address'. // // This field can be elided, and will marshal its zero value as "ip_address". Type constant.IPAddress `json:"type,required"` @@ -536,7 +536,7 @@ type ReservedFixedIPListParams struct { Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` // Ordering reserved fixed IP list result by name, status, `updated_at`, // `created_at` or `fixed_ip_address` fields and directions (status.asc), default - // is "`fixed_ip_address`.asc" + // is "fixed_ip_address.asc" OrderBy param.Opt[string] `query:"order_by,omitzero" json:"-"` // Set to true if the response should only list VIPs VipOnly param.Opt[bool] `query:"vip_only,omitzero" json:"-"` diff --git a/cloud/securitygroup.go b/cloud/securitygroup.go index b547cf20..4a6f1991 100644 --- a/cloud/securitygroup.go +++ b/cloud/securitygroup.go @@ -29,6 +29,7 @@ import ( type SecurityGroupService struct { Options []option.RequestOption Rules SecurityGroupRuleService + tasks TaskService } // NewSecurityGroupService generates a new service that applies the given options @@ -38,13 +39,14 @@ func NewSecurityGroupService(opts ...option.RequestOption) (r SecurityGroupServi r = SecurityGroupService{} r.Options = opts r.Rules = NewSecurityGroupRuleService(opts...) + r.tasks = NewTaskService(opts...) return } -// **Deprecated** Use `/v2/security_groups//` instead. -// -// Deprecated: deprecated -func (r *SecurityGroupService) New(ctx context.Context, params SecurityGroupNewParams, opts ...option.RequestOption) (res *SecurityGroup, err error) { +// Creates a new security group with the specified configuration. If no egress +// rules are provided, default set of egress rules will be applied If rules are +// explicitly set to empty, no rules will be created. +func (r *SecurityGroupService) New(ctx context.Context, params SecurityGroupNewParams, opts ...option.RequestOption) (res *TaskIDList, err error) { opts = slices.Concat(r.Options, opts) precfg, err := requestconfig.PreRequestOptions(opts...) if err != nil { @@ -60,16 +62,67 @@ func (r *SecurityGroupService) New(ctx context.Context, params SecurityGroupNewP err = errors.New("missing required region_id parameter") return } - path := fmt.Sprintf("cloud/v1/securitygroups/%v/%v", params.ProjectID.Value, params.RegionID.Value) + path := fmt.Sprintf("cloud/v2/security_groups/%v/%v", params.ProjectID.Value, params.RegionID.Value) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return } -// **Deprecated** Use `/v2/security_groups///` -// instead. +// NewAndPoll creates a security group and polls for completion of the first task. Use the [TaskService.Poll] method if +// you need to poll for all tasks. +func (r *SecurityGroupService) NewAndPoll(ctx context.Context, params SecurityGroupNewParams, opts ...option.RequestOption) (res *SecurityGroup, err error) { + resource, err := r.New(ctx, params, opts...) + if err != nil { + return + } + + opts = slices.Concat(r.Options, opts) + precfg, err := requestconfig.PreRequestOptions(opts...) + if err != nil { + return + } + var getParams SecurityGroupGetParams + requestconfig.UseDefaultParam(¶ms.ProjectID, precfg.CloudProjectID) + requestconfig.UseDefaultParam(¶ms.RegionID, precfg.CloudRegionID) + getParams.ProjectID = params.ProjectID + getParams.RegionID = params.RegionID + + if len(resource.Tasks) != 1 { + return nil, errors.New("expected exactly one task to be created") + } + taskID := resource.Tasks[0] + task, err := r.tasks.Poll(ctx, taskID, opts...) + if err != nil { + return + } + + if !task.JSON.CreatedResources.Valid() || len(task.CreatedResources.SecurityGroups) != 1 { + return nil, errors.New("expected exactly one security group to be created in a task") + } + resourceID := task.CreatedResources.SecurityGroups[0] + + return r.Get(ctx, resourceID, getParams, opts...) +} + +// Updates the specified security group with the provided changes. +// +// **Behavior:** +// +// - Simple fields (name, description) will be updated if provided +// - Undefined fields will remain unchanged +// - If no change is detected for a specific field compared to the current security +// group state, that field will be skipped +// - If no changes are detected at all across all fields, no task will be created +// and an empty task list will be returned // -// Deprecated: deprecated -func (r *SecurityGroupService) Update(ctx context.Context, groupID string, params SecurityGroupUpdateParams, opts ...option.RequestOption) (res *SecurityGroup, err error) { +// **Important - Security Group Rules:** +// +// - Rules must be specified completely as the desired final state +// - The system compares the provided rules against the current state +// - Rules that exist in the request but not in the current state will be added +// - Rules that exist in the current state but not in the request will be removed +// - To keep existing rules, they must be included in the request alongside any new +// rules +func (r *SecurityGroupService) Update(ctx context.Context, groupID string, params SecurityGroupUpdateParams, opts ...option.RequestOption) (res *TaskIDList, err error) { opts = slices.Concat(r.Options, opts) precfg, err := requestconfig.PreRequestOptions(opts...) if err != nil { @@ -89,11 +142,42 @@ func (r *SecurityGroupService) Update(ctx context.Context, groupID string, param err = errors.New("missing required group_id parameter") return } - path := fmt.Sprintf("cloud/v1/securitygroups/%v/%v/%s", params.ProjectID.Value, params.RegionID.Value, groupID) + path := fmt.Sprintf("cloud/v2/security_groups/%v/%v/%s", params.ProjectID.Value, params.RegionID.Value, groupID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, params, &res, opts...) return } +// UpdateAndPoll updates a security group and polls for completion of the first task. Use the [TaskService.Poll] method if +// you need to poll for all tasks. +func (r *SecurityGroupService) UpdateAndPoll(ctx context.Context, groupID string, params SecurityGroupUpdateParams, opts ...option.RequestOption) (res *SecurityGroup, err error) { + resource, err := r.Update(ctx, groupID, params, opts...) + if err != nil { + return + } + + opts = slices.Concat(r.Options, opts) + precfg, err := requestconfig.PreRequestOptions(opts...) + if err != nil { + return + } + var getParams SecurityGroupGetParams + requestconfig.UseDefaultParam(¶ms.ProjectID, precfg.CloudProjectID) + requestconfig.UseDefaultParam(¶ms.RegionID, precfg.CloudRegionID) + getParams.ProjectID = params.ProjectID + getParams.RegionID = params.RegionID + + if len(resource.Tasks) == 0 { + return nil, errors.New("expected at least one task to be created") + } + taskID := resource.Tasks[0] + _, err = r.tasks.Poll(ctx, taskID, opts...) + if err != nil { + return nil, err + } + + return r.Get(ctx, groupID, getParams, opts...) +} + // List all security groups in the specified project and region. func (r *SecurityGroupService) List(ctx context.Context, params SecurityGroupListParams, opts ...option.RequestOption) (res *pagination.OffsetPage[SecurityGroup], err error) { var raw *http.Response @@ -403,31 +487,12 @@ type SecurityGroupNewParams struct { ProjectID param.Opt[int64] `path:"project_id,omitzero,required" json:"-"` // Region ID RegionID param.Opt[int64] `path:"region_id,omitzero,required" json:"-"` - // Security group - SecurityGroup SecurityGroupNewParamsSecurityGroup `json:"security_group,omitzero,required"` - // List of instances - Instances []string `json:"instances,omitzero"` - paramObj -} - -func (r SecurityGroupNewParams) MarshalJSON() (data []byte, err error) { - type shadow SecurityGroupNewParams - return param.MarshalObject(r, (*shadow)(&r)) -} -func (r *SecurityGroupNewParams) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) -} - -// Security group -// -// The property Name is required. -type SecurityGroupNewParamsSecurityGroup struct { // Security group name Name string `json:"name,required"` // Security group description Description param.Opt[string] `json:"description,omitzero"` // Security group rules - SecurityGroupRules []SecurityGroupNewParamsSecurityGroupSecurityGroupRule `json:"security_group_rules,omitzero"` + Rules []SecurityGroupNewParamsRule `json:"rules,omitzero"` // Key-value tags to associate with the resource. A tag is a key-value pair that // can be associated with a resource, enabling efficient filtering and grouping for // better organization and management. Both tag keys and values have a maximum @@ -438,16 +503,16 @@ type SecurityGroupNewParamsSecurityGroup struct { paramObj } -func (r SecurityGroupNewParamsSecurityGroup) MarshalJSON() (data []byte, err error) { - type shadow SecurityGroupNewParamsSecurityGroup +func (r SecurityGroupNewParams) MarshalJSON() (data []byte, err error) { + type shadow SecurityGroupNewParams return param.MarshalObject(r, (*shadow)(&r)) } -func (r *SecurityGroupNewParamsSecurityGroup) UnmarshalJSON(data []byte) error { +func (r *SecurityGroupNewParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The property Direction is required. -type SecurityGroupNewParamsSecurityGroupSecurityGroupRule struct { +type SecurityGroupNewParamsRule struct { // Ingress or egress, which is the direction in which the security group is applied // // Any of "egress", "ingress". @@ -475,22 +540,22 @@ type SecurityGroupNewParamsSecurityGroupSecurityGroupRule struct { paramObj } -func (r SecurityGroupNewParamsSecurityGroupSecurityGroupRule) MarshalJSON() (data []byte, err error) { - type shadow SecurityGroupNewParamsSecurityGroupSecurityGroupRule +func (r SecurityGroupNewParamsRule) MarshalJSON() (data []byte, err error) { + type shadow SecurityGroupNewParamsRule return param.MarshalObject(r, (*shadow)(&r)) } -func (r *SecurityGroupNewParamsSecurityGroupSecurityGroupRule) UnmarshalJSON(data []byte) error { +func (r *SecurityGroupNewParamsRule) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } func init() { - apijson.RegisterFieldValidator[SecurityGroupNewParamsSecurityGroupSecurityGroupRule]( + apijson.RegisterFieldValidator[SecurityGroupNewParamsRule]( "direction", "egress", "ingress", ) - apijson.RegisterFieldValidator[SecurityGroupNewParamsSecurityGroupSecurityGroupRule]( + apijson.RegisterFieldValidator[SecurityGroupNewParamsRule]( "ethertype", "IPv4", "IPv6", ) - apijson.RegisterFieldValidator[SecurityGroupNewParamsSecurityGroupSecurityGroupRule]( + apijson.RegisterFieldValidator[SecurityGroupNewParamsRule]( "protocol", "ah", "any", "dccp", "egp", "esp", "gre", "icmp", "igmp", "ipencap", "ipip", "ipv6-encap", "ipv6-frag", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "ipv6-route", "ospf", "pgm", "rsvp", "sctp", "tcp", "udp", "udplite", "vrrp", ) } @@ -500,10 +565,12 @@ type SecurityGroupUpdateParams struct { ProjectID param.Opt[int64] `path:"project_id,omitzero,required" json:"-"` // Region ID RegionID param.Opt[int64] `path:"region_id,omitzero,required" json:"-"` + // Security group description + Description param.Opt[string] `json:"description,omitzero"` // Name Name param.Opt[string] `json:"name,omitzero"` - // List of rules to create or delete - ChangedRules []SecurityGroupUpdateParamsChangedRule `json:"changed_rules,omitzero"` + // Security group rules + Rules []SecurityGroupUpdateParamsRule `json:"rules,omitzero"` // Update key-value tags using JSON Merge Patch semantics (RFC 7386). Provide // key-value pairs to add or update tags. Set tag values to `null` to remove tags. // Unspecified tags remain unchanged. Read-only tags are always preserved and @@ -514,20 +581,15 @@ type SecurityGroupUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` @@ -542,34 +604,27 @@ func (r *SecurityGroupUpdateParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// The property Action is required. -type SecurityGroupUpdateParamsChangedRule struct { - // Action for a rule - // - // Any of "create", "delete". - Action string `json:"action,omitzero,required"` - // The remote group UUID to associate with this security group rule - RemoteGroupID param.Opt[string] `json:"remote_group_id,omitzero" format:"uuid4"` - // The remote IP prefix that is matched by this security group rule - RemoteIPPrefix param.Opt[string] `json:"remote_ip_prefix,omitzero" format:"ipvanynetwork"` - // UUID of rule to be deleted. Required for action 'delete' only - SecurityGroupRuleID param.Opt[string] `json:"security_group_rule_id,omitzero" format:"uuid4"` +type SecurityGroupUpdateParamsRule struct { // Security grpup rule description Description param.Opt[string] `json:"description,omitzero"` // The maximum port number in the range that is matched by the security group rule PortRangeMax param.Opt[int64] `json:"port_range_max,omitzero"` // The minimum port number in the range that is matched by the security group rule PortRangeMin param.Opt[int64] `json:"port_range_min,omitzero"` - // Must be IPv4 or IPv6, and addresses represented in CIDR must match the ingress - // or egress rules. - // - // Any of "IPv4", "IPv6". - Ethertype string `json:"ethertype,omitzero"` + // The remote group UUID to associate with this security group rule + RemoteGroupID param.Opt[string] `json:"remote_group_id,omitzero" format:"uuid4"` + // The remote IP prefix that is matched by this security group rule + RemoteIPPrefix param.Opt[string] `json:"remote_ip_prefix,omitzero" format:"ipvanynetwork"` // Ingress or egress, which is the direction in which the security group rule is // applied // // Any of "egress", "ingress". Direction string `json:"direction,omitzero"` + // Must be IPv4 or IPv6, and addresses represented in CIDR must match the ingress + // or egress rules. + // + // Any of "IPv4", "IPv6". + Ethertype string `json:"ethertype,omitzero"` // Protocol // // Any of "ah", "any", "dccp", "egp", "esp", "gre", "icmp", "igmp", "ipencap", @@ -579,25 +634,22 @@ type SecurityGroupUpdateParamsChangedRule struct { paramObj } -func (r SecurityGroupUpdateParamsChangedRule) MarshalJSON() (data []byte, err error) { - type shadow SecurityGroupUpdateParamsChangedRule +func (r SecurityGroupUpdateParamsRule) MarshalJSON() (data []byte, err error) { + type shadow SecurityGroupUpdateParamsRule return param.MarshalObject(r, (*shadow)(&r)) } -func (r *SecurityGroupUpdateParamsChangedRule) UnmarshalJSON(data []byte) error { +func (r *SecurityGroupUpdateParamsRule) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } func init() { - apijson.RegisterFieldValidator[SecurityGroupUpdateParamsChangedRule]( - "action", "create", "delete", - ) - apijson.RegisterFieldValidator[SecurityGroupUpdateParamsChangedRule]( + apijson.RegisterFieldValidator[SecurityGroupUpdateParamsRule]( "direction", "egress", "ingress", ) - apijson.RegisterFieldValidator[SecurityGroupUpdateParamsChangedRule]( + apijson.RegisterFieldValidator[SecurityGroupUpdateParamsRule]( "ethertype", "IPv4", "IPv6", ) - apijson.RegisterFieldValidator[SecurityGroupUpdateParamsChangedRule]( + apijson.RegisterFieldValidator[SecurityGroupUpdateParamsRule]( "protocol", "ah", "any", "dccp", "egp", "esp", "gre", "icmp", "igmp", "ipencap", "ipip", "ipv6-encap", "ipv6-frag", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "ipv6-route", "ospf", "pgm", "rsvp", "sctp", "tcp", "udp", "udplite", "vrrp", ) } diff --git a/cloud/securitygroup_test.go b/cloud/securitygroup_test.go index c914f7d1..10d331c3 100644 --- a/cloud/securitygroup_test.go +++ b/cloud/securitygroup_test.go @@ -27,26 +27,23 @@ func TestSecurityGroupNewWithOptionalParams(t *testing.T) { option.WithAPIKey("My API Key"), ) _, err := client.Cloud.SecurityGroups.New(context.TODO(), cloud.SecurityGroupNewParams{ - ProjectID: gcore.Int(1), - RegionID: gcore.Int(1), - SecurityGroup: cloud.SecurityGroupNewParamsSecurityGroup{ - Name: "my_security_group", - Description: gcore.String("Some description"), - SecurityGroupRules: []cloud.SecurityGroupNewParamsSecurityGroupSecurityGroupRule{{ - Direction: "ingress", - Description: gcore.String("Some description"), - Ethertype: "IPv4", - PortRangeMax: gcore.Int(80), - PortRangeMin: gcore.Int(80), - Protocol: "tcp", - RemoteGroupID: gcore.String("00000000-0000-4000-8000-000000000000"), - RemoteIPPrefix: gcore.String("10.0.0.0/8"), - }}, - Tags: map[string]string{ - "my-tag": "my-tag-value", - }, + ProjectID: gcore.Int(1), + RegionID: gcore.Int(1), + Name: "my_security_group", + Description: gcore.String("My security group description"), + Rules: []cloud.SecurityGroupNewParamsRule{{ + Direction: "ingress", + Description: gcore.String("Some description"), + Ethertype: "IPv4", + PortRangeMax: gcore.Int(80), + PortRangeMin: gcore.Int(80), + Protocol: "tcp", + RemoteGroupID: gcore.String("00000000-0000-4000-8000-000000000000"), + RemoteIPPrefix: gcore.String("10.0.0.0/8"), + }}, + Tags: map[string]string{ + "my-tag": "my-tag-value", }, - Instances: []string{"00000000-0000-4000-8000-000000000000"}, }) if err != nil { var apierr *gcore.Error @@ -71,23 +68,22 @@ func TestSecurityGroupUpdateWithOptionalParams(t *testing.T) { ) _, err := client.Cloud.SecurityGroups.Update( context.TODO(), - "024a29e9-b4b7-4c91-9a46-505be123d9f8", + "00000000-0000-4000-8000-000000000000", cloud.SecurityGroupUpdateParams{ - ProjectID: gcore.Int(1), - RegionID: gcore.Int(1), - ChangedRules: []cloud.SecurityGroupUpdateParamsChangedRule{{ - Action: "delete", - Description: gcore.String("Some description"), - Direction: "egress", - Ethertype: "IPv4", - PortRangeMax: gcore.Int(80), - PortRangeMin: gcore.Int(80), - Protocol: "tcp", - RemoteGroupID: gcore.String("00000000-0000-4000-8000-000000000000"), - RemoteIPPrefix: gcore.String("10.0.0.0/8"), - SecurityGroupRuleID: gcore.String("00000000-0000-4000-8000-000000000000"), + ProjectID: gcore.Int(1), + RegionID: gcore.Int(1), + Description: gcore.String("Some description"), + Name: gcore.String("some_name"), + Rules: []cloud.SecurityGroupUpdateParamsRule{{ + Description: gcore.String("Some description"), + Direction: "egress", + Ethertype: "IPv4", + PortRangeMax: gcore.Int(80), + PortRangeMin: gcore.Int(80), + Protocol: "tcp", + RemoteGroupID: gcore.String("00000000-0000-4000-8000-000000000000"), + RemoteIPPrefix: gcore.String("10.0.0.0/8"), }}, - Name: gcore.String("some_name"), Tags: cloud.TagUpdateMap{ "foo": "my-tag-value", }, diff --git a/cloud/task.go b/cloud/task.go index 79320b74..b48b77a3 100644 --- a/cloud/task.go +++ b/cloud/task.go @@ -382,53 +382,49 @@ type TaskListParams struct { Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Offset value is used to exclude the first set of records from the result Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` - // Filter the tasks by their type one of ['`activate_ddos_profile`', - // '`attach_bm_to_reserved_fixed_ip`', '`attach_vm_interface`', - // '`attach_vm_to_reserved_fixed_ip`', '`attach_volume`', - // '`create_ai_cluster_gpu`', '`create_bm`', '`create_caas_container`', - // '`create_dbaas_postgres_cluster`', '`create_ddos_profile`', - // '`create_faas_function`', '`create_faas_namespace`', '`create_fip`', - // '`create_gpu_virtual_cluster`', '`create_image`', - // '`create_inference_application`', '`create_inference_instance`', - // '`create_k8s_cluster_pool_v2`', '`create_k8s_cluster_v2`', '`create_l7policy`', - // '`create_l7rule`', '`create_lblistener`', '`create_lbmember`', - // '`create_lbpool`', '`create_lbpool_health_monitor`', '`create_loadbalancer`', - // '`create_network`', '`create_reserved_fixed_ip`', '`create_router`', - // '`create_secret`', '`create_security_group`', '`create_servergroup`', - // '`create_sfs`', '`create_snapshot`', '`create_subnet`', '`create_vm`', - // '`create_volume`', '`deactivate_ddos_profile`', '`delete_ai_cluster_gpu`', - // '`delete_caas_container`', '`delete_dbaas_postgres_cluster`', - // '`delete_ddos_profile`', '`delete_faas_function`', '`delete_faas_namespace`', - // '`delete_fip`', '`delete_gpu_virtual_cluster`', '`delete_gpu_virtual_server`', - // '`delete_image`', '`delete_inference_application`', - // '`delete_inference_instance`', '`delete_k8s_cluster_pool_v2`', - // '`delete_k8s_cluster_v2`', '`delete_l7policy`', '`delete_l7rule`', - // '`delete_lblistener`', '`delete_lbmember`', '`delete_lbmetadata`', - // '`delete_lbpool`', '`delete_loadbalancer`', '`delete_network`', - // '`delete_project`', '`delete_reserved_fixed_ip`', '`delete_router`', - // '`delete_secret`', '`delete_servergroup`', '`delete_sfs`', '`delete_snapshot`', - // '`delete_subnet`', '`delete_vm`', '`delete_volume`', '`detach_vm_interface`', - // '`detach_volume`', '`download_image`', '`downscale_ai_cluster_gpu`', - // '`downscale_gpu_virtual_cluster`', '`extend_sfs`', '`extend_volume`', - // '`failover_loadbalancer`', '`hard_reboot_gpu_baremetal_server`', - // '`hard_reboot_gpu_virtual_cluster`', '`hard_reboot_gpu_virtual_server`', - // '`hard_reboot_vm`', '`patch_caas_container`', '`patch_dbaas_postgres_cluster`', - // '`patch_faas_function`', '`patch_faas_namespace`', '`patch_lblistener`', - // '`patch_lbpool`', '`put_into_server_group`', '`put_l7rule`', '`rebuild_bm`', - // '`rebuild_gpu_baremetal_node`', '`remove_from_server_group`', - // '`replace_lbmetadata`', '`resize_k8s_cluster_v2`', '`resize_loadbalancer`', - // '`resize_vm`', '`resume_vm`', '`revert_volume`', - // '`soft_reboot_gpu_baremetal_server`', '`soft_reboot_gpu_virtual_cluster`', - // '`soft_reboot_gpu_virtual_server`', '`soft_reboot_vm`', - // '`start_gpu_baremetal_server`', '`start_gpu_virtual_cluster`', - // '`start_gpu_virtual_server`', '`start_vm`', '`stop_gpu_baremetal_server`', - // '`stop_gpu_virtual_cluster`', '`stop_gpu_virtual_server`', '`stop_vm`', - // '`suspend_vm`', '`sync_private_flavors`', '`update_ddos_profile`', - // '`update_inference_application`', '`update_inference_instance`', - // '`update_k8s_cluster_v2`', '`update_l7policy`', '`update_lbmetadata`', - // '`update_port_allowed_address_pairs`', '`update_security_group`', - // '`update_sfs`', '`update_tags_gpu_virtual_cluster`', '`upgrade_k8s_cluster_v2`', - // '`upscale_ai_cluster_gpu`', '`upscale_gpu_virtual_cluster`'] + // Filter the tasks by their type one of ['activate_ddos_profile', + // 'attach_bm_to_reserved_fixed_ip', 'attach_vm_interface', + // 'attach_vm_to_reserved_fixed_ip', 'attach_volume', 'create_ai_cluster_gpu', + // 'create_bm', 'create_caas_container', 'create_dbaas_postgres_cluster', + // 'create_ddos_profile', 'create_faas_function', 'create_faas_namespace', + // 'create_fip', 'create_gpu_virtual_cluster', 'create_image', + // 'create_inference_application', 'create_inference_instance', + // 'create_k8s_cluster_pool_v2', 'create_k8s_cluster_v2', 'create_l7policy', + // 'create_l7rule', 'create_lblistener', 'create_lbmember', 'create_lbpool', + // 'create_lbpool_health_monitor', 'create_loadbalancer', 'create_network', + // 'create_reserved_fixed_ip', 'create_router', 'create_secret', + // 'create_security_group', 'create_servergroup', 'create_sfs', 'create_snapshot', + // 'create_subnet', 'create_vm', 'create_volume', 'deactivate_ddos_profile', + // 'delete_ai_cluster_gpu', 'delete_caas_container', + // 'delete_dbaas_postgres_cluster', 'delete_ddos_profile', 'delete_faas_function', + // 'delete_faas_namespace', 'delete_fip', 'delete_gpu_virtual_cluster', + // 'delete_gpu_virtual_server', 'delete_image', 'delete_inference_application', + // 'delete_inference_instance', 'delete_k8s_cluster_pool_v2', + // 'delete_k8s_cluster_v2', 'delete_l7policy', 'delete_l7rule', + // 'delete_lblistener', 'delete_lbmember', 'delete_lbmetadata', 'delete_lbpool', + // 'delete_loadbalancer', 'delete_network', 'delete_project', + // 'delete_reserved_fixed_ip', 'delete_router', 'delete_secret', + // 'delete_servergroup', 'delete_sfs', 'delete_snapshot', 'delete_subnet', + // 'delete_vm', 'delete_volume', 'detach_vm_interface', 'detach_volume', + // 'download_image', 'downscale_ai_cluster_gpu', 'downscale_gpu_virtual_cluster', + // 'extend_sfs', 'extend_volume', 'failover_loadbalancer', + // 'hard_reboot_gpu_baremetal_server', 'hard_reboot_gpu_virtual_cluster', + // 'hard_reboot_gpu_virtual_server', 'hard_reboot_vm', 'patch_caas_container', + // 'patch_dbaas_postgres_cluster', 'patch_faas_function', 'patch_faas_namespace', + // 'patch_lblistener', 'patch_lbpool', 'put_into_server_group', 'put_l7rule', + // 'rebuild_bm', 'rebuild_gpu_baremetal_node', 'remove_from_server_group', + // 'replace_lbmetadata', 'resize_k8s_cluster_v2', 'resize_loadbalancer', + // 'resize_vm', 'resume_vm', 'revert_volume', 'soft_reboot_gpu_baremetal_server', + // 'soft_reboot_gpu_virtual_cluster', 'soft_reboot_gpu_virtual_server', + // 'soft_reboot_vm', 'start_gpu_baremetal_server', 'start_gpu_virtual_cluster', + // 'start_gpu_virtual_server', 'start_vm', 'stop_gpu_baremetal_server', + // 'stop_gpu_virtual_cluster', 'stop_gpu_virtual_server', 'stop_vm', 'suspend_vm', + // 'sync_private_flavors', 'update_ddos_profile', 'update_floating_ip', + // 'update_inference_application', 'update_inference_instance', + // 'update_k8s_cluster_v2', 'update_l7policy', 'update_lbmetadata', + // 'update_port_allowed_address_pairs', 'update_router', 'update_security_group', + // 'update_sfs', 'update_tags_gpu_virtual_cluster', 'upgrade_k8s_cluster_v2', + // 'upscale_ai_cluster_gpu', 'upscale_gpu_virtual_cluster'] TaskType param.Opt[string] `query:"task_type,omitzero" json:"-"` // ISO formatted datetime string. Filter the tasks by creation date less than or // equal to `to_timestamp` @@ -443,7 +439,7 @@ type TaskListParams struct { // The region ID to filter the tasks by region. Supports multiple values of kind // key=value1&key=value2 RegionID []int64 `query:"region_id,omitzero" json:"-"` - // (DEPRECATED Use '`order_by`' instead) Sorting by creation date. Oldest first, or + // (DEPRECATED Use 'order_by' instead) Sorting by creation date. Oldest first, or // most recent first // // Any of "asc", "desc". @@ -472,7 +468,7 @@ const ( TaskListParamsOrderByDesc TaskListParamsOrderBy = "desc" ) -// (DEPRECATED Use '`order_by`' instead) Sorting by creation date. Oldest first, or +// (DEPRECATED Use 'order_by' instead) Sorting by creation date. Oldest first, or // most recent first type TaskListParamsSorting string diff --git a/cloud/usagereport.go b/cloud/usagereport.go index bb6da893..010c0fe1 100644 --- a/cloud/usagereport.go +++ b/cloud/usagereport.go @@ -3940,7 +3940,7 @@ func init() { } type UsageReportGetParamsTagsCondition struct { - // The name of the tag to filter (e.g., '`os_version`'). + // The name of the tag to filter (e.g., 'os_version'). Key param.Opt[string] `json:"key,omitzero"` // Determines how strictly the tag value must match the specified value. If true, // the tag value must exactly match the given value. If false, a less strict match diff --git a/cloud/volume.go b/cloud/volume.go index 1ece36a6..b4b86a50 100644 --- a/cloud/volume.go +++ b/cloud/volume.go @@ -797,20 +797,15 @@ type VolumeUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` diff --git a/cloud/volumesnapshot.go b/cloud/volumesnapshot.go index fc11ede3..d7065631 100644 --- a/cloud/volumesnapshot.go +++ b/cloud/volumesnapshot.go @@ -315,20 +315,15 @@ type VolumeSnapshotUpdateParams struct { // - **Add/update tags:** // `{'tags': {'environment': 'production', 'team': 'backend'}}` adds new tags or // updates existing ones. - // - // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. - // + // - **Delete tags:** `{'tags': {'old_tag': null}}` removes specific tags. // - **Remove all tags:** `{'tags': null}` removes all user-managed tags (read-only // tags are preserved). - // // - **Partial update:** `{'tags': {'environment': 'staging'}}` only updates // specified tags. - // // - **Mixed operations:** // `{'tags': {'environment': 'production', 'cost_center': 'engineering', 'deprecated_tag': null}}` - // adds/updates 'environment' and '`cost_center`' while removing - // '`deprecated_tag`', preserving other existing tags. - // + // adds/updates 'environment' and 'cost_center' while removing 'deprecated_tag', + // preserving other existing tags. // - **Replace all:** first delete existing tags with null values, then add new // ones in the same request. Tags TagUpdateMap `json:"tags,omitzero"` diff --git a/examples/cloud/floatingip/floatingip.go b/examples/cloud/floatingip/floatingip.go index 6ab14d95..aa8d2a10 100644 --- a/examples/cloud/floatingip/floatingip.go +++ b/examples/cloud/floatingip/floatingip.go @@ -49,8 +49,8 @@ func main() { listAllFloatingIPs(&client) getFloatingIPByID(&client, floatingIP.ID) updateFloatingIP(&client, floatingIP.ID) - assignFloatingIP(&client, floatingIP.ID, portID) - unassignFloatingIP(&client, floatingIP.ID) + updateAndAssignFloatingIP(&client, floatingIP.ID, portID) + updateAndUnassignFloatingIP(&client, floatingIP.ID) deleteFloatingIP(&client, floatingIP.ID) } @@ -108,59 +108,64 @@ func getFloatingIPByID(client *gcore.Client, floatingIPID string) { fmt.Println("==============================") } -func assignFloatingIP(client *gcore.Client, floatingIPID string, portID string) { - fmt.Println("\n=== ASSIGN FLOATING IP ===") - - params := cloud.FloatingIPAssignParams{ - PortID: portID, - } +func deleteFloatingIP(client *gcore.Client, floatingIPID string) { + fmt.Println("\n=== DELETE FLOATING IP ===") - floatingIP, err := client.Cloud.FloatingIPs.Assign(context.Background(), floatingIPID, params) + err := client.Cloud.FloatingIPs.DeleteAndPoll(context.Background(), floatingIPID, cloud.FloatingIPDeleteParams{}) if err != nil { - log.Fatalf("Error assigning floating IP: %v", err) + log.Fatalf("Error deleting floating IP: %v", err) } - fmt.Printf("Assigned Floating IP: ID=%s, PortID=%v, FixedIPAddress=%v\n", - floatingIP.ID, floatingIP.PortID, floatingIP.FixedIPAddress) + fmt.Printf("Floating IP with ID %s successfully deleted\n", floatingIPID) fmt.Println("===========================") } -func unassignFloatingIP(client *gcore.Client, floatingIPID string) { - fmt.Println("\n=== UNASSIGN FLOATING IP ===") +func updateFloatingIP(client *gcore.Client, floatingIPID string) { + fmt.Println("\n=== UPDATE FLOATING IP (TAGS ONLY) ===") - floatingIP, err := client.Cloud.FloatingIPs.Unassign(context.Background(), floatingIPID, cloud.FloatingIPUnassignParams{}) + params := cloud.FloatingIPUpdateParams{ + Tags: map[string]string{"env": "prod"}, + } + floatingIP, err := client.Cloud.FloatingIPs.UpdateAndPoll(context.Background(), floatingIPID, params) if err != nil { - log.Fatalf("Error unassigning floating IP: %v", err) + log.Fatalf("Error updating floating IP: %v", err) } - fmt.Printf("Unassigned Floating IP: ID=%s\n", floatingIP.ID) - fmt.Println("=============================") + fmt.Printf("Updated Floating IP: ID=%s, Status=%s, FloatingIPAddress=%s\n", + floatingIP.ID, floatingIP.Status, floatingIP.FloatingIPAddress) + fmt.Println("===========================") } -func deleteFloatingIP(client *gcore.Client, floatingIPID string) { - fmt.Println("\n=== DELETE FLOATING IP ===") +func updateAndAssignFloatingIP(client *gcore.Client, floatingIPID string, portID string) { + fmt.Println("\n=== UPDATE AND ASSIGN FLOATING IP (v2 API) ===") - err := client.Cloud.FloatingIPs.DeleteAndPoll(context.Background(), floatingIPID, cloud.FloatingIPDeleteParams{}) + params := cloud.FloatingIPUpdateParams{ + PortID: param.Opt[string]{Value: portID}, + Tags: map[string]string{"status": "assigned"}, + } + floatingIP, err := client.Cloud.FloatingIPs.UpdateAndPoll(context.Background(), floatingIPID, params) if err != nil { - log.Fatalf("Error deleting floating IP: %v", err) + log.Fatalf("Error updating and assigning floating IP: %v", err) } - fmt.Printf("Floating IP with ID %s successfully deleted\n", floatingIPID) + fmt.Printf("Assigned Floating IP: ID=%s, PortID=%v, FixedIPAddress=%v, Status=%s\n", + floatingIP.ID, floatingIP.PortID, floatingIP.FixedIPAddress, floatingIP.Status) fmt.Println("===========================") } -func updateFloatingIP(client *gcore.Client, floatingIPID string) { - fmt.Println("\n=== UPDATE FLOATING IP ===") +func updateAndUnassignFloatingIP(client *gcore.Client, floatingIPID string) { + fmt.Println("\n=== UPDATE AND UNASSIGN FLOATING IP (v2 API) ===") + // Setting PortID to null unassigns the floating IP params := cloud.FloatingIPUpdateParams{ - Tags: map[string]string{"env": "prod"}, + PortID: param.Null[string](), + Tags: map[string]string{"status": "unassigned"}, } - floatingIP, err := client.Cloud.FloatingIPs.Update(context.Background(), floatingIPID, params) + floatingIP, err := client.Cloud.FloatingIPs.UpdateAndPoll(context.Background(), floatingIPID, params) if err != nil { - log.Fatalf("Error updating floating IP: %v", err) + log.Fatalf("Error updating and unassigning floating IP: %v", err) } - fmt.Printf("Updated Floating IP: ID=%s, Status=%s, FloatingIPAddress=%s\n", - floatingIP.ID, floatingIP.Status, floatingIP.FloatingIPAddress) + fmt.Printf("Unassigned Floating IP: ID=%s, Status=%s\n", floatingIP.ID, floatingIP.Status) fmt.Println("===========================") } diff --git a/examples/cloud/securitygroup/securitygroup.go b/examples/cloud/securitygroup/securitygroup.go index b410ef4e..b31da57c 100644 --- a/examples/cloud/securitygroup/securitygroup.go +++ b/examples/cloud/securitygroup/securitygroup.go @@ -54,11 +54,9 @@ func main() { func createSecurityGroup(client *gcore.Client) string { fmt.Println("\n=== CREATE SECURITY GROUP ===") - sg, err := client.Cloud.SecurityGroups.New(context.Background(), cloud.SecurityGroupNewParams{ - SecurityGroup: cloud.SecurityGroupNewParamsSecurityGroup{ - Name: "gcore-go-example", - Description: gcore.String("gcore-go-example security group"), - }, + sg, err := client.Cloud.SecurityGroups.NewAndPoll(context.Background(), cloud.SecurityGroupNewParams{ + Name: "gcore-go-example", + Description: gcore.String("gcore-go-example security group"), }) if err != nil { log.Fatalf("Error creating security group: %v", err) @@ -100,7 +98,7 @@ func getSecurityGroup(client *gcore.Client, groupID string) { func updateSecurityGroup(client *gcore.Client, groupID string) { fmt.Println("\n=== UPDATE SECURITY GROUP ===") - sg, err := client.Cloud.SecurityGroups.Update(context.Background(), groupID, cloud.SecurityGroupUpdateParams{ + sg, err := client.Cloud.SecurityGroups.UpdateAndPoll(context.Background(), groupID, cloud.SecurityGroupUpdateParams{ Name: gcore.String("gcore-go-example-updated"), }) if err != nil { diff --git a/internal/requestconfig/optionfilter.go b/internal/requestconfig/optionfilter.go new file mode 100644 index 00000000..438ad350 --- /dev/null +++ b/internal/requestconfig/optionfilter.go @@ -0,0 +1,60 @@ +package requestconfig + +import ( + "net/http" + "net/url" + "reflect" +) + +// WithoutRequestBody clears any request body set by previous options. +// Used internally in polling methods to ensure Poll() and Get() calls have no request body. +func WithoutRequestBody() RequestOption { + return RequestOptionFunc(func(r *RequestConfig) error { + r.Body = nil + return nil + }) +} + +// ExcludeResponseBodyInto returns a new slice of options with WithResponseBodyInto removed. +// Used for action methods and Poll() to ensure they use default deserialization (TaskIDList, Task). +func ExcludeResponseBodyInto(opts ...RequestOption) []RequestOption { + if len(opts) == 0 { + return opts + } + + filtered := make([]RequestOption, 0, len(opts)) + for _, opt := range opts { + if !modifiesResponseBodyInto(opt) { + filtered = append(filtered, opt) + } + } + return filtered +} + +// modifiesResponseBodyInto checks if an option modifies the ResponseBodyInto field. +func modifiesResponseBodyInto(opt RequestOption) bool { + optFunc, ok := opt.(RequestOptionFunc) + if !ok { + return false + } + + // Create a minimally initialized test config + cfg := newMinimalConfig() + originalResponseBodyInto := cfg.ResponseBodyInto + + // Apply the option + _ = optFunc.Apply(cfg) + + // Check if ResponseBodyInto changed + return !reflect.DeepEqual(originalResponseBodyInto, cfg.ResponseBodyInto) +} + +// newMinimalConfig creates a minimally initialized RequestConfig for option detection. +func newMinimalConfig() *RequestConfig { + req, _ := http.NewRequest("GET", "http://localhost", nil) + baseURL, _ := url.Parse("http://localhost") + return &RequestConfig{ + Request: req, + BaseURL: baseURL, + } +} diff --git a/internal/requestconfig/optionfilter_test.go b/internal/requestconfig/optionfilter_test.go new file mode 100644 index 00000000..ddc209b1 --- /dev/null +++ b/internal/requestconfig/optionfilter_test.go @@ -0,0 +1,85 @@ +package requestconfig + +import ( + "net/http" + "testing" +) + +func TestExcludeResponseBodyInto(t *testing.T) { + t.Run("WithResponseBodyInto is filtered", func(t *testing.T) { + var customDest interface{} + opts := []RequestOption{ + RequestOptionFunc(func(r *RequestConfig) error { + r.ResponseBodyInto = &customDest + return nil + }), + } + + filtered := ExcludeResponseBodyInto(opts...) + if len(filtered) != 0 { + t.Errorf("Expected WithResponseBodyInto to be filtered out, got %d options", len(filtered)) + } + }) + + t.Run("WithResponseInto is NOT filtered", func(t *testing.T) { + var res *http.Response + opts := []RequestOption{ + RequestOptionFunc(func(r *RequestConfig) error { + r.ResponseInto = &res + return nil + }), + } + + filtered := ExcludeResponseBodyInto(opts...) + if len(filtered) != 1 { + t.Errorf("Expected WithResponseInto to NOT be filtered, got %d options", len(filtered)) + } + }) + + t.Run("Mixed options", func(t *testing.T) { + var customDest interface{} + var res *http.Response + opts := []RequestOption{ + RequestOptionFunc(func(r *RequestConfig) error { + r.ResponseBodyInto = &customDest + return nil + }), + RequestOptionFunc(func(r *RequestConfig) error { + r.ResponseInto = &res + return nil + }), + RequestOptionFunc(func(r *RequestConfig) error { + r.Request.Header.Set("X-Test", "value") + return nil + }), + } + + filtered := ExcludeResponseBodyInto(opts...) + if len(filtered) != 2 { + t.Errorf("Expected 2 options after filtering (ResponseInto + Header), got %d", len(filtered)) + } + }) + + t.Run("Other options are kept", func(t *testing.T) { + var customDest interface{} + opts := []RequestOption{ + RequestOptionFunc(func(r *RequestConfig) error { + r.ResponseBodyInto = &customDest + return nil + }), + RequestOptionFunc(func(r *RequestConfig) error { + r.Request.Header.Set("X-Test", "value") + return nil + }), + RequestOptionFunc(func(r *RequestConfig) error { + r.Body = nil + return nil + }), + } + + filtered := ExcludeResponseBodyInto(opts...) + if len(filtered) != 2 { + t.Errorf("Expected 2 options after filtering (Header + Body), got %d", len(filtered)) + } + }) +} diff --git a/internal/version.go b/internal/version.go index ecc4b711..7d5879c5 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.29.0" // x-release-please-version +const PackageVersion = "0.30.0" // x-release-please-version diff --git a/streaming/aitask.go b/streaming/aitask.go index 80265553..4fda9692 100644 --- a/streaming/aitask.go +++ b/streaming/aitask.go @@ -282,8 +282,8 @@ func (r *AITaskService) Get(ctx context.Context, taskID string, opts ...option.R // // Parameter sections: // -// - "`language_support`" – AI Translation: check if a language pair is supported -// or not for AI translation. +// - "language_support" – AI Translation: check if a language pair is supported or +// not for AI translation. // - this list will expand as new AI methods are added. // // **`language_support`** @@ -291,7 +291,7 @@ func (r *AITaskService) Get(ctx context.Context, taskID string, opts ...option.R // There are many languages available for transcription. But not all languages can // be automatically translated to and from with good quality. In order to determine // the availability of translation from the audio language to the desired subtitle -// language, you can use this type of "`language_support`". +// language, you can use this type of "language_support". // // AI models are constantly improving, so this method can be used for dynamic // determination. @@ -321,7 +321,7 @@ func (r *AITaskService) GetAISettings(ctx context.Context, query AITaskGetAISett } type AIContentmoderationHardnudity struct { - // AI content moderation with "`hard_nudity`" algorithm + // AI content moderation with "hard_nudity" algorithm // // Any of "hard_nudity", "sport", "nsfw", "soft_nudity". Category AIContentmoderationHardnudityCategory `json:"category,required"` @@ -369,7 +369,7 @@ func (r *AIContentmoderationHardnudity) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// AI content moderation with "`hard_nudity`" algorithm +// AI content moderation with "hard_nudity" algorithm type AIContentmoderationHardnudityCategory string const ( @@ -459,7 +459,7 @@ const ( ) type AIContentmoderationSoftnudity struct { - // AI content moderation with "`soft_nudity`" algorithm + // AI content moderation with "soft_nudity" algorithm // // Any of "soft_nudity", "sport", "nsfw", "hard_nudity". Category AIContentmoderationSoftnudityCategory `json:"category,required"` @@ -510,7 +510,7 @@ func (r *AIContentmoderationSoftnudity) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// AI content moderation with "`soft_nudity`" algorithm +// AI content moderation with "soft_nudity" algorithm type AIContentmoderationSoftnudityCategory string const ( @@ -858,7 +858,7 @@ type AITaskTaskDataAITranscribe struct { // processing. ClientUserID string `json:"client_user_id"` // Indicates which language it is clearly necessary to translate into. If this is - // not set, the original language will be used from attribute "`audio_language`". + // not set, the original language will be used from attribute "audio_language". // // Please note that: // @@ -1543,7 +1543,7 @@ type AITaskNewParams struct { // processing. ClientUserID param.Opt[string] `json:"client_user_id,omitzero"` // Indicates which language it is clearly necessary to translate into. If this is - // not set, the original language will be used from attribute "`audio_language`". + // not set, the original language will be used from attribute "audio_language". // // Please note that: // @@ -1615,8 +1615,7 @@ type AITaskListParams struct { // Which field to use when ordering the results: `task_id`, status, and // `task_name`. Sorting is done in ascending (ASC) order. // - // If parameter is omitted then "`started_at` DESC" is used for ordering by - // default. + // If parameter is omitted then "started_at DESC" is used for ordering by default. // // Any of "task_id", "status", "task_name", "started_at". Ordering AITaskListParamsOrdering `query:"ordering,omitzero" json:"-"` @@ -1644,8 +1643,7 @@ func (r AITaskListParams) URLQuery() (v url.Values, err error) { // Which field to use when ordering the results: `task_id`, status, and // `task_name`. Sorting is done in ascending (ASC) order. // -// If parameter is omitted then "`started_at` DESC" is used for ordering by -// default. +// If parameter is omitted then "started_at DESC" is used for ordering by default. type AITaskListParamsOrdering string const ( diff --git a/streaming/directory.go b/streaming/directory.go index b1fb7f2b..6bb76f7d 100644 --- a/streaming/directory.go +++ b/streaming/directory.go @@ -43,7 +43,7 @@ func (r *DirectoryService) New(ctx context.Context, body DirectoryNewParams, opt return } -// Change a directory name or move to another "`parent_id`". +// Change a directory name or move to another "parent_id". func (r *DirectoryService) Update(ctx context.Context, directoryID int64, body DirectoryUpdateParams, opts ...option.RequestOption) (res *DirectoryBase, err error) { opts = slices.Concat(r.Options, opts) path := fmt.Sprintf("streaming/directories/%v", directoryID) diff --git a/streaming/playlist.go b/streaming/playlist.go index ceebe51f..25376b3b 100644 --- a/streaming/playlist.go +++ b/streaming/playlist.go @@ -191,7 +191,7 @@ type Playlist struct { // A URL to a master playlist HLS (master-cmaf.m3u8) with CMAF-based chunks. Chunks // are in fMP4 container. // - // It is possible to use the same suffix-options as described in the "`hls_url`" + // It is possible to use the same suffix-options as described in the "hls_url" // attribute. // // Caution. Solely master.m3u8 (and master[-options].m3u8) is officially documented @@ -309,7 +309,7 @@ type PlaylistParam struct { // A URL to a master playlist HLS (master-cmaf.m3u8) with CMAF-based chunks. Chunks // are in fMP4 container. // - // It is possible to use the same suffix-options as described in the "`hls_url`" + // It is possible to use the same suffix-options as described in the "hls_url" // attribute. // // Caution. Solely master.m3u8 (and master[-options].m3u8) is officially documented @@ -475,16 +475,16 @@ type PlaylistVideo struct { // ID of the directory where the video should be uploaded. (beta) DirectoryID int64 `json:"directory_id"` // Authorization HTTP request header. Will be used as credentials to authenticate a - // request to download a file (specified in "`origin_url`" parameter) on an - // external server. + // request to download a file (specified in "origin_url" parameter) on an external + // server. // // Syntax: `Authorization: ` // // Examples: // - // - "`origin_http_headers`": "Authorization: Basic ..." - // - "`origin_http_headers`": "Authorization: Bearer ..." - // - "`origin_http_headers`": "Authorization: APIKey ..." Example of usage when + // - "origin_http_headers": "Authorization: Basic ..." + // - "origin_http_headers": "Authorization: Bearer ..." + // - "origin_http_headers": "Authorization: APIKey ..." Example of usage when // downloading a file from Google Drive: // // ``` @@ -507,7 +507,7 @@ type PlaylistVideo struct { // After uploading the video, the system will automatically create several // screenshots (they will be stored in "screenshots" attribute) from which you can // select an default screenshot. This "poster" field is for uploading your own - // image. Also use attribute "`screenshot_id`" to select poster as a default + // image. Also use attribute "screenshot_id" to select poster as a default // screnshot. // // Attribute accepts single image as base64-encoded string diff --git a/streaming/qualityset.go b/streaming/qualityset.go index 4ff6b51a..20f38afc 100644 --- a/streaming/qualityset.go +++ b/streaming/qualityset.go @@ -95,13 +95,13 @@ func (r *QualitySetService) List(ctx context.Context, opts ...option.RequestOpti // Live transcoding management: // // - You can specify quality set explicitly in POST /streams method, look at -// attribute "`quality_set_id`". +// attribute "quality_set_id". // - Otherwise these default values will be used by the system by default. // // VOD transcoding management: // // - You can specify quality set explicitly in POST /videos method, look at -// attribute "`quality_set_id`". +// attribute "quality_set_id". // - Otherwise these default values will be used by the system by default. func (r *QualitySetService) SetDefault(ctx context.Context, body QualitySetSetDefaultParams, opts ...option.RequestOption) (res *QualitySets, err error) { opts = slices.Concat(r.Options, opts) diff --git a/streaming/statistic.go b/streaming/statistic.go index 37d3b38a..fb167a1d 100644 --- a/streaming/statistic.go +++ b/streaming/statistic.go @@ -1121,9 +1121,9 @@ type StatisticGetLiveUniqueViewersParams struct { From string `query:"from,required" json:"-"` // End of time frame. Format is date time in ISO 8601 To string `query:"to,required" json:"-"` - // Filter by "`client_user_id`" + // Filter by "client_user_id" ClientUserID param.Opt[int64] `query:"client_user_id,omitzero" json:"-"` - // Filter by "`stream_id`" + // Filter by "stream_id" StreamID param.Opt[int64] `query:"stream_id,omitzero" json:"-"` // Specifies the time interval for grouping data // @@ -1156,7 +1156,7 @@ type StatisticGetLiveWatchTimeCdnParams struct { // Start of the time period for counting minutes of watching. Format is date time // in ISO 8601. From string `query:"from,required" json:"-"` - // Filter by field "`client_user_id`" + // Filter by field "client_user_id" ClientUserID param.Opt[int64] `query:"client_user_id,omitzero" json:"-"` // Filter by `stream_id` StreamID param.Opt[int64] `query:"stream_id,omitzero" json:"-"` @@ -1192,7 +1192,7 @@ const ( ) type StatisticGetLiveWatchTimeTotalCdnParams struct { - // Filter by field "`client_user_id`" + // Filter by field "client_user_id" ClientUserID param.Opt[int64] `query:"client_user_id,omitzero" json:"-"` // Start of the time period for counting minutes of watching. Format is date time // in ISO 8601. If omitted, the earliest start time for viewing is taken @@ -1681,7 +1681,7 @@ type StatisticGetVodWatchTimeCdnParams struct { // Start of the time period for counting minutes of watching. Format is date time // in ISO 8601. From string `query:"from,required" json:"-"` - // Filter by field "`client_user_id`" + // Filter by field "client_user_id" ClientUserID param.Opt[int64] `query:"client_user_id,omitzero" json:"-"` // Filter by video's slug Slug param.Opt[string] `query:"slug,omitzero" json:"-"` @@ -1717,7 +1717,7 @@ const ( ) type StatisticGetVodWatchTimeTotalCdnParams struct { - // Filter by field "`client_user_id`" + // Filter by field "client_user_id" ClientUserID param.Opt[int64] `query:"client_user_id,omitzero" json:"-"` // Start of the time period for counting minutes of watching. Format is date time // in ISO 8601. If omitted, the earliest start time for viewing is taken diff --git a/streaming/stream.go b/streaming/stream.go index cfe2a504..6b2f1fcf 100644 --- a/streaming/stream.go +++ b/streaming/stream.go @@ -122,8 +122,8 @@ func (r *StreamService) ListAutoPaging(ctx context.Context, query StreamListPara // is impossible to restore data and files after this. // // But if the live had recordings, they continue to remain independent Video -// entities. The "`stream_id`" parameter will simply point to a stream that no -// longer exists. +// entities. The "stream_id" parameter will simply point to a stream that no longer +// exists. // // Perhaps, instead of deleting, you may use the stream deactivation: // @@ -191,7 +191,7 @@ func (r *StreamService) ClearDvr(ctx context.Context, streamID int64, opts ...op // **Cutting a clip from a source:** // // In order to use clips recording feature, DVR must be enabled for a stream: -// "`dvr_enabled`: true". The DVR serves as a source for creating clips: +// "dvr_enabled: true". The DVR serves as a source for creating clips: // // - By default live stream DVR is set to 1 hour (3600 seconds). You can create an // instant clip using any segment of this time period by specifying the desired @@ -224,7 +224,7 @@ func (r *StreamService) Get(ctx context.Context, streamID int64, opts ...option. // Get list of non expired instant clips for a stream. // // You can now use both MP4 just-in-time packager and HLS for all clips. Get URLs -// from "`hls_master`" and "`mp4_master`". +// from "hls_master" and "mp4_master". // // **How to download renditions of clips:** // @@ -255,22 +255,22 @@ func (r *StreamService) ListClips(ctx context.Context, streamID int64, opts ...o // separate video VOD: // // - ID of the stream from which the recording was organized is added to -// "`stream_id`" field. You can find the video by that value later. +// "stream_id" field. You can find the video by that value later. // - Title of the video is based on pattern "Stream Record: {`stream_title`}, // {`recording_end_time_utc`}". -// - Recording start time is stored in "`recording_started_at`" field. +// - Recording start time is stored in "recording_started_at" field. // - You can record the original stream or the transcoded one. Only the transcoded // version will contain overlays. Set the appropriate recording method when // creating the stream or before calling this recording method. Details in the -// "`record_type`" parameter of the stream. +// "record_type" parameter of the stream. // - If you have access to the premium feature of saving the original stream (so // not just transcoded renditions), then the link to the original file will be in -// the "`origin_url`" field. Look at the description of the field how to use it. +// the "origin_url" field. Look at the description of the field how to use it. // // Stream must be live for the recording to start, please check fields "live" -// and/or "`backup_live`". After the recording starts, field "recording" will -// switch to "true", and the recording duration in seconds will appear in the -// "`recording_duration`" field. +// and/or "backup_live". After the recording starts, field "recording" will switch +// to "true", and the recording duration in seconds will appear in the +// "recording_duration" field. // // Please, keep in mind that recording doesn't start instantly, it takes ±3-7 // seconds to initialize the process after executing this method. @@ -329,7 +329,7 @@ type Clip struct { // can be added to left and right. // // Duration of cutted segment cannot be greater than DVR duration for this stream. - // Therefore, to change the maximum, use "`dvr_duration`" parameter of this stream. + // Therefore, to change the maximum, use "dvr_duration" parameter of this stream. Duration int64 `json:"duration,required"` // Creation date and time. Format is date time in ISO 8601 CreatedAt string `json:"created_at"` @@ -355,7 +355,7 @@ type Clip struct { Expiration int64 `json:"expiration"` // Link to HLS .m3u8 with immediate clip. The link retains same adaptive bitrate as // in the stream for end viewers. For additional restrictions, see the description - // of parameter "`mp4_master`". + // of parameter "mp4_master". HlsMaster string `json:"hls_master"` // Link to MP4 with immediate clip. The link points to max rendition quality. // Request of the URL can return: @@ -438,7 +438,7 @@ type Stream struct { // - false – auto recording is disabled AutoRecord bool `json:"auto_record"` // State of receiving and transcoding master stream from source by backup server if - // you pushing stream to "`backup_push_url`" or "`backup_push_url_srt`". + // you pushing stream to "backup_push_url" or "backup_push_url_srt". // // Displays the backup server status of PUSH method only. For PULL a "live" field // is always used, even when origin servers are switched using round robin @@ -539,8 +539,8 @@ type Stream struct { // - and its possible to enable ±3 sec for LL-HLS, just ask our Support Team. // // It is also possible to use modifier-attributes, which are described in the - // "`hls_mpegts_url`" field above. If you need to get MPEG-TS (.ts) chunks, look at - // the attribute "`hls_mpegts_url`". + // "hls_mpegts_url" field above. If you need to get MPEG-TS (.ts) chunks, look at + // the attribute "hls_mpegts_url". // // Read more information in the article "How Low Latency streaming works" in the // Knowledge Base. @@ -556,7 +556,7 @@ type Stream struct { // Some legacy devices or software may require MPEG-TS (.ts) segments as a format // for streaming, so we provide this options keeping backward compatibility with // any of your existing workflows. For other cases it's better to use - // "`hls_cmaf_url`" instead. + // "hls_cmaf_url" instead. // // You can use this legacy HLSv6 format based on MPEG-TS segmenter in parallel with // main HLS CMAF. Both formats are sharing same segments size, manifest length @@ -566,9 +566,9 @@ type Stream struct { // // - ?`get_duration_sec`=true – Adds the real segment duration in seconds to chunk // requests. A chunk duration will be automatically added to a chunk request - // string with the "`duration_sec`" attribute. The value is an integer for a - // length multiple of whole seconds, or a fractional number separated by a dot - // for chunks that are not multiples of seconds. This attribute allows you to + // string with the "duration_sec" attribute. The value is an integer for a length + // multiple of whole seconds, or a fractional number separated by a dot for + // chunks that are not multiples of seconds. This attribute allows you to // determine duration in seconds at the level of analyzing the logs of CDN // requests and compare it with file size (so to use it in your analytics). // @@ -598,8 +598,8 @@ type Stream struct { // into an iframe on your website and the video will automatically play in all // browsers. // - // Please, remember that transcoded streams from "`hls_cmaf_url`" with .m3u8 at the - // end, and from "`dash_url`" with .mpd at the end are to be played inside video + // Please, remember that transcoded streams from "hls_cmaf_url" with .m3u8 at the + // end, and from "dash_url" with .mpd at the end are to be played inside video // players only. For example: AVplayer on iOS, Exoplayer on Android, HTML web // player in browser, etc. General bowsers like Chrome, Firefox, etc cannot play // transcoded streams with .m3u8 and .mpd at the end. The only exception is Safari, @@ -666,9 +666,9 @@ type Stream struct { // For advanced customers only: For your complexly distributed broadcast systems, // it is also possible to additionally output an array of multi-regional ingestion // points for manual selection from them. To activate this mode, contact your - // manager or the Support Team to activate the "`multi_region_push_urls`" attibute. + // manager or the Support Team to activate the "multi_region_push_urls" attibute. // But if you clearly don’t understand why you need this, then it’s best to use the - // default single URL in the "`push_url`" attribute. + // default single URL in the "push_url" attribute. PushURL string `json:"push_url"` // URL to PUSH master stream to our main server using SRT protocol. // @@ -829,7 +829,7 @@ type Stream struct { // requests and the stream is deactivated (the "active" field switches to "false"). // // Please, note that this field is for PULL only, so is not suitable for PUSH. Look - // at fields "`push_url`" and "`push_url_srt`" from GET method. + // at fields "push_url" and "push_url_srt" from GET method. Uri string `json:"uri"` // Current height of frame of the original stream, if stream is transcoding VideoHeight float64 `json:"video_height"` @@ -1176,7 +1176,7 @@ type StreamNewParams struct { // requests and the stream is deactivated (the "active" field switches to "false"). // // Please, note that this field is for PULL only, so is not suitable for PUSH. Look - // at fields "`push_url`" and "`push_url_srt`" from GET method. + // at fields "push_url" and "push_url_srt" from GET method. Uri param.Opt[string] `json:"uri,omitzero"` // IDs of broadcasts which will include this stream BroadcastIDs []int64 `json:"broadcast_ids,omitzero"` @@ -1352,7 +1352,7 @@ type StreamUpdateParamsStream struct { // requests and the stream is deactivated (the "active" field switches to "false"). // // Please, note that this field is for PULL only, so is not suitable for PUSH. Look - // at fields "`push_url`" and "`push_url_srt`" from GET method. + // at fields "push_url" and "push_url_srt" from GET method. Uri param.Opt[string] `json:"uri,omitzero"` // IDs of broadcasts which will include this stream BroadcastIDs []int64 `json:"broadcast_ids,omitzero"` @@ -1430,7 +1430,7 @@ type StreamNewClipParams struct { // can be added to left and right. // // Duration of cutted segment cannot be greater than DVR duration for this stream. - // Therefore, to change the maximum, use "`dvr_duration`" parameter of this stream. + // Therefore, to change the maximum, use "dvr_duration" parameter of this stream. Duration int64 `json:"duration,required"` // Expire time of the clip via a public link. // diff --git a/streaming/streaming.go b/streaming/streaming.go index f10d7c96..0505b567 100644 --- a/streaming/streaming.go +++ b/streaming/streaming.go @@ -72,16 +72,16 @@ type CreateVideoParam struct { // ID of the directory where the video should be uploaded. (beta) DirectoryID param.Opt[int64] `json:"directory_id,omitzero"` // Authorization HTTP request header. Will be used as credentials to authenticate a - // request to download a file (specified in "`origin_url`" parameter) on an - // external server. + // request to download a file (specified in "origin_url" parameter) on an external + // server. // // Syntax: `Authorization: ` // // Examples: // - // - "`origin_http_headers`": "Authorization: Basic ..." - // - "`origin_http_headers`": "Authorization: Bearer ..." - // - "`origin_http_headers`": "Authorization: APIKey ..." Example of usage when + // - "origin_http_headers": "Authorization: Basic ..." + // - "origin_http_headers": "Authorization: Bearer ..." + // - "origin_http_headers": "Authorization: APIKey ..." Example of usage when // downloading a file from Google Drive: // // ``` @@ -104,7 +104,7 @@ type CreateVideoParam struct { // After uploading the video, the system will automatically create several // screenshots (they will be stored in "screenshots" attribute) from which you can // select an default screenshot. This "poster" field is for uploading your own - // image. Also use attribute "`screenshot_id`" to select poster as a default + // image. Also use attribute "screenshot_id" to select poster as a default // screnshot. // // Attribute accepts single image as base64-encoded string @@ -373,7 +373,7 @@ type Video struct { // return just 1 video codec in a manifest. Read the Product Documentation for // details. // - // Read more what is ABR soft-limiting in the "`hls_url`" field above. + // Read more what is ABR soft-limiting in the "hls_url" field above. // // Caution. Solely master.mpd is officially documented and intended for your use. // Any additional internal manifests, sub-manifests, parameters, chunk names, file @@ -383,9 +383,9 @@ type Video struct { DashURL string `json:"dash_url"` // Additional text field for video description Description string `json:"description"` - // Video duration in milliseconds. May differ from "`origin_video_duration`" value - // if the video was uploaded with clipping through the parameters - // "`clip_start_seconds`" and "`clip_duration_seconds`" + // Video duration in milliseconds. May differ from "origin_video_duration" value if + // the video was uploaded with clipping through the parameters "clip_start_seconds" + // and "clip_duration_seconds" Duration int64 `json:"duration"` // Video processing error text will be saved here if "status: error" Error string `json:"error"` @@ -393,7 +393,7 @@ type Video struct { // are in fMP4 container. It's a code-agnostic container, which allows to use any // like H264, H265, AV1, etc. // - // It is possible to use the same suffix-options as described in the "`hls_url`" + // It is possible to use the same suffix-options as described in the "hls_url" // attribute. // // Caution. Solely master.m3u8 (and master[-options].m3u8) is officially documented @@ -498,7 +498,7 @@ type Video struct { // URL to the original non-transcoded stream recording with original quality, saved // in MP4 format. File is created immediately after the completion of the stream // recording. The stream from which the recording was made is reflected in - // "`stream_id`" field. + // "stream_id" field. // // Can be used for internal operations when a recording needs to be received faster // than the transcoded versions are ready. But this version is not intended for @@ -607,8 +607,7 @@ type Video struct { StreamID int64 `json:"stream_id"` // Number of video views through the built-in HTML video player of the Streaming // Platform only. This attribute does not count views from other external players - // and native OS players, so here may be less number of views than in - // "`cdn_views`". + // and native OS players, so here may be less number of views than in "cdn_views". Views int64 `json:"views"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { diff --git a/streaming/video.go b/streaming/video.go index 0f068658..ce8c2679 100644 --- a/streaming/video.go +++ b/streaming/video.go @@ -55,7 +55,6 @@ func NewVideoService(opts ...option.RequestOption) (r VideoService) { // execution file will be uploaded and will be sent to transcoding automatically, // you don't have to do anything else. Use extra field `origin_http_headers` if // authorization is required on the external server. -// // - **Direct upload from a local device** – If you need to upload video directly // from your local device or from a mobile app, then use this method. Keep // `origin_url` empty and use TUS protocol ([tus.io](https://tus.io)) to upload @@ -120,7 +119,7 @@ func (r *VideoService) New(ctx context.Context, body VideoNewParams, opts ...opt // // It's allowed to update only those public parameters that are described in POST // method to create a new “video” entity. So it's not possible to change calculated -// parameters like "id", "duration", "`hls_url`", etc. +// parameters like "id", "duration", "hls_url", etc. // // Examples of changing: // @@ -129,9 +128,9 @@ func (r *VideoService) New(ctx context.Context, body VideoNewParams, opts ...opt // // Please note that some parameters are used on initial step (before transcoding) // only, so after transcoding there is no use in changing their values. For -// example, "`origin_url`" parameter is used for downloading an original file from -// a source and never used after transcoding; or "priority" parameter is used to -// set priority of processing and never used after transcoding. +// example, "origin_url" parameter is used for downloading an original file from a +// source and never used after transcoding; or "priority" parameter is used to set +// priority of processing and never used after transcoding. func (r *VideoService) Update(ctx context.Context, videoID int64, body VideoUpdateParams, opts ...option.RequestOption) (res *Video, err error) { opts = slices.Concat(r.Options, opts) path := fmt.Sprintf("streaming/videos/%v", videoID) @@ -411,7 +410,7 @@ type VideoListParams struct { // IDs of the videos to find. You can specify one or more identifiers separated by // commas. Example, ?id=1,101,1001 ID param.Opt[string] `query:"id,omitzero" json:"-"` - // Find videos where "`client_user_id`" meta field is equal to the search value + // Find videos where "client_user_id" meta field is equal to the search value ClientUserID param.Opt[int64] `query:"client_user_id,omitzero" json:"-"` // Restriction to return only the specified attributes, instead of the entire // dataset. Specify, if you need to get short response. The following fields are @@ -439,7 +438,7 @@ type VideoListParams struct { // - ready // - error Status param.Opt[string] `query:"status,omitzero" json:"-"` - // Find videos recorded from a specific stream, so for which "`stream_id`" field is + // Find videos recorded from a specific stream, so for which "stream_id" field is // equal to the search value StreamID param.Opt[int64] `query:"stream_id,omitzero" json:"-"` paramObj diff --git a/streaming/videosubtitle.go b/streaming/videosubtitle.go index cb456f50..66a2b21e 100644 --- a/streaming/videosubtitle.go +++ b/streaming/videosubtitle.go @@ -52,7 +52,7 @@ func NewVideoSubtitleService(opts ...option.RequestOption) (r VideoSubtitleServi // // Language is 3-letter language code according to ISO-639-2 (bibliographic code). // Specify language you need, or just look at our list in the attribute -// "`audio_language`" of section +// "audio_language" of section // ["AI Speech Recognition"](/docs/api-reference/streaming/ai/create-ai-asr-task). // // You can add multiple subtitles in the same language, language uniqueness is not diff --git a/waap/domainadvancedrule.go b/waap/domainadvancedrule.go index 45d73baa..32c6479a 100644 --- a/waap/domainadvancedrule.go +++ b/waap/domainadvancedrule.go @@ -130,10 +130,10 @@ type WaapAdvancedRule struct { // The "access" phase is responsible for modifying the request before it is sent to // the origin server. // - // The "`header_filter`" phase is responsible for modifying the HTTP headers of a + // The "header_filter" phase is responsible for modifying the HTTP headers of a // response before they are sent back to the client. // - // The "`body_filter`" phase is responsible for modifying the body of a response + // The "body_filter" phase is responsible for modifying the body of a response // before it is sent back to the client. // // Any of "access", "header_filter", "body_filter". @@ -243,10 +243,10 @@ func (r *WaapAdvancedRuleActionTag) UnmarshalJSON(data []byte) error { // The "access" phase is responsible for modifying the request before it is sent to // the origin server. // -// The "`header_filter`" phase is responsible for modifying the HTTP headers of a +// The "header_filter" phase is responsible for modifying the HTTP headers of a // response before they are sent back to the client. // -// The "`body_filter`" phase is responsible for modifying the body of a response +// The "body_filter" phase is responsible for modifying the body of a response // before it is sent back to the client. type WaapAdvancedRulePhase string @@ -278,10 +278,10 @@ type DomainAdvancedRuleNewParams struct { // The "access" phase is responsible for modifying the request before it is sent to // the origin server. // - // The "`header_filter`" phase is responsible for modifying the HTTP headers of a + // The "header_filter" phase is responsible for modifying the HTTP headers of a // response before they are sent back to the client. // - // The "`body_filter`" phase is responsible for modifying the body of a response + // The "body_filter" phase is responsible for modifying the body of a response // before it is sent back to the client. // // Any of "access", "header_filter", "body_filter". @@ -375,10 +375,10 @@ func (r *DomainAdvancedRuleNewParamsActionTag) UnmarshalJSON(data []byte) error // The "access" phase is responsible for modifying the request before it is sent to // the origin server. // -// The "`header_filter`" phase is responsible for modifying the HTTP headers of a +// The "header_filter" phase is responsible for modifying the HTTP headers of a // response before they are sent back to the client. // -// The "`body_filter`" phase is responsible for modifying the body of a response +// The "body_filter" phase is responsible for modifying the body of a response // before it is sent back to the client. type DomainAdvancedRuleNewParamsPhase string @@ -411,10 +411,10 @@ type DomainAdvancedRuleUpdateParams struct { // The "access" phase is responsible for modifying the request before it is sent to // the origin server. // - // The "`header_filter`" phase is responsible for modifying the HTTP headers of a + // The "header_filter" phase is responsible for modifying the HTTP headers of a // response before they are sent back to the client. // - // The "`body_filter`" phase is responsible for modifying the body of a response + // The "body_filter" phase is responsible for modifying the body of a response // before it is sent back to the client. // // Any of "access", "header_filter", "body_filter". @@ -507,10 +507,10 @@ func (r *DomainAdvancedRuleUpdateParamsActionTag) UnmarshalJSON(data []byte) err // The "access" phase is responsible for modifying the request before it is sent to // the origin server. // -// The "`header_filter`" phase is responsible for modifying the HTTP headers of a +// The "header_filter" phase is responsible for modifying the HTTP headers of a // response before they are sent back to the client. // -// The "`body_filter`" phase is responsible for modifying the body of a response +// The "body_filter" phase is responsible for modifying the body of a response // before it is sent back to the client. type DomainAdvancedRuleUpdateParamsPhase string @@ -545,10 +545,10 @@ type DomainAdvancedRuleListParams struct { // The "access" phase is responsible for modifying the request before it is sent to // the origin server. // - // The "`header_filter`" phase is responsible for modifying the HTTP headers of a + // The "header_filter" phase is responsible for modifying the HTTP headers of a // response before they are sent back to the client. // - // The "`body_filter`" phase is responsible for modifying the body of a response + // The "body_filter" phase is responsible for modifying the body of a response // before it is sent back to the client. // // Any of "access", "header_filter", "body_filter". @@ -600,10 +600,10 @@ const ( // The "access" phase is responsible for modifying the request before it is sent to // the origin server. // -// The "`header_filter`" phase is responsible for modifying the HTTP headers of a +// The "header_filter" phase is responsible for modifying the HTTP headers of a // response before they are sent back to the client. // -// The "`body_filter`" phase is responsible for modifying the body of a response +// The "body_filter" phase is responsible for modifying the body of a response // before it is sent back to the client. type DomainAdvancedRuleListParamsPhase string