Skip to content

Commit 9123fbd

Browse files
feat(entities-vaults): konnect config store (#1496)
* feat(entities-vaults): konnect config store * chore(*): update vault form tests and add docs * feat(*): add updated_at col in secret list * fix(*): carry is_sensitive in edit body * chore(*): remove unused css * feat(*): make the value input resizable * test(*): add secret component tests
1 parent 7aac568 commit 9123fbd

25 files changed

+1683
-111
lines changed

packages/entities/entities-shared/src/types/entity-delete-modal.ts

+1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ export enum EntityTypes {
2323
jwt = 'JWT Credential',
2424
Target = 'target',
2525
Policy = 'policy',
26+
Secret = 'secret',
2627
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# SecretForm.vue
2+
3+
A form component for Konnect config store secrets. *This component should only be used in Konnect*.
4+
5+
- [Requirements](#requirements)
6+
- [Usage](#usage)
7+
- [Install](#install)
8+
- [Props](#props)
9+
- [Events](#events)
10+
- [Usage example](#usage-example)
11+
- [TypeScript interfaces](#typescript-interfaces)
12+
13+
## Requirements
14+
15+
- `vue` and `vue-router` must be initialized in the host application
16+
- `@kong/kongponents` must be added as a dependency in the host application, globally available via the Vue Plugin installation, and the package's style imports must be added in the app entry file. [See here for instructions on installing Kongponents](https://kongponents.konghq.com/#globally-install-all-kongponents).
17+
- `@kong-ui-public/i18n` must be available as a `dependency` in the host application.
18+
- `axios` must be installed as a dependency in the host application
19+
20+
## Usage
21+
22+
### Install
23+
24+
[See instructions for installing the `@kong-ui-public/entities-vaults` package.](../README.md#install)
25+
26+
### Props
27+
28+
#### `config`
29+
30+
- type: `Object as PropType<KonnectSecretFormConfig>`
31+
- required: `true`
32+
- default: `undefined`
33+
- properties:
34+
- `app`:
35+
- type: `'konnect'`
36+
- required: `true`
37+
- default: `undefined`
38+
- App name.
39+
40+
- `apiBaseUrl`:
41+
- type: `string`
42+
- required: `true`
43+
- default: `undefined`
44+
- Base URL for API requests.
45+
46+
- `axiosRequestConfig`:
47+
- type: `AxiosRequestConfig`
48+
- required: `false`
49+
- default: `undefined`
50+
- An optional configuration object for the underlying Axios request.
51+
52+
- `cancelRoute`:
53+
- type: `RouteLocationRaw`
54+
- required: `true`
55+
- default: `undefined`
56+
- Route to return to when canceling creation of a secret.
57+
58+
- `controlPlaneId`:
59+
- type: `string`
60+
- required: `true`
61+
- default: `undefined`
62+
- Name of the current control plane.
63+
64+
#### `vaultId`
65+
66+
- type: `String`
67+
- required: `true`
68+
69+
Current vault ID.
70+
71+
#### `secretId`
72+
73+
- type: `String`
74+
- required: `false`
75+
- default: `''`
76+
77+
If a valid `secretId` is provided, it will put the form in Edit mode instead of Create.
78+
79+
### Events
80+
81+
#### error
82+
83+
An `@error` event is emitted when form validation fails. The event payload is the response error.
84+
85+
#### loading
86+
87+
A `@loading` event is emitted when loading state changes. The event payload is a boolean.
88+
89+
#### update
90+
91+
A `@update` event is emitted when the form is saved. The event payload is the secret object.
92+
93+
### Usage example
94+
95+
Please refer to the [sandbox](../sandbox/pages/VaultConfigCardPage.vue). The form is accessible by clicking the `+ Store New Secret` button or `Edit` action of an existing secret.
96+
97+
## TypeScript interfaces
98+
99+
TypeScript interfaces [are available here](../src/types/secret-form.ts) and can be directly imported into your host application. The following type interfaces are available for import:
100+
101+
```ts
102+
import type {
103+
BaseSecretFormConfig,
104+
KonnectSecretFormConfig,
105+
SecretStateFields,
106+
SecretState
107+
} from '@kong-ui-public/entities-vaults'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# SecretList.vue
2+
3+
A list component for Konnect config store secrets. *This component should only be used in Konnect*.
4+
5+
- [Requirements](#requirements)
6+
- [Usage](#usage)
7+
- [Install](#install)
8+
- [Props](#props)
9+
- [Events](#events)
10+
- [Usage example](#usage-example)
11+
- [TypeScript interfaces](#typescript-interfaces)
12+
13+
## Requirements
14+
15+
- `vue` and `vue-router` must be initialized in the host application
16+
- `@kong/kongponents` must be added as a dependency in the host application, globally available via the Vue Plugin installation, and the package's style imports must be added in the app entry file. [See here for instructions on installing Kongponents](https://kongponents.konghq.com/#globally-install-all-kongponents).
17+
- `@kong-ui-public/i18n` must be available as a `dependency` in the host application.
18+
- `axios` must be installed as a dependency in the host application
19+
20+
## Usage
21+
22+
### Install
23+
24+
[See instructions for installing the `@kong-ui-public/entities-vaults` package.](../README.md#install)
25+
26+
### Props
27+
28+
#### `config`
29+
30+
- type: `Object as PropType<KonnectSecretListConfig>`
31+
- required: `true`
32+
- default: `undefined`
33+
- properties:
34+
- `app`:
35+
- type: `'konnect'`
36+
- required: `true`
37+
- default: `undefined`
38+
- App name.
39+
40+
- `apiBaseUrl`:
41+
- type: `string`
42+
- required: `true`
43+
- default: `undefined`
44+
- Base URL for API requests.
45+
46+
- `axiosRequestConfig`:
47+
- type: `AxiosRequestConfig`
48+
- required: `false`
49+
- default: `undefined`
50+
- An optional configuration object for the underlying Axios request.
51+
52+
- `cancelRoute`:
53+
- type: `RouteLocationRaw`
54+
- required: `true`
55+
- default: `undefined`
56+
- Route to return to when canceling creating or editing a secret.
57+
58+
- `createRoute`:
59+
- type: `RouteLocationRaw`
60+
- required: `true`
61+
- default: `undefined`
62+
- Route for creating a secret.
63+
64+
- `getEditRoute`:
65+
- type: `(id: string) => RouteLocationRaw`
66+
- required: `true`
67+
- default: `undefined`
68+
- A function that returns the route for editing a secret.
69+
70+
- `additionMessageForEmptyState`:
71+
- type: `string`
72+
- required: `false`
73+
- default: `undefined`
74+
- Additional message to show when there are no records.
75+
76+
- `controlPlaneId`:
77+
- type: `string`
78+
- required: `true`
79+
- default: `undefined`
80+
- Name of the current control plane.
81+
82+
#### `vaultId`
83+
84+
- type: `String`
85+
- required: `true`
86+
- default: `undefined`
87+
- Current vault ID.
88+
89+
#### `cacheIdentifier`
90+
91+
- type: `String`
92+
- required: `false`
93+
- default: `''`
94+
95+
Used to override the default unique identifier for the table's entry in the cache. This should be unique across the Vue App.
96+
Note: the default value is usually sufficient unless the app needs to support multiple separate instances of the table.
97+
98+
#### `canCreate`
99+
100+
- type: `Function as PropType<() => boolean | Promise<boolean>>`
101+
- required: `false`
102+
- default: `async () => true`
103+
104+
A synchronous or asynchronous function, that returns a boolean, that evaluates if the user can create a new entity.
105+
106+
#### `canDelete`
107+
108+
- type: `Function as PropType<(row: object) => boolean | Promise<boolean>>`
109+
- required: `false`
110+
- default: `async () => true`
111+
112+
A synchronous or asynchronous function, that returns a boolean, that evaluates if the user can delete a given entity.
113+
114+
#### `canEdit`
115+
116+
- type: `Function as PropType<(row: object) => boolean | Promise<boolean>>`
117+
- required: `false`
118+
- default: `async () => true`
119+
120+
A synchronous or asynchronous function, that returns a boolean, that evaluates if the user can edit a given entity.
121+
122+
### Events
123+
124+
#### error
125+
126+
An `@error` event is emitted when the table fails to fetch secrets or delete a secret. The event payload is the response error.
127+
128+
#### delete:success
129+
130+
A `@delete:success` event is emitted when a secret is successfully deleted. The event payload is the secret item data object.
131+
132+
### Usage example
133+
134+
Please refer to the [sandbox](../sandbox/pages/VaultConfigCardPage.vue).
135+
136+
## TypeScript interfaces
137+
138+
TypeScript interfaces [are available here](../src/types/secret-list.ts) and can be directly imported into your host application. The following type interfaces are available for import:
139+
140+
```ts
141+
import type {
142+
KonnectSecretListConfig,
143+
SecretEntityRow,
144+
} from '@kong-ui-public/entities-vaults'

packages/entities/entities-vaults/docs/vault-form.md

+6
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ A form component for Vaults.
7474
- *Specific to Konnect*. Show/hide Azure option.
7575
- **Note:** This is experimental and not supported by the backend right now
7676

77+
- `konnectConfigStoreAvailable`
78+
- type: `boolean`
79+
- required: `false`
80+
- default: `undefined`
81+
- *Specific to Konnect*. Show/hide Konnect Config Store option.
82+
7783
- `ttl`
7884
- type: `boolean`
7985
- required: `true`

packages/entities/entities-vaults/fixtures/mockData.ts

+22
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,25 @@ export const konnectCardConfig: KonnectVaultEntityConfig = {
7070
apiBaseUrl: '/us/kong-api',
7171
entityId: '1234',
7272
}
73+
74+
export const secrets: FetcherRawResponse = {
75+
data: [
76+
{
77+
key: 'secret-1',
78+
},
79+
{
80+
key: 'secret-2',
81+
},
82+
],
83+
total: 2,
84+
}
85+
86+
export const secrets100: any[] = Array(100)
87+
.fill(null)
88+
.map((_, i) => ({
89+
key: `secret-${i + 1}`,
90+
}))
91+
92+
export const secret = {
93+
key: 'secret-1',
94+
}

packages/entities/entities-vaults/sandbox/index.ts

+10
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ const init = async () => {
3838
name: 'edit-vault',
3939
component: () => import('./pages/VaultFormPage.vue'),
4040
},
41+
{
42+
path: '/vault/:vaultId/secret/create',
43+
name: 'create-secret',
44+
component: () => import('./pages/SecretFormPage.vue'),
45+
},
46+
{
47+
path: '/vault/:vaultId/secret/:secretId/edit',
48+
name: 'edit-secret',
49+
component: () => import('./pages/SecretFormPage.vue'),
50+
},
4151
],
4252
})
4353

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<template>
2+
<h2>Konnect API</h2>
3+
<SecretForm
4+
:config="konnectConfig"
5+
:secret-id="secretId"
6+
:vault-id="vaultId"
7+
@error="onError"
8+
@update="onUpdate"
9+
/>
10+
</template>
11+
12+
<script setup lang="ts">
13+
import { computed, ref } from 'vue'
14+
import { useRoute, useRouter } from 'vue-router'
15+
import type { AxiosError } from 'axios'
16+
import type { KonnectSecretFormConfig } from '../../src'
17+
import { SecretForm } from '../../src'
18+
19+
const route = useRoute()
20+
const router = useRouter()
21+
const controlPlaneId = import.meta.env.VITE_KONNECT_CONTROL_PLANE_ID || ''
22+
23+
const vaultId = computed((): string => route?.params?.vaultId as string || '')
24+
const secretId = computed((): string => route?.params?.secretId as string || '')
25+
26+
const konnectConfig = ref<KonnectSecretFormConfig>({
27+
app: 'konnect',
28+
apiBaseUrl: '/us/kong-api', // `/{geo}/kong-api`, with leading slash and no trailing slash; Consuming app would pass in something like `https://us.api.konghq.com`
29+
// Set the root `.env.development.local` variable to a control plane your PAT can access
30+
controlPlaneId,
31+
cancelRoute: { name: 'view-vault', params: { id: vaultId.value } },
32+
})
33+
34+
const onError = (error: AxiosError) => {
35+
console.log(`Error: ${error}`)
36+
}
37+
38+
const onUpdate = (payload: Record<string, any>) => {
39+
console.log('update', payload)
40+
41+
router.push({ name: 'view-vault', params: { id: vaultId.value } })
42+
}
43+
</script>

0 commit comments

Comments
 (0)