Skip to content

feat(api): add managed custom-domain TLS types - #12

Draft
swkeever wants to merge 1 commit into
mainfrom
skeever/vol-314-managed-tls
Draft

swkeever wants to merge 1 commit into
mainfrom
skeever/vol-314-managed-tls

Conversation

@swkeever

@swkeever swkeever commented Aug 31, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • add the managed TLS schema delta to the SDK’s current API contract
  • generate explicit managed and BYOC request types while keeping the legacy BYOC model compatible
  • decode discriminated unions from JSON string keys in the generator template
  • expose managed lifecycle state, DNS verification records, and apex ALIAS routing records
  • add the shared managed TLS contract scenario and response assertions

Verification

  • bin/check-openapi
  • bundle exec rubocop --parallel
  • bundle exec rspec
  • contract feature dry run
  • gem build volcano-sdk.gemspec

Paired with https://github.com/Kong/volcano-hosting/pull/958

VOL-314

@swkeever

swkeever commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-03T17:01:22.977462Z d9bf0ba Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2b803d2ed5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# @param [Mixed] Data to be matched against the list of oneOf items
# @return [Object] Returns the model or the data itself
def build(data)
discriminator_value = data[openapi_discriminator_name]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle string discriminator keys when building TLS configs

When CreateFrontendCustomDomainRequest.build_from_hash receives a normal JSON-parsed hash, the nested TLS object has a string key such as "mode", but this lookup uses only the symbol :mode. Both managed and BYOC inputs therefore produce nil, after which the request model's required tls setter raises ArgumentError; normalize the nested keys or check both string and symbol forms before dispatching to the concrete TLS model.

Useful? React with 👍 / 👎.

Comment thread openapi/openapi.yaml Outdated
example: handler
is_public:
type: boolean
default: false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve visibility when redeploying existing functions

When this upsert operation targets an existing public function and the caller omits is_public, the repository's request validator injects schema defaults, so this declaration turns the omitted field into false and can make the function private during an otherwise ordinary code redeploy. The operation explicitly updates existing functions, and the generated Ruby client leaves this optional field out unless supplied; remove the schema default and apply false only on the create path so updates can distinguish omission from an explicit visibility change.

Useful? React with 👍 / 👎.

@swkeever
swkeever force-pushed the skeever/vol-314-managed-tls branch from 2b803d2 to c48f716 Compare September 3, 2026 14:18
@swkeever

swkeever commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c48f716d2f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/volcano/auth_oauth_api.rb Outdated
freeze_oauth_api_data(data)
rescue KeyError, NoMethodError
raise TypeError, 'Expected OAuth provider API response data'
raise TypeError, 'Expected OAuth provider API response data' unless response_body.is_a?(Hash)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept top-level arrays from OAuth provider APIs

When the provider returns a top-level JSON array—as the documented GitHub /user/repos endpoint normally does—this Hash-only check raises TypeError for custom transports, while the generated transport's new Hash<String, Object> return type converts the array into a malformed hash with array elements as keys and nil values. The previous implementation deliberately returned and recursively froze any JSON value from data; the raw-response contract and facade must likewise support arrays rather than requiring an object.

Useful? React with 👍 / 👎.

Comment on lines +115 to +118
if attributes.key?(:'openapi_spec')
if (value = attributes[:'openapi_spec']).is_a?(Hash)
self.openapi_spec = value
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve explicit null when clearing function metadata

When a caller follows the schema's instruction to clear existing metadata with UpdateFunctionRequest.new(openapi_spec: nil), this Hash guard never assigns @openapi_spec. The model's to_hash intentionally omits nullable attributes whose instance variable was never defined, so the request serializes as {} instead of {openapi_spec: nil} and the server retains the old OpenAPI document. Explicit nil must be assigned so omission remains distinguishable from clearing.

Useful? React with 👍 / 👎.

Comment thread openapi/openapi.yaml Outdated
- is_public
- invocation_mode
- http_auth_mode
- openapi_spec

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop requiring metadata that list responses omit

The same schema says that function list responses omit the OpenAPI document, but PaginatedFunctions.data references Function and this required entry makes every such item invalid unless it contains an openapi_spec key (even when its value is null). Response validators and stricter generated clients will therefore reject the documented list payload; use a list-item schema without the document or make this property optional.

Useful? React with 👍 / 👎.

Comment thread openapi/openapi.yaml Outdated
Comment on lines +12235 to +12238
description: |
Names what to restore. Supply exactly one of `backup_name` or
`restore_to`.
properties:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Encode the exclusive database restore target

Although the request contract requires exactly one target, the schema makes both backup_name and restore_to independently optional and supplies no oneOf constraint. Consequently the generated CreateDatabaseRestoreRequest#valid? accepts both {} and requests containing both fields, even though the endpoint documents that either input is guaranteed to return 400; encode the exclusivity in the schema so generated clients can construct and validate only usable restore requests.

Useful? React with 👍 / 👎.

@swkeever
swkeever force-pushed the skeever/vol-314-managed-tls branch from c48f716 to 7da01ec Compare September 3, 2026 15:40
@swkeever

swkeever commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 7da01ecd59

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@swkeever
swkeever force-pushed the skeever/vol-314-managed-tls branch from 7da01ec to 8f90941 Compare September 3, 2026 16:14
@swkeever

swkeever commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8f90941819

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread openapi/openapi.yaml
Comment on lines +12619 to +12620
required:
- mode

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require BYOC certificate and key together

When a project-config apply includes only one half of a BYOC rotation, such as {mode: "byoc", certificate_pem: "..."}, this schema and the generated BYOCProjectConfigFrontendCustomDomainTLSConfig#valid? accept it even though a usable rotation requires the corresponding private key. Mode-only must remain valid for secret-free exports and unchanged existing domains, but the schema should constrain certificate material to either be entirely absent or include both certificate_pem and private_key_pem, so clients reject partial rotations before the server returns a validation error.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d9bf0ba. The project-config schema now rejects partial certificate material while still allowing mode-only exports, and the Ruby adapter enforces the same pair invariant because the generator does not emit conditional-schema validation.

Given('a managed custom-domain TLS request') do
generated = Volcano.const_get(:Generated, false)
tls = generated::ManagedFrontendCustomDomainTLSConfig.new(mode: 'managed')
@contract.managed_tls_request = generated::CreateFrontendCustomDomainRequest.new(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add the managed TLS fields to the contract world

When the new managed-TLS feature is actually executed rather than only checked with Cucumber's --dry-run, this assignment immediately raises NoMethodError because VolcanoContract::World defines no managed_tls_request= accessor; the subsequent managed_tls_wire and managed_tls_response assignments are missing accessors as well. Add these fields to World or keep this scenario's state in step-local instance variables so the new contract scenario can run.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d9bf0ba. The contract world now owns all three managed TLS scenario fields; the focused scenario executes successfully, not only in dry-run discovery.

@swkeever
swkeever force-pushed the skeever/vol-314-managed-tls branch from 8f90941 to d9bf0ba Compare September 3, 2026 16:56
@swkeever

swkeever commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: d9bf0ba30a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant