Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions cmd/openapi2kong.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,22 @@ func executeOpenapi2Kong(cmd *cobra.Command, _ []string) error {
}
}

var reuseServices bool
{
reuseServices, err = cmd.Flags().GetBool("reuse-services")
if err != nil {
return fmt.Errorf("failed getting cli argument 'reuse-services'; %w", err)
}
}

options := openapi2kong.O2kOptions{
Tags: entityTags,
DocName: docName,
OIDC: generateSecurity,
IgnoreSecurityErrors: ignoreSecurityErrors,
InsoCompat: insoCompatibility,
IgnoreCircularRefs: ignoreCircularRefs,
ReuseServices: reuseServices,
}

trackInfo := deckformat.HistoryNewEntry("openapi2kong")
Expand Down Expand Up @@ -147,4 +156,6 @@ directive from the file)`)
openapi2kongCmd.Flags().BoolP("ignore-security-errors", "", false, "ignore errors for unsupported security schemes")
openapi2kongCmd.Flags().BoolP("inso-compatible", "", false, "generate the config in an Inso compatible way")
openapi2kongCmd.Flags().BoolP("ignore-circular-refs", "", false, "ignore circular references in the spec")
openapi2kongCmd.Flags().BoolP("reuse-services", "", false, "reuse services when multiple paths have identical "+
"server configurations and no path-level plugins")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"_format_version": "3.0",
"services": [
{
"host": "server1.com",
"id": "0907c4ab-d9e4-5d21-813b-c57a97eeaad9",
"name": "simple-api-overview",
"path": "/",
"plugins": [],
"port": 443,
"protocol": "https",
"routes": [
{
"id": "4d47cf34-1c69-5228-acf1-b2c05994bd02",
"methods": [
"GET"
],
"name": "simple-api-overview_get-doc-service",
"paths": [
"~/path1/(?\u003cpathparam\u003e[^#?/]+)$"
],
"plugins": [],
"regex_priority": 100,
"strip_path": false,
"tags": [
"OAS3_import",
"OAS3file_25-routes-with-headers.yaml"
]
},
{
"id": "27ea9a0a-216e-5c92-ae0b-8c9aa8493750",
"methods": [
"GET"
],
"name": "simple-api-overview_get-path2-service",
"paths": [
"~/path2$"
],
"plugins": [],
"regex_priority": 200,
"strip_path": false,
"tags": [
"OAS3_import",
"OAS3file_25-routes-with-headers.yaml"
]
}
],
"tags": [
"OAS3_import",
"OAS3file_25-routes-with-headers.yaml"
]
}
],
"upstreams": []
}
Comment thread
shivaygupta-dotcom marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"_format_version": "3.0",
"services": [
{
"host": "api.example.com",
"id": "e2a5410a-10a5-5983-943e-53d9907339ec",
"name": "test-api_user",
"path": "/userservice/v1",
"plugins": [],
"port": 443,
"protocol": "https",
"routes": [
{
"id": "6f644a83-6865-5618-91a5-469612a425d3",
"methods": [
"POST"
],
"name": "test-api_user_post",
"paths": [
"~/user$"
],
"plugins": [],
"regex_priority": 200,
"strip_path": false,
"tags": [
"OAS3_import",
"OAS3file_30-reuse-identical-services.yaml"
]
},
{
"id": "13a57c04-8579-569a-a0ba-25219440b03d",
"methods": [
"GET"
],
"name": "test-api_users_get",
"paths": [
"~/users$"
],
"plugins": [],
"regex_priority": 200,
"strip_path": false,
"tags": [
"OAS3_import",
"OAS3file_30-reuse-identical-services.yaml"
]
},
{
"id": "5f4a62d1-a71f-54e8-8cf5-ff8a3fab4d32",
"methods": [
"GET"
],
"name": "test-api_users-id_get",
"paths": [
"~/users/(?<id>[^#?/]+)$"
],
"plugins": [],
"regex_priority": 100,
"strip_path": false,
"tags": [
"OAS3_import",
"OAS3file_30-reuse-identical-services.yaml"
]
}
],
"tags": [
"OAS3_import",
"OAS3file_30-reuse-identical-services.yaml"
]
}
],
"upstreams": []
}

53 changes: 53 additions & 0 deletions openapi2kong/oas3_testfiles/30-reuse-identical-services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Test: Service reuse when identical path-level servers exist
#
# When multiple paths define the same path-level servers, only ONE service
# should be created with all routes attached to it.
#
# Expected behavior:
# - /users, /users/{id}, and /user all have identical path-level servers
# - Only 1 service should be created (not 3)
# - All 3 routes should be attached to the single service

openapi: 3.0.3
info:
title: Test API
version: 1.0.0
description: This is a test API for service reuse demonstration.

x-test-config:
reuseServices: true

paths:
/users:
get:
summary: Get a list of users
responses:
"200":
description: A list of users
servers:
- url: https://api.example.com/userservice/v1

/users/{id}:
get:
summary: Get a user by ID
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"200":
description: A single user
servers:
- url: https://api.example.com/userservice/v1

/user:
post:
summary: Create a new user
responses:
"201":
description: User created successfully
servers:
- url: https://api.example.com/userservice/v1

Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"_format_version": "3.0",
"services": [
{
"host": "api.example.com",
"id": "3e49c123-65d4-5b46-b6a1-bf0eb2c46077",
"name": "multi-service-api-with-plugins_orders",
"path": "/v1",
"plugins": [],
"port": 443,
"protocol": "https",
"routes": [
{
"id": "ca924a13-bcab-5886-a4f8-2387eb92a747",
"methods": [
"GET"
],
"name": "multi-service-api-with-plugins_orders_get",
"paths": [
"~/orders$"
],
"plugins": [],
"regex_priority": 200,
"strip_path": false,
"tags": [
"OAS3_import",
"OAS3file_31-reuse-with-plugins-on-routes.yaml"
]
}
],
"tags": [
"OAS3_import",
"OAS3file_31-reuse-with-plugins-on-routes.yaml"
]
},
{
"host": "api.example.com",
"id": "0c8d6ae0-1b14-5264-8135-fc544d8b89a9",
"name": "multi-service-api-with-plugins_users",
"path": "/v1",
"plugins": [
{
"config": {
"minute": 100,
"policy": "local"
},
"id": "1bcd1368-3e5b-5d79-8526-5caba1cd1eb0",
"name": "rate-limiting",
"tags": [
"OAS3_import",
"OAS3file_31-reuse-with-plugins-on-routes.yaml"
]
}
],
"port": 443,
"protocol": "https",
"routes": [
{
"id": "af8b1575-6102-56e5-9ad9-9a2220ba8c29",
"methods": [
"GET"
],
"name": "multi-service-api-with-plugins_users_get",
"paths": [
"~/users$"
],
"plugins": [],
"regex_priority": 200,
"strip_path": false,
"tags": [
"OAS3_import",
"OAS3file_31-reuse-with-plugins-on-routes.yaml"
]
}
],
"tags": [
"OAS3_import",
"OAS3file_31-reuse-with-plugins-on-routes.yaml"
]
}
],
"upstreams": []
}
43 changes: 43 additions & 0 deletions openapi2kong/oas3_testfiles/31-reuse-with-plugins-on-routes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Test: NO service reuse when path-level plugins exist
#
# When a path has x-kong-plugin-* extensions, we should NOT reuse
# services even if server configurations are identical. This prevents
# unintended plugin propagation to other routes.
#
# Expected behavior:
# - /users has a rate-limiting plugin
# - /orders has NO plugin but same server
# - 2 separate services should be created (not 1)
# - This ensures rate-limiting doesn't accidentally apply to /orders

openapi: 3.0.3
info:
title: Multi-Service API with Plugins
version: 1.0.0

x-test-config:
reuseServices: true

paths:
/users:
get:
summary: Get users (rate limited)
responses:
"200":
description: A list of users
servers:
- url: https://api.example.com/v1
x-kong-plugin-rate-limiting:
config:
minute: 100
policy: local

/orders:
get:
summary: Get orders (no rate limiting)
responses:
"200":
description: A list of orders
servers:
- url: https://api.example.com/v1

Loading
Loading