Skip to content

Feat: ai gateway file convert#2137

Merged
harshadixit12 merged 15 commits into
mainfrom
feat/ai-gateway-file-convert
Jul 22, 2026
Merged

Feat: ai gateway file convert#2137
harshadixit12 merged 15 commits into
mainfrom
feat/ai-gateway-file-convert

Conversation

@harshadixit12

@harshadixit12 harshadixit12 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

In this PR, we are adding support for a new command deck file ai2kong which accepts a AI gateway declarative config, and converts it to kong 3.x format declarative config to be used with on prem AI Gateway.

Implements

#2148

@harshadixit12 harshadixit12 changed the title Feat/ai gateway file convert Feat: ai gateway file convert Jul 14, 2026
@codecov-commenter

codecov-commenter commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 20.29340% with 326 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.95%. Comparing base (0808448) to head (9759b05).

Files with missing lines Patch % Lines
cmd/ai_sync.go 0.00% 92 Missing ⚠️
cmd/ai_dump.go 11.45% 83 Missing and 2 partials ⚠️
tests/integration/test_utils.go 0.00% 62 Missing ⚠️
cmd/ai.go 51.47% 25 Missing and 8 partials ⚠️
cmd/common.go 0.00% 26 Missing ⚠️
cmd/file_ai2kong.go 71.15% 7 Missing and 8 partials ⚠️
cmd/gateway_dump.go 0.00% 8 Missing ⚠️
cmd/root.go 0.00% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2137      +/-   ##
==========================================
- Coverage   36.69%   35.95%   -0.75%     
==========================================
  Files          78       82       +4     
  Lines        7429     7827     +398     
