diff --git a/packages/core/forms/src/forms/ACMEForm.vue b/packages/core/forms/src/forms/ACMEForm.vue
index ac1a52961e..154699d009 100644
--- a/packages/core/forms/src/forms/ACMEForm.vue
+++ b/packages/core/forms/src/forms/ACMEForm.vue
@@ -390,4 +390,8 @@ const onChangeStorage = (payload: string, schema: string): void => {
.description {
margin-bottom: 12px;
}
+
+:deep(.k-tabs ul[role="tablist"]) {
+ margin-bottom: 32px;
+}
diff --git a/packages/core/forms/src/forms/ExitTransformer.vue b/packages/core/forms/src/forms/ExitTransformer.vue
index 792215d09f..54fe338d79 100644
--- a/packages/core/forms/src/forms/ExitTransformer.vue
+++ b/packages/core/forms/src/forms/ExitTransformer.vue
@@ -60,8 +60,8 @@ const finalSchema = computed((): Object => {
f.type = 'array'
f.valueArrayType = 'array'
f.itemContainerComponent = 'FieldArrayItem'
- f.fieldClasses = 'w-100'
- f.fieldItemsClasses = 'w-100 mt-2 mb-2'
+ f.fieldClasses = 'exit-transformer-array-item-container'
+ f.fieldItemsClasses = 'exit-transformer-array-item'
f.inputAttributes = { ...f.inputAttributes, type: 'textarea' }
}
return f
@@ -69,3 +69,13 @@ const finalSchema = computed((): Object => {
return final
})
+
+
diff --git a/packages/core/forms/src/forms/OIDCForm.vue b/packages/core/forms/src/forms/OIDCForm.vue
index 5ef5b7fe20..a2477cb4a7 100644
--- a/packages/core/forms/src/forms/OIDCForm.vue
+++ b/packages/core/forms/src/forms/OIDCForm.vue
@@ -322,6 +322,10 @@ export default {
margin-top: 24px;
}
+ .k-input-switch .k-label {
+ margin-top: 0;
+ }
+
.auth-method-container {
display: flex;
flex-wrap: wrap;
@@ -383,4 +387,17 @@ export default {
width: 300px;
}
}
+
+:deep(.auth-array-item-container) {
+ width: 100%;
+}
+
+:deep(.auth-array-item) {
+ display: flex;
+ margin-top: 8px;
+}
+
+:deep(.k-button.auth-array-item-new) {
+ margin-top: 24px;
+}
diff --git a/packages/core/forms/src/forms/PostFunction.vue b/packages/core/forms/src/forms/PostFunction.vue
index 916a57f90c..4ab62628f2 100644
--- a/packages/core/forms/src/forms/PostFunction.vue
+++ b/packages/core/forms/src/forms/PostFunction.vue
@@ -60,8 +60,8 @@ const finalSchema = computed((): Object => {
f.type = 'array'
f.valueArrayType = 'array'
f.itemContainerComponent = 'FieldArrayItem'
- f.fieldClasses = 'w-100'
- f.fieldItemsClasses = 'w-100 mt-2 mb-2'
+ f.fieldClasses = 'post-function-array-item-container'
+ f.fieldItemsClasses = 'post-function-array-item'
f.inputAttributes = { ...f.inputAttributes, type: 'textarea' }
}
return f
@@ -69,3 +69,13 @@ const finalSchema = computed((): Object => {
return final
})
+
+
diff --git a/packages/core/forms/src/forms/schemas/OIDCAuth.js b/packages/core/forms/src/forms/schemas/OIDCAuth.js
index 9bdeeb9198..921c283b24 100644
--- a/packages/core/forms/src/forms/schemas/OIDCAuth.js
+++ b/packages/core/forms/src/forms/schemas/OIDCAuth.js
@@ -37,11 +37,11 @@ export default {
valueType: 'string',
valueArrayType: 'array',
itemContainerComponent: 'FieldArrayItem',
- fieldClasses: 'w-100',
- fieldItemsClasses: 'd-flex mt-2 w-90',
+ fieldClasses: 'auth-array-item-container',
+ fieldItemsClasses: 'auth-array-item',
inputAttributes: { class: 'form-control', style: { minWidth: '200px' } },
validator: 'array',
- styleClasses: 'w-100',
+ newElementButtonLabelClasses: 'auth-array-item-new',
newElementButtonLabel: '+ Add',
}, {
inputType: 'text',
@@ -51,11 +51,11 @@ export default {
valueType: 'string',
valueArrayType: 'array',
itemContainerComponent: 'FieldArrayItem',
- fieldClasses: 'w-100',
- fieldItemsClasses: 'd-flex mt-2 w-90',
+ fieldClasses: 'auth-array-item-container',
+ fieldItemsClasses: 'auth-array-item',
inputAttributes: { class: 'form-control', style: { minWidth: '200px' } },
validator: 'array',
- styleClasses: 'w-100',
+ newElementButtonLabelClasses: 'auth-array-item-new',
newElementButtonLabel: '+ Add',
}, {
inputType: 'text',
@@ -65,11 +65,11 @@ export default {
valueType: 'string',
valueArrayType: 'array',
itemContainerComponent: 'FieldArrayItem',
- fieldClasses: 'w-100',
- fieldItemsClasses: 'd-flex mt-2 w-90',
+ fieldClasses: 'auth-array-item-container',
+ fieldItemsClasses: 'auth-array-item',
inputAttributes: { class: 'form-control', style: { minWidth: '200px' } },
validator: 'array',
- styleClasses: 'w-100',
+ newElementButtonLabelClasses: 'auth-array-item-new',
newElementButtonLabel: '+ Add',
}],
}
diff --git a/packages/core/forms/src/generator/FormGenerator.vue b/packages/core/forms/src/generator/FormGenerator.vue
index 14f7e969db..e55b5b0647 100644
--- a/packages/core/forms/src/generator/FormGenerator.vue
+++ b/packages/core/forms/src/generator/FormGenerator.vue
@@ -374,7 +374,6 @@ export default {
}
}
.label {
- background-color: $kui-color-background-neutral-weakest;
box-shadow: none;
&:before,
&:after {
diff --git a/packages/core/forms/src/generator/fields/advanced/FieldMetric.vue b/packages/core/forms/src/generator/fields/advanced/FieldMetric.vue
index 8e36d79a23..34760e5b3d 100644
--- a/packages/core/forms/src/generator/fields/advanced/FieldMetric.vue
+++ b/packages/core/forms/src/generator/fields/advanced/FieldMetric.vue
@@ -73,7 +73,7 @@ export default {
cursor: pointer;
display: flex;
height: 45px;
- padding: 0 16px 0 5px;
+ padding: 0 16px;
position: relative;
transition: transform .2s cubic-bezier(0.41,0.35,1,0.28) 0s, background-color .2s ease-in;
width: 100%;
diff --git a/packages/core/forms/src/generator/fields/optional/fieldSwitch.vue b/packages/core/forms/src/generator/fields/optional/fieldSwitch.vue
index 381db418b7..eb790e00a6 100644
--- a/packages/core/forms/src/generator/fields/optional/fieldSwitch.vue
+++ b/packages/core/forms/src/generator/fields/optional/fieldSwitch.vue
@@ -61,6 +61,7 @@ $field-switch-height: 30px;
height: inherit;
position: relative;
text-transform: uppercase;
+ width: 100%;
}
.label:before,
.label:after {
@@ -87,7 +88,6 @@ $field-switch-height: 30px;
text-shadow: 0 1px rgba(0, 0, 0, 0.2);
}
input:checked ~ .label {
- background: #e1b42b;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15), inset 0 0 3px rgba(0, 0, 0, 0.2);
}
input:checked ~ .label:before {
diff --git a/packages/entities/entities-plugins/docs/plugin-form.md b/packages/entities/entities-plugins/docs/plugin-form.md
index ecde1cc92b..547504b98a 100644
--- a/packages/entities/entities-plugins/docs/plugin-form.md
+++ b/packages/entities/entities-plugins/docs/plugin-form.md
@@ -119,6 +119,14 @@ Manually toggle visibility of plugin scope selection control.
A boolean indicating whether the form is being used to create a plugin or an auth credential.
+#### `developer`
+
+- type: `Boolean`
+- required: `false`
+- default: `false`
+
+*Specific to Kong Manager*. A boolean indicating whether the form is being used to create or update a plugin for a portal developer.
+
#### `isWizardStep`
- type: `Boolean`
diff --git a/packages/entities/entities-plugins/src/components/PluginEntityForm.vue b/packages/entities/entities-plugins/src/components/PluginEntityForm.vue
index c25b2b4e32..b347a22a24 100644
--- a/packages/entities/entities-plugins/src/components/PluginEntityForm.vue
+++ b/packages/entities/entities-plugins/src/components/PluginEntityForm.vue
@@ -76,7 +76,6 @@ const props = defineProps({
if (!config || !['konnect', 'kongManager'].includes(config?.app)) return false
if (config.app === 'konnect' && !config.controlPlaneId) return false
if (config.app === 'kongManager' && typeof config.workspace !== 'string') return false
- if (!config.cancelRoute || !config.backRoute) return false
return true
},
},
@@ -416,6 +415,9 @@ const getModel = (): Record => {
// fired whenever the form data is modified
const onModelUpdated = (model: Record, schema: string) => {
const newData = { [schema]: model }
+ if (typeof props.schema[schema]?.modelTransformer === 'function') {
+ newData[schema] = props.schema[schema].modelTransformer(model)
+ }
const newModel = Object.assign({}, formModel, newData)
Object.assign(formModel, newModel)
@@ -433,8 +435,11 @@ const updateModel = (data: Record, parent?: string) => {
let modelKey = parent ? `${parent}-${key}` : key
let scheme = props.schema[modelKey]
- // If `scheme` is undefined, it is either because the key is not the deepest nested key of the schema object
- // or the field name has dashes in it and its schema key was converted to underscores during initiation.
+ // If `scheme` is undefined, it is because
+ // 1. the key is not the deepest nested key of the schema object
+ // 2. or the field name has dashes in it and its schema key was converted to underscores during initiation
+ // 3. or `parent` is already a schema key and `key` is a nested key of its value object
+ // For reasons 2 and 3, we need special logic to find the correct schema key
if (!scheme) {
const underscoredModelKey = parent ? `${parent}-${key.replace(/-/g, '_')}` : key.replace(/-/g, '_')
@@ -443,6 +448,12 @@ const updateModel = (data: Record, parent?: string) => {
modelKey = underscoredModelKey
scheme = props.schema[modelKey]
}
+
+ // Here we check if `parent` is a schema key and `key` is a nested key of its value object
+ if (parent && props.schema[parent]?.keyFromObject === key) {
+ modelKey = parent
+ scheme = props.schema[modelKey]
+ }
}
const value = data[key]
@@ -629,10 +640,14 @@ onBeforeMount(() => {
display: none;
}
- .form-group hr.divider,
+ .form-group hr.divider {
+ border-color: $kui-color-border;
+ opacity: .3;
+ }
+
.form-group hr.wide-divider {
border-color: $kui-color-border;
- opacity: .2;
+ opacity: .6;
}
.form-group label {
diff --git a/packages/entities/entities-plugins/src/components/PluginForm.cy.ts b/packages/entities/entities-plugins/src/components/PluginForm.cy.ts
index 383341eedf..6c78d74bd1 100644
--- a/packages/entities/entities-plugins/src/components/PluginForm.cy.ts
+++ b/packages/entities/entities-plugins/src/components/PluginForm.cy.ts
@@ -121,11 +121,17 @@ describe('', () => {
alias?: string
status?: number
credential?: boolean
+ entityType?: string
entityId?: string
}) => {
- const url = params?.credential
- ? `${baseConfigKM.apiBaseUrl}/${baseConfigKM.workspace}/consumers/${params.entityId}/acls/${params.id}`
- : `${baseConfigKM.apiBaseUrl}/${baseConfigKM.workspace}/plugins/${params.id}`
+ let url: string
+ if (params?.credential) {
+ url = `${baseConfigKM.apiBaseUrl}/${baseConfigKM.workspace}/consumers/${params.entityId}/acls/${params.id}`
+ } else if (params?.entityType && params?.entityId) {
+ url = `${baseConfigKM.apiBaseUrl}/${baseConfigKM.workspace}/${params.entityType}/${params.entityId}/plugins/${params.id}`
+ } else {
+ url = `${baseConfigKM.apiBaseUrl}/${baseConfigKM.workspace}/plugins/${params.id}`
+ }
cy.intercept(
{
@@ -354,7 +360,13 @@ describe('', () => {
it('should show edit form', () => {
const config = { ...baseConfigKM, entityId: scopedService.id, entityType: 'services' }
interceptKMSchema()
- interceptKMOperatePlugin({ method: 'GET', alias: 'getPlugin', id: plugin1.id })
+ interceptKMOperatePlugin({
+ method: 'GET',
+ alias: 'getPlugin',
+ id: plugin1.id,
+ entityId: scopedService.id,
+ entityType: 'services',
+ })
interceptKMScopedEntity({ entityType: config.entityType })
cy.mount(PluginForm, {
@@ -397,9 +409,21 @@ describe('', () => {
const config = { ...baseConfigKM, entityId: scopedService.id, entityType: 'services' }
interceptKMSchema()
interceptKMScopedEntity({ entityType: config.entityType })
- interceptKMOperatePlugin({ method: 'GET', alias: 'getPlugin', id: plugin1.id })
+ interceptKMOperatePlugin({
+ method: 'GET',
+ alias: 'getPlugin',
+ id: plugin1.id,
+ entityId: scopedService.id,
+ entityType: 'services',
+ })
interceptKMValidatePlugin()
- interceptKMOperatePlugin({ method: 'PATCH', alias: 'updatePlugin', id: plugin1.id })
+ interceptKMOperatePlugin({
+ method: 'PATCH',
+ alias: 'updatePlugin',
+ id: plugin1.id,
+ entityId: scopedService.id,
+ entityType: 'services',
+ })
cy.mount(PluginForm, {
global: { components: { VueFormGenerator } },
@@ -454,7 +478,13 @@ describe('', () => {
const config = { ...baseConfigKM, entityId: scopedService.id, entityType: 'services' }
interceptKMSchema()
interceptKMScopedEntity({ entityType: config.entityType })
- interceptKMOperatePlugin({ method: 'GET', alias: 'getPlugin', id: plugin1.id })
+ interceptKMOperatePlugin({
+ method: 'GET',
+ alias: 'getPlugin',
+ id: plugin1.id,
+ entityId: scopedService.id,
+ entityType: 'services',
+ })
cy.mount(PluginForm, {
global: { components: { VueFormGenerator } },
@@ -721,11 +751,17 @@ describe('', () => {
alias?: string
status?: number
credential?: boolean
+ entityType?: string
entityId?: string
}) => {
- const url = params?.credential
- ? `${baseConfigKonnect.apiBaseUrl}/v2/control-planes/${baseConfigKonnect.controlPlaneId}/core-entities/consumers/${params.entityId}/acls/${params.id}`
- : `${baseConfigKonnect.apiBaseUrl}/v2/control-planes/${baseConfigKonnect.controlPlaneId}/core-entities/plugins/${params.id}`
+ let url: string
+ if (params?.credential) {
+ url = `${baseConfigKonnect.apiBaseUrl}/v2/control-planes/${baseConfigKonnect.controlPlaneId}/core-entities/consumers/${params.entityId}/acls/${params.id}`
+ } else if (params?.entityType && params?.entityId) {
+ url = `${baseConfigKonnect.apiBaseUrl}/v2/control-planes/${baseConfigKonnect.controlPlaneId}/core-entities/${params.entityType}/${params.entityId}/plugins/${params.id}`
+ } else {
+ url = `${baseConfigKonnect.apiBaseUrl}/v2/control-planes/${baseConfigKonnect.controlPlaneId}/core-entities/plugins/${params.id}`
+ }
cy.intercept(
{
@@ -974,7 +1010,13 @@ describe('', () => {
it('should show edit form', () => {
const config = { ...baseConfigKonnect, entityId: scopedService.id, entityType: 'services' }
interceptKonnectSchema()
- interceptKonnectOperatePlugin({ method: 'GET', alias: 'getPlugin', id: plugin1.id })
+ interceptKonnectOperatePlugin({
+ method: 'GET',
+ alias: 'getPlugin',
+ id: plugin1.id,
+ entityId: scopedService.id,
+ entityType: 'services',
+ })
interceptKonnectScopedEntity({ entityType: config.entityType })
cy.mount(PluginForm, {
@@ -1018,9 +1060,21 @@ describe('', () => {
const config = { ...baseConfigKonnect, entityId: scopedService.id, entityType: 'services' }
interceptKonnectSchema()
interceptKonnectScopedEntity({ entityType: config.entityType })
- interceptKonnectOperatePlugin({ method: 'GET', alias: 'getPlugin', id: plugin1.id })
+ interceptKonnectOperatePlugin({
+ method: 'GET',
+ alias: 'getPlugin',
+ id: plugin1.id,
+ entityId: scopedService.id,
+ entityType: 'services',
+ })
interceptKonnectValidatePlugin()
- interceptKonnectOperatePlugin({ method: 'PUT', alias: 'updatePlugin', id: plugin1.id })
+ interceptKonnectOperatePlugin({
+ method: 'PUT',
+ alias: 'updatePlugin',
+ id: plugin1.id,
+ entityId: scopedService.id,
+ entityType: 'services',
+ })
cy.mount(PluginForm, {
global: { components: { VueFormGenerator } },
@@ -1074,7 +1128,13 @@ describe('', () => {
const config = { ...baseConfigKonnect, entityId: scopedService.id, entityType: 'services' }
interceptKonnectSchema()
interceptKonnectScopedEntity({ entityType: config.entityType })
- interceptKonnectOperatePlugin({ method: 'GET', alias: 'getPlugin', id: plugin1.id })
+ interceptKonnectOperatePlugin({
+ method: 'GET',
+ alias: 'getPlugin',
+ id: plugin1.id,
+ entityId: scopedService.id,
+ entityType: 'services',
+ })
cy.mount(PluginForm, {
global: { components: { VueFormGenerator } },
diff --git a/packages/entities/entities-plugins/src/components/PluginForm.vue b/packages/entities/entities-plugins/src/components/PluginForm.vue
index 33cf99cebb..136a3f2adf 100644
--- a/packages/entities/entities-plugins/src/components/PluginForm.vue
+++ b/packages/entities/entities-plugins/src/components/PluginForm.vue
@@ -106,7 +106,6 @@ import {
type PluginFormFields,
type DefaultPluginsSchemaRecord,
type DefaultPluginsFormSchema,
- type EntityType,
type PluginEntityInfo,
} from '../types'
import endpoints from '../plugins-endpoints'
@@ -167,6 +166,12 @@ const props = defineProps({
default: false,
},
+ /** For Kong Manager portal developers */
+ developer: {
+ type: Boolean,
+ default: false,
+ },
+
/** Don't render buttons and allow the host app to handle submitting the payload */
isWizardStep: {
type: Boolean,
@@ -228,7 +233,13 @@ const fetchUrl = computed((): string => {
}
// plugin
- return endpoints.form[props.config.app].edit
+ if (props.config.entityType && props.config.entityId) {
+ return endpoints.form[props.config.app].edit.forEntity
+ .replace(/{entityType}/gi, props.config.entityType)
+ .replace(/{entityId}/gi, props.config.entityId)
+ } else {
+ return endpoints.form[props.config.app].edit.all
+ }
})
const entityMap = computed((): Record => {
@@ -365,14 +376,14 @@ const defaultFormSchema: DefaultPluginsSchemaRecord = reactive({
},
})
-// This is specifically used for credential plugins
+// This is specifically used for credential plugins and portal developer plugins
// To create an 'ACL' credential we will end up submitting to a URL like: ///acl
const resourceEndpoint = computed((): string => {
- const entityPath: EntityType = 'consumers'
+ const entityPath: string = props.developer ? 'developers' : 'consumers'
const type = credentialMetaData[props.pluginType]?.endpoint || '/plugins'
- return `${entityPath}/${props.config.entityId}${type}`
+ return `${entityPath}/${props.config.entityId}${props.developer ? '/credentials' : ''}${type}`
})
const getArrayType = (list: unknown[]): string => {
@@ -389,6 +400,7 @@ const formatPluginFieldLabel = (label: string) => {
const buildFormSchema = (parentKey: string, response: Record, initialFormSchema: Record) => {
let schema = (response && response.fields) || []
const pluginSchema = customSchemas[props.pluginType as keyof typeof customSchemas]
+ const credentialSchema = credentialMetaData[props.pluginType]?.schema?.fields
// schema can either be an object or an array of objects. If it's an array, convert it to an object
if (Array.isArray(schema)) {
@@ -570,6 +582,18 @@ const buildFormSchema = (parentKey: string, response: Record, initi
}
+ if (treatAsCredential.value && props.config.app === 'kongManager' && credentialSchema) {
+ for (let i = 0; i < credentialSchema.length; i++) {
+ if (credentialSchema[i][field]) {
+ initialFormSchema[field] = {
+ ...initialFormSchema[field],
+ ...credentialSchema[i][field],
+ }
+ break
+ }
+ }
+ }
+
// required fields, if it's boolean (a checkbox) it will be marked as required even though it isn't
if (scheme.required && scheme.type !== 'boolean') {
initialFormSchema[field].required = true
@@ -615,6 +639,8 @@ const buildFormSchema = (parentKey: string, response: Record, initi
if (scheme.len_min > 0) {
initialFormSchema[field].submitWhenNull = true
}
+ } else if (scheme.type === 'foreign') {
+ valueType = 'object'
} else if (scheme.default && Array.isArray(scheme.default)) {
valueType = 'array'
initialFormSchema[field].valueArrayType = getArrayType(scheme.default)
@@ -842,8 +868,11 @@ const validateSubmitUrl = computed((): string => {
* Build the submit URL
*/
const submitUrl = computed((): string => {
+ const isScoped = props.config.entityType && props.config.entityId && !props.developer
// plugin endpoint vs credential endpoint
- const submitEndpoint = !treatAsCredential.value ? endpoints.form[props.config.app][formType.value] : endpoints.form[props.config.app].credential[formType.value]
+ const submitEndpoint = !treatAsCredential.value
+ ? endpoints.form[props.config.app][formType.value][isScoped ? 'forEntity' : 'all']
+ : endpoints.form[props.config.app].credential[formType.value]
let url = `${props.config.apiBaseUrl}${submitEndpoint}`
@@ -857,6 +886,9 @@ const submitUrl = computed((): string => {
url = url.replace(/{resourceEndpoint}/gi, resourceEndpoint.value)
// Always replace the id when editing
url = url.replace(/{id}/gi, props.pluginId)
+ // replace entityType and entityId if scoped
+ url = url.replace(/{entityType}/gi, props.config.entityType || '')
+ url = url.replace(/{entityId}/gi, props.config.entityId || '')
return url
})
diff --git a/packages/entities/entities-plugins/src/composables/plugin-schemas/VaultAuth.ts b/packages/entities/entities-plugins/src/composables/plugin-schemas/VaultAuth.ts
new file mode 100644
index 0000000000..0a60ec984c
--- /dev/null
+++ b/packages/entities/entities-plugins/src/composables/plugin-schemas/VaultAuth.ts
@@ -0,0 +1,14 @@
+import type { VaultAuthSchema } from '../../types/plugins/vault-auth'
+
+export const vaultAuthSchema: VaultAuthSchema = {
+ 'config-vault': {
+ type: 'AutoSuggest',
+ entity: 'vaults',
+ placeholder: 'Select a Vault',
+ inputValues: {
+ fields: ['prefix', 'name', 'id'],
+ },
+ modelTransformer: (val: string) => ({ id: val }),
+ keyFromObject: 'id',
+ },
+}
diff --git a/packages/entities/entities-plugins/src/composables/usePluginMeta.ts b/packages/entities/entities-plugins/src/composables/usePluginMeta.ts
index b3267895bd..8e2d9c3135 100644
--- a/packages/entities/entities-plugins/src/composables/usePluginMeta.ts
+++ b/packages/entities/entities-plugins/src/composables/usePluginMeta.ts
@@ -286,7 +286,6 @@ export const usePluginMetaData = () => {
name: t('plugins.meta.pre-function.name'),
scope: [PluginScope.GLOBAL, PluginScope.SERVICE, PluginScope.ROUTE],
imageName: 'kong-function',
- docsUrlName: 'serverless-functions',
},
'post-function': {
description: t('plugins.meta.post-function.description'),
@@ -295,7 +294,6 @@ export const usePluginMetaData = () => {
name: t('plugins.meta.post-function.name'),
scope: [PluginScope.GLOBAL, PluginScope.SERVICE, PluginScope.ROUTE],
imageName: 'kong-function',
- docsUrlName: 'serverless-functions',
},
datadog: {
description: t('plugins.meta.datadog.description'),
diff --git a/packages/entities/entities-plugins/src/composables/useSchemas.ts b/packages/entities/entities-plugins/src/composables/useSchemas.ts
index 91fd6843cc..5f52fe37e1 100644
--- a/packages/entities/entities-plugins/src/composables/useSchemas.ts
+++ b/packages/entities/entities-plugins/src/composables/useSchemas.ts
@@ -15,6 +15,7 @@ import { routeByHeaderSchema } from './plugin-schemas/RouteByHeader'
import { graphqlRateLimitingAdvancedSchema } from './plugin-schemas/GraphQLRateLimitingAdvanced'
import { statsDSchema } from './plugin-schemas/StatsD'
import { samlSchema } from './plugin-schemas/SAML'
+import { vaultAuthSchema } from './plugin-schemas/VaultAuth'
import { ArrayStringFieldSchema } from './plugin-schemas/ArrayStringFieldSchema'
import RequestValidatorSchema from './plugin-schemas/RequestValidator'
import ZipkinSchema from './plugin-schemas/Zipkin'
@@ -74,6 +75,10 @@ export const useSchemas = (entityId?: string) => {
...routeByHeaderSchema,
},
+ 'vault-auth': {
+ ...vaultAuthSchema,
+ },
+
mocking: {
...mockingSchema,
},
diff --git a/packages/entities/entities-plugins/src/plugins-endpoints.ts b/packages/entities/entities-plugins/src/plugins-endpoints.ts
index d160eefaff..e902d1c170 100644
--- a/packages/entities/entities-plugins/src/plugins-endpoints.ts
+++ b/packages/entities/entities-plugins/src/plugins-endpoints.ts
@@ -20,8 +20,14 @@ export default {
},
form: {
konnect: {
- create: '/v2/control-planes/{controlPlaneId}/core-entities/plugins',
- edit: '/v2/control-planes/{controlPlaneId}/core-entities/plugins/{id}',
+ create: {
+ all: '/v2/control-planes/{controlPlaneId}/core-entities/plugins',
+ forEntity: '/v2/control-planes/{controlPlaneId}/core-entities/{entityType}/{entityId}/plugins',
+ },
+ edit: {
+ all: '/v2/control-planes/{controlPlaneId}/core-entities/plugins/{id}',
+ forEntity: '/v2/control-planes/{controlPlaneId}/core-entities/{entityType}/{entityId}/plugins/{id}',
+ },
pluginSchema: '/v2/control-planes/{controlPlaneId}/schemas/core-entities/plugins/{plugin}',
credential: {
create: '/v2/control-planes/{controlPlaneId}/core-entities/{resourceEndpoint}',
@@ -34,8 +40,14 @@ export default {
entityGetAll: '/v2/control-planes/{controlPlaneId}/core-entities/{entity}?size=1000',
},
kongManager: {
- create: '/{workspace}/plugins',
- edit: '/{workspace}/plugins/{id}',
+ create: {
+ all: '/{workspace}/plugins',
+ forEntity: '/{workspace}/{entityType}/{entityId}/plugins',
+ },
+ edit: {
+ all: '/{workspace}/plugins/{id}',
+ forEntity: '/{workspace}/{entityType}/{entityId}/plugins/{id}',
+ },
pluginSchema: '/{workspace}/schemas/plugins/{plugin}',
credential: {
create: '/{workspace}/{resourceEndpoint}',
diff --git a/packages/entities/entities-plugins/src/types/plugin-form.ts b/packages/entities/entities-plugins/src/types/plugin-form.ts
index a999f9adb3..e3caf54f5e 100644
--- a/packages/entities/entities-plugins/src/types/plugin-form.ts
+++ b/packages/entities/entities-plugins/src/types/plugin-form.ts
@@ -12,6 +12,7 @@ import type { KafkaSchema } from './plugins/kafka-schema'
import type { UpstreamTlsSchema } from './plugins/upstream-tls'
import type { RateLimitingSchema } from './plugins/rate-limiting'
import type { RouteByHeaderSchema } from './plugins/route-by-header'
+import type { VaultAuthSchema } from './plugins/vault-auth'
import type { GraphQLRateLimitingAdvancedSchema } from './plugins/graphql-rate-limiting-advanced'
import type { SAMLSchema } from './plugins/saml'
@@ -193,6 +194,7 @@ export interface CustomSchemas {
'rate-limiting': RateLimitingSchema
'rate-limiting-advanced': RateLimitingSchema
'route-by-header': RouteByHeaderSchema
+ 'vault-auth': VaultAuthSchema
'graphql-rate-limiting-advanced': GraphQLRateLimitingAdvancedSchema
'response-ratelimiting': RateLimitingSchema
'pre-function': CommonSchemaFields & Record
diff --git a/packages/entities/entities-plugins/src/types/plugin.ts b/packages/entities/entities-plugins/src/types/plugin.ts
index d938311ee7..2f90a31bca 100644
--- a/packages/entities/entities-plugins/src/types/plugin.ts
+++ b/packages/entities/entities-plugins/src/types/plugin.ts
@@ -62,7 +62,6 @@ export interface PluginEntityInfo {
export type PluginMetaData = {
description: string // A string to describe a Plugin.
- docsUrlName?: string // An optional field for plugin's documentation URL.
group: PluginGroup // Plugin categories meta.
imageName?: string // An optional tag to define plugin's icon image.
isEnterprise: boolean // The value will be True if the Plugin is enterprise only.
diff --git a/packages/entities/entities-plugins/src/types/plugins/vault-auth.d.ts b/packages/entities/entities-plugins/src/types/plugins/vault-auth.d.ts
new file mode 100644
index 0000000000..dfbf43d97a
--- /dev/null
+++ b/packages/entities/entities-plugins/src/types/plugins/vault-auth.d.ts
@@ -0,0 +1,14 @@
+import type { CommonSchemaFields } from './shared'
+
+export interface VaultAuthSchema extends CommonSchemaFields {
+ 'config-vault': {
+ type: string
+ entity: string
+ placeholder: string
+ inputValues: {
+ fields: string[]
+ }
+ modelTransformer: (val: string) => { id: string }
+ keyFromObject: string
+ }
+}