Skip to content

Commit

Permalink
chore(dataplanes): add bundle downloading functionality
Browse files Browse the repository at this point in the history
Signed-off-by: John Cowen <[email protected]>
  • Loading branch information
johncowen committed Jan 6, 2025
1 parent 10d9440 commit 9df858a
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 7 deletions.
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/kuma-gui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"prepare": "husky"
},
"dependencies": {
"@gera2ld/tarjs": "^0.3.1",
"@kong-ui-public/app-layout": "^4.2.63",
"@kong-ui-public/i18n": "^2.2.10",
"@kong/icons": "^1.20.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
:refresh="props.src !== '' ? refresh : () => {}"
>
<XProgress
v-if="props.src !== ''"
v-bind="$attrs"
:variant="props.variant === 'default' ? 'legacy' : props.variant"
/>
Expand Down
14 changes: 14 additions & 0 deletions packages/kuma-gui/src/app/data-planes/locales/en-us/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ data-planes:
builtin-gateway-data-plane-summary-config-view: YAML
delegated-gateway-data-plane-summary-overview-view: Overview
delegated-gateway-data-plane-summary-config-view: YAML
download:
title: Download bundle
description: !!text/markdown |
Include the following:
error: !!text/markdown |
Unable to generate bundle, please try again.
action: Download
options:
xds: XDS Configuration
eds: Include EDS
dataplane: Dataplane Configuration
policies: Poilicies
clusters: Envoy Clusters Logs
stats: Envoy Stats Logs
about:
title: About this Data Plane Proxy
gateway: 'Gateway'
Expand Down
71 changes: 71 additions & 0 deletions packages/kuma-gui/src/app/data-planes/sources.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TarWriter } from '@gera2ld/tarjs'

import {
Dataplane,
DataplaneOverview,
Expand All @@ -6,6 +8,7 @@ import {
} from './data'
import type { Can } from '../application/services/can'
import type { DataSourceResponse } from '@/app/application'
import { YAML } from '@/app/application'
import { defineSources, type Source } from '@/app/application/services/data-source'
import type KumaApi from '@/app/kuma/services/kuma-api/KumaApi'
import type { PaginatedApiListResponse as CollectionResponse, ApiKindListResponse as KindCollectionResponse } from '@/types/api.d'
Expand Down Expand Up @@ -75,6 +78,74 @@ export const sources = (source: Source, api: KumaApi, can: Can) => {
'/meshes/:mesh/dataplanes/:name/as/kubernetes': async (params) => {
return api.getDataplaneFromMesh(params, { format: 'kubernetes' })
},
'/meshes/:mesh/dataplanes/:name/as/tarball/:spec': async (params) => {
const { mesh, name } = params
const spec = JSON.parse(params.spec)
const requests = Object.entries(spec).filter(([_, value]) => {
return value
}).reduce((prev, [key]) => {
switch (key) {
case 'dataplane':
prev.push(async () => {
return {
name: 'dataplane.yaml',
content: YAML.stringify(await api.getDataplaneFromMesh({
mesh,
name,
})),
}
})
break
case 'xds':
prev.push(async () => {
return {
name: 'xds.json',
content: JSON.stringify(await api.getDataplaneXds({
mesh,
dppName: name,
}, {
include_eds: spec.eds,
})),
}
})
break
case 'stats':
prev.push(async () => {
return {
name: 'stats.txt',
content: await api.getDataplaneStats({
mesh,
dppName: name,
}),
}
})
break
case 'clusters':
prev.push(async () => {
return {
name: 'clusters.txt',
content: await api.getDataplaneClusters({
mesh,
dppName: name,
}),
}
})
break
}
return prev
}, [] as (() => Promise<{ name: string, content: string }>)[])

const files = await Promise.all(requests.map(item => item()))
const tarball = new TarWriter()
const id = `${mesh}_${name}`
files.forEach(({ name, content }) => {
tarball.addFile(`${id}/${name}`, content)
})
return {
name: `${id}.tar`,
url: URL.createObjectURL(new Blob([await tarball.write()], { type: 'application/tar' })),
}
},

'/meshes/:mesh/dataplanes/:name/sidecar-dataplane-policies': async (params) => {
return SidecarDataplane.fromCollection(await api.getSidecarDataplanePolicies(params))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
mesh: '',
dataPlane: '',
}"
v-slot="{ route, t }"
v-slot="{ route, t, uri }"
>
<DataSource
:src="`/meshes/${route.params.mesh}/dataplane-overviews/${route.params.dataPlane}`"
v-slot="{ data, error }: DataplaneOverviewSource"
:src="uri(sources, '/meshes/:mesh/dataplane-overviews/:name', {
mesh: route.params.mesh,
name: route.params.dataPlane,
})"
v-slot="{ data, error }"
>
<AppView
:breadcrumbs="[
Expand Down Expand Up @@ -38,13 +41,122 @@
#title
>
<h1>
<TextWithCopyButton :text="data.name">
<XCopyButton
:text="data.name"
>
<RouteTitle
:title="t('data-planes.routes.item.title', { name: data.name })"
/>
</TextWithCopyButton>
</XCopyButton>
</h1>
</template>
<template
#actions
>
<XDisclosure
v-slot="{ expanded, toggle }"
>
<XAction
appearance="primary"
@click="toggle"
>
Download Bundle
</XAction>
<XTeleportTemplate
v-if="expanded"
:to="{ name: 'modal-layer' }"
>
<XDisclosure
v-slot="{ expanded: downloading, toggle: download }"
>
<form
@submit.prevent="download"
>
<XModal
:title="t('data-planes.routes.item.download.title')"
@cancel="toggle"
>
<fieldset
:disabled="downloading"
>
<XI18n
t="data-planes.routes.item.download.description"
/>
<ul>
<template
v-for="(spec, key) in specs"
:key="typeof spec"
>
<li
v-if="key !== 'eds'"
>
<XCheckbox
v-model="specs[key]"
>
{{ t(`data-planes.routes.item.download.options.${key}`) }}
</XCheckbox>
<ul
v-if="key === 'xds'"
>
<li>
<XCheckbox v-model="specs.eds">
{{ t('data-planes.routes.item.download.options.eds') }}
</XCheckbox>
</li>
</ul>
</li>
</template>
</ul>
</fieldset>
<template
#footer-actions
>
<XLayout
type="separated"
>
<DataLoader
variant="spinner"
:src="downloading ? uri(sources, '/meshes/:mesh/dataplanes/:name/as/tarball/:spec', {
mesh: route.params.mesh,
name: route.params.dataPlane,
spec: JSON.stringify(
specs,
),
}, {
cacheControl: 'no-cache',
}) : ''"
@change="downloadBundle"
@error="download"
>
<template
#error
>
<XAlert
appearance="warning"
show-icon
>
<XI18n
t="data-planes.routes.item.download.error"
/>
</XAlert>
</template>
</DataLoader>
<XAction
appearance="primary"
type="submit"
:disabled="downloading"
>
{{ t('data-planes.routes.item.download.action') }}
</XAction>
</XLayout>
</template>
</XModal>
</form>
</XDisclosure>
</XTeleportTemplate>
</XDisclosure>
</template>

<DataLoader
:data="[data]"
:errors="[error]"
Expand Down Expand Up @@ -79,10 +191,40 @@
</template>

<script lang="ts" setup>
import { DataplaneOverviewSource } from '../sources'
import TextWithCopyButton from '@/app/common/TextWithCopyButton.vue'
import { ref } from 'vue'
import { sources } from '../sources'
import type { Mesh } from '@/app/meshes/data'
const props = defineProps<{
mesh: Mesh
}>()
const specs = ref({
eds: false,
xds: false,
dataplane: false,
// policies: false,
clusters: false,
stats: false,
})
const downloadBundle = async (bundle: { name: string, url: string }) => {
const a = document.createElement('a')
a.download = bundle.name
a.href = bundle.url
setTimeout(() => { window.URL.revokeObjectURL(a.href) }, 60000)
// await Promise.resolve()
a.click()
}
</script>
<style lang="scss" scoped>
form {
:deep(p) {
margin-bottom: 1em !important;
}
ul {
margin: 0;
list-style-type: none;
}
}
</style>
8 changes: 8 additions & 0 deletions packages/kuma-gui/src/app/kuma/services/kuma-api/KumaApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ export default class KumaApi extends Api {
return this.client.get(`/meshes/${mesh}/dataplanes/${dppName}/xds`, { params })
}

getDataplaneStats({ mesh, dppName }: { mesh: string, dppName: string, params?: any }, params?: any): Promise<string> {
return this.client.get(`/meshes/${mesh}/dataplanes/${dppName}/stats`, { params })
}

getDataplaneClusters({ mesh, dppName }: { mesh: string, dppName: string, params?: any }, params?: any): Promise<string> {
return this.client.get(`/meshes/${mesh}/dataplanes/${dppName}/clusters`, { params })
}

getAllMeshServicesFromMesh({ mesh }: { mesh: string }, params?: PaginationParameters): Promise<PaginatedApiListResponse<MeshService>> {
return this.client.get(`/meshes/${mesh}/meshservices`, { params })
}
Expand Down
1 change: 1 addition & 0 deletions packages/kuma-gui/src/app/x/components/x-modal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# x-modal
18 changes: 18 additions & 0 deletions packages/kuma-gui/src/app/x/components/x-modal/XModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<KModal
:visible="true"
>
<template
v-for="(_, key) in slots"
:key="key"
#[`${key}`]
>
<slot :name="key" />
</template>
</KModal>
</template>
<script lang="ts" setup>
import { KModal } from '@kong/kongponents'
import { useSlots } from 'vue'
const slots = useSlots()
</script>
3 changes: 3 additions & 0 deletions packages/kuma-gui/src/app/x/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import XI18n from './components/x-i18n/XI18n.vue'
import XIcon from './components/x-icon/XIcon.vue'
import XInput from './components/x-input/XInput.vue'
import XLayout from './components/x-layout/XLayout.vue'
import XModal from './components/x-modal/XModal.vue'
import XProgress from './components/x-progress/XProgress.vue'
import XPrompt from './components/x-prompt/XPrompt.vue'
import XProvider from './components/x-provider/XProvider.vue'
Expand Down Expand Up @@ -48,6 +49,7 @@ declare module 'vue' {
XBreadcrumbs: typeof XBreadcrumbs
XEmptyState: typeof XEmptyState
XLayout: typeof XLayout
XModal: typeof XModal
XPrompt: typeof XPrompt
XProvider: typeof XProvider
XProgress: typeof XProgress
Expand Down Expand Up @@ -98,6 +100,7 @@ export const services = (app: Record<string, Token>): ServiceDefinition[] => {
['XI18n', XI18n],
['XInput', XInput],
['XLayout', XLayout],
['XModal', XModal],
['XPrompt', XPrompt],
['XProvider', XProvider],
['XProgress', XProgress],
Expand Down

0 comments on commit 9df858a

Please sign in to comment.