==========================================
+ Hits         2726     2814      +88     
- Misses       4457     4748     +291     
- Partials      246      265      +19     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@harshadixit12
harshadixit12 marked this pull request as ready for review July 14, 2026 09:01
Comment thread cmd/file_ai2kong.go Outdated
// Print warnings to stderr
if len(warnings) > 0 {
for _, warning := range warnings {
fmt.Fprintf(os.Stderr, "Warning: %v\n", warning)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This would break json output, right?
Are we concerned about that right now?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see that we are using YAML everywhere for now. We can revisit this later. Let's add a TODO comment on top so that we don't miss this when we add JSON support.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ideally - yes, we should - but i'll get to this once all PRs have been merged.

Comment thread cmd/file_ai2kong.go Outdated
return fmt.Errorf("failed to read source file: %w", err)
}

converted, warnings, err := convert.Convert(sourceContent, convert.Options{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nitpick: Can we import this as ai2kong and call ai2kong.Convert()?
It will be more verbose and avoid the confusing repetition.

Comment thread cmd/file_ai2kong.go
}

func validateAi2KongFlags(_ *cobra.Command, _ []string) error {
if convertSourceFile == "" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can take only one file at a time for conversion, right?
If yes, can we add a validation for that too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For flag type of string - cobra follows "last value" wins - so additional validation is not needed. (same in openapi2kong)

Comment thread cmd/file_ai2kong.go Outdated
if docMap, ok := doc.(map[string]interface{}); ok {
if infoMap, ok := docMap["_info"].(map[string]interface{}); ok {
// _info exists, update select_tags
infoMap["select_tags"] = []string{"managed-by:deck-ai"}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This can over-write the existing select-tags.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is converting an ai gateway file -> deck, the ai gateway file won't have select tags at global level

Comment thread cmd/file_ai2kong.go Outdated
} else {
// _info doesn't exist, create it with select_tags
docMap["_info"] = map[string]interface{}{
"select_tags": []string{"managed-by:deck-ai"},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  1. managed-by:deck-ai should be a constant
  2. Elsewhere, the convention I have seen is managed_by. Should we follow that or is this one a request from product?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will be made constant - this was a suggestion, not a request. I'll update it to managed_by.

Comment thread cmd/file_ai2kong.go Outdated
cmd := &cobra.Command{
Use: "ai2kong",
Short: "Generate Kong configuration from AI Gateway configuration",
Long: `This command takes an AI Gateway 2.0 entity model and converts it to a standard decK state file`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since we are adding a tag ourselves for our internal working, I think we should explicitly call that out in the description. It will help endusers to know that the tag addition is expected and they shouldn't remove it.

Comment thread cmd/file_ai2kong.go Outdated
}

// Parse the converted YAML to add select_tags to _info
var doc interface{}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: I feel L64 to L81 can be abstracted out in a different function.

Comment thread cmd/file_ai2kong.go Outdated
defer outFile.Close()
outputWriter = outFile
} else {
outputWriter = os.Stdout

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This can be the default IMO rather than adding a nesting here with else.

Comment thread cmd/file_ai2kong.go Outdated
}

// marshalToYAML encodes v as YAML using a two-space indent.
func marshalToYAML(v interface{}) ([]byte, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any reason for a separate func for this?

err = yaml.Unmarshal([]byte(output), &currentOutput)
require.NoError(t, err)

assert.Equal(t, expectedOutput, currentOutput)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we consider syncing the output to an ai gateway for validity?
We need to support the decomposed flow as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was planning to do that in the tests for sync and dump in the chained PR

Comment thread cmd/file_ai2kong.go Outdated
var (
convertSourceFile string
convertOutputFile string
managedByTag = "managed_by:deck-ai"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

const

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

renamed this in the chained PR and made it a const - 25fdbde

Prashansa-K
Prashansa-K previously approved these changes Jul 17, 2026
Comment thread cmd/ai_sync.go
}

for _, f := range files {
content, err := os.ReadFile(f)

@aikido-pr-checks aikido-pr-checks Bot Jul 21, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Potential file inclusion attack via reading file - high severity
If an attacker can control the input leading into the ReadFile function, they might be able to read sensitive files and launch further attacks with that information.

Suggested change
content, err := os.ReadFile(f)
if strings.Contains(f, "..") {
return nil, fmt.Errorf("invalid file path")
}
content, err := os.ReadFile(f)

Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

GitHub Action actions/checkout persist Git credentials in workflow - low severity
actions/checkout v2 and above persist the default GITHUB_TOKEN in the repository's local git config when persist-credentials is not set to false, during the workflow run. Subsequent workflow steps or third-party actions can read this token from git configuration, increasing the risk of credential theft or misuse within the pipeline. In order to limit the attack surface when external actions are compromised, ensure persist-credentials is set to false.

Show fix

Remediation: Set persist-credentials: false on actions/checkout steps that do not need to push commits back to the repository. Only keep persist-credentials: true when the workflow explicitly performs authenticated git push operations.

Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

* feat: support diff and dump

* style: lint-fix

* fix: error out if syncing to konnect

* fix: use positional arg for ai sync

* fix: written format version in dump

* fix: add go.work and go.work.sum to gitignore

* chore: remove go.work and go.work.sum from tracking

* tests: add integration tests for sync and dump

* ci: add integration test workflow for ai-gateway

* fix: rename tag and rebase with file ai2kong

* tests: use new rc, add more tests

* fix: avoid adding global tags in ai gateway format

* fix: address feedback

* chore: bump go-kong and go-database-reconciler

* fix: optimise checking for ai select tag

* fix: remove db propagation delay flag and add more tests for tag matching

* Feat/support json and multi file sync (#2158)

* feat: support json in ai2kong, ai sync and ai dump

* feat: support syncing multiple files

* style: refactor based on self review
@harshadixit12
harshadixit12 force-pushed the feat/ai-gateway-file-convert branch from 17e8b7c to f7f5841 Compare July 21, 2026 12:39
@harshadixit12

Copy link
Copy Markdown
Contributor Author

@Prashansa-K need review on 3 new commits -
f7f5841
a68ee04
9759b05

@harshadixit12
harshadixit12 merged commit 3cd9bc8 into main Jul 22, 2026
49 checks passed
@harshadixit12
harshadixit12 deleted the feat/ai-gateway-file-convert branch July 22, 2026 03:53
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.

3 participants