├── .nvmrc ├── src ├── renderer │ ├── components │ │ ├── details │ │ │ ├── index.tsx │ │ │ ├── controlplane │ │ │ │ ├── index.tsx │ │ │ │ ├── resource-set-details.module.scss.d.ts │ │ │ │ ├── resource-set-details.module.scss │ │ │ │ ├── flux-report-details.module.scss.d.ts │ │ │ │ ├── resource-set-input-provider-details.module.scss.d.ts │ │ │ │ ├── flux-instance-details.module.scss.d.ts │ │ │ │ ├── flux-report-details.module.scss │ │ │ │ ├── resource-set-input-provider-details.module.scss │ │ │ │ └── flux-instance-details.module.scss │ │ │ ├── source │ │ │ │ ├── git-repository-details.module.scss.d.ts │ │ │ │ ├── git-repository-details.module.scss │ │ │ │ ├── helm-repository-details-v1.tsx │ │ │ │ ├── helm-repository-details-v1beta1.tsx │ │ │ │ ├── helm-repository-details-v1beta2.tsx │ │ │ │ ├── bucket-details-v1.tsx │ │ │ │ ├── bucket-details-v1beta1.tsx │ │ │ │ ├── bucket-details-v1beta2.tsx │ │ │ │ ├── helm-chart-details-v1.tsx │ │ │ │ ├── helm-chart-details-v1beta1.tsx │ │ │ │ └── helm-chart-details-v1beta2.tsx │ │ │ ├── image │ │ │ │ ├── image-update-automation-details.module.scss.d.ts │ │ │ │ ├── image-update-automation-details.module.scss │ │ │ │ ├── image-policy-details-v1.tsx │ │ │ │ ├── image-policy-details-v1beta1.tsx │ │ │ │ ├── image-policy-details-v1beta2.tsx │ │ │ │ └── image-repository-details-v1beta1.tsx │ │ │ ├── notification │ │ │ │ ├── receiver-details.module.scss.d.ts │ │ │ │ ├── receiver-details.module.scss │ │ │ │ ├── alert-details-v1beta1.tsx │ │ │ │ ├── alert-details-v1beta2.tsx │ │ │ │ ├── alert-details-v1beta3.tsx │ │ │ │ ├── provider-details-v1beta1.tsx │ │ │ │ ├── provider-details-v1beta2.tsx │ │ │ │ └── provider-details-v1beta3.tsx │ │ │ ├── helm │ │ │ │ ├── helm-release-details.module.scss.d.ts │ │ │ │ └── helm-release-details.module.scss │ │ │ └── kustomize │ │ │ │ ├── kustomization-details.module.scss.d.ts │ │ │ │ └── kustomization-details.module.scss │ │ ├── pie-chart.module.scss │ │ ├── spec-access-from.module.scss │ │ ├── pie-chart.module.scss.d.ts │ │ ├── spec-patches.module.scss.d.ts │ │ ├── yaml-dump.module.scss.d.ts │ │ ├── spec-patches.module.scss │ │ ├── spec-access-from.module.scss.d.ts │ │ ├── status-artifact.module.scss.d.ts │ │ ├── status-history.module.scss.d.ts │ │ ├── yaml-dump.module.scss │ │ ├── info-page.module.scss.d.ts │ │ ├── status-artifact.module.scss │ │ ├── status-history.module.scss │ │ ├── error-page.module.scss.d.ts │ │ ├── error-page.module.scss │ │ ├── status-inventory.module.scss.d.ts │ │ ├── info-page.module.scss │ │ ├── status-inventory.module.scss │ │ ├── maybe-link.tsx │ │ ├── object-ref-tooltip.tsx │ │ ├── info-page.tsx │ │ ├── humanizeBytes.tsx │ │ ├── link-to-namespace.tsx │ │ ├── duration-absolute.tsx │ │ ├── link-to-secret.tsx │ │ ├── link-to-storage-class.tsx │ │ ├── link-to-service-account.tsx │ │ ├── link-to-object.tsx │ │ ├── link-to-resource-set-input-provider.tsx │ │ ├── yaml-dump.tsx │ │ ├── spec-access-from.tsx │ │ ├── status-artifact.tsx │ │ ├── error-page.tsx │ │ ├── status-history.tsx │ │ ├── spec-patches.tsx │ │ └── status-conditions.ts │ ├── vars.scss │ ├── k8s │ │ ├── core │ │ │ └── types.ts │ │ └── fluxcd │ │ │ ├── utils.ts │ │ │ ├── notification │ │ │ ├── alert-v1beta1.ts │ │ │ ├── alert-v1beta2.ts │ │ │ ├── alert-v1beta3.ts │ │ │ ├── receiver-v1.ts │ │ │ ├── receiver-v1beta1.ts │ │ │ ├── receiver-v1beta2.ts │ │ │ ├── receiver-v1beta3.ts │ │ │ ├── provider-v1beta1.ts │ │ │ ├── provider-v1beta2.ts │ │ │ └── provider-v1beta3.ts │ │ │ ├── source │ │ │ ├── bucket-v1.ts │ │ │ ├── bucket-v1beta1.ts │ │ │ ├── bucket-v1beta2.ts │ │ │ ├── helmchart-v1.ts │ │ │ ├── helmchart-v1beta1.ts │ │ │ ├── helmchart-v1beta2.ts │ │ │ ├── helmrepository-v1.ts │ │ │ ├── helmrepository-v1beta1.ts │ │ │ ├── helmrepository-v1beta2.ts │ │ │ ├── ocirepository-v1.ts │ │ │ ├── ocirepository-v1beta2.ts │ │ │ ├── gitrepository-v1.ts │ │ │ ├── gitrepository-v1beta1.ts │ │ │ └── gitrepository-v1beta2.ts │ │ │ ├── image │ │ │ ├── imagepolicy-v1.ts │ │ │ ├── imagepolicy-v1beta1.ts │ │ │ ├── imagepolicy-v1beta2.ts │ │ │ ├── imagerepository-v1beta1.ts │ │ │ ├── imagerepository-v1.ts │ │ │ ├── imagerepository-v1beta2.ts │ │ │ ├── imageupdateautomation-v1beta1.ts │ │ │ ├── imageupdateautomation-v1.ts │ │ │ └── imageupdateautomation-v1beta2.ts │ │ │ ├── types.ts │ │ │ └── controlplane │ │ │ ├── fluxreport-v1.ts │ │ │ ├── resourceset-v1.ts │ │ │ └── resourcesetinputprovider-v1.ts │ ├── pages │ │ ├── source │ │ │ ├── helmrepositories.module.scss.d.ts │ │ │ ├── ocirepositories.module.scss.d.ts │ │ │ ├── gitrepositories.module.scss.d.ts │ │ │ ├── helmrepositories.module.scss │ │ │ ├── ocirepositories.module.scss │ │ │ ├── buckets.module.scss.d.ts │ │ │ ├── helmcharts.module.scss.d.ts │ │ │ ├── buckets.module.scss │ │ │ ├── gitrepositories.module.scss │ │ │ └── helmcharts.module.scss │ │ ├── notifications │ │ │ ├── receivers.module.scss.d.ts │ │ │ ├── alerts.module.scss.d.ts │ │ │ ├── providers.module.scss.d.ts │ │ │ ├── alerts.module.scss │ │ │ ├── receivers.module.scss │ │ │ ├── providers.module.scss │ │ │ ├── receivers-v1.tsx │ │ │ ├── receivers-v1beta1.tsx │ │ │ ├── receivers-v1beta2.tsx │ │ │ ├── receivers-v1beta3.tsx │ │ │ ├── alerts-v1beta1.tsx │ │ │ ├── alerts-v1beta2.tsx │ │ │ ├── alerts-v1beta3.tsx │ │ │ ├── providers-v1beta1.tsx │ │ │ ├── providers-v1beta2.tsx │ │ │ └── providers-v1beta3.tsx │ │ ├── controlplane │ │ │ ├── fluxinstances.module.scss.d.ts │ │ │ ├── resourcesets.module.scss.d.ts │ │ │ ├── resourcesetinputproviders.module.scss.d.ts │ │ │ ├── fluxinstances.module.scss │ │ │ ├── resourcesets.module.scss │ │ │ ├── resourcesetinputproviders.module.scss │ │ │ ├── fluxreports.module.scss.d.ts │ │ │ └── fluxreports.module.scss │ │ ├── image │ │ │ ├── imageupdateautomations.module.scss.d.ts │ │ │ ├── imagerepositories.module.scss.d.ts │ │ │ ├── imagepolicies.module.scss.d.ts │ │ │ ├── imageupdateautomations.module.scss │ │ │ ├── imagerepositories.module.scss │ │ │ └── imagepolicies.module.scss │ │ ├── overview.module.scss.d.ts │ │ ├── available-version.module.scss.d.ts │ │ ├── kustomize │ │ │ ├── kustomizations.module.scss.d.ts │ │ │ └── kustomizations.module.scss │ │ ├── helm │ │ │ ├── helmreleases.module.scss.d.ts │ │ │ └── helmreleases.module.scss │ │ ├── overview.module.scss │ │ └── available-version.module.scss │ ├── utils.ts │ ├── menus │ │ ├── fluxcd-object-reconcile-menu-item.tsx │ │ ├── fluxcd-object-spec-suspend-resume-menu-item.tsx │ │ └── fluxcd-object-annotation-suspend-resume-menu-item.tsx │ └── icons │ │ └── fluxcd.svg └── main │ └── index.ts ├── pnpm-workspace.yaml ├── docs └── images │ └── dashboard.png ├── .markdownlint.yaml ├── .trunk ├── .gitignore └── trunk.yaml ├── .editorconfig ├── .yamllint.yaml ├── .prettierignore ├── .yamlfmt.yaml ├── svgo.config.mjs ├── tsconfig.json ├── .gitignore ├── .github └── workflows │ ├── trunk-check.yaml │ ├── cleanup-cache.yaml │ ├── osv-scanner.yaml │ ├── check.yaml │ ├── test-update.yaml │ └── tag.yaml ├── knip.jsonc └── LICENSE /.nvmrc: -------------------------------------------------------------------------------- 1 | 22.16.0 2 | -------------------------------------------------------------------------------- /src/renderer/components/details/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./controlplane"; 2 | -------------------------------------------------------------------------------- /src/renderer/components/pie-chart.module.scss: -------------------------------------------------------------------------------- 1 | .title { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | onlyBuiltDependencies: 2 | - '@parcel/watcher' 3 | - esbuild 4 | 5 | shellEmulator: true 6 | -------------------------------------------------------------------------------- /src/renderer/vars.scss: -------------------------------------------------------------------------------- 1 | // Dimensions 2 | $unit: 8px; 3 | $padding: $unit; 4 | $margin: $unit; 5 | $gap: $padding; 6 | -------------------------------------------------------------------------------- /docs/images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/freelensapp/freelens-fluxcd-extension/HEAD/docs/images/dashboard.png -------------------------------------------------------------------------------- /.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | # Prettier friendly markdownlint config (all formatting rules disabled) 2 | extends: markdownlint/style/prettier 3 | -------------------------------------------------------------------------------- /.trunk/.gitignore: -------------------------------------------------------------------------------- 1 | *out 2 | *logs 3 | *actions 4 | *notifications 5 | *tools 6 | plugins 7 | user_trunk.yaml 8 | user.yaml 9 | tmp 10 | -------------------------------------------------------------------------------- /src/renderer/components/spec-access-from.module.scss: -------------------------------------------------------------------------------- 1 | .matchLabels { 2 | display: flex; 3 | gap: 0.5rem; 4 | flex-wrap: wrap; 5 | } 6 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./flux-instance-details-v1"; 2 | export * from "./flux-report-details-v1"; 3 | -------------------------------------------------------------------------------- /src/renderer/components/pie-chart.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly title: "title"; 3 | }; 4 | export = classNames; 5 | -------------------------------------------------------------------------------- /src/renderer/components/spec-patches.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly title: "title"; 3 | }; 4 | export = classNames; 5 | -------------------------------------------------------------------------------- /src/renderer/components/yaml-dump.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly editor: "editor"; 3 | }; 4 | export = classNames; 5 | -------------------------------------------------------------------------------- /src/main/index.ts: -------------------------------------------------------------------------------- 1 | import { Main } from "@freelensapp/extensions"; 2 | 3 | export default class FluxCDExtensionMain extends Main.LensExtension {} 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | -------------------------------------------------------------------------------- /src/renderer/components/spec-patches.module.scss: -------------------------------------------------------------------------------- 1 | @use "../vars"; 2 | 3 | .title { 4 | margin-top: vars.$margin * 2; 5 | margin-bottom: vars.$margin; 6 | } 7 | -------------------------------------------------------------------------------- /src/renderer/components/spec-access-from.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly matchLabels: "matchLabels"; 3 | }; 4 | export = classNames; 5 | -------------------------------------------------------------------------------- /src/renderer/components/status-artifact.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly artifact: "artifact"; 3 | readonly title: "title"; 4 | }; 5 | export = classNames; 6 | -------------------------------------------------------------------------------- /src/renderer/components/status-history.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly history: "history"; 3 | readonly title: "title"; 4 | }; 5 | export = classNames; 6 | -------------------------------------------------------------------------------- /src/renderer/components/yaml-dump.module.scss: -------------------------------------------------------------------------------- 1 | .editor { 2 | resize: none; 3 | overflow: hidden; 4 | border: 1px solid var(--borderFaintColor); 5 | border-radius: 4px; 6 | } 7 | -------------------------------------------------------------------------------- /.yamllint.yaml: -------------------------------------------------------------------------------- 1 | rules: 2 | quoted-strings: 3 | required: only-when-needed 4 | extra-allowed: ["{|}"] 5 | key-duplicates: {} 6 | octal-values: 7 | forbid-implicit-octal: true 8 | -------------------------------------------------------------------------------- /src/renderer/components/info-page.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly infoPage: "infoPage"; 3 | readonly infoMessage: "infoMessage"; 4 | }; 5 | export = classNames; 6 | -------------------------------------------------------------------------------- /src/renderer/components/status-artifact.module.scss: -------------------------------------------------------------------------------- 1 | @use "../vars"; 2 | 3 | .artifact { 4 | .title { 5 | margin-top: vars.$margin * 2; 6 | margin-bottom: vars.$margin; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/renderer/components/status-history.module.scss: -------------------------------------------------------------------------------- 1 | @use "../vars"; 2 | 3 | .history { 4 | .title { 5 | margin-top: vars.$margin * 2; 6 | margin-bottom: vars.$margin; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/renderer/components/error-page.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly errorPage: "errorPage"; 3 | readonly errorMessage: "errorMessage"; 4 | }; 5 | export = classNames; 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | ## Ignore files handled by Biome 2 | *.css 3 | *.html 4 | *.js 5 | *.json 6 | *.json5 7 | *.jsonc 8 | *.jsx 9 | *.md 10 | *.mjs 11 | *.mts 12 | *.ts 13 | *.tsx 14 | *.xml 15 | *.yaml 16 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/git-repository-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly details: "details"; 3 | readonly title: "title"; 4 | readonly editor: "editor"; 5 | }; 6 | export = classNames; 7 | -------------------------------------------------------------------------------- /src/renderer/components/details/image/image-update-automation-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly details: "details"; 3 | readonly title: "title"; 4 | readonly editor: "editor"; 5 | }; 6 | export = classNames; 7 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/resource-set-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly title: "title"; 3 | readonly inputs: "inputs"; 4 | readonly index: "index"; 5 | readonly content: "content"; 6 | }; 7 | export = classNames; 8 | -------------------------------------------------------------------------------- /.yamlfmt.yaml: -------------------------------------------------------------------------------- 1 | doublestar: true 2 | exclude: 3 | - .trunk/trunk.yaml 4 | - pnpm-workspace.yaml 5 | formatter: 6 | eof_newline: false 7 | indentless_arrays: false 8 | max_line_length: 300 9 | retain_line_breaks_single: true 10 | trim_trailing_whitespace: true 11 | -------------------------------------------------------------------------------- /src/renderer/components/error-page.module.scss: -------------------------------------------------------------------------------- 1 | .errorPage { 2 | display: flex; 3 | justify-content: center; 4 | width: 100%; 5 | height: 100%; 6 | } 7 | 8 | .errorMessage { 9 | display: flex; 10 | align-items: center; 11 | color: var(--colorError); 12 | } 13 | -------------------------------------------------------------------------------- /src/renderer/components/status-inventory.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly inventory: "inventory"; 3 | readonly tableCell: "tableCell"; 4 | readonly kind: "kind"; 5 | readonly name: "name"; 6 | readonly namespace: "namespace"; 7 | }; 8 | export = classNames; 9 | -------------------------------------------------------------------------------- /src/renderer/components/info-page.module.scss: -------------------------------------------------------------------------------- 1 | @use "../vars"; 2 | 3 | .infoPage { 4 | display: flex; 5 | justify-content: center; 6 | width: 100%; 7 | height: 100%; 8 | } 9 | 10 | .infoMessage { 11 | display: flex; 12 | align-items: center; 13 | color: var(--colorInfo); 14 | } 15 | -------------------------------------------------------------------------------- /svgo.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: [ 3 | { 4 | name: "preset-default", 5 | params: { 6 | overrides: { 7 | removeViewBox: false, 8 | sortAttrs: true, 9 | removeOffCanvasPaths: true, 10 | }, 11 | }, 12 | }, 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /src/renderer/components/status-inventory.module.scss: -------------------------------------------------------------------------------- 1 | @use "../vars"; 2 | 3 | .inventory { 4 | :global(.TableCell) { 5 | &.kind { 6 | flex-grow: 0.5; 7 | } 8 | 9 | &.name { 10 | flex-grow: 0.7; 11 | } 12 | 13 | &.namespace { 14 | flex-grow: 0.5; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/resource-set-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .title { 4 | margin-top: vars.$margin * 2; 5 | margin-bottom: vars.$margin; 6 | } 7 | 8 | .inputs { 9 | .index { 10 | min-width: 60px; 11 | } 12 | 13 | .content { 14 | min-width: 300px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/renderer/k8s/core/types.ts: -------------------------------------------------------------------------------- 1 | export interface Selector { 2 | group?: string; 3 | version?: string; 4 | kind?: string; 5 | namespace?: string; 6 | name?: string; 7 | annotationSelector?: string; 8 | labelSelector?: string; 9 | } 10 | 11 | export interface Patch { 12 | patch: string; 13 | target: Selector; 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@electron-toolkit/tsconfig/tsconfig.node.json", 3 | "include": ["*.ts", "src/**/*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "esModuleInterop": true, 7 | "moduleResolution": "node10", 8 | "jsx": "react-jsx", 9 | "types": ["vite/client", "electron-vite/node"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/renderer/components/details/notification/receiver-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly details: "details"; 3 | readonly resources: "resources"; 4 | readonly tableCell: "tableCell"; 5 | readonly kind: "kind"; 6 | readonly name: "name"; 7 | readonly namespace: "namespace"; 8 | }; 9 | export = classNames; 10 | -------------------------------------------------------------------------------- /src/renderer/pages/source/helmrepositories.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly url: "url"; 5 | readonly resumed: "resumed"; 6 | readonly condition: "condition"; 7 | readonly status: "status"; 8 | readonly age: "age"; 9 | }; 10 | export = classNames; 11 | -------------------------------------------------------------------------------- /src/renderer/pages/source/ocirepositories.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly url: "url"; 5 | readonly resumed: "resumed"; 6 | readonly condition: "condition"; 7 | readonly status: "status"; 8 | readonly age: "age"; 9 | }; 10 | export = classNames; 11 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/receivers.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly type: "type"; 5 | readonly resumed: "resumed"; 6 | readonly condition: "condition"; 7 | readonly status: "status"; 8 | readonly age: "age"; 9 | }; 10 | export = classNames; 11 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/alerts.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly severity: "severity"; 5 | readonly resumed: "resumed"; 6 | readonly condition: "condition"; 7 | readonly status: "status"; 8 | readonly age: "age"; 9 | }; 10 | export = classNames; 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.d.ts 2 | *.gz 3 | *.lock 4 | *.log 5 | *.map 6 | *.out 7 | *.tgz 8 | *.tmp 9 | *~ 10 | ?.* 11 | 12 | !custom.d.ts 13 | !env.d.ts 14 | !*.css.d.ts 15 | !*.scss.d.ts 16 | 17 | /dist/ 18 | 19 | /freelens/ 20 | 21 | .turbo 22 | 23 | /coverage/ 24 | /node_modules/ 25 | /out/ 26 | 27 | /.nyc_output/ 28 | 29 | *.DS_Store 30 | /.idea 31 | /.vscode 32 | -------------------------------------------------------------------------------- /src/renderer/pages/controlplane/fluxinstances.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly revision: "revision"; 5 | readonly enabled: "enabled"; 6 | readonly condition: "condition"; 7 | readonly status: "status"; 8 | readonly age: "age"; 9 | }; 10 | export = classNames; 11 | -------------------------------------------------------------------------------- /src/renderer/pages/controlplane/resourcesets.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly revision: "revision"; 5 | readonly enabled: "enabled"; 6 | readonly condition: "condition"; 7 | readonly status: "status"; 8 | readonly age: "age"; 9 | }; 10 | export = classNames; 11 | -------------------------------------------------------------------------------- /src/renderer/pages/image/imageupdateautomations.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly lastRun: "lastRun"; 5 | readonly resumed: "resumed"; 6 | readonly condition: "condition"; 7 | readonly status: "status"; 8 | readonly age: "age"; 9 | }; 10 | export = classNames; 11 | -------------------------------------------------------------------------------- /src/renderer/pages/overview.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly overviewStatuses: "overviewStatuses"; 3 | readonly statuses: "statuses"; 4 | readonly chartColumn: "chartColumn"; 5 | readonly chartTitle: "chartTitle"; 6 | readonly chartItem: "chartItem"; 7 | readonly fluxContent: "fluxContent"; 8 | }; 9 | export = classNames; 10 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/git-repository-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .details { 4 | .title { 5 | margin-top: vars.$margin * 2; 6 | margin-bottom: vars.$margin; 7 | } 8 | } 9 | 10 | .editor { 11 | resize: none; 12 | overflow: hidden; 13 | border: 1px solid var(--borderFaintColor); 14 | border-radius: 4px; 15 | } 16 | -------------------------------------------------------------------------------- /src/renderer/components/details/helm/helm-release-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly details: "details"; 3 | readonly title: "title"; 4 | readonly editor: "editor"; 5 | readonly history: "history"; 6 | readonly tableCell: "tableCell"; 7 | readonly version: "version"; 8 | readonly status: "status"; 9 | }; 10 | export = classNames; 11 | -------------------------------------------------------------------------------- /src/renderer/pages/available-version.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly unavailablePage: "unavailablePage"; 3 | readonly unavailableContent: "unavailableContent"; 4 | readonly unavailableTitle: "unavailableTitle"; 5 | readonly unavailableMessage: "unavailableMessage"; 6 | readonly unavailableDetails: "unavailableDetails"; 7 | }; 8 | export = classNames; 9 | -------------------------------------------------------------------------------- /src/renderer/pages/image/imagerepositories.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly image: "image"; 5 | readonly tags: "tags"; 6 | readonly resumed: "resumed"; 7 | readonly condition: "condition"; 8 | readonly status: "status"; 9 | readonly age: "age"; 10 | }; 11 | export = classNames; 12 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/providers.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly type: "type"; 5 | readonly channel: "channel"; 6 | readonly resumed: "resumed"; 7 | readonly condition: "condition"; 8 | readonly status: "status"; 9 | readonly age: "age"; 10 | }; 11 | export = classNames; 12 | -------------------------------------------------------------------------------- /src/renderer/components/details/notification/receiver-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .details { 4 | .resources { 5 | :global(.TableCell) { 6 | &.kind { 7 | flex-grow: 0.5; 8 | } 9 | 10 | &.name { 11 | flex-grow: 0.7; 12 | } 13 | 14 | &.namespace { 15 | flex-grow: 0.5; 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/renderer/pages/controlplane/resourcesetinputproviders.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly type: "type"; 5 | readonly url: "url"; 6 | readonly enabled: "enabled"; 7 | readonly condition: "condition"; 8 | readonly status: "status"; 9 | readonly age: "age"; 10 | }; 11 | export = classNames; 12 | -------------------------------------------------------------------------------- /src/renderer/pages/kustomize/kustomizations.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly source: "source"; 5 | readonly revision: "revision"; 6 | readonly resumed: "resumed"; 7 | readonly condition: "condition"; 8 | readonly status: "status"; 9 | readonly age: "age"; 10 | }; 11 | export = classNames; 12 | -------------------------------------------------------------------------------- /src/renderer/pages/image/imagepolicies.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly repository: "repository"; 5 | readonly latestTag: "latestTag"; 6 | readonly resumed: "resumed"; 7 | readonly condition: "condition"; 8 | readonly status: "status"; 9 | readonly age: "age"; 10 | }; 11 | export = classNames; 12 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/alerts.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.severity { 4 | flex-grow: 0.7; 5 | } 6 | 7 | &.resumed { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.condition { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.status { 16 | flex-grow: 1.5; 17 | } 18 | 19 | &.age { 20 | flex-grow: 0.3; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/receivers.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.type { 4 | flex-grow: 0.7; 5 | } 6 | 7 | &.resumed { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.condition { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.status { 16 | flex-grow: 1.5; 17 | } 18 | 19 | &.age { 20 | flex-grow: 0.3; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/pages/source/gitrepositories.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly revision: "revision"; 5 | readonly url: "url"; 6 | readonly ref: "ref"; 7 | readonly resumed: "resumed"; 8 | readonly condition: "condition"; 9 | readonly status: "status"; 10 | readonly age: "age"; 11 | }; 12 | export = classNames; 13 | -------------------------------------------------------------------------------- /src/renderer/pages/source/helmrepositories.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.url { 4 | flex-grow: 1.5; 5 | } 6 | 7 | &.resumed { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.condition { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.status { 16 | flex-grow: 1.5; 17 | } 18 | 19 | &.age { 20 | flex-grow: 0.3; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/pages/source/ocirepositories.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.url { 4 | flex-grow: 1.5; 5 | } 6 | 7 | &.resumed { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.condition { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.status { 16 | flex-grow: 1.5; 17 | } 18 | 19 | &.age { 20 | flex-grow: 0.3; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/pages/controlplane/fluxinstances.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.revision { 4 | flex-grow: 1.3; 5 | } 6 | 7 | &.enabled { 8 | flex-grow: 0.4; 9 | } 10 | 11 | &.condition { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.status { 16 | flex-grow: 1.5; 17 | } 18 | 19 | &.age { 20 | flex-grow: 0.3; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/pages/controlplane/resourcesets.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.revision { 4 | flex-grow: 1.3; 5 | } 6 | 7 | &.enabled { 8 | flex-grow: 0.4; 9 | } 10 | 11 | &.condition { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.status { 16 | flex-grow: 1.5; 17 | } 18 | 19 | &.age { 20 | flex-grow: 0.3; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/pages/image/imageupdateautomations.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.lastRun { 4 | flex-grow: 0.7; 5 | } 6 | 7 | &.resumed { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.condition { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.status { 16 | flex-grow: 1.5; 17 | } 18 | 19 | &.age { 20 | flex-grow: 0.3; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/pages/source/buckets.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly revision: "revision"; 5 | readonly provider: "provider"; 6 | readonly bucket: "bucket"; 7 | readonly resumed: "resumed"; 8 | readonly condition: "condition"; 9 | readonly status: "status"; 10 | readonly age: "age"; 11 | }; 12 | export = classNames; 13 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/flux-report-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly title: "title"; 3 | readonly tableCell: "tableCell"; 4 | readonly apiVersion: "apiVersion"; 5 | readonly kind: "kind"; 6 | readonly running: "running"; 7 | readonly failing: "failing"; 8 | readonly suspended: "suspended"; 9 | readonly totalSize: "totalSize"; 10 | }; 11 | export = classNames; 12 | -------------------------------------------------------------------------------- /src/renderer/pages/helm/helmreleases.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly source: "source"; 5 | readonly resumed: "resumed"; 6 | readonly chartVersion: "chartVersion"; 7 | readonly appVersion: "appVersion"; 8 | readonly condition: "condition"; 9 | readonly status: "status"; 10 | readonly age: "age"; 11 | }; 12 | export = classNames; 13 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/resource-set-input-provider-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly title: "title"; 3 | readonly schedules: "schedules"; 4 | readonly cron: "cron"; 5 | readonly timeZone: "timeZone"; 6 | readonly window: "window"; 7 | readonly exportedInputs: "exportedInputs"; 8 | readonly index: "index"; 9 | readonly content: "content"; 10 | }; 11 | export = classNames; 12 | -------------------------------------------------------------------------------- /src/renderer/components/maybe-link.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | export function MaybeLink(props: React.ComponentProps): React.ReactElement { 5 | const { children, to, ...rest } = props; 6 | if (to) { 7 | return ( 8 | 9 | {children} 10 | 11 | ); 12 | } else { 13 | return <>{children}; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/renderer/pages/image/imagerepositories.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.image { 4 | flex-grow: 1; 5 | } 6 | 7 | &.tags { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.resumed { 12 | flex-grow: 0.5; 13 | } 14 | 15 | &.condition { 16 | flex-grow: 0.7; 17 | } 18 | 19 | &.status { 20 | flex-grow: 1.5; 21 | } 22 | 23 | &.age { 24 | flex-grow: 0.3; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/renderer/components/details/image/image-update-automation-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .details { 4 | .title { 5 | margin-top: vars.$margin * 2; 6 | margin-bottom: vars.$margin; 7 | 8 | span { 9 | margin-left: vars.$gap; 10 | font-weight: bold; 11 | } 12 | } 13 | } 14 | 15 | .editor { 16 | resize: none; 17 | overflow: hidden; 18 | border: 1px solid var(--borderFaintColor); 19 | border-radius: 4px; 20 | } 21 | -------------------------------------------------------------------------------- /src/renderer/pages/kustomize/kustomizations.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.source { 4 | flex-grow: 1; 5 | } 6 | 7 | &.revision { 8 | flex-grow: 1.3; 9 | } 10 | 11 | &.resumed { 12 | flex-grow: 0.5; 13 | } 14 | 15 | &.condition { 16 | flex-grow: 0.7; 17 | } 18 | 19 | &.status { 20 | flex-grow: 1.5; 21 | } 22 | 23 | &.age { 24 | flex-grow: 0.3; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/providers.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.type { 4 | flex-grow: 0.5; 5 | } 6 | 7 | &.channel { 8 | flex-grow: 0.7; 9 | } 10 | 11 | &.resumed { 12 | flex-grow: 0.5; 13 | } 14 | 15 | &.condition { 16 | flex-grow: 0.7; 17 | } 18 | 19 | &.status { 20 | flex-grow: 1.5; 21 | } 22 | 23 | &.age { 24 | flex-grow: 0.3; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/renderer/pages/image/imagepolicies.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.repository { 4 | flex-grow: 0.7; 5 | } 6 | 7 | &.latestTag { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.resumed { 12 | flex-grow: 0.5; 13 | } 14 | 15 | &.condition { 16 | flex-grow: 0.7; 17 | } 18 | 19 | &.status { 20 | flex-grow: 1.5; 21 | } 22 | 23 | &.age { 24 | flex-grow: 0.3; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/renderer/components/object-ref-tooltip.tsx: -------------------------------------------------------------------------------- 1 | import type { NamespacedObjectKindReference } from "../k8s/fluxcd/types"; 2 | 3 | interface ObjectRefTooltipProps { 4 | objectRef: NamespacedObjectKindReference; 5 | } 6 | 7 | export function ObjectRefTooltip({ objectRef }: ObjectRefTooltipProps) { 8 | return ( 9 | 10 | apiVersion: {objectRef.apiVersion} 11 |
12 | kind: {objectRef.kind} 13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/renderer/pages/controlplane/resourcesetinputproviders.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.type { 4 | flex-grow: 0.5; 5 | } 6 | 7 | &.url { 8 | flex-grow: 1.5; 9 | } 10 | 11 | &.enabled { 12 | flex-grow: 0.4; 13 | } 14 | 15 | &.condition { 16 | flex-grow: 0.7; 17 | } 18 | 19 | &.status { 20 | flex-grow: 1.5; 21 | } 22 | 23 | &.age { 24 | flex-grow: 0.3; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/flux-instance-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly title: "title"; 3 | readonly components: "components"; 4 | readonly component: "component"; 5 | readonly inventory: "inventory"; 6 | readonly kind: "kind"; 7 | readonly name: "name"; 8 | readonly namespace: "namespace"; 9 | readonly patch: "patch"; 10 | readonly sync: "sync"; 11 | readonly syncDetails: "syncDetails"; 12 | }; 13 | export = classNames; 14 | -------------------------------------------------------------------------------- /src/renderer/components/info-page.tsx: -------------------------------------------------------------------------------- 1 | import styles from "./info-page.module.scss"; 2 | import stylesInline from "./info-page.module.scss?inline"; 3 | 4 | export interface InfoPageProps { 5 | message?: string; 6 | } 7 | 8 | export function InfoPage({ message }: InfoPageProps) { 9 | return ( 10 | <> 11 | 12 |
13 |

{message}

14 |
15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/utils.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { NamespacedObjectKindReference } from "./types"; 6 | 7 | export function getRefUrl( 8 | ref: LocalObjectReference | NamespacedObjectKindReference, 9 | parentObject?: Renderer.K8sApi.KubeObject, 10 | ) { 11 | if (!ref) return; 12 | return Renderer.K8sApi.apiManager.lookupApiLink(ref, parentObject); 13 | } 14 | -------------------------------------------------------------------------------- /src/renderer/pages/controlplane/fluxreports.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly version: "version"; 5 | readonly failing: "failing"; 6 | readonly running: "running"; 7 | readonly suspended: "suspended"; 8 | readonly lastUpdated: "lastUpdated"; 9 | readonly enabled: "enabled"; 10 | readonly condition: "condition"; 11 | readonly status: "status"; 12 | readonly age: "age"; 13 | }; 14 | export = classNames; 15 | -------------------------------------------------------------------------------- /src/renderer/pages/source/helmcharts.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly page: "page"; 3 | readonly tableCell: "tableCell"; 4 | readonly revision: "revision"; 5 | readonly url: "url"; 6 | readonly chart: "chart"; 7 | readonly version: "version"; 8 | readonly sourceKind: "sourceKind"; 9 | readonly sourceName: "sourceName"; 10 | readonly resumed: "resumed"; 11 | readonly condition: "condition"; 12 | readonly status: "status"; 13 | readonly age: "age"; 14 | }; 15 | export = classNames; 16 | -------------------------------------------------------------------------------- /src/renderer/pages/source/buckets.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.revision { 4 | flex-grow: 1.3; 5 | } 6 | 7 | &.provider { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.bucket { 12 | flex-grow: 1.5; 13 | } 14 | 15 | &.resumed { 16 | flex-grow: 0.5; 17 | } 18 | 19 | &.condition { 20 | flex-grow: 0.7; 21 | } 22 | 23 | &.status { 24 | flex-grow: 1.5; 25 | } 26 | 27 | &.age { 28 | flex-grow: 0.3; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/renderer/pages/source/gitrepositories.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.revision { 4 | flex-grow: 1.3; 5 | } 6 | 7 | &.url { 8 | flex-grow: 1.5; 9 | } 10 | 11 | &.ref { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.resumed { 16 | flex-grow: 0.5; 17 | } 18 | 19 | &.condition { 20 | flex-grow: 0.7; 21 | } 22 | 23 | &.status { 24 | flex-grow: 1.5; 25 | } 26 | 27 | &.age { 28 | flex-grow: 0.3; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/renderer/pages/helm/helmreleases.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.source { 4 | flex-grow: 1; 5 | } 6 | 7 | &.resumed { 8 | flex-grow: 0.5; 9 | } 10 | 11 | &.chartVersion { 12 | flex-grow: 0.7; 13 | } 14 | 15 | &.appVersion { 16 | flex-grow: 0.7; 17 | } 18 | 19 | &.condition { 20 | flex-grow: 0.7; 21 | } 22 | 23 | &.status { 24 | flex-grow: 1.3; 25 | } 26 | 27 | &.age { 28 | flex-grow: 0.3; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/renderer/components/details/helm/helm-release-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .details { 4 | .title { 5 | margin-top: vars.$margin * 2; 6 | margin-bottom: vars.$margin; 7 | } 8 | } 9 | 10 | .editor { 11 | resize: none; 12 | overflow: hidden; 13 | border: 1px solid var(--borderFaintColor); 14 | border-radius: 4px; 15 | } 16 | 17 | .history { 18 | :global(.TableCell) { 19 | &.version { 20 | flex-grow: 0.5; 21 | } 22 | 23 | &.status { 24 | flex-grow: 0.8; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/renderer/components/details/kustomize/kustomization-details.module.scss.d.ts: -------------------------------------------------------------------------------- 1 | declare const classNames: { 2 | readonly details: "details"; 3 | readonly title: "title"; 4 | readonly editor: "editor"; 5 | readonly substitution: "substitution"; 6 | readonly tableCell: "tableCell"; 7 | readonly key: "key"; 8 | readonly value: "value"; 9 | readonly inventory: "inventory"; 10 | readonly kind: "kind"; 11 | readonly name: "name"; 12 | readonly namespace: "namespace"; 13 | readonly healthChecks: "healthChecks"; 14 | }; 15 | export = classNames; 16 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/flux-report-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .title { 4 | margin-top: vars.$margin * 2; 5 | margin-bottom: vars.$margin; 6 | } 7 | 8 | :global(.TableCell) { 9 | &.apiVersion { 10 | flex-grow: 1; 11 | } 12 | 13 | &.kind { 14 | flex-grow: 0.8; 15 | } 16 | 17 | &.running { 18 | flex-grow: 0.5; 19 | } 20 | 21 | &.failing { 22 | flex-grow: 0.5; 23 | } 24 | 25 | &.suspended { 26 | flex-grow: 0.5; 27 | } 28 | 29 | &.totalSize { 30 | flex-grow: 0.7; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/resource-set-input-provider-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .title { 4 | margin-top: vars.$margin * 2; 5 | margin-bottom: vars.$margin; 6 | font-weight: bold; 7 | } 8 | 9 | .schedules { 10 | .cron { 11 | min-width: 150px; 12 | } 13 | 14 | .timeZone { 15 | min-width: 100px; 16 | } 17 | 18 | .window { 19 | min-width: 80px; 20 | } 21 | } 22 | 23 | .exportedInputs { 24 | .index { 25 | min-width: 60px; 26 | } 27 | 28 | .content { 29 | min-width: 300px; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/trunk-check.yaml: -------------------------------------------------------------------------------- 1 | name: Trunk Check 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - "*" 10 | workflow_dispatch: {} 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | trunk: 17 | name: Trunk Check 18 | 19 | runs-on: ubuntu-22.04 20 | timeout-minutes: 15 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v6 25 | 26 | - name: Trunk Check 27 | uses: trunk-io/trunk-action@v1 28 | with: 29 | check-mode: all 30 | -------------------------------------------------------------------------------- /src/renderer/components/details/controlplane/flux-instance-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .title { 4 | margin-top: vars.$margin * 2; 5 | margin-bottom: vars.$margin; 6 | } 7 | 8 | .components { 9 | .component { 10 | margin-bottom: 1rem; 11 | padding: 0.5rem; 12 | border: 1px solid var(--borderFaintColor); 13 | border-radius: 4px; 14 | } 15 | } 16 | 17 | .inventory { 18 | .kind, 19 | .name, 20 | .namespace { 21 | min-width: 120px; 22 | } 23 | } 24 | 25 | .patch { 26 | margin-bottom: 1rem; 27 | padding: 0.5rem; 28 | } 29 | 30 | .sync { 31 | .syncDetails { 32 | margin-top: 0.5rem; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/renderer/pages/controlplane/fluxreports.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.version { 4 | flex-grow: 0.5; 5 | } 6 | 7 | &.failing { 8 | flex-grow: 0.3; 9 | } 10 | 11 | &.running { 12 | flex-grow: 0.3; 13 | } 14 | 15 | &.suspended { 16 | flex-grow: 0.3; 17 | } 18 | 19 | &.lastUpdated { 20 | flex-grow: 0.4; 21 | } 22 | 23 | &.enabled { 24 | flex-grow: 0.4; 25 | } 26 | 27 | &.condition { 28 | flex-grow: 0.7; 29 | } 30 | 31 | &.status { 32 | flex-grow: 1.5; 33 | } 34 | 35 | &.age { 36 | flex-grow: 0.3; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /knip.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/knip@5/schema-jsonc.json", 3 | 4 | "entry": ["out/{main,renderer}/index.js!", "src/main/index.ts", "src/renderer/index.tsx"], 5 | "project": ["*.{js,mjs,ts}", "out/**/*.js!", "src/**/*.{ts,tsx}"], 6 | 7 | "ignoreBinaries": ["build:.*", "electron-rebuild"], 8 | "ignoreDependencies": [ 9 | // used as vite plugin 10 | "@babel/plugin-proposal-decorators", 11 | // part of the extensions API 12 | "@types/chart.js" 13 | ], 14 | 15 | "typescript": { 16 | "config": ["tsconfig.json"] 17 | }, 18 | "vite": { 19 | "config": ["electron.vite.config.js"] 20 | }, 21 | 22 | "exclude": ["exports"] 23 | } 24 | -------------------------------------------------------------------------------- /.github/workflows/cleanup-cache.yaml: -------------------------------------------------------------------------------- 1 | name: Cleanup cache 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - closed 7 | 8 | permissions: 9 | actions: write 10 | contents: write 11 | pull-requests: read 12 | 13 | jobs: 14 | cleanup-cache: 15 | name: cleanup cache 16 | 17 | runs-on: ubuntu-24.04 18 | 19 | steps: 20 | - name: Cleanup cache 21 | run: gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id' | xargs -n1 -r -t gh cache delete 22 | continue-on-error: true 23 | env: 24 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | GH_REPO: ${{ github.repository }} 26 | BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge 27 | -------------------------------------------------------------------------------- /src/renderer/pages/source/helmcharts.module.scss: -------------------------------------------------------------------------------- 1 | .page { 2 | :global(.TableCell) { 3 | &.revision { 4 | flex-grow: 1.3; 5 | } 6 | 7 | &.url { 8 | flex-grow: 1.5; 9 | } 10 | 11 | &.chart { 12 | flex-grow: 0.5; 13 | } 14 | 15 | &.version { 16 | flex-grow: 0.5; 17 | } 18 | 19 | &.sourceKind { 20 | flex-grow: 0.5; 21 | } 22 | 23 | &.sourceName { 24 | flex-grow: 0.5; 25 | } 26 | 27 | &.resumed { 28 | flex-grow: 0.6; 29 | } 30 | 31 | &.condition { 32 | flex-grow: 0.7; 33 | } 34 | 35 | &.status { 36 | flex-grow: 1.5; 37 | } 38 | 39 | &.age { 40 | flex-grow: 0.3; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/renderer/components/humanizeBytes.tsx: -------------------------------------------------------------------------------- 1 | import { Common, Renderer } from "@freelensapp/extensions"; 2 | 3 | const { bytesToUnits, unitsToBytes } = Common.Util; 4 | 5 | const { 6 | Component: { WithTooltip }, 7 | } = Renderer; 8 | 9 | interface HumanizeBytesProps { 10 | value?: string | number | null; 11 | } 12 | 13 | export function HumanizeBytes({ value }: HumanizeBytesProps) { 14 | if (value === undefined || value === null) return null; 15 | const stringValue = typeof value === "number" ? value.toString() : value; 16 | const newValue = bytesToUnits(unitsToBytes(stringValue)); 17 | if (newValue !== "N/A") { 18 | const tooltip = stringValue; 19 | const displayValue = newValue; 20 | return {displayValue}; 21 | } 22 | return <>{stringValue}; 23 | } 24 | -------------------------------------------------------------------------------- /src/renderer/components/link-to-namespace.tsx: -------------------------------------------------------------------------------- 1 | import { Common, Renderer } from "@freelensapp/extensions"; 2 | import { getMaybeDetailsUrl } from "../utils"; 3 | 4 | const { 5 | Util: { stopPropagation }, 6 | } = Common; 7 | 8 | const { 9 | Component: { MaybeLink, WithTooltip }, 10 | K8sApi: { namespacesApi }, 11 | } = Renderer; 12 | 13 | interface LinkToNamespaceProps { 14 | namespace?: string; 15 | } 16 | 17 | export function LinkToNamespace({ namespace }: LinkToNamespaceProps) { 18 | if (!namespace) return null; 19 | return ( 20 | 29 | {namespace} 30 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /src/renderer/components/duration-absolute.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Freelens Authors. All rights reserved. 3 | * Copyright (c) OpenLens Authors. All rights reserved. 4 | * Licensed under MIT License. See LICENSE in root directory for more information. 5 | */ 6 | 7 | import { Renderer } from "@freelensapp/extensions"; 8 | 9 | const { 10 | Component: { LocaleDate, ReactiveDuration }, 11 | } = Renderer; 12 | 13 | export interface DurationAbsoluteTimestampProps { 14 | timestamp: string | undefined; 15 | } 16 | 17 | export const DurationAbsoluteTimestamp = ({ timestamp }: DurationAbsoluteTimestampProps) => { 18 | if (!timestamp) { 19 | return <>{""}; 20 | } 21 | 22 | return ( 23 | <> 24 | 25 | {" ago "} 26 | ( 27 | ) 28 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /src/renderer/components/link-to-secret.tsx: -------------------------------------------------------------------------------- 1 | import { Common, Renderer } from "@freelensapp/extensions"; 2 | import { getMaybeDetailsUrl } from "../utils"; 3 | 4 | const { 5 | Util: { stopPropagation }, 6 | } = Common; 7 | 8 | const { 9 | Component: { MaybeLink, WithTooltip }, 10 | K8sApi: { secretsApi }, 11 | } = Renderer; 12 | 13 | interface LinkToSecretProps { 14 | name?: string; 15 | namespace?: string; 16 | } 17 | 18 | export function LinkToSecret({ name, namespace }: LinkToSecretProps) { 19 | if (!name || !namespace) return null; 20 | return ( 21 | 31 | {name} 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /src/renderer/pages/overview.module.scss: -------------------------------------------------------------------------------- 1 | @use "../vars"; 2 | 3 | .overviewStatuses { 4 | background: var(--contentColor); 5 | } 6 | 7 | .statuses { 8 | display: grid; 9 | grid-template-columns: repeat(auto-fit, 120px); 10 | justify-content: space-evenly; 11 | grid-gap: 8px; 12 | padding: 16px; 13 | } 14 | 15 | .chartColumn { 16 | align-self: end; 17 | } 18 | 19 | .chartTitle { 20 | color: var(--colorInfo); 21 | } 22 | 23 | .chartItem { 24 | margin-bottom: 16px; 25 | } 26 | 27 | .fluxContent { 28 | --flex-gap: #{vars.$padding * 2}; 29 | min-height: 100%; 30 | 31 | height: 100%; 32 | overflow-y: auto; 33 | 34 | header { 35 | background: var(--contentColor); 36 | position: relative; 37 | padding: vars.$padding * 2; 38 | 39 | text-align: center; 40 | padding-bottom: 3em; 41 | 42 | h5 { 43 | color: var(--textColorPrimary); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/renderer/components/link-to-storage-class.tsx: -------------------------------------------------------------------------------- 1 | import { Common, Renderer } from "@freelensapp/extensions"; 2 | import { getMaybeDetailsUrl } from "../utils"; 3 | 4 | const { 5 | Util: { stopPropagation }, 6 | } = Common; 7 | 8 | const { 9 | Component: { MaybeLink, WithTooltip }, 10 | K8sApi: { storageClassApi }, 11 | } = Renderer; 12 | 13 | interface LinkToStorageClassProps { 14 | storageClassName?: string; 15 | } 16 | 17 | export function LinkToStorageClass({ storageClassName }: LinkToStorageClassProps) { 18 | if (!storageClassName) return null; 19 | return ( 20 | 29 | {storageClassName} 30 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/osv-scanner.yaml: -------------------------------------------------------------------------------- 1 | name: OSV-Scanner 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - "*" 10 | schedule: 11 | - cron: 38 20 * * 1 12 | workflow_dispatch: {} 13 | 14 | permissions: 15 | actions: read 16 | contents: read 17 | security-events: write 18 | 19 | jobs: 20 | scan-scheduled: 21 | name: OSV scan scheduled 22 | 23 | if: github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' 24 | uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@v2.3.0 25 | with: 26 | fail-on-vuln: false 27 | 28 | scan-pr: 29 | name: OSV scan PR 30 | 31 | if: github.event_name == 'pull_request' || github.event_name == 'merge_group' 32 | uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@v2.3.0 33 | with: 34 | fail-on-vuln: false 35 | -------------------------------------------------------------------------------- /src/renderer/components/link-to-service-account.tsx: -------------------------------------------------------------------------------- 1 | import { Common, Renderer } from "@freelensapp/extensions"; 2 | import { getMaybeDetailsUrl } from "../utils"; 3 | 4 | const { 5 | Util: { stopPropagation }, 6 | } = Common; 7 | 8 | const { 9 | Component: { MaybeLink, WithTooltip }, 10 | K8sApi: { serviceAccountsApi }, 11 | } = Renderer; 12 | 13 | interface LinkToServiceAccountProps { 14 | name?: string; 15 | namespace?: string; 16 | } 17 | 18 | export function LinkToServiceAccount({ name, namespace }: LinkToServiceAccountProps) { 19 | if (!name || !namespace) return null; 20 | return ( 21 | 31 | {name} 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /src/renderer/pages/available-version.module.scss: -------------------------------------------------------------------------------- 1 | @use "../vars"; 2 | 3 | .unavailablePage { 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | width: 100%; 8 | height: 100%; 9 | } 10 | 11 | .unavailableContent { 12 | display: flex; 13 | flex-direction: column; 14 | align-items: center; 15 | text-align: center; 16 | max-width: 500px; 17 | padding: vars.$padding * 3; 18 | } 19 | 20 | .unavailableTitle { 21 | font-size: 1.5em; 22 | font-weight: 500; 23 | margin-bottom: vars.$margin * 3; 24 | color: var(--textColorPrimary); 25 | } 26 | 27 | .unavailableMessage { 28 | color: var(--textColorSecondary); 29 | margin-bottom: vars.$margin * 3; 30 | line-height: 1.5; 31 | } 32 | 33 | .unavailableDetails { 34 | font-size: 0.9em; 35 | color: var(--textColorTertiary); 36 | line-height: 1.4; 37 | 38 | code { 39 | background-color: var(--contentColor); 40 | padding: 2px 6px; 41 | border-radius: 3px; 42 | font-family: monospace; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/renderer/components/details/kustomize/kustomization-details.module.scss: -------------------------------------------------------------------------------- 1 | @use "../../../vars"; 2 | 3 | .details { 4 | .title { 5 | margin-top: vars.$margin * 2; 6 | margin-bottom: vars.$margin; 7 | } 8 | } 9 | 10 | .editor { 11 | resize: none; 12 | overflow: hidden; 13 | border: 1px solid var(--borderFaintColor); 14 | border-radius: 4px; 15 | } 16 | 17 | .substitution { 18 | :global(.TableCell) { 19 | &.key { 20 | flex-grow: 0.7; 21 | } 22 | 23 | &.value { 24 | flex-grow: 1.3; 25 | } 26 | } 27 | } 28 | 29 | .inventory { 30 | :global(.TableCell) { 31 | &.kind { 32 | flex-grow: 0.5; 33 | } 34 | 35 | &.name { 36 | flex-grow: 0.7; 37 | } 38 | 39 | &.namespace { 40 | flex-grow: 0.5; 41 | } 42 | } 43 | } 44 | 45 | .healthChecks { 46 | :global(.TableCell) { 47 | &.kind { 48 | flex-grow: 0.5; 49 | } 50 | 51 | &.name { 52 | flex-grow: 0.7; 53 | } 54 | 55 | &.namespace { 56 | flex-grow: 0.5; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/renderer/components/link-to-object.tsx: -------------------------------------------------------------------------------- 1 | import { Common, Renderer } from "@freelensapp/extensions"; 2 | import { getRefUrl } from "../k8s/fluxcd/utils"; 3 | import { getMaybeDetailsUrl } from "../utils"; 4 | 5 | import type { KubeObject, LocalObjectReference } from "@freelensapp/kube-object"; 6 | 7 | import type { NamespacedObjectKindReference } from "../k8s/fluxcd/types"; 8 | 9 | const { 10 | Util: { stopPropagation }, 11 | } = Common; 12 | 13 | const { 14 | Component: { MaybeLink, WithTooltip }, 15 | } = Renderer; 16 | 17 | interface LinkToObjectProps { 18 | objectRef?: LocalObjectReference | NamespacedObjectKindReference; 19 | object?: KubeObject; 20 | tooltip?: string | React.ReactNode; 21 | content?: string | React.ReactNode; 22 | } 23 | 24 | export function LinkToObject({ objectRef, object, tooltip, content }: LinkToObjectProps) { 25 | if (!objectRef || !object) return null; 26 | return ( 27 | 28 | {content ?? objectRef?.name} 29 | 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /src/renderer/components/link-to-resource-set-input-provider.tsx: -------------------------------------------------------------------------------- 1 | import { Common, Renderer } from "@freelensapp/extensions"; 2 | import { ResourceSetInputProvider } from "../k8s/fluxcd/controlplane/resourcesetinputprovider-v1"; 3 | import { getMaybeDetailsUrl } from "../utils"; 4 | 5 | const { 6 | Util: { stopPropagation }, 7 | } = Common; 8 | 9 | const { 10 | Component: { MaybeLink, WithTooltip }, 11 | } = Renderer; 12 | 13 | interface LinkToResourceSetInputProviderProps { 14 | name?: string; 15 | namespace?: string; 16 | } 17 | 18 | export function LinkToResourceSetInputProvider({ name, namespace }: LinkToResourceSetInputProviderProps) { 19 | if (!name || !namespace) return null; 20 | 21 | // try { 22 | const resourceSetInputProviderApi = ResourceSetInputProvider.getApi(); 23 | 24 | return ( 25 | 35 | {name} 36 | 37 | ); 38 | // } catch { 39 | // return null; 40 | // } 41 | } 42 | -------------------------------------------------------------------------------- /src/renderer/components/yaml-dump.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import yaml from "js-yaml"; 3 | import { observer } from "mobx-react"; 4 | import { defaultYamlDumpOptions, getHeight } from "../utils"; 5 | import styles from "./yaml-dump.module.scss"; 6 | import stylesInline from "./yaml-dump.module.scss?inline"; 7 | 8 | const { 9 | Component: { MonacoEditor }, 10 | } = Renderer; 11 | 12 | export function yamlDump(data: any): string { 13 | return yaml.dump(data, defaultYamlDumpOptions).replace(/[\r\n]+$/, ""); 14 | } 15 | 16 | export interface YamlDumpProps { 17 | data?: any; 18 | } 19 | 20 | export const YamlDump: React.FC = observer((props) => { 21 | const { data } = props; 22 | 23 | const dataDump = yaml.dump(data, defaultYamlDumpOptions).replace(/[\r\n]+$/, ""); 24 | 25 | return ( 26 | <> 27 | 28 | 42 | 43 | ); 44 | }); 45 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/alert-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 6 | 7 | export interface AlertSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | providerRef: LocalObjectReference; 9 | eventSeverity?: "info" | "error"; 10 | eventSources?: NamespacedObjectKindReference[]; 11 | } 12 | 13 | export interface AlertStatus extends FluxCDKubeObjectStatus {} 14 | 15 | export class Alert extends Renderer.K8sApi.LensExtensionKubeObject< 16 | Renderer.K8sApi.KubeObjectMetadata, 17 | AlertStatus, 18 | AlertSpec 19 | > { 20 | static readonly kind = "Alert"; 21 | static readonly namespaced = true; 22 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta1/alerts"; 23 | 24 | static readonly crd = { 25 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta1"], 26 | plural: "alerts", 27 | singular: "alert", 28 | shortNames: [], 29 | title: "Alerts", 30 | }; 31 | } 32 | 33 | export class AlertApi extends Renderer.K8sApi.KubeApi {} 34 | export class AlertStore extends Renderer.K8sApi.KubeObjectStore {} 35 | -------------------------------------------------------------------------------- /src/renderer/utils.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import crypto from "crypto"; 3 | 4 | import type { DumpOptions } from "js-yaml"; 5 | 6 | const { 7 | Navigation: { getDetailsUrl }, 8 | } = Renderer; 9 | 10 | export function checksum(data: any): string { 11 | return crypto.createHash("sha256").update(JSON.stringify(data)).digest("hex").substring(0, 16); 12 | } 13 | 14 | export function getMaybeDetailsUrl(url?: string): string { 15 | if (url) { 16 | return getDetailsUrl(url); 17 | } else { 18 | return ""; 19 | } 20 | } 21 | 22 | export function getHeight(data?: string): number { 23 | const lineHeight = 18; 24 | if (!data) return lineHeight; 25 | 26 | const lines = data.split("\n").length; 27 | if (lines < 5) return 5 * lineHeight; 28 | if (lines > 20) return 20 * lineHeight; 29 | return lines * lineHeight; 30 | } 31 | 32 | export const defaultYamlDumpOptions: DumpOptions = { 33 | noArrayIndent: true, 34 | noCompatMode: true, 35 | noRefs: true, 36 | quotingType: '"', 37 | sortKeys: true, 38 | }; 39 | 40 | export function createEnumFromKeys>(obj: T): Record { 41 | return Object.keys(obj).reduce( 42 | (acc, key) => { 43 | acc[key as keyof T] = key as keyof T; 44 | return acc; 45 | }, 46 | {} as Record, 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /src/renderer/components/spec-access-from.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import styles from "./spec-access-from.module.scss"; 4 | import stylesInline from "./spec-access-from.module.scss?inline"; 5 | 6 | import type { AccessFrom } from "../k8s/fluxcd/types"; 7 | 8 | const { 9 | Component: { Badge, DrawerItem }, 10 | } = Renderer; 11 | 12 | export interface SpecAccessFromProps { 13 | accessFrom?: AccessFrom; 14 | } 15 | 16 | export const SpecAccessFrom: React.FC = observer((props) => { 17 | const { accessFrom } = props; 18 | 19 | if (!accessFrom) return null; 20 | 21 | return ( 22 | <> 23 | 24 |
25 | 26 | {accessFrom?.namespaceSelectors.map((namespaceSelector) => ( 27 |
28 |
Match Labels:
29 |
30 | {Object.entries(namespaceSelector.matchLabels ?? {}).map(([key, value], index) => ( 31 | 32 | ))} 33 |
34 |
35 | ))} 36 |
37 |
38 | 39 | ); 40 | }); 41 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/alert-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 6 | 7 | export interface AlertSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | providerRef: LocalObjectReference; 9 | eventSeverity?: "info" | "error"; 10 | eventSources?: NamespacedObjectKindReference[]; 11 | eventMetadata?: Record; 12 | exclusionList?: string[]; 13 | summary?: string; 14 | suspend?: boolean; 15 | } 16 | 17 | export interface AlertStatus extends FluxCDKubeObjectStatus {} 18 | 19 | export class Alert extends Renderer.K8sApi.LensExtensionKubeObject< 20 | Renderer.K8sApi.KubeObjectMetadata, 21 | AlertStatus, 22 | AlertSpec 23 | > { 24 | static readonly kind = "Alert"; 25 | static readonly namespaced = true; 26 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta2/alerts"; 27 | 28 | static readonly crd = { 29 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta2"], 30 | plural: "alerts", 31 | singular: "alert", 32 | shortNames: [], 33 | title: "Alerts", 34 | }; 35 | } 36 | 37 | export class AlertApi extends Renderer.K8sApi.KubeApi {} 38 | export class AlertStore extends Renderer.K8sApi.KubeObjectStore {} 39 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/alert-v1beta3.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 6 | 7 | export interface AlertSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | providerRef: LocalObjectReference; 9 | eventSeverity?: "info" | "error"; 10 | eventSources?: NamespacedObjectKindReference[]; 11 | eventMetadata?: Record; 12 | exclusionList?: string[]; 13 | summary?: string; 14 | suspend?: boolean; 15 | } 16 | 17 | export interface AlertStatus extends FluxCDKubeObjectStatus {} 18 | 19 | export class Alert extends Renderer.K8sApi.LensExtensionKubeObject< 20 | Renderer.K8sApi.KubeObjectMetadata, 21 | AlertStatus, 22 | AlertSpec 23 | > { 24 | static readonly kind = "Alert"; 25 | static readonly namespaced = true; 26 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta3/alerts"; 27 | 28 | static readonly crd = { 29 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta3"], 30 | plural: "alerts", 31 | singular: "alert", 32 | shortNames: [], 33 | title: "Alerts", 34 | }; 35 | } 36 | 37 | export class AlertApi extends Renderer.K8sApi.KubeApi {} 38 | export class AlertStore extends Renderer.K8sApi.KubeObjectStore {} 39 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/bucket-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface BucketSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | provider?: "generic" | "aws" | "azure" | "gcp"; 9 | bucketName: string; 10 | endpoint: string; 11 | insecure?: boolean; 12 | region?: string; 13 | secretRef?: LocalObjectReference; 14 | interval: string; 15 | timeout?: string; 16 | suspend?: boolean; 17 | } 18 | 19 | export interface BucketStatus extends FluxCDKubeObjectStatus { 20 | url?: string; 21 | artifact?: Artifact; 22 | } 23 | 24 | export class Bucket extends Renderer.K8sApi.LensExtensionKubeObject< 25 | Renderer.K8sApi.KubeObjectMetadata, 26 | BucketStatus, 27 | BucketSpec 28 | > { 29 | static readonly kind = "Bucket"; 30 | static readonly namespaced = true; 31 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1/buckets"; 32 | 33 | static readonly crd = { 34 | apiVersions: ["source.toolkit.fluxcd.io/v1"], 35 | plural: "buckets", 36 | singular: "bucket", 37 | shortNames: [], 38 | title: "Buckets", 39 | }; 40 | } 41 | 42 | export class BucketApi extends Renderer.K8sApi.KubeApi {} 43 | export class BucketStore extends Renderer.K8sApi.KubeObjectStore {} 44 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/bucket-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface BucketSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | provider?: "generic" | "aws" | "azure" | "gcp"; 9 | bucketName: string; 10 | endpoint: string; 11 | insecure?: boolean; 12 | region?: string; 13 | secretRef?: LocalObjectReference; 14 | interval: string; 15 | timeout?: string; 16 | suspend?: boolean; 17 | } 18 | 19 | export interface BucketStatus extends FluxCDKubeObjectStatus { 20 | url?: string; 21 | artifact?: Artifact; 22 | } 23 | 24 | export class Bucket extends Renderer.K8sApi.LensExtensionKubeObject< 25 | Renderer.K8sApi.KubeObjectMetadata, 26 | BucketStatus, 27 | BucketSpec 28 | > { 29 | static readonly kind = "Bucket"; 30 | static readonly namespaced = true; 31 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta1/buckets"; 32 | 33 | static readonly crd = { 34 | apiVersions: ["source.toolkit.fluxcd.io/v1beta1"], 35 | plural: "buckets", 36 | singular: "bucket", 37 | shortNames: [], 38 | title: "Buckets", 39 | }; 40 | } 41 | 42 | export class BucketApi extends Renderer.K8sApi.KubeApi {} 43 | export class BucketStore extends Renderer.K8sApi.KubeObjectStore {} 44 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/bucket-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface BucketSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | provider?: "generic" | "aws" | "azure" | "gcp"; 9 | bucketName: string; 10 | endpoint: string; 11 | insecure?: boolean; 12 | region?: string; 13 | secretRef?: LocalObjectReference; 14 | interval: string; 15 | timeout?: string; 16 | suspend?: boolean; 17 | } 18 | 19 | export interface BucketStatus extends FluxCDKubeObjectStatus { 20 | url?: string; 21 | artifact?: Artifact; 22 | } 23 | 24 | export class Bucket extends Renderer.K8sApi.LensExtensionKubeObject< 25 | Renderer.K8sApi.KubeObjectMetadata, 26 | BucketStatus, 27 | BucketSpec 28 | > { 29 | static readonly kind = "Bucket"; 30 | static readonly namespaced = true; 31 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta2/buckets"; 32 | 33 | static readonly crd = { 34 | apiVersions: ["source.toolkit.fluxcd.io/v1beta2"], 35 | plural: "buckets", 36 | singular: "bucket", 37 | shortNames: [], 38 | title: "Buckets", 39 | }; 40 | } 41 | 42 | export class BucketApi extends Renderer.K8sApi.KubeApi {} 43 | export class BucketStore extends Renderer.K8sApi.KubeObjectStore {} 44 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/helm-repository-details-v1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { HelmRepository } from "../../../k8s/fluxcd/source/helmrepository-v1"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const HelmRepositoryDetails: React.FC> = observer( 13 | (props) => { 14 | const { object } = props; 15 | const namespace = object.getNs(); 16 | 17 | return ( 18 |
19 | 20 | 21 | 22 | {object.spec.interval} 23 | {object.spec.timeout ?? "60s"} 24 | 27 | 30 | 31 | 32 |
33 | ); 34 | }, 35 | ); 36 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/helm-repository-details-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { HelmRepository } from "../../../k8s/fluxcd/source/helmrepository-v1beta1"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const HelmRepositoryDetails: React.FC> = observer( 13 | (props) => { 14 | const { object } = props; 15 | const namespace = object.getNs(); 16 | 17 | return ( 18 |
19 | 20 | 21 | 22 | {object.spec.interval} 23 | {object.spec.timeout ?? "60s"} 24 | 27 | 30 | 31 | 32 |
33 | ); 34 | }, 35 | ); 36 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/helm-repository-details-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { HelmRepository } from "../../../k8s/fluxcd/source/helmrepository-v1beta2"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const HelmRepositoryDetails: React.FC> = observer( 13 | (props) => { 14 | const { object } = props; 15 | const namespace = object.getNs(); 16 | 17 | return ( 18 |
19 | 20 | 21 | 22 | {object.spec.interval} 23 | {object.spec.timeout ?? "60s"} 24 | 27 | 30 | 31 | 32 |
33 | ); 34 | }, 35 | ); 36 | -------------------------------------------------------------------------------- /src/renderer/components/details/notification/alert-details-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Alert } from "../../../k8s/fluxcd/notification/alert-v1beta1"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | 7 | const { 8 | Component: { Badge, BadgeBoolean, DrawerItem }, 9 | } = Renderer; 10 | 11 | export const AlertDetails: React.FC> = observer((props) => { 12 | const { object } = props; 13 | 14 | return ( 15 |
16 | 17 | 18 | 19 | {object.spec.eventSeverity} 20 | 21 | {object.spec.eventSources?.map((eventSource) => { 22 | const badge = ; 23 | return ( 24 | 25 | {eventSource.name === "*" ? ( 26 | badge 27 | ) : ( 28 | 29 | )} 30 | 31 | ); 32 | })} 33 | 34 | 35 | 36 | 37 |
38 | ); 39 | }); 40 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/receiver-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 6 | 7 | export interface ReceiverSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | type: 9 | | "generic" 10 | | "generic-hmac" 11 | | "github" 12 | | "gitlab" 13 | | "bitbucket" 14 | | "harbor" 15 | | "dockerhub" 16 | | "quay" 17 | | "gcr" 18 | | "nexus" 19 | | "acr"; 20 | events: string[]; 21 | resources: NamespacedObjectKindReference[]; 22 | secretRef?: LocalObjectReference; 23 | suspend?: boolean; 24 | } 25 | 26 | export interface ReceiverStatus extends FluxCDKubeObjectStatus { 27 | url?: string; 28 | } 29 | 30 | export class Receiver extends Renderer.K8sApi.LensExtensionKubeObject< 31 | Renderer.K8sApi.KubeObjectMetadata, 32 | ReceiverStatus, 33 | ReceiverSpec 34 | > { 35 | static readonly kind = "Receiver"; 36 | static readonly namespaced = true; 37 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1/receivers"; 38 | 39 | static readonly crd = { 40 | apiVersions: ["notification.toolkit.fluxcd.io/v1"], 41 | plural: "receivers", 42 | singular: "receiver", 43 | shortNames: [], 44 | title: "Receivers", 45 | }; 46 | } 47 | 48 | export class ReceiverApi extends Renderer.K8sApi.KubeApi {} 49 | export class ReceiverStore extends Renderer.K8sApi.KubeObjectStore {} 50 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/receiver-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 6 | 7 | export interface ReceiverSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | type: 9 | | "generic" 10 | | "generic-hmac" 11 | | "github" 12 | | "gitlab" 13 | | "bitbucket" 14 | | "harbor" 15 | | "dockerhub" 16 | | "quay" 17 | | "gcr" 18 | | "nexus" 19 | | "acr"; 20 | events: string[]; 21 | resources: NamespacedObjectKindReference[]; 22 | secretRef?: LocalObjectReference; 23 | suspend?: boolean; 24 | } 25 | 26 | export interface ReceiverStatus extends FluxCDKubeObjectStatus { 27 | url?: string; 28 | } 29 | 30 | export class Receiver extends Renderer.K8sApi.LensExtensionKubeObject< 31 | Renderer.K8sApi.KubeObjectMetadata, 32 | ReceiverStatus, 33 | ReceiverSpec 34 | > { 35 | static readonly kind = "Receiver"; 36 | static readonly namespaced = true; 37 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta1/receivers"; 38 | 39 | static readonly crd = { 40 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta1"], 41 | plural: "receivers", 42 | singular: "receiver", 43 | shortNames: [], 44 | title: "Receivers", 45 | }; 46 | } 47 | 48 | export class ReceiverApi extends Renderer.K8sApi.KubeApi {} 49 | export class ReceiverStore extends Renderer.K8sApi.KubeObjectStore {} 50 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/receiver-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 6 | 7 | export interface ReceiverSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | type: 9 | | "generic" 10 | | "generic-hmac" 11 | | "github" 12 | | "gitlab" 13 | | "bitbucket" 14 | | "harbor" 15 | | "dockerhub" 16 | | "quay" 17 | | "gcr" 18 | | "nexus" 19 | | "acr"; 20 | events: string[]; 21 | resources: NamespacedObjectKindReference[]; 22 | secretRef?: LocalObjectReference; 23 | suspend?: boolean; 24 | } 25 | 26 | export interface ReceiverStatus extends FluxCDKubeObjectStatus { 27 | url?: string; 28 | } 29 | 30 | export class Receiver extends Renderer.K8sApi.LensExtensionKubeObject< 31 | Renderer.K8sApi.KubeObjectMetadata, 32 | ReceiverStatus, 33 | ReceiverSpec 34 | > { 35 | static readonly kind = "Receiver"; 36 | static readonly namespaced = true; 37 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta2/receivers"; 38 | 39 | static readonly crd = { 40 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta2"], 41 | plural: "receivers", 42 | singular: "receiver", 43 | shortNames: [], 44 | title: "Receivers", 45 | }; 46 | } 47 | 48 | export class ReceiverApi extends Renderer.K8sApi.KubeApi {} 49 | export class ReceiverStore extends Renderer.K8sApi.KubeObjectStore {} 50 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/receiver-v1beta3.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 6 | 7 | export interface ReceiverSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | type: 9 | | "generic" 10 | | "generic-hmac" 11 | | "github" 12 | | "gitlab" 13 | | "bitbucket" 14 | | "harbor" 15 | | "dockerhub" 16 | | "quay" 17 | | "gcr" 18 | | "nexus" 19 | | "acr"; 20 | events: string[]; 21 | resources: NamespacedObjectKindReference[]; 22 | secretRef?: LocalObjectReference; 23 | suspend?: boolean; 24 | } 25 | 26 | export interface ReceiverStatus extends FluxCDKubeObjectStatus { 27 | url?: string; 28 | } 29 | 30 | export class Receiver extends Renderer.K8sApi.LensExtensionKubeObject< 31 | Renderer.K8sApi.KubeObjectMetadata, 32 | ReceiverStatus, 33 | ReceiverSpec 34 | > { 35 | static readonly kind = "Receiver"; 36 | static readonly namespaced = true; 37 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta3/receivers"; 38 | 39 | static readonly crd = { 40 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta3"], 41 | plural: "receivers", 42 | singular: "receiver", 43 | shortNames: [], 44 | title: "Receivers", 45 | }; 46 | } 47 | 48 | export class ReceiverApi extends Renderer.K8sApi.KubeApi {} 49 | export class ReceiverStore extends Renderer.K8sApi.KubeObjectStore {} 50 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/helmchart-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 4 | 5 | export interface LocalHelmChartSourceReference { 6 | apiVersion?: string; 7 | kind: "HelmRepository" | "HelmChart" | "Bucket"; 8 | name: string; 9 | } 10 | 11 | export interface HelmChartSpec extends FluxCDKubeObjectSpecWithSuspend { 12 | chart: string; 13 | version?: string; 14 | sourceRef: LocalHelmChartSourceReference; 15 | interval: string; 16 | reconcileStrategy?: "ChartVersion" | "Revision"; 17 | valuesFiles?: string[]; 18 | valuesFile?: string; 19 | suspend?: boolean; 20 | accessFrom?: AccessFrom; 21 | } 22 | 23 | export interface HelmChartStatus extends FluxCDKubeObjectStatus { 24 | url?: string; 25 | artifact?: Artifact; 26 | } 27 | 28 | export class HelmChart extends Renderer.K8sApi.LensExtensionKubeObject< 29 | Renderer.K8sApi.KubeObjectMetadata, 30 | HelmChartStatus, 31 | HelmChartSpec 32 | > { 33 | static readonly kind = "HelmChart"; 34 | static readonly namespaced = true; 35 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1/helmrepositories"; 36 | 37 | static readonly crd = { 38 | apiVersions: ["source.toolkit.fluxcd.io/v1"], 39 | plural: "helmcharts", 40 | singular: "helmchart", 41 | shortNames: ["hc"], 42 | title: "Helm Charts", 43 | }; 44 | } 45 | 46 | export class HelmChartApi extends Renderer.K8sApi.KubeApi {} 47 | export class HelmChartStore extends Renderer.K8sApi.KubeObjectStore {} 48 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/helmchart-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 4 | 5 | export interface LocalHelmChartSourceReference { 6 | apiVersion?: string; 7 | kind: "HelmRepository" | "HelmChart" | "Bucket"; 8 | name: string; 9 | } 10 | 11 | export interface HelmChartSpec extends FluxCDKubeObjectSpecWithSuspend { 12 | chart: string; 13 | version?: string; 14 | sourceRef: LocalHelmChartSourceReference; 15 | interval: string; 16 | reconcileStrategy?: "ChartVersion" | "Revision"; 17 | valuesFiles?: string[]; 18 | valuesFile?: string; 19 | suspend?: boolean; 20 | accessFrom?: AccessFrom; 21 | } 22 | 23 | export interface HelmChartStatus extends FluxCDKubeObjectStatus { 24 | url?: string; 25 | artifact?: Artifact; 26 | } 27 | 28 | export class HelmChart extends Renderer.K8sApi.LensExtensionKubeObject< 29 | Renderer.K8sApi.KubeObjectMetadata, 30 | HelmChartStatus, 31 | HelmChartSpec 32 | > { 33 | static readonly kind = "HelmChart"; 34 | static readonly namespaced = true; 35 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta1/helmrepositories"; 36 | 37 | static readonly crd = { 38 | apiVersions: ["source.toolkit.fluxcd.io/v1beta1"], 39 | plural: "helmcharts", 40 | singular: "helmchart", 41 | shortNames: ["hc"], 42 | title: "Helm Charts", 43 | }; 44 | } 45 | 46 | export class HelmChartApi extends Renderer.K8sApi.KubeApi {} 47 | export class HelmChartStore extends Renderer.K8sApi.KubeObjectStore {} 48 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/helmchart-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 4 | 5 | export interface LocalHelmChartSourceReference { 6 | apiVersion?: string; 7 | kind: "HelmRepository" | "HelmChart" | "Bucket"; 8 | name: string; 9 | } 10 | 11 | export interface HelmChartSpec extends FluxCDKubeObjectSpecWithSuspend { 12 | chart: string; 13 | version?: string; 14 | sourceRef: LocalHelmChartSourceReference; 15 | interval: string; 16 | reconcileStrategy?: "ChartVersion" | "Revision"; 17 | valuesFiles?: string[]; 18 | valuesFile?: string; 19 | suspend?: boolean; 20 | accessFrom?: AccessFrom; 21 | } 22 | 23 | export interface HelmChartStatus extends FluxCDKubeObjectStatus { 24 | url?: string; 25 | artifact?: Artifact; 26 | } 27 | 28 | export class HelmChart extends Renderer.K8sApi.LensExtensionKubeObject< 29 | Renderer.K8sApi.KubeObjectMetadata, 30 | HelmChartStatus, 31 | HelmChartSpec 32 | > { 33 | static readonly kind = "HelmChart"; 34 | static readonly namespaced = true; 35 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta2/helmrepositories"; 36 | 37 | static readonly crd = { 38 | apiVersions: ["source.toolkit.fluxcd.io/v1beta2"], 39 | plural: "helmcharts", 40 | singular: "helmchart", 41 | shortNames: ["hc"], 42 | title: "Helm Charts", 43 | }; 44 | } 45 | 46 | export class HelmChartApi extends Renderer.K8sApi.KubeApi {} 47 | export class HelmChartStore extends Renderer.K8sApi.KubeObjectStore {} 48 | -------------------------------------------------------------------------------- /src/renderer/components/details/image/image-policy-details-v1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { ImagePolicy } from "../../../k8s/fluxcd/image/imagepolicy-v1"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | 7 | const { 8 | Component: { DrawerItem }, 9 | } = Renderer; 10 | 11 | export const ImagePolicyDetails: React.FC> = observer( 12 | (props) => { 13 | const { object } = props; 14 | 15 | return ( 16 | <> 17 |
18 | 19 | 20 | 21 | 24 | 27 | 30 | 34 |
35 | 36 | ); 37 | }, 38 | ); 39 | -------------------------------------------------------------------------------- /src/renderer/components/details/image/image-policy-details-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { ImagePolicy } from "../../../k8s/fluxcd/image/imagepolicy-v1beta1"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | 7 | const { 8 | Component: { DrawerItem }, 9 | } = Renderer; 10 | 11 | export const ImagePolicyDetails: React.FC> = observer( 12 | (props) => { 13 | const { object } = props; 14 | 15 | return ( 16 | <> 17 |
18 | 19 | 20 | 21 | 24 | 27 | 30 | 34 |
35 | 36 | ); 37 | }, 38 | ); 39 | -------------------------------------------------------------------------------- /src/renderer/components/details/image/image-policy-details-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { ImagePolicy } from "../../../k8s/fluxcd/image/imagepolicy-v1beta2"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | 7 | const { 8 | Component: { DrawerItem }, 9 | } = Renderer; 10 | 11 | export const ImagePolicyDetails: React.FC> = observer( 12 | (props) => { 13 | const { object } = props; 14 | 15 | return ( 16 | <> 17 |
18 | 19 | 20 | 21 | 24 | 27 | 30 | 34 |
35 | 36 | ); 37 | }, 38 | ); 39 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/bucket-details-v1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Bucket } from "../../../k8s/fluxcd/source/bucket-v1"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const BucketDetails: React.FC> = observer((props) => { 13 | const { object } = props; 14 | const namespace = object.getNs(); 15 | 16 | return ( 17 |
18 | 19 | 20 | 21 | {object.spec.interval} 22 | {object.spec.timeout ?? "60s"} 23 | {object.spec.provider ?? "generic"} 24 | {object.spec.bucketName} 25 | 28 | 31 | 34 | 35 | 36 |
37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /src/renderer/menus/fluxcd-object-reconcile-menu-item.tsx: -------------------------------------------------------------------------------- 1 | import { Common, Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { FluxCDKubeObjectSpecWithSuspend } from "../k8s/fluxcd/types"; 4 | 5 | const { 6 | Component: { MenuItem, Icon }, 7 | } = Renderer; 8 | 9 | type FluxCDKubeObjectWithMetadata = Renderer.K8sApi.LensExtensionKubeObject< 10 | Renderer.K8sApi.KubeObjectMetadata, 11 | unknown, 12 | unknown 13 | >; 14 | type FluxCDKubeObjectWithMetadataCtor = typeof Renderer.K8sApi.LensExtensionKubeObject< 15 | Renderer.K8sApi.KubeObjectMetadata, 16 | unknown, 17 | unknown 18 | >; 19 | 20 | export interface FluxCDObjectReconcileMenuItemProps 21 | extends Common.Types.KubeObjectMenuItemProps> { 22 | resource: FluxCDKubeObjectWithMetadataCtor; 23 | } 24 | 25 | export function FluxCDObjectReconcileMenuItem(props: FluxCDObjectReconcileMenuItemProps) { 26 | const { object, toolbar, resource } = props; 27 | if (!object) return <>; 28 | 29 | const store = resource.getStore(); 30 | if (!store) return <>; 31 | 32 | const reconcile = async () => { 33 | await store.patch( 34 | object, 35 | { 36 | metadata: { 37 | annotations: { "reconcile.fluxcd.io/requestedAt": new Date().toISOString() }, 38 | }, 39 | }, 40 | "merge", 41 | ); 42 | }; 43 | 44 | return ( 45 | 46 | 47 | Reconcile 48 | 49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Freelens Authors. 2 | 3 | Copyright (c) 2020 Mirantis, Inc. 4 | 5 | Portions of this software are licensed as follows: 6 | 7 | * All content residing under the "docs/" directory of this repository, if that 8 | directory exists, is licensed under "Creative Commons: CC BY-SA 4.0 license". 9 | * All third party components incorporated into the Lens Software are licensed 10 | under the original license provided by the owner of the applicable component. 11 | * Content outside of the above mentioned directories or restrictions above is 12 | available under the "MIT" license as defined below. 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | SOFTWARE. 31 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/bucket-details-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Bucket } from "../../../k8s/fluxcd/source/bucket-v1beta1"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const BucketDetails: React.FC> = observer((props) => { 13 | const { object } = props; 14 | const namespace = object.getNs(); 15 | 16 | return ( 17 |
18 | 19 | 20 | 21 | {object.spec.interval} 22 | {object.spec.timeout ?? "60s"} 23 | {object.spec.provider ?? "generic"} 24 | {object.spec.bucketName} 25 | 28 | 31 | 34 | 35 | 36 |
37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/bucket-details-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Bucket } from "../../../k8s/fluxcd/source/bucket-v1beta2"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const BucketDetails: React.FC> = observer((props) => { 13 | const { object } = props; 14 | const namespace = object.getNs(); 15 | 16 | return ( 17 |
18 | 19 | 20 | 21 | {object.spec.interval} 22 | {object.spec.timeout ?? "60s"} 23 | {object.spec.provider ?? "generic"} 24 | {object.spec.bucketName} 25 | 28 | 31 | 34 | 35 | 36 |
37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imagepolicy-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { FluxCDKubeObjectStatus, NamespacedObjectReference } from "../types"; 4 | 5 | export interface SemVerPolicy { 6 | range: string; 7 | } 8 | 9 | export interface AlphabeticalPolicy { 10 | order?: "asc" | "desc"; 11 | } 12 | 13 | export interface NumericalPolicy { 14 | order?: "asc" | "desc"; 15 | } 16 | 17 | export interface ImagePolicyChoice { 18 | semver?: SemVerPolicy; 19 | alphabetical?: AlphabeticalPolicy; 20 | numerical?: NumericalPolicy; 21 | } 22 | 23 | export interface TagFilter { 24 | pattern: string; 25 | extract: string; 26 | } 27 | 28 | export interface ImagePolicySpec { 29 | imageRepositoryRef: NamespacedObjectReference; 30 | policy: ImagePolicyChoice; 31 | filterTags?: TagFilter; 32 | } 33 | 34 | export interface ImagePolicyStatus extends FluxCDKubeObjectStatus { 35 | latestImage?: string; 36 | } 37 | 38 | export class ImagePolicy extends Renderer.K8sApi.LensExtensionKubeObject< 39 | Renderer.K8sApi.KubeObjectMetadata, 40 | ImagePolicyStatus, 41 | ImagePolicySpec 42 | > { 43 | static readonly kind = "ImagePolicy"; 44 | static readonly namespaced = true; 45 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1/imagepolicies"; 46 | 47 | static readonly crd = { 48 | apiVersions: ["image.toolkit.fluxcd.io/v1"], 49 | plural: "imagepolicies", 50 | singular: "imagepolicy", 51 | shortNames: [], 52 | title: "Image Policies", 53 | }; 54 | } 55 | 56 | export class ImagePolicyApi extends Renderer.K8sApi.KubeApi {} 57 | export class ImagePolicyStore extends Renderer.K8sApi.KubeObjectStore {} 58 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imagepolicy-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { FluxCDKubeObjectStatus, NamespacedObjectReference } from "../types"; 4 | 5 | export interface SemVerPolicy { 6 | range: string; 7 | } 8 | 9 | export interface AlphabeticalPolicy { 10 | order?: "asc" | "desc"; 11 | } 12 | 13 | export interface NumericalPolicy { 14 | order?: "asc" | "desc"; 15 | } 16 | 17 | export interface ImagePolicyChoice { 18 | semver?: SemVerPolicy; 19 | alphabetical?: AlphabeticalPolicy; 20 | numerical?: NumericalPolicy; 21 | } 22 | 23 | export interface TagFilter { 24 | pattern: string; 25 | extract: string; 26 | } 27 | 28 | export interface ImagePolicySpec { 29 | imageRepositoryRef: NamespacedObjectReference; 30 | policy: ImagePolicyChoice; 31 | filterTags?: TagFilter; 32 | } 33 | 34 | export interface ImagePolicyStatus extends FluxCDKubeObjectStatus { 35 | latestImage?: string; 36 | } 37 | 38 | export class ImagePolicy extends Renderer.K8sApi.LensExtensionKubeObject< 39 | Renderer.K8sApi.KubeObjectMetadata, 40 | ImagePolicyStatus, 41 | ImagePolicySpec 42 | > { 43 | static readonly kind = "ImagePolicy"; 44 | static readonly namespaced = true; 45 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1beta1/imagepolicies"; 46 | 47 | static readonly crd = { 48 | apiVersions: ["image.toolkit.fluxcd.io/v1beta1"], 49 | plural: "imagepolicies", 50 | singular: "imagepolicy", 51 | shortNames: [], 52 | title: "Image Policies", 53 | }; 54 | } 55 | 56 | export class ImagePolicyApi extends Renderer.K8sApi.KubeApi {} 57 | export class ImagePolicyStore extends Renderer.K8sApi.KubeObjectStore {} 58 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imagepolicy-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { FluxCDKubeObjectStatus, NamespacedObjectReference } from "../types"; 4 | 5 | export interface SemVerPolicy { 6 | range: string; 7 | } 8 | 9 | export interface AlphabeticalPolicy { 10 | order?: "asc" | "desc"; 11 | } 12 | 13 | export interface NumericalPolicy { 14 | order?: "asc" | "desc"; 15 | } 16 | 17 | export interface ImagePolicyChoice { 18 | semver?: SemVerPolicy; 19 | alphabetical?: AlphabeticalPolicy; 20 | numerical?: NumericalPolicy; 21 | } 22 | 23 | export interface TagFilter { 24 | pattern: string; 25 | extract: string; 26 | } 27 | 28 | export interface ImagePolicySpec { 29 | imageRepositoryRef: NamespacedObjectReference; 30 | policy: ImagePolicyChoice; 31 | filterTags?: TagFilter; 32 | } 33 | 34 | export interface ImagePolicyStatus extends FluxCDKubeObjectStatus { 35 | latestImage?: string; 36 | } 37 | 38 | export class ImagePolicy extends Renderer.K8sApi.LensExtensionKubeObject< 39 | Renderer.K8sApi.KubeObjectMetadata, 40 | ImagePolicyStatus, 41 | ImagePolicySpec 42 | > { 43 | static readonly kind = "ImagePolicy"; 44 | static readonly namespaced = true; 45 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1beta2/imagepolicies"; 46 | 47 | static readonly crd = { 48 | apiVersions: ["image.toolkit.fluxcd.io/v1beta2"], 49 | plural: "imagepolicies", 50 | singular: "imagepolicy", 51 | shortNames: [], 52 | title: "Image Policies", 53 | }; 54 | } 55 | 56 | export class ImagePolicyApi extends Renderer.K8sApi.KubeApi {} 57 | export class ImagePolicyStore extends Renderer.K8sApi.KubeObjectStore {} 58 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imagerepository-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface ScanResult { 8 | tagCount: number; 9 | scanTime?: string; 10 | } 11 | 12 | export interface ImageRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 13 | image?: string; 14 | interval: string; 15 | timeout?: string; 16 | secretRef?: LocalObjectReference; 17 | serviceAccountName?: string; 18 | certSecretRef?: LocalObjectReference; 19 | suspend?: boolean; 20 | accessFrom?: AccessFrom; 21 | exclusionList?: string[]; 22 | } 23 | 24 | export interface ImageRepositoryStatus extends FluxCDKubeObjectStatus { 25 | canonicalImageName?: string; 26 | lastScanResult?: ScanResult; 27 | } 28 | 29 | export class ImageRepository extends Renderer.K8sApi.LensExtensionKubeObject< 30 | Renderer.K8sApi.KubeObjectMetadata, 31 | ImageRepositoryStatus, 32 | ImageRepositorySpec 33 | > { 34 | static readonly kind = "ImageRepository"; 35 | static readonly namespaced = true; 36 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1beta1/imagerepositories"; 37 | 38 | static readonly crd = { 39 | apiVersions: ["image.toolkit.fluxcd.io/v1beta1"], 40 | plural: "imagerepositories", 41 | singular: "imagerepository", 42 | shortNames: [], 43 | title: "Image Repositories", 44 | }; 45 | } 46 | 47 | export class ImageRepositoryApi extends Renderer.K8sApi.KubeApi {} 48 | export class ImageRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 49 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imagerepository-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface ScanResult { 8 | tagCount: number; 9 | scanTime?: string; 10 | latestTags: string[]; 11 | } 12 | 13 | export interface ImageRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 14 | image?: string; 15 | interval: string; 16 | timeout?: string; 17 | secretRef?: LocalObjectReference; 18 | serviceAccountName?: string; 19 | certSecretRef?: LocalObjectReference; 20 | suspend?: boolean; 21 | accessFrom?: AccessFrom; 22 | exclusionList?: string[]; 23 | } 24 | 25 | export interface ImageRepositoryStatus extends FluxCDKubeObjectStatus { 26 | canonicalImageName?: string; 27 | lastScanResult?: ScanResult; 28 | } 29 | 30 | export class ImageRepository extends Renderer.K8sApi.LensExtensionKubeObject< 31 | Renderer.K8sApi.KubeObjectMetadata, 32 | ImageRepositoryStatus, 33 | ImageRepositorySpec 34 | > { 35 | static readonly kind = "ImageRepository"; 36 | static readonly namespaced = true; 37 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1/imagerepositories"; 38 | 39 | static readonly crd = { 40 | apiVersions: ["image.toolkit.fluxcd.io/v1"], 41 | plural: "imagerepositories", 42 | singular: "imagerepository", 43 | shortNames: [], 44 | title: "Image Repositories", 45 | }; 46 | } 47 | 48 | export class ImageRepositoryApi extends Renderer.K8sApi.KubeApi {} 49 | export class ImageRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 50 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imagerepository-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface ScanResult { 8 | tagCount: number; 9 | scanTime?: string; 10 | latestTags: string[]; 11 | } 12 | 13 | export interface ImageRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 14 | image?: string; 15 | interval: string; 16 | timeout?: string; 17 | secretRef?: LocalObjectReference; 18 | serviceAccountName?: string; 19 | certSecretRef?: LocalObjectReference; 20 | suspend?: boolean; 21 | accessFrom?: AccessFrom; 22 | exclusionList?: string[]; 23 | } 24 | 25 | export interface ImageRepositoryStatus extends FluxCDKubeObjectStatus { 26 | canonicalImageName?: string; 27 | lastScanResult?: ScanResult; 28 | } 29 | 30 | export class ImageRepository extends Renderer.K8sApi.LensExtensionKubeObject< 31 | Renderer.K8sApi.KubeObjectMetadata, 32 | ImageRepositoryStatus, 33 | ImageRepositorySpec 34 | > { 35 | static readonly kind = "ImageRepository"; 36 | static readonly namespaced = true; 37 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1beta2/imagerepositories"; 38 | 39 | static readonly crd = { 40 | apiVersions: ["image.toolkit.fluxcd.io/v1beta2"], 41 | plural: "imagerepositories", 42 | singular: "imagerepository", 43 | shortNames: [], 44 | title: "Image Repositories", 45 | }; 46 | } 47 | 48 | export class ImageRepositoryApi extends Renderer.K8sApi.KubeApi {} 49 | export class ImageRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 50 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/helm-chart-details-v1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { HelmChart } from "../../../k8s/fluxcd/source/helmchart-v1"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const HelmChartDetails: React.FC> = observer((props) => { 13 | const { object } = props; 14 | 15 | return ( 16 |
17 | 18 | 19 | 20 | {object.spec.interval} 21 | {object.spec.chart} 22 | {object.spec.version ?? "*"} 23 | {object.spec.reconcileStrategy ?? "ChartVersion"} 24 | 25 | 26 | 27 | 31 | 34 | 35 | 36 |
37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/helm-chart-details-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { HelmChart } from "../../../k8s/fluxcd/source/helmchart-v1beta1"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const HelmChartDetails: React.FC> = observer((props) => { 13 | const { object } = props; 14 | 15 | return ( 16 |
17 | 18 | 19 | 20 | {object.spec.interval} 21 | {object.spec.chart} 22 | {object.spec.version ?? "*"} 23 | {object.spec.reconcileStrategy ?? "ChartVersion"} 24 | 25 | 26 | 27 | 31 | 34 | 35 | 36 |
37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /src/renderer/components/details/source/helm-chart-details-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { HelmChart } from "../../../k8s/fluxcd/source/helmchart-v1beta2"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | import { StatusArtifact } from "../../status-artifact"; 7 | 8 | const { 9 | Component: { BadgeBoolean, DrawerItem }, 10 | } = Renderer; 11 | 12 | export const HelmChartDetails: React.FC> = observer((props) => { 13 | const { object } = props; 14 | 15 | return ( 16 |
17 | 18 | 19 | 20 | {object.spec.interval} 21 | {object.spec.chart} 22 | {object.spec.version ?? "*"} 23 | {object.spec.reconcileStrategy ?? "ChartVersion"} 24 | 25 | 26 | 27 | 31 | 34 | 35 | 36 |
37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /src/renderer/components/status-artifact.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { DurationAbsoluteTimestamp } from "./duration-absolute"; 4 | import { HumanizeBytes } from "./humanizeBytes"; 5 | import styles from "./status-artifact.module.scss"; 6 | import stylesInline from "./status-artifact.module.scss?inline"; 7 | 8 | import type { Artifact } from "../k8s/fluxcd/types"; 9 | 10 | const { 11 | Component: { DrawerTitle, DrawerItem }, 12 | } = Renderer; 13 | 14 | export interface StatusArtifactProps { 15 | artifact?: Artifact; 16 | } 17 | 18 | export const StatusArtifact: React.FC = observer((props) => { 19 | const { artifact } = props; 20 | 21 | if (!artifact) return null; 22 | 23 | return ( 24 | <> 25 | 26 |
27 | Artifact 28 |
29 | {artifact.path} 30 | {artifact.url} 31 | 34 | 37 | 40 | 41 | 42 | 43 |
44 |
45 | 46 | ); 47 | }); 48 | -------------------------------------------------------------------------------- /src/renderer/components/details/notification/alert-details-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Alert } from "../../../k8s/fluxcd/notification/alert-v1beta2"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | 7 | const { 8 | Component: { Badge, BadgeBoolean, DrawerItem, DrawerItemLabels }, 9 | } = Renderer; 10 | 11 | export const AlertDetails: React.FC> = observer((props) => { 12 | const { object } = props; 13 | 14 | return ( 15 |
16 | 17 | 18 | 19 | {object.spec.eventSeverity} 20 | 21 | {object.spec.eventSources?.map((eventSource) => { 22 | const badge = ; 23 | return ( 24 | 25 | {eventSource.name === "*" ? ( 26 | badge 27 | ) : ( 28 | 29 | )} 30 | 31 | ); 32 | })} 33 | 34 | 35 | 36 | 37 |
43 | ); 44 | }); 45 | -------------------------------------------------------------------------------- /src/renderer/components/details/notification/alert-details-v1beta3.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Alert } from "../../../k8s/fluxcd/notification/alert-v1beta3"; 5 | import { LinkToObject } from "../../link-to-object"; 6 | 7 | const { 8 | Component: { Badge, BadgeBoolean, DrawerItem, DrawerItemLabels }, 9 | } = Renderer; 10 | 11 | export const AlertDetails: React.FC> = observer((props) => { 12 | const { object } = props; 13 | 14 | return ( 15 |
16 | 17 | 18 | 19 | {object.spec.eventSeverity} 20 | 21 | {object.spec.eventSources?.map((eventSource) => { 22 | const badge = ; 23 | return ( 24 | 25 | {eventSource.name === "*" ? ( 26 | badge 27 | ) : ( 28 | 29 | )} 30 | 31 | ); 32 | })} 33 | 34 | 35 | 36 | 37 |
43 | ); 44 | }); 45 | -------------------------------------------------------------------------------- /src/renderer/components/details/notification/provider-details-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Provider } from "../../../k8s/fluxcd/notification/provider-v1beta1"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | 7 | const { 8 | Component: { BadgeBoolean, DrawerItem }, 9 | } = Renderer; 10 | 11 | export const ProviderDetails: React.FC> = observer((props) => { 12 | const { object } = props; 13 | const namespace = object.getNs(); 14 | 15 | return ( 16 |
17 | 18 | 19 | 20 | 23 | 26 | 29 | 32 | 35 | 38 | 41 |
42 | ); 43 | }); 44 | -------------------------------------------------------------------------------- /src/renderer/components/details/notification/provider-details-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Provider } from "../../../k8s/fluxcd/notification/provider-v1beta2"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | 7 | const { 8 | Component: { BadgeBoolean, DrawerItem }, 9 | } = Renderer; 10 | 11 | export const ProviderDetails: React.FC> = observer((props) => { 12 | const { object } = props; 13 | const namespace = object.getNs(); 14 | 15 | return ( 16 |
17 | 18 | 19 | 20 | 23 | 26 | 29 | 32 | 35 | 38 | 41 |
42 | ); 43 | }); 44 | -------------------------------------------------------------------------------- /src/renderer/components/details/notification/provider-details-v1beta3.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { Provider } from "../../../k8s/fluxcd/notification/provider-v1beta3"; 5 | import { LinkToSecret } from "../../link-to-secret"; 6 | 7 | const { 8 | Component: { BadgeBoolean, DrawerItem }, 9 | } = Renderer; 10 | 11 | export const ProviderDetails: React.FC> = observer((props) => { 12 | const { object } = props; 13 | const namespace = object.getNs(); 14 | 15 | return ( 16 |
17 | 18 | 19 | 20 | 23 | 26 | 29 | 32 | 35 | 38 | 41 |
42 | ); 43 | }); 44 | -------------------------------------------------------------------------------- /src/renderer/components/error-page.tsx: -------------------------------------------------------------------------------- 1 | import { Common, type Renderer } from "@freelensapp/extensions"; 2 | import React from "react"; 3 | import styles from "./error-page.module.scss"; 4 | import stylesInline from "./error-page.module.scss?inline"; 5 | 6 | export interface ErrorPageProps { 7 | error?: unknown; 8 | extension: Renderer.LensExtension; 9 | children?: React.ReactNode; 10 | } 11 | 12 | export function ErrorPage({ error, extension, children }: ErrorPageProps) { 13 | if (error) { 14 | Common.logger.error(`[${extension.name}]: ${error}`); 15 | } 16 | return ( 17 | <> 18 | 19 |
20 | {error ?

{String(error)}

: <>} 21 | {children} 22 |
23 | 24 | ); 25 | } 26 | 27 | /** 28 | * Wraps component in try/catch block and prints ErrorPage on error. 29 | * Handles "API not registered" errors gracefully by returning null, allowing available-version pages to try alternative API versions. 30 | * 31 | * ```ts 32 | * export const Component = (props: ComponentProps) => withErrorPage(props, () => { 33 | * throw new Error("something died"); 34 | * }) 35 | * ``` 36 | */ 37 | export function withErrorPage

( 38 | props: P, 39 | wrapped: (props: P) => JSX.Element, 40 | ) { 41 | try { 42 | return wrapped(props); 43 | } catch (error) { 44 | const errorMessage = String(error); 45 | 46 | if (errorMessage.includes("not registered") || errorMessage.includes("getStore")) { 47 | Common.logger.debug(`[@freelensapp/fluxcd-extension]: API not available - ${error}`); 48 | return null; 49 | } 50 | 51 | return ; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/renderer/icons/fluxcd.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/provider-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface ProviderSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | type?: 9 | | "slack" 10 | | "discord" 11 | | "msteams" 12 | | "rocket" 13 | | "generic" 14 | | "generic-hmac" 15 | | "github" 16 | | "gitlab" 17 | | "bitbucket" 18 | | "azuredevops" 19 | | "googlechat" 20 | | "webex" 21 | | "sentry" 22 | | "azureeventhub" 23 | | "telegram" 24 | | "lark" 25 | | "matrix" 26 | | "opsgenie" 27 | | "alertmanager" 28 | | "grafana" 29 | | "githubdispatch"; 30 | channel?: string; 31 | username?: string; 32 | address?: string; 33 | timeout?: string; 34 | proxy?: string; 35 | secretRef?: LocalObjectReference; 36 | certSecretRef?: LocalObjectReference; 37 | suspend?: boolean; 38 | } 39 | 40 | export interface ProviderStatus extends FluxCDKubeObjectStatus {} 41 | 42 | export class Provider extends Renderer.K8sApi.LensExtensionKubeObject< 43 | Renderer.K8sApi.KubeObjectMetadata, 44 | ProviderStatus, 45 | ProviderSpec 46 | > { 47 | static readonly kind = "Provider"; 48 | static readonly namespaced = true; 49 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta1/providers"; 50 | 51 | static readonly crd = { 52 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta1"], 53 | plural: "providers", 54 | singular: "provider", 55 | shortNames: [], 56 | title: "Providers", 57 | }; 58 | } 59 | 60 | export class ProviderApi extends Renderer.K8sApi.KubeApi {} 61 | export class ProviderStore extends Renderer.K8sApi.KubeObjectStore {} 62 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/provider-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface ProviderSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | type?: 9 | | "slack" 10 | | "discord" 11 | | "msteams" 12 | | "rocket" 13 | | "generic" 14 | | "generic-hmac" 15 | | "github" 16 | | "gitlab" 17 | | "bitbucket" 18 | | "azuredevops" 19 | | "googlechat" 20 | | "webex" 21 | | "sentry" 22 | | "azureeventhub" 23 | | "telegram" 24 | | "lark" 25 | | "matrix" 26 | | "opsgenie" 27 | | "alertmanager" 28 | | "grafana" 29 | | "githubdispatch"; 30 | channel?: string; 31 | username?: string; 32 | address?: string; 33 | timeout?: string; 34 | proxy?: string; 35 | secretRef?: LocalObjectReference; 36 | certSecretRef?: LocalObjectReference; 37 | suspend?: boolean; 38 | } 39 | 40 | export interface ProviderStatus extends FluxCDKubeObjectStatus {} 41 | 42 | export class Provider extends Renderer.K8sApi.LensExtensionKubeObject< 43 | Renderer.K8sApi.KubeObjectMetadata, 44 | ProviderStatus, 45 | ProviderSpec 46 | > { 47 | static readonly kind = "Provider"; 48 | static readonly namespaced = true; 49 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta2/providers"; 50 | 51 | static readonly crd = { 52 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta2"], 53 | plural: "providers", 54 | singular: "provider", 55 | shortNames: [], 56 | title: "Providers", 57 | }; 58 | } 59 | 60 | export class ProviderApi extends Renderer.K8sApi.KubeApi {} 61 | export class ProviderStore extends Renderer.K8sApi.KubeObjectStore {} 62 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/notification/provider-v1beta3.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface ProviderSpec extends FluxCDKubeObjectSpecWithSuspend { 8 | type?: 9 | | "slack" 10 | | "discord" 11 | | "msteams" 12 | | "rocket" 13 | | "generic" 14 | | "generic-hmac" 15 | | "github" 16 | | "gitlab" 17 | | "bitbucket" 18 | | "azuredevops" 19 | | "googlechat" 20 | | "webex" 21 | | "sentry" 22 | | "azureeventhub" 23 | | "telegram" 24 | | "lark" 25 | | "matrix" 26 | | "opsgenie" 27 | | "alertmanager" 28 | | "grafana" 29 | | "githubdispatch"; 30 | channel?: string; 31 | username?: string; 32 | address?: string; 33 | timeout?: string; 34 | proxy?: string; 35 | secretRef?: LocalObjectReference; 36 | certSecretRef?: LocalObjectReference; 37 | suspend?: boolean; 38 | } 39 | 40 | export interface ProviderStatus extends FluxCDKubeObjectStatus {} 41 | 42 | export class Provider extends Renderer.K8sApi.LensExtensionKubeObject< 43 | Renderer.K8sApi.KubeObjectMetadata, 44 | ProviderStatus, 45 | ProviderSpec 46 | > { 47 | static readonly kind = "Provider"; 48 | static readonly namespaced = true; 49 | static readonly apiBase = "/apis/notification.toolkit.fluxcd.io/v1beta3/providers"; 50 | 51 | static readonly crd = { 52 | apiVersions: ["notification.toolkit.fluxcd.io/v1beta3"], 53 | plural: "providers", 54 | singular: "provider", 55 | shortNames: [], 56 | title: "Providers", 57 | }; 58 | } 59 | 60 | export class ProviderApi extends Renderer.K8sApi.KubeApi {} 61 | export class ProviderStore extends Renderer.K8sApi.KubeObjectStore {} 62 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/helmrepository-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface HelmRepositoryRef { 8 | branch?: string; 9 | tag?: string; 10 | semver?: string; 11 | commit?: string; 12 | name?: string; 13 | } 14 | 15 | export interface HelmRepositoryInclude { 16 | repository: LocalObjectReference; 17 | fromPath: string; 18 | toPath: string; 19 | } 20 | 21 | export interface HelmRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 22 | url: string; 23 | secretRef?: LocalObjectReference; 24 | passCredentials?: boolean; 25 | interval: string; 26 | timeout?: string; 27 | suspend?: boolean; 28 | accessFrom?: AccessFrom; 29 | // source.toolkit.fluxcd.io/v1 30 | type?: "helm" | "oci"; 31 | } 32 | 33 | export interface HelmRepositoryStatus extends FluxCDKubeObjectStatus { 34 | url?: string; 35 | artifact?: Artifact; 36 | } 37 | 38 | export class HelmRepository extends Renderer.K8sApi.LensExtensionKubeObject< 39 | Renderer.K8sApi.KubeObjectMetadata, 40 | HelmRepositoryStatus, 41 | HelmRepositorySpec 42 | > { 43 | static readonly kind = "HelmRepository"; 44 | static readonly namespaced = true; 45 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1/helmrepositories"; 46 | 47 | static readonly crd = { 48 | apiVersions: ["source.toolkit.fluxcd.io/v1"], 49 | plural: "helmrepositories", 50 | singular: "helmrepository", 51 | shortNames: ["helmrepo"], 52 | title: "Helm Repositories", 53 | }; 54 | } 55 | 56 | export class HelmRepositoryApi extends Renderer.K8sApi.KubeApi {} 57 | export class HelmRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 58 | -------------------------------------------------------------------------------- /.github/workflows/check.yaml: -------------------------------------------------------------------------------- 1 | name: Check 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - "*" 10 | workflow_dispatch: {} 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | knip: 17 | name: check 18 | 19 | runs-on: ubuntu-22.04 20 | timeout-minutes: 60 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v6 25 | 26 | - name: Setup node 27 | uses: actions/setup-node@v6 28 | with: 29 | node-version-file: .nvmrc 30 | package-manager-cache: false 31 | 32 | - name: Setup pnpm 33 | run: corepack enable 34 | 35 | - name: Get pnpm cache directory 36 | shell: bash 37 | run: echo "pnpm_cache_dir=$(pnpm store path)" >> ${GITHUB_ENV} 38 | 39 | - name: Use pnpm cache 40 | uses: actions/cache@v4 41 | with: 42 | path: ${{ env.pnpm_cache_dir }} 43 | key: ubuntu-22.04-x64-node-${{ hashFiles('**/pnpm-lock.yaml') }} 44 | restore-keys: | 45 | ubuntu-22.04-x64-node- 46 | 47 | - name: Install pnpm dependencies 48 | id: install-pnpm 49 | run: timeout 300 pnpm install --color=always --prefer-offline --frozen-lockfile 50 | continue-on-error: true 51 | 52 | - name: Install pnpm dependencies (retry) 53 | if: steps.install-pnpm.outcome == 'failure' 54 | run: timeout 300 pnpm install --color=always --prefer-offline --frozen-lockfile 55 | 56 | - name: Build packages 57 | run: pnpm --color=always --stream build:production 58 | 59 | - name: Check types 60 | run: pnpm --color=always --stream type:check 61 | 62 | - name: Check linters 63 | run: pnpm --color=always --stream lint:check 64 | 65 | - name: Check Knip 66 | run: pnpm --color=always --stream knip:check 67 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/helmrepository-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface HelmRepositoryRef { 8 | branch?: string; 9 | tag?: string; 10 | semver?: string; 11 | commit?: string; 12 | name?: string; 13 | } 14 | 15 | export interface HelmRepositoryInclude { 16 | repository: LocalObjectReference; 17 | fromPath: string; 18 | toPath: string; 19 | } 20 | 21 | export interface HelmRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 22 | url: string; 23 | secretRef?: LocalObjectReference; 24 | passCredentials?: boolean; 25 | interval: string; 26 | timeout?: string; 27 | suspend?: boolean; 28 | accessFrom?: AccessFrom; 29 | // source.toolkit.fluxcd.io/v1 30 | type?: "helm" | "oci"; 31 | } 32 | 33 | export interface HelmRepositoryStatus extends FluxCDKubeObjectStatus { 34 | url?: string; 35 | artifact?: Artifact; 36 | } 37 | 38 | export class HelmRepository extends Renderer.K8sApi.LensExtensionKubeObject< 39 | Renderer.K8sApi.KubeObjectMetadata, 40 | HelmRepositoryStatus, 41 | HelmRepositorySpec 42 | > { 43 | static readonly kind = "HelmRepository"; 44 | static readonly namespaced = true; 45 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta1/helmrepositories"; 46 | 47 | static readonly crd = { 48 | apiVersions: ["source.toolkit.fluxcd.io/v1beta1"], 49 | plural: "helmrepositories", 50 | singular: "helmrepository", 51 | shortNames: ["helmrepo"], 52 | title: "Helm Repositories", 53 | }; 54 | } 55 | 56 | export class HelmRepositoryApi extends Renderer.K8sApi.KubeApi {} 57 | export class HelmRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 58 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/helmrepository-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface HelmRepositoryRef { 8 | branch?: string; 9 | tag?: string; 10 | semver?: string; 11 | commit?: string; 12 | name?: string; 13 | } 14 | 15 | export interface HelmRepositoryInclude { 16 | repository: LocalObjectReference; 17 | fromPath: string; 18 | toPath: string; 19 | } 20 | 21 | export interface HelmRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 22 | url: string; 23 | secretRef?: LocalObjectReference; 24 | passCredentials?: boolean; 25 | interval: string; 26 | timeout?: string; 27 | suspend?: boolean; 28 | accessFrom?: AccessFrom; 29 | // source.toolkit.fluxcd.io/v1 30 | type?: "helm" | "oci"; 31 | } 32 | 33 | export interface HelmRepositoryStatus extends FluxCDKubeObjectStatus { 34 | url?: string; 35 | artifact?: Artifact; 36 | } 37 | 38 | export class HelmRepository extends Renderer.K8sApi.LensExtensionKubeObject< 39 | Renderer.K8sApi.KubeObjectMetadata, 40 | HelmRepositoryStatus, 41 | HelmRepositorySpec 42 | > { 43 | static readonly kind = "HelmRepository"; 44 | static readonly namespaced = true; 45 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta2/helmrepositories"; 46 | 47 | static readonly crd = { 48 | apiVersions: ["source.toolkit.fluxcd.io/v1beta2"], 49 | plural: "helmrepositories", 50 | singular: "helmrepository", 51 | shortNames: ["helmrepo"], 52 | title: "Helm Repositories", 53 | }; 54 | } 55 | 56 | export class HelmRepositoryApi extends Renderer.K8sApi.KubeApi {} 57 | export class HelmRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 58 | -------------------------------------------------------------------------------- /.github/workflows/test-update.yaml: -------------------------------------------------------------------------------- 1 | name: Test update 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - "*" 10 | workflow_dispatch: {} 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | knip: 17 | name: test update 18 | 19 | runs-on: ubuntu-22.04 20 | timeout-minutes: 60 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v6 25 | 26 | - name: Setup node 27 | uses: actions/setup-node@v6 28 | with: 29 | node-version-file: .nvmrc 30 | package-manager-cache: false 31 | 32 | - name: Setup pnpm 33 | run: corepack enable 34 | 35 | - name: Get pnpm cache directory 36 | shell: bash 37 | run: echo "pnpm_cache_dir=$(pnpm store path)" >> ${GITHUB_ENV} 38 | 39 | - name: Use pnpm cache 40 | uses: actions/cache@v4 41 | with: 42 | path: ${{ env.pnpm_cache_dir }} 43 | key: ubuntu-22.04-x64-node-${{ hashFiles('**/pnpm-lock.yaml') }} 44 | restore-keys: | 45 | ubuntu-22.04-x64-node- 46 | 47 | - name: Install pnpm dependencies 48 | id: install-pnpm 49 | run: timeout 300 pnpm install --color=always --prefer-offline --frozen-lockfile 50 | continue-on-error: true 51 | 52 | - name: Install pnpm dependencies (retry) 53 | if: steps.install-pnpm.outcome == 'failure' 54 | run: timeout 300 pnpm install --color=always --prefer-offline --frozen-lockfile 55 | 56 | - name: Update pnpm dependencies 57 | id: update-pnpm 58 | run: timeout 300 pnpm update -D @freelensapp/extensions@latest --color=always 59 | continue-on-error: true 60 | 61 | - name: Update pnpm dependencies (retry) 62 | if: steps.update-pnpm.outcome == 'failure' 63 | run: timeout 300 pnpm update -D @freelensapp/extensions@latest --color=always 64 | 65 | - name: Build packages 66 | run: pnpm --color=always --stream build 67 | -------------------------------------------------------------------------------- /src/renderer/components/status-history.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { checksum } from "../utils"; 4 | import styles from "./status-history.module.scss"; 5 | import stylesInline from "./status-history.module.scss?inline"; 6 | 7 | import type { History } from "../k8s/fluxcd/types"; 8 | 9 | const { 10 | Component: { DrawerItem, DrawerItemLabels, DrawerTitle, DurationAbsoluteTimestamp, Icon }, 11 | } = Renderer; 12 | 13 | export interface StatusHistoryProps { 14 | history?: History; 15 | } 16 | 17 | export const StatusHistory: React.FC = observer((props) => { 18 | const { history } = props; 19 | 20 | if (!history || !history.length) return null; 21 | 22 | return ( 23 | <> 24 | 25 |

26 | History 27 | {history.map((snapshot) => ( 28 |
29 |
30 | 31 |
32 | {snapshot.digest} 33 | 34 | 35 | 36 | 37 | 38 | 39 | {snapshot.lastReconciledDuration} 40 | {snapshot.lastReconciledStatus} 41 | {snapshot.totalReconciliations} 42 |
44 | ))} 45 |
46 | 47 | ); 48 | }); 49 | -------------------------------------------------------------------------------- /src/renderer/menus/fluxcd-object-spec-suspend-resume-menu-item.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { FluxCDKubeObjectSpecWithSuspend } from "../k8s/fluxcd/types"; 4 | 5 | const { 6 | Component: { MenuItem, Icon }, 7 | } = Renderer; 8 | 9 | type FluxCDKubeObjectWithSuspend = Renderer.K8sApi.LensExtensionKubeObject< 10 | Renderer.K8sApi.KubeObjectMetadata, 11 | unknown, 12 | FluxCDKubeObjectSpecWithSuspend 13 | >; 14 | type FluxCDKubeObjectWithSuspendCtor = typeof Renderer.K8sApi.LensExtensionKubeObject< 15 | Renderer.K8sApi.KubeObjectMetadata, 16 | unknown, 17 | FluxCDKubeObjectSpecWithSuspend 18 | >; 19 | 20 | export interface FluxCDObjectSpecSuspendResumeMenuItemProps 21 | extends Renderer.Component.KubeObjectMenuProps { 22 | resource: FluxCDKubeObjectWithSuspendCtor; 23 | } 24 | 25 | export function FluxCDObjectSpecSuspendResumeMenuItem(props: FluxCDObjectSpecSuspendResumeMenuItemProps) { 26 | const { object, toolbar, resource } = props; 27 | if (!object) return <>; 28 | 29 | const store = resource.getStore(); 30 | if (!store) return <>; 31 | 32 | const suspend = async () => { 33 | await store.patch( 34 | object, 35 | { 36 | spec: { 37 | suspend: true, 38 | }, 39 | }, 40 | "merge", 41 | ); 42 | }; 43 | 44 | const resume = async () => { 45 | await store.patch( 46 | object, 47 | { 48 | spec: { 49 | suspend: false, 50 | }, 51 | }, 52 | "merge", 53 | ); 54 | }; 55 | 56 | if (object.spec.suspend) { 57 | return ( 58 | 59 | 60 | Resume 61 | 62 | ); 63 | } else { 64 | return ( 65 | 66 | 67 | Suspend 68 | 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /.github/workflows/tag.yaml: -------------------------------------------------------------------------------- 1 | name: Automated tag 2 | 3 | on: 4 | issue_comment: 5 | types: 6 | - created 7 | pull_request: 8 | branches: 9 | - main 10 | types: 11 | - closed 12 | 13 | permissions: 14 | contents: write 15 | id-token: write 16 | pull-requests: read 17 | 18 | jobs: 19 | create-tag: 20 | name: tag 21 | 22 | runs-on: ubuntu-24.04 23 | environment: automated 24 | timeout-minutes: 10 25 | 26 | if: (startsWith(github.event.issue.title, 'Automated npm version') && github.event.issue.state == 'closed' && github.event.comment.body == '/tag') || (startsWith(github.event.pull_request.title, 'Automated npm version') && github.event.pull_request.merged) 27 | steps: 28 | - name: Checkout 29 | uses: actions/checkout@v6 30 | with: 31 | fetch-depth: 0 32 | ref: main 33 | 34 | - name: Get version from package.json 35 | id: package-json 36 | run: | 37 | echo "version=$(jq -r .version package.json)" >> $GITHUB_OUTPUT 38 | 39 | - name: Check if version is release 40 | id: check-version 41 | run: | 42 | if [[ "${{ steps.package-json.outputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 43 | echo "is_release=true" >> $GITHUB_OUTPUT 44 | else 45 | echo "is_release=false" >> $GITHUB_OUTPUT 46 | fi 47 | 48 | - name: Create tag from the main branch 49 | if: steps.check-version.outputs.is_release == 'true' 50 | uses: actions/github-script@v8 51 | with: 52 | script: | 53 | const mainRef = await github.rest.git.getRef({ 54 | owner: context.repo.owner, 55 | repo: context.repo.repo, 56 | ref: 'heads/main', 57 | }); 58 | const result = await github.rest.git.createRef({ 59 | owner: context.repo.owner, 60 | repo: context.repo.repo, 61 | ref: 'refs/tags/v${{ steps.package-json.outputs.version }}', 62 | sha: mainRef.data.object.sha, 63 | }); 64 | console.log(result); 65 | github-token: ${{ secrets.GH_TOKEN }} 66 | -------------------------------------------------------------------------------- /src/renderer/menus/fluxcd-object-annotation-suspend-resume-menu-item.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | const { 4 | Component: { MenuItem, Icon }, 5 | } = Renderer; 6 | 7 | type FluxCDKubeObjectWithMetadata = Renderer.K8sApi.LensExtensionKubeObject< 8 | Renderer.K8sApi.KubeObjectMetadata, 9 | unknown, 10 | unknown 11 | >; 12 | type FluxCDKubeObjectWithMetadataCtor = typeof Renderer.K8sApi.LensExtensionKubeObject< 13 | Renderer.K8sApi.KubeObjectMetadata, 14 | unknown, 15 | unknown 16 | >; 17 | 18 | export interface FluxCDObjectAnnotationSuspendResumeMenuItemProps 19 | extends Renderer.Component.KubeObjectMenuProps { 20 | resource: FluxCDKubeObjectWithMetadataCtor; 21 | } 22 | 23 | export function FluxCDObjectAnnotationSuspendResumeMenuItem(props: FluxCDObjectAnnotationSuspendResumeMenuItemProps) { 24 | const { object, toolbar, resource } = props; 25 | if (!object) return <>; 26 | 27 | const store = resource.getStore(); 28 | if (!store) return <>; 29 | 30 | const suspend = async () => { 31 | await store.patch( 32 | object, 33 | { 34 | metadata: { 35 | annotations: { "fluxcd.controlplane.io/reconcile": "disabled" }, 36 | }, 37 | }, 38 | "merge", 39 | ); 40 | }; 41 | 42 | const resume = async () => { 43 | await store.patch( 44 | object, 45 | { 46 | metadata: { 47 | annotations: { "fluxcd.controlplane.io/reconcile": "enabled" }, 48 | }, 49 | }, 50 | "merge", 51 | ); 52 | }; 53 | 54 | if ((object.metadata.annotations?.["fluxcd.controlplane.io/reconcile"] ?? "enabled") === "enabled") { 55 | return ( 56 | 57 | 58 | Suspend 59 | 60 | ); 61 | } else { 62 | return ( 63 | 64 | 65 | Resume 66 | 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/types.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { Condition, LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { Selector } from "../core/types"; 6 | 7 | export interface NamespacedObjectReference extends LocalObjectReference { 8 | namespace?: string; 9 | } 10 | 11 | export interface NamespacedObjectKindReference extends NamespacedObjectReference { 12 | apiVersion?: string; 13 | kind: string; 14 | } 15 | 16 | export interface NamespaceSelector { 17 | matchLabels?: Record; 18 | } 19 | 20 | export interface AccessFrom { 21 | namespaceSelectors: NamespaceSelector[]; 22 | } 23 | 24 | export interface Artifact { 25 | path: string; 26 | url: string; 27 | revision: string; 28 | checksum: string; 29 | lastUpdateTime?: string; 30 | size?: number; 31 | } 32 | 33 | export interface Image { 34 | name: string; 35 | newName?: string; 36 | newTag?: string; 37 | digest?: string; 38 | } 39 | 40 | export interface JSON6902Patch { 41 | patch: { 42 | op: "add" | "remove" | "replace" | "move" | "copy" | "test"; 43 | path: string; 44 | from?: string; 45 | value?: any; 46 | }[]; 47 | target: Selector; 48 | } 49 | 50 | export interface Snapshot { 51 | digest: string; 52 | firstReconciled: string; 53 | lastReconciled: string; 54 | lastReconciledDuration: string; 55 | lastReconciledStatus: string; 56 | totalReconciliations: number; 57 | metadata?: Record; 58 | } 59 | 60 | export type History = Snapshot[]; 61 | 62 | export interface ResourceInventory { 63 | entries: ResourceRef[]; 64 | } 65 | 66 | export interface ResourceRef { 67 | id: string; 68 | v: string; 69 | } 70 | 71 | export interface Snapshot { 72 | checksum: string; 73 | entries: { 74 | namespace: string; 75 | kinds: Record; 76 | }[]; 77 | } 78 | 79 | export interface FluxCDKubeObjectCRD extends Renderer.K8sApi.LensExtensionKubeObjectCRD { 80 | title: string; 81 | } 82 | 83 | export interface FluxCDKubeObjectSpecWithSuspend { 84 | suspend?: boolean; 85 | } 86 | 87 | export interface FluxCDKubeObjectStatus { 88 | observedGeneration?: number; 89 | lastHandledReconcileAt?: string; 90 | conditions?: Condition[]; 91 | } 92 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/controlplane/fluxreport-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { Condition } from "@freelensapp/kube-object"; 4 | 5 | export interface FluxDistributionStatus { 6 | entitlement: string; 7 | status: string; 8 | version?: string; 9 | managedBy?: string; 10 | } 11 | 12 | export interface ClusterInfo { 13 | serverVersion: string; 14 | platform: string; 15 | nodes?: number; 16 | } 17 | 18 | export interface OperatorInfo { 19 | apiVersion: string; 20 | version: string; 21 | platform: string; 22 | } 23 | 24 | export interface FluxComponentStatus { 25 | name: string; 26 | ready: boolean; 27 | status: string; 28 | image: string; 29 | } 30 | 31 | export interface FluxReconcilerStats { 32 | running: number; 33 | failing: number; 34 | suspended: number; 35 | totalSize?: string; 36 | } 37 | 38 | export interface FluxReconcilerStatus { 39 | apiVersion: string; 40 | kind: string; 41 | stats?: FluxReconcilerStats; 42 | } 43 | 44 | export interface FluxSyncStatus { 45 | id: string; 46 | path?: string; 47 | ready: boolean; 48 | status: string; 49 | source?: string; 50 | } 51 | 52 | export interface FluxReportSpec { 53 | distribution: FluxDistributionStatus; 54 | cluster?: ClusterInfo; 55 | operator?: OperatorInfo; 56 | components?: FluxComponentStatus[]; 57 | reconcilers?: FluxReconcilerStatus[]; 58 | sync?: FluxSyncStatus; 59 | } 60 | 61 | export interface FluxReportStatus { 62 | // ReconcileRequestStatus: 63 | lastHandledReconcileAt?: string; 64 | // FluxReportStatus: 65 | conditions?: Condition[]; 66 | } 67 | 68 | export class FluxReport extends Renderer.K8sApi.LensExtensionKubeObject< 69 | Renderer.K8sApi.KubeObjectMetadata, 70 | FluxReportStatus, 71 | FluxReportSpec 72 | > { 73 | static readonly kind = "FluxReport"; 74 | static readonly namespaced = true; 75 | static readonly apiBase = "/apis/fluxcd.controlplane.io/v1/fluxreports"; 76 | 77 | static readonly crd = { 78 | apiVersions: ["fluxcd.controlplane.io/v1"], 79 | plural: "fluxreports", 80 | singular: "fluxreport", 81 | shortNames: [], 82 | title: "Flux Reports", 83 | }; 84 | } 85 | 86 | export class FluxReportApi extends Renderer.K8sApi.KubeApi {} 87 | export class FluxReportStore extends Renderer.K8sApi.KubeObjectStore {} 88 | -------------------------------------------------------------------------------- /src/renderer/components/spec-patches.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { checksum } from "../utils"; 4 | import styles from "./spec-patches.module.scss"; 5 | import stylesInline from "./spec-patches.module.scss?inline"; 6 | import { YamlDump } from "./yaml-dump"; 7 | 8 | import type { Patch } from "../k8s/core/types"; 9 | 10 | const { 11 | Component: { DrawerItem, DrawerTitle, Icon }, 12 | } = Renderer; 13 | 14 | export interface SpecPatchesProps { 15 | patches?: Patch[]; 16 | } 17 | 18 | export const SpecPatches: React.FC = observer((props) => { 19 | const { patches } = props; 20 | 21 | if (!patches || !patches.length) return null; 22 | 23 | return ( 24 | <> 25 | 26 | Patches 27 | {patches.map((patch, index) => { 28 | if (!patch) return null; 29 | 30 | return ( 31 |
32 |
33 | {index + 1} 34 |
35 | 38 | 41 | 44 | 47 | 50 | 53 | 56 |
Patch
57 | 58 |
59 | ); 60 | })} 61 | 62 | ); 63 | }); 64 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/ocirepository-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface OCIRepositoryRef { 8 | digest?: string; 9 | semver?: string; 10 | semverFilter?: string; 11 | tag?: string; 12 | } 13 | 14 | export interface OCILayerSelector { 15 | mediaType?: string; 16 | operation?: "extract" | "copy"; 17 | } 18 | 19 | export interface OIDCIdentityMatch { 20 | issuer: string; 21 | subject: string; 22 | } 23 | 24 | export interface OCIRepositoryVerification { 25 | provider: "cosign"; 26 | secretRef?: LocalObjectReference; 27 | matchOIDCIdentity?: OIDCIdentityMatch[]; 28 | } 29 | 30 | export interface OCIRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 31 | url: string; 32 | ref?: OCIRepositoryRef; 33 | layerSelector?: OCILayerSelector; 34 | provider?: "generic" | "aws" | "azure" | "gcp"; 35 | secretRef?: LocalObjectReference; 36 | verify?: OCIRepositoryVerification; 37 | serviceAccountName?: string; 38 | certSecretRef?: LocalObjectReference; 39 | proxySecretRef?: LocalObjectReference; 40 | interval: string; 41 | timeout?: string; 42 | insecure?: boolean; 43 | suspend?: boolean; 44 | } 45 | 46 | export interface OCIRepositoryStatus extends FluxCDKubeObjectStatus { 47 | url?: string; 48 | artifact?: Artifact; 49 | contentConfigChecksum?: string; 50 | observedIgnore?: string; 51 | observedLayerSelector?: OCILayerSelector; 52 | } 53 | 54 | export class OCIRepository extends Renderer.K8sApi.LensExtensionKubeObject< 55 | Renderer.K8sApi.KubeObjectMetadata, 56 | OCIRepositoryStatus, 57 | OCIRepositorySpec 58 | > { 59 | static readonly kind = "OCIRepository"; 60 | static readonly namespaced = true; 61 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1/ocirepositories"; 62 | 63 | static readonly crd = { 64 | apiVersions: ["source.toolkit.fluxcd.io/v1"], 65 | plural: "ocirepositories", 66 | singular: "ocirepository", 67 | shortNames: ["ocirepo"], 68 | title: "OCI Repositories", 69 | }; 70 | } 71 | 72 | export class OCIRepositoryApi extends Renderer.K8sApi.KubeApi {} 73 | export class OCIRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 74 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/controlplane/resourceset-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { Condition, LabelSelector } from "@freelensapp/kube-object"; 4 | 5 | import type { History } from "../types"; 6 | 7 | export interface CommonMetadata { 8 | annotations?: Record; 9 | labels?: Record; 10 | } 11 | 12 | export interface InputStrategySpec { 13 | name?: "Flatten" | "Permute"; 14 | } 15 | 16 | export interface InputProviderReference { 17 | apiVersion?: "fluxcd.controlplane.io/v1"; 18 | kind: "ResourceSetInputProvider"; 19 | name?: string; 20 | selector?: LabelSelector; 21 | } 22 | 23 | export interface Dependency { 24 | apiVersion: string; 25 | kind: string; 26 | name: string; 27 | namespace?: string; 28 | ready?: boolean; 29 | readyExpr?: string; 30 | } 31 | 32 | type ResourceSetInput = Record; 33 | 34 | export interface ResourceRef { 35 | id: string; 36 | v: string; 37 | } 38 | 39 | export interface ResourceInventory { 40 | entries: ResourceRef[]; 41 | } 42 | 43 | export interface ResourceSetSpec { 44 | commonMetadata?: CommonMetadata; 45 | inputStrategy?: InputStrategySpec; 46 | inputs?: ResourceSetInput[]; 47 | inputsFrom?: InputProviderReference[]; 48 | resources?: any[]; 49 | resourcesTemplate?: string; 50 | dependsOn?: Dependency[]; 51 | serviceAccountName?: string; 52 | wait?: boolean; 53 | } 54 | 55 | export interface ResourceSetStatus { 56 | lastHandledReconcileAt?: string; 57 | conditions?: Condition[]; 58 | inventory?: ResourceInventory; 59 | lastAppliedRevision?: string; 60 | history?: History; 61 | } 62 | 63 | export class ResourceSet extends Renderer.K8sApi.LensExtensionKubeObject< 64 | Renderer.K8sApi.KubeObjectMetadata, 65 | ResourceSetStatus, 66 | ResourceSetSpec 67 | > { 68 | static readonly kind = "ResourceSet"; 69 | static readonly namespaced = true; 70 | static readonly apiBase = "/apis/fluxcd.controlplane.io/v1/resourcesets"; 71 | 72 | static readonly crd = { 73 | apiVersions: ["fluxcd.controlplane.io/v1"], 74 | plural: "resourcesets", 75 | singular: "resourceset", 76 | shortNames: ["rset"], 77 | title: "Resource Sets", 78 | }; 79 | } 80 | 81 | export class ResourceSetApi extends Renderer.K8sApi.KubeApi {} 82 | export class ResourceSetStore extends Renderer.K8sApi.KubeObjectStore {} 83 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/ocirepository-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface OCIRepositoryRef { 8 | digest?: string; 9 | semver?: string; 10 | semverFilter?: string; 11 | tag?: string; 12 | } 13 | 14 | export interface OCILayerSelector { 15 | mediaType?: string; 16 | operation?: "extract" | "copy"; 17 | } 18 | 19 | export interface OIDCIdentityMatch { 20 | issuer: string; 21 | subject: string; 22 | } 23 | 24 | export interface OCIRepositoryVerification { 25 | provider: "cosign"; 26 | secretRef?: LocalObjectReference; 27 | matchOIDCIdentity?: OIDCIdentityMatch[]; 28 | } 29 | 30 | export interface OCIRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 31 | url: string; 32 | ref?: OCIRepositoryRef; 33 | layerSelector?: OCILayerSelector; 34 | provider?: "generic" | "aws" | "azure" | "gcp"; 35 | secretRef?: LocalObjectReference; 36 | verify?: OCIRepositoryVerification; 37 | serviceAccountName?: string; 38 | certSecretRef?: LocalObjectReference; 39 | proxySecretRef?: LocalObjectReference; 40 | interval: string; 41 | timeout?: string; 42 | insecure?: boolean; 43 | suspend?: boolean; 44 | } 45 | 46 | export interface OCIRepositoryStatus extends FluxCDKubeObjectStatus { 47 | url?: string; 48 | artifact?: Artifact; 49 | contentConfigChecksum?: string; 50 | observedIgnore?: string; 51 | observedLayerSelector?: OCILayerSelector; 52 | } 53 | 54 | export class OCIRepository extends Renderer.K8sApi.LensExtensionKubeObject< 55 | Renderer.K8sApi.KubeObjectMetadata, 56 | OCIRepositoryStatus, 57 | OCIRepositorySpec 58 | > { 59 | static readonly kind = "OCIRepository"; 60 | static readonly namespaced = true; 61 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta2/ocirepositories"; 62 | 63 | static readonly crd = { 64 | apiVersions: ["source.toolkit.fluxcd.io/v1beta2"], 65 | plural: "ocirepositories", 66 | singular: "ocirepository", 67 | shortNames: ["ocirepo"], 68 | title: "OCI Repositories", 69 | }; 70 | } 71 | 72 | export class OCIRepositoryApi extends Renderer.K8sApi.KubeApi {} 73 | export class OCIRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 74 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/receivers-v1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Receiver, type ReceiverApi } from "../../k8s/fluxcd/notification/receiver-v1"; 5 | import styles from "./receivers.module.scss"; 6 | import stylesInline from "./receivers.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Receiver; 13 | type KubeObject = Receiver; 14 | type KubeObjectApi = ReceiverApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | type: (object: KubeObject) => object.spec.type, 20 | age: (object: KubeObject) => object.getCreationTimestamp(), 21 | }; 22 | 23 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 24 | { title: "Name", sortBy: "name" }, 25 | { title: "Namespace", sortBy: "namespace" }, 26 | { title: "Type", sortBy: "type", className: styles.type }, 27 | { title: "Age", sortBy: "age", className: styles.age }, 28 | ]; 29 | 30 | export interface ReceiversPageProps { 31 | extension: Renderer.LensExtension; 32 | } 33 | 34 | export const ReceiversPage = observer((props: ReceiversPageProps) => 35 | withErrorPage(props, () => { 36 | const store = KubeObject.getStore(); 37 | 38 | return ( 39 | <> 40 | 41 | 42 | tableId={`${KubeObject.crd.plural}Table`} 43 | className={styles.page} 44 | store={store} 45 | sortingCallbacks={sortingCallbacks} 46 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 47 | renderHeaderTitle={KubeObject.crd.title} 48 | renderTableHeader={renderTableHeader} 49 | renderTableContents={(object: KubeObject) => [ 50 | {object.getName()}, 51 | , 52 | {object.spec.type}, 53 | , 54 | ]} 55 | /> 56 | 57 | ); 58 | }), 59 | ); 60 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/receivers-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Receiver, type ReceiverApi } from "../../k8s/fluxcd/notification/receiver-v1beta1"; 5 | import styles from "./receivers.module.scss"; 6 | import stylesInline from "./receivers.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Receiver; 13 | type KubeObject = Receiver; 14 | type KubeObjectApi = ReceiverApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | type: (object: KubeObject) => object.spec.type, 20 | age: (object: KubeObject) => object.getCreationTimestamp(), 21 | }; 22 | 23 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 24 | { title: "Name", sortBy: "name" }, 25 | { title: "Namespace", sortBy: "namespace" }, 26 | { title: "Type", sortBy: "type", className: styles.type }, 27 | { title: "Age", sortBy: "age", className: styles.age }, 28 | ]; 29 | 30 | export interface ReceiversPageProps { 31 | extension: Renderer.LensExtension; 32 | } 33 | 34 | export const ReceiversPage = observer((props: ReceiversPageProps) => 35 | withErrorPage(props, () => { 36 | const store = KubeObject.getStore(); 37 | 38 | return ( 39 | <> 40 | 41 | 42 | tableId={`${KubeObject.crd.plural}Table`} 43 | className={styles.page} 44 | store={store} 45 | sortingCallbacks={sortingCallbacks} 46 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 47 | renderHeaderTitle={KubeObject.crd.title} 48 | renderTableHeader={renderTableHeader} 49 | renderTableContents={(object: KubeObject) => [ 50 | {object.getName()}, 51 | , 52 | {object.spec.type}, 53 | , 54 | ]} 55 | /> 56 | 57 | ); 58 | }), 59 | ); 60 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/receivers-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Receiver, type ReceiverApi } from "../../k8s/fluxcd/notification/receiver-v1beta2"; 5 | import styles from "./receivers.module.scss"; 6 | import stylesInline from "./receivers.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Receiver; 13 | type KubeObject = Receiver; 14 | type KubeObjectApi = ReceiverApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | type: (object: KubeObject) => object.spec.type, 20 | age: (object: KubeObject) => object.getCreationTimestamp(), 21 | }; 22 | 23 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 24 | { title: "Name", sortBy: "name" }, 25 | { title: "Namespace", sortBy: "namespace" }, 26 | { title: "Type", sortBy: "type", className: styles.type }, 27 | { title: "Age", sortBy: "age", className: styles.age }, 28 | ]; 29 | 30 | export interface ReceiversPageProps { 31 | extension: Renderer.LensExtension; 32 | } 33 | 34 | export const ReceiversPage = observer((props: ReceiversPageProps) => 35 | withErrorPage(props, () => { 36 | const store = KubeObject.getStore(); 37 | 38 | return ( 39 | <> 40 | 41 | 42 | tableId={`${KubeObject.crd.plural}Table`} 43 | className={styles.page} 44 | store={store} 45 | sortingCallbacks={sortingCallbacks} 46 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 47 | renderHeaderTitle={KubeObject.crd.title} 48 | renderTableHeader={renderTableHeader} 49 | renderTableContents={(object: KubeObject) => [ 50 | {object.getName()}, 51 | , 52 | {object.spec.type}, 53 | , 54 | ]} 55 | /> 56 | 57 | ); 58 | }), 59 | ); 60 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/receivers-v1beta3.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Receiver, type ReceiverApi } from "../../k8s/fluxcd/notification/receiver-v1beta3"; 5 | import styles from "./receivers.module.scss"; 6 | import stylesInline from "./receivers.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Receiver; 13 | type KubeObject = Receiver; 14 | type KubeObjectApi = ReceiverApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | type: (object: KubeObject) => object.spec.type, 20 | age: (object: KubeObject) => object.getCreationTimestamp(), 21 | }; 22 | 23 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 24 | { title: "Name", sortBy: "name" }, 25 | { title: "Namespace", sortBy: "namespace" }, 26 | { title: "Type", sortBy: "type", className: styles.type }, 27 | { title: "Age", sortBy: "age", className: styles.age }, 28 | ]; 29 | 30 | export interface ReceiversPageProps { 31 | extension: Renderer.LensExtension; 32 | } 33 | 34 | export const ReceiversPage = observer((props: ReceiversPageProps) => 35 | withErrorPage(props, () => { 36 | const store = KubeObject.getStore(); 37 | 38 | return ( 39 | <> 40 | 41 | 42 | tableId={`${KubeObject.crd.plural}Table`} 43 | className={styles.page} 44 | store={store} 45 | sortingCallbacks={sortingCallbacks} 46 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 47 | renderHeaderTitle={KubeObject.crd.title} 48 | renderTableHeader={renderTableHeader} 49 | renderTableContents={(object: KubeObject) => [ 50 | {object.getName()}, 51 | , 52 | {object.spec.type}, 53 | , 54 | ]} 55 | /> 56 | 57 | ); 58 | }), 59 | ); 60 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/alerts-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Alert, type AlertApi } from "../../k8s/fluxcd/notification/alert-v1beta1"; 5 | import styles from "./alerts.module.scss"; 6 | import stylesInline from "./alerts.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Alert; 13 | type KubeObject = Alert; 14 | type KubeObjectApi = AlertApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | severity: (object: KubeObject) => object.spec.eventSeverity ?? "info", 20 | age: (object: KubeObject) => object.getCreationTimestamp(), 21 | }; 22 | 23 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 24 | { title: "Name", sortBy: "name" }, 25 | { title: "Namespace", sortBy: "namespace" }, 26 | { title: "Severity", sortBy: "severity", className: styles.severity }, 27 | { title: "Age", sortBy: "age", className: styles.age }, 28 | ]; 29 | 30 | export interface AlertsPageProps { 31 | extension: Renderer.LensExtension; 32 | } 33 | 34 | export const AlertsPage = observer((props: AlertsPageProps) => 35 | withErrorPage(props, () => { 36 | const store = KubeObject.getStore(); 37 | 38 | return ( 39 | <> 40 | 41 | 42 | tableId={`${KubeObject.crd.plural}Table`} 43 | className={styles.page} 44 | store={store} 45 | sortingCallbacks={sortingCallbacks} 46 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 47 | renderHeaderTitle={KubeObject.crd.title} 48 | renderTableHeader={renderTableHeader} 49 | renderTableContents={(object: KubeObject) => [ 50 | {object.getName()}, 51 | , 52 | {object.spec.eventSeverity ?? "info"}, 53 | , 54 | ]} 55 | /> 56 | 57 | ); 58 | }), 59 | ); 60 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/alerts-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Alert, type AlertApi } from "../../k8s/fluxcd/notification/alert-v1beta2"; 5 | import styles from "./alerts.module.scss"; 6 | import stylesInline from "./alerts.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Alert; 13 | type KubeObject = Alert; 14 | type KubeObjectApi = AlertApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | severity: (object: KubeObject) => object.spec.eventSeverity ?? "info", 20 | age: (object: KubeObject) => object.getCreationTimestamp(), 21 | }; 22 | 23 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 24 | { title: "Name", sortBy: "name" }, 25 | { title: "Namespace", sortBy: "namespace" }, 26 | { title: "Severity", sortBy: "severity", className: styles.severity }, 27 | { title: "Age", sortBy: "age", className: styles.age }, 28 | ]; 29 | 30 | export interface AlertsPageProps { 31 | extension: Renderer.LensExtension; 32 | } 33 | 34 | export const AlertsPage = observer((props: AlertsPageProps) => 35 | withErrorPage(props, () => { 36 | const store = KubeObject.getStore(); 37 | 38 | return ( 39 | <> 40 | 41 | 42 | tableId={`${KubeObject.crd.plural}Table`} 43 | className={styles.page} 44 | store={store} 45 | sortingCallbacks={sortingCallbacks} 46 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 47 | renderHeaderTitle={KubeObject.crd.title} 48 | renderTableHeader={renderTableHeader} 49 | renderTableContents={(object: KubeObject) => [ 50 | {object.getName()}, 51 | , 52 | {object.spec.eventSeverity ?? "info"}, 53 | , 54 | ]} 55 | /> 56 | 57 | ); 58 | }), 59 | ); 60 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/alerts-v1beta3.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Alert, type AlertApi } from "../../k8s/fluxcd/notification/alert-v1beta3"; 5 | import styles from "./alerts.module.scss"; 6 | import stylesInline from "./alerts.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Alert; 13 | type KubeObject = Alert; 14 | type KubeObjectApi = AlertApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | severity: (object: KubeObject) => object.spec.eventSeverity ?? "info", 20 | age: (object: KubeObject) => object.getCreationTimestamp(), 21 | }; 22 | 23 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 24 | { title: "Name", sortBy: "name" }, 25 | { title: "Namespace", sortBy: "namespace" }, 26 | { title: "Severity", sortBy: "severity", className: styles.severity }, 27 | { title: "Age", sortBy: "age", className: styles.age }, 28 | ]; 29 | 30 | export interface AlertsPageProps { 31 | extension: Renderer.LensExtension; 32 | } 33 | 34 | export const AlertsPage = observer((props: AlertsPageProps) => 35 | withErrorPage(props, () => { 36 | const store = KubeObject.getStore(); 37 | 38 | return ( 39 | <> 40 | 41 | 42 | tableId={`${KubeObject.crd.plural}Table`} 43 | className={styles.page} 44 | store={store} 45 | sortingCallbacks={sortingCallbacks} 46 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 47 | renderHeaderTitle={KubeObject.crd.title} 48 | renderTableHeader={renderTableHeader} 49 | renderTableContents={(object: KubeObject) => [ 50 | {object.getName()}, 51 | , 52 | {object.spec.eventSeverity ?? "info"}, 53 | , 54 | ]} 55 | /> 56 | 57 | ); 58 | }), 59 | ); 60 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/providers-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Provider, type ProviderApi } from "../../k8s/fluxcd/notification/provider-v1beta1"; 5 | import styles from "./providers.module.scss"; 6 | import stylesInline from "./providers.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Provider; 13 | type KubeObject = Provider; 14 | type KubeObjectApi = ProviderApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | type: (object: KubeObject) => object.spec.type, 20 | channel: (object: KubeObject) => object.spec.channel, 21 | age: (object: KubeObject) => object.getCreationTimestamp(), 22 | }; 23 | 24 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 25 | { title: "Name", sortBy: "name" }, 26 | { title: "Namespace", sortBy: "namespace" }, 27 | { title: "Type", sortBy: "type", className: styles.type }, 28 | { title: "Channel", sortBy: "channel", className: styles.channel }, 29 | { title: "Age", sortBy: "age", className: styles.age }, 30 | ]; 31 | 32 | export interface ProvidersPageProps { 33 | extension: Renderer.LensExtension; 34 | } 35 | 36 | export const ProvidersPage = observer((props: ProvidersPageProps) => 37 | withErrorPage(props, () => { 38 | const store = KubeObject.getStore(); 39 | 40 | return ( 41 | <> 42 | 43 | 44 | tableId={`${KubeObject.crd.plural}Table`} 45 | className={styles.page} 46 | store={store} 47 | sortingCallbacks={sortingCallbacks} 48 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 49 | renderHeaderTitle={KubeObject.crd.title} 50 | renderTableHeader={renderTableHeader} 51 | renderTableContents={(object: KubeObject) => [ 52 | {object.getName()}, 53 | , 54 | {object.spec.type}, 55 | {object.spec.channel}, 56 | , 57 | ]} 58 | /> 59 | 60 | ); 61 | }), 62 | ); 63 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/providers-v1beta2.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Provider, type ProviderApi } from "../../k8s/fluxcd/notification/provider-v1beta2"; 5 | import styles from "./providers.module.scss"; 6 | import stylesInline from "./providers.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Provider; 13 | type KubeObject = Provider; 14 | type KubeObjectApi = ProviderApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | type: (object: KubeObject) => object.spec.type, 20 | channel: (object: KubeObject) => object.spec.channel, 21 | age: (object: KubeObject) => object.getCreationTimestamp(), 22 | }; 23 | 24 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 25 | { title: "Name", sortBy: "name" }, 26 | { title: "Namespace", sortBy: "namespace" }, 27 | { title: "Type", sortBy: "type", className: styles.type }, 28 | { title: "Channel", sortBy: "channel", className: styles.channel }, 29 | { title: "Age", sortBy: "age", className: styles.age }, 30 | ]; 31 | 32 | export interface ProvidersPageProps { 33 | extension: Renderer.LensExtension; 34 | } 35 | 36 | export const ProvidersPage = observer((props: ProvidersPageProps) => 37 | withErrorPage(props, () => { 38 | const store = KubeObject.getStore(); 39 | 40 | return ( 41 | <> 42 | 43 | 44 | tableId={`${KubeObject.crd.plural}Table`} 45 | className={styles.page} 46 | store={store} 47 | sortingCallbacks={sortingCallbacks} 48 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 49 | renderHeaderTitle={KubeObject.crd.title} 50 | renderTableHeader={renderTableHeader} 51 | renderTableContents={(object: KubeObject) => [ 52 | {object.getName()}, 53 | , 54 | {object.spec.type}, 55 | {object.spec.channel}, 56 | , 57 | ]} 58 | /> 59 | 60 | ); 61 | }), 62 | ); 63 | -------------------------------------------------------------------------------- /src/renderer/pages/notifications/providers-v1beta3.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import { withErrorPage } from "../../components/error-page"; 4 | import { Provider, type ProviderApi } from "../../k8s/fluxcd/notification/provider-v1beta3"; 5 | import styles from "./providers.module.scss"; 6 | import stylesInline from "./providers.module.scss?inline"; 7 | 8 | const { 9 | Component: { KubeObjectAge, KubeObjectListLayout, NamespaceSelectBadge, WithTooltip }, 10 | } = Renderer; 11 | 12 | const KubeObject = Provider; 13 | type KubeObject = Provider; 14 | type KubeObjectApi = ProviderApi; 15 | 16 | const sortingCallbacks = { 17 | name: (object: KubeObject) => object.getName(), 18 | namespace: (object: KubeObject) => object.getNs(), 19 | type: (object: KubeObject) => object.spec.type, 20 | channel: (object: KubeObject) => object.spec.channel, 21 | age: (object: KubeObject) => object.getCreationTimestamp(), 22 | }; 23 | 24 | const renderTableHeader: { title: string; sortBy: keyof typeof sortingCallbacks; className?: string }[] = [ 25 | { title: "Name", sortBy: "name" }, 26 | { title: "Namespace", sortBy: "namespace" }, 27 | { title: "Type", sortBy: "type", className: styles.type }, 28 | { title: "Channel", sortBy: "channel", className: styles.channel }, 29 | { title: "Age", sortBy: "age", className: styles.age }, 30 | ]; 31 | 32 | export interface ProvidersPageProps { 33 | extension: Renderer.LensExtension; 34 | } 35 | 36 | export const ProvidersPage = observer((props: ProvidersPageProps) => 37 | withErrorPage(props, () => { 38 | const store = KubeObject.getStore(); 39 | 40 | return ( 41 | <> 42 | 43 | 44 | tableId={`${KubeObject.crd.plural}Table`} 45 | className={styles.page} 46 | store={store} 47 | sortingCallbacks={sortingCallbacks} 48 | searchFilters={[(object: KubeObject) => object.getSearchFields()]} 49 | renderHeaderTitle={KubeObject.crd.title} 50 | renderTableHeader={renderTableHeader} 51 | renderTableContents={(object: KubeObject) => [ 52 | {object.getName()}, 53 | , 54 | {object.spec.type}, 55 | {object.spec.channel}, 56 | , 57 | ]} 58 | /> 59 | 60 | ); 61 | }), 62 | ); 63 | -------------------------------------------------------------------------------- /src/renderer/components/status-conditions.ts: -------------------------------------------------------------------------------- 1 | import moment from "moment"; 2 | 3 | import type { Condition } from "@freelensapp/kube-object"; 4 | 5 | function timeToUnix(dateStr?: string): number { 6 | const m = moment(dateStr, moment.ISO_8601, true); 7 | return m.isValid() ? m.unix() : 0; 8 | } 9 | 10 | const conditionTypePrioritiesDefault = { 11 | PodScheduled: 1, 12 | PodReadyToStartContainers: 2, 13 | ContainersReady: 3, 14 | ArtifactInStorage: 3, 15 | Released: 3, 16 | Initialized: 4, 17 | Synced: 4, 18 | Ready: 5, 19 | }; 20 | 21 | /** 22 | * Sort conditions (the newer first) using heuristic: first sorts fields by 23 | * date and if the date is the same then checks priority from the object. 24 | */ 25 | export function sortConditions( 26 | conditions: Condition[], 27 | conditionTypePriorities: Record = conditionTypePrioritiesDefault, 28 | ): Condition[] | undefined { 29 | return conditions?.sort( 30 | (a, b) => 31 | timeToUnix(b.lastTransitionTime) - timeToUnix(a.lastTransitionTime) || 32 | (conditionTypePriorities[b.type] ?? 0) - (conditionTypePriorities[a.type] ?? 0), 33 | ); 34 | } 35 | 36 | export function getLastCondition(conditions: Condition[]): Condition | undefined { 37 | return (sortConditions(conditions) ?? [])[0]; 38 | } 39 | 40 | export function getConditionText(conditions?: Condition[]) { 41 | if (!conditions || !conditions.length) return "Unknown"; 42 | const condition = getLastCondition(conditions); 43 | if ("suspend" in conditions && conditions.suspend) return "Suspended"; 44 | if (condition?.type === "Ready" && condition?.status === "True") return "Ready"; 45 | if (condition?.status === "False") return "Not Ready"; 46 | if (condition?.type == "Stalled") return "Stalled"; 47 | if (conditions) return "In Progress"; 48 | return "Unknown"; 49 | } 50 | 51 | export function getStatusMessage(conditions?: Condition[]) { 52 | if (!conditions || !conditions.length) return; 53 | return getLastCondition(conditions)?.message; 54 | } 55 | 56 | /** 57 | * Returns a CSS class name that is defined in the main application. 58 | */ 59 | export function getConditionClass(conditions?: Condition[]) { 60 | const status = getConditionText(conditions); 61 | switch (status) { 62 | case "In Progress": 63 | return "warning"; 64 | case "Not Ready": 65 | return "error"; 66 | case "Ready": 67 | return "success"; 68 | case "Suspended": 69 | return "info"; 70 | default: 71 | return ""; 72 | } 73 | } 74 | 75 | export function getLastUpdated(conditions?: Condition[]) { 76 | if (!conditions || !conditions.length) return; 77 | return getLastCondition(conditions)?.lastTransitionTime; 78 | } 79 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/controlplane/resourcesetinputprovider-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { Condition } from "@freelensapp/kube-object"; 4 | 5 | export interface ResourceSetInput { 6 | [key: string]: any; 7 | } 8 | 9 | export interface Schedule { 10 | cron: string; 11 | timeZone?: string; 12 | window?: string; 13 | } 14 | 15 | export interface NextSchedule extends Schedule { 16 | when: string; 17 | } 18 | 19 | export interface ResourceSetInputFilter { 20 | includeBranch?: string; 21 | excludeBranch?: string; 22 | includeTag?: string; 23 | excludeTag?: string; 24 | labels?: string[]; 25 | limit?: number; 26 | semver?: string; 27 | } 28 | 29 | export interface ResourceSetInputSkip { 30 | labels?: string[]; 31 | } 32 | 33 | export interface LocalObjectReference { 34 | name: string; 35 | } 36 | 37 | export interface ResourceSetInputProviderSpec { 38 | type: 39 | | "Static" 40 | | "GitHubBranch" 41 | | "GitHubTag" 42 | | "GitHubPullRequest" 43 | | "GitLabBranch" 44 | | "GitLabTag" 45 | | "GitLabMergeRequest" 46 | | "AzureDevOpsBranch" 47 | | "AzureDevOpsTag" 48 | | "AzureDevOpsPullRequest" 49 | | "OCIArtifactTag" 50 | | "ACRArtifactTag" 51 | | "ECRArtifactTag" 52 | | "GARArtifactTag;"; 53 | url?: string; 54 | serviceAccountName?: string; 55 | secretRef?: LocalObjectReference; 56 | certSecretRef?: LocalObjectReference; 57 | defaultValues?: ResourceSetInput; 58 | filter?: ResourceSetInputFilter; 59 | skip?: ResourceSetInputSkip; 60 | schedule?: Schedule[]; 61 | } 62 | 63 | export interface ResourceSetInputProviderStatus { 64 | lastHandledReconcileAt?: string; 65 | lastHandledForceAt?: string; 66 | conditions?: Condition[]; 67 | exportedInputs?: ResourceSetInput[]; 68 | lastExportedRevision?: string; 69 | nextSchedule?: NextSchedule; 70 | } 71 | 72 | export class ResourceSetInputProvider extends Renderer.K8sApi.LensExtensionKubeObject< 73 | Renderer.K8sApi.KubeObjectMetadata, 74 | ResourceSetInputProviderStatus, 75 | ResourceSetInputProviderSpec 76 | > { 77 | static readonly kind = "ResourceSetInputProvider"; 78 | static readonly namespaced = true; 79 | static readonly apiBase = "/apis/fluxcd.controlplane.io/v1/resourcesetinputproviders"; 80 | 81 | static readonly crd = { 82 | apiVersions: ["fluxcd.controlplane.io/v1"], 83 | plural: "resourcesetinputproviders", 84 | singular: "resourcesetinputprovider", 85 | shortNames: ["rsip"], 86 | title: "Resource Set Input Providers", 87 | }; 88 | } 89 | 90 | export class ResourceSetInputProviderApi extends Renderer.K8sApi.KubeApi {} 91 | export class ResourceSetInputProviderStore extends Renderer.K8sApi.KubeObjectStore {} 92 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imageupdateautomation-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { GitRepositoryRef } from "../source/gitrepository-v1"; 6 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 7 | 8 | export interface GitCheckoutSpec { 9 | ref: GitRepositoryRef; 10 | } 11 | 12 | export interface CommitUser { 13 | name?: string; 14 | email: string; 15 | } 16 | 17 | export interface SigningKey { 18 | secretRef?: LocalObjectReference; 19 | } 20 | 21 | export interface CommitSpec { 22 | author?: CommitUser; 23 | signingKey?: SigningKey; 24 | messageTemplate?: string; 25 | } 26 | 27 | export interface PushSpec { 28 | branch?: string; 29 | refspec?: string; 30 | options?: Record; 31 | } 32 | 33 | export interface GitSpec { 34 | checkout?: GitCheckoutSpec; 35 | commit?: CommitSpec; 36 | push?: PushSpec; 37 | } 38 | 39 | export interface UpdateStrategy { 40 | strategy: string; 41 | path?: string; 42 | } 43 | 44 | export interface ImageRef { 45 | name: string; 46 | tag: string; 47 | digest?: string; 48 | } 49 | 50 | export interface ImageUpdateAutomationSpec extends FluxCDKubeObjectSpecWithSuspend { 51 | sourceRef: NamespacedObjectKindReference; 52 | git?: GitSpec; 53 | interval: string; 54 | update?: UpdateStrategy; 55 | suspend?: boolean; 56 | } 57 | 58 | export interface ImageUpdateAutomationStatus extends FluxCDKubeObjectStatus { 59 | lastAutomationRunTime?: string; 60 | lastPushCommit?: string; 61 | lastPushTime?: string; 62 | } 63 | 64 | export class ImageUpdateAutomation extends Renderer.K8sApi.LensExtensionKubeObject< 65 | Renderer.K8sApi.KubeObjectMetadata, 66 | ImageUpdateAutomationStatus, 67 | ImageUpdateAutomationSpec 68 | > { 69 | static readonly kind = "ImageUpdateAutomation"; 70 | static readonly namespaced = true; 71 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1beta1/imageupdateautomations"; 72 | 73 | static readonly crd = { 74 | apiVersions: ["image.toolkit.fluxcd.io/v1beta1"], 75 | plural: "imageupdateautomations", 76 | singular: "imageupdateautomation", 77 | shortNames: [], 78 | title: "Image Update Automations", 79 | }; 80 | 81 | static getCommitAuthor(object: ImageUpdateAutomation): string | undefined { 82 | const { email, name } = object.spec.git?.commit?.author ?? {}; 83 | if (!email) return; 84 | return name ? `${name} <${email}>` : email; 85 | } 86 | } 87 | 88 | export class ImageUpdateAutomationApi extends Renderer.K8sApi.KubeApi {} 89 | export class ImageUpdateAutomationStore extends Renderer.K8sApi.KubeObjectStore {} 90 | -------------------------------------------------------------------------------- /src/renderer/components/details/image/image-repository-details-v1beta1.tsx: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | import { observer } from "mobx-react"; 3 | import React from "react"; 4 | import { ImageRepository } from "../../../k8s/fluxcd/image/imagerepository-v1beta1"; 5 | import { DurationAbsoluteTimestamp } from "../../duration-absolute"; 6 | import { LinkToSecret } from "../../link-to-secret"; 7 | import { LinkToServiceAccount } from "../../link-to-service-account"; 8 | import { SpecAccessFrom } from "../../spec-access-from"; 9 | 10 | const { 11 | Component: { BadgeBoolean, DrawerItem, DrawerTitle }, 12 | } = Renderer; 13 | 14 | export const ImageRepositoryDetails: React.FC> = observer( 15 | (props) => { 16 | const { object } = props; 17 | const namespace = object.getNs(); 18 | 19 | return ( 20 | <> 21 |
22 | 23 | 24 | 25 | {object.spec.interval} 26 | {object.spec.timeout} 27 | {object.spec.image} 28 | 35 | 38 | 41 | 44 | 45 | 46 | 47 | {object.status?.lastScanResult && ( 48 |
49 | Scan Result 50 | 51 | 52 | 53 | {object.status.lastScanResult.tagCount} 54 |
55 | )} 56 |
57 | 58 | ); 59 | }, 60 | ); 61 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imageupdateautomation-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { GitRepositoryRef } from "../source/gitrepository-v1"; 6 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 7 | 8 | export interface GitCheckoutSpec { 9 | ref: GitRepositoryRef; 10 | } 11 | 12 | export interface CommitUser { 13 | name?: string; 14 | email: string; 15 | } 16 | 17 | export interface SigningKey { 18 | secretRef?: LocalObjectReference; 19 | } 20 | 21 | export interface CommitSpec { 22 | author?: CommitUser; 23 | signingKey?: SigningKey; 24 | messageTemplate?: string; 25 | } 26 | 27 | export interface PushSpec { 28 | branch?: string; 29 | refspec?: string; 30 | options?: Record; 31 | } 32 | 33 | export interface GitSpec { 34 | checkout?: GitCheckoutSpec; 35 | commit?: CommitSpec; 36 | push?: PushSpec; 37 | } 38 | 39 | export interface UpdateStrategy { 40 | strategy: string; 41 | path?: string; 42 | } 43 | 44 | export interface ImageRef { 45 | name: string; 46 | tag: string; 47 | digest?: string; 48 | } 49 | 50 | export interface ImageUpdateAutomationSpec extends FluxCDKubeObjectSpecWithSuspend { 51 | sourceRef: NamespacedObjectKindReference; 52 | git?: GitSpec; 53 | interval: string; 54 | update?: UpdateStrategy; 55 | suspend?: boolean; 56 | } 57 | 58 | export interface ImageUpdateAutomationStatus extends FluxCDKubeObjectStatus { 59 | lastAutomationRunTime?: string; 60 | lastPushCommit?: string; 61 | lastPushTime?: string; 62 | observedPolicies?: Record; 63 | } 64 | 65 | export class ImageUpdateAutomation extends Renderer.K8sApi.LensExtensionKubeObject< 66 | Renderer.K8sApi.KubeObjectMetadata, 67 | ImageUpdateAutomationStatus, 68 | ImageUpdateAutomationSpec 69 | > { 70 | static readonly kind = "ImageUpdateAutomation"; 71 | static readonly namespaced = true; 72 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1/imageupdateautomations"; 73 | 74 | static readonly crd = { 75 | apiVersions: ["image.toolkit.fluxcd.io/v1"], 76 | plural: "imageupdateautomations", 77 | singular: "imageupdateautomation", 78 | shortNames: [], 79 | title: "Image Update Automations", 80 | }; 81 | 82 | static getCommitAuthor(object: ImageUpdateAutomation): string | undefined { 83 | const { email, name } = object.spec.git?.commit?.author ?? {}; 84 | if (!email) return; 85 | return name ? `${name} <${email}>` : email; 86 | } 87 | } 88 | 89 | export class ImageUpdateAutomationApi extends Renderer.K8sApi.KubeApi {} 90 | export class ImageUpdateAutomationStore extends Renderer.K8sApi.KubeObjectStore {} 91 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/gitrepository-v1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface GitRepositoryRef { 8 | branch?: string; 9 | tag?: string; 10 | semver?: string; 11 | commit?: string; 12 | name?: string; 13 | } 14 | 15 | export interface GitRepositoryInclude { 16 | repository: LocalObjectReference; 17 | fromPath: string; 18 | toPath: string; 19 | } 20 | 21 | export interface GitRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 22 | url: string; 23 | secretRef?: LocalObjectReference; 24 | interval: string; 25 | timeout?: string; 26 | ref?: GitRepositoryRef; 27 | verify?: { mode?: string; secretRef?: LocalObjectReference }; 28 | ignore?: string; 29 | suspend?: boolean; 30 | gitImplementation?: "go-git" | "libgit2"; 31 | recurseSubmodules?: boolean; 32 | include?: GitRepositoryInclude[]; 33 | accessFrom?: AccessFrom; 34 | } 35 | 36 | export interface GitRepositoryStatus extends FluxCDKubeObjectStatus { 37 | url?: string; 38 | artifact?: Artifact; 39 | includedArtifacts?: Artifact[]; 40 | } 41 | 42 | export class GitRepository extends Renderer.K8sApi.LensExtensionKubeObject< 43 | Renderer.K8sApi.KubeObjectMetadata, 44 | GitRepositoryStatus, 45 | GitRepositorySpec 46 | > { 47 | static readonly kind = "GitRepository"; 48 | static readonly namespaced = true; 49 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1/gitrepositories"; 50 | 51 | static readonly crd = { 52 | apiVersions: ["source.toolkit.fluxcd.io/v1"], 53 | plural: "gitrepositories", 54 | singular: "gitrepository", 55 | shortNames: ["gitrepo"], 56 | title: "Git Repositories", 57 | }; 58 | 59 | static getGitRef(ref?: GitRepositoryRef): string | undefined { 60 | if (!ref) return; 61 | return ref.name?.replace(/^refs\/(heads|tags)\//, "") ?? ref.branch ?? ref.tag ?? ref.semver ?? ref.commit; 62 | } 63 | 64 | static getGitRefFull(ref?: GitRepositoryRef): string | undefined { 65 | if (!ref) return; 66 | if (ref.name) return `name: ${ref.name}`; 67 | if (ref.branch) return `branch: ${ref.branch}`; 68 | if (ref.tag) return `tag: ${ref.tag}`; 69 | if (ref.semver) return `semver: ${ref.semver}`; 70 | if (ref.commit) return `commit: ${ref.commit}`; 71 | return; 72 | } 73 | 74 | static getGitRevision(object: GitRepository): string | undefined { 75 | return object.status?.artifact?.revision?.replace(/^refs\/(heads|tags)\//, ""); 76 | } 77 | } 78 | 79 | export class GitRepositoryApi extends Renderer.K8sApi.KubeApi {} 80 | export class GitRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 81 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/image/imageupdateautomation-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { GitRepositoryRef } from "../source/gitrepository-v1"; 6 | import type { FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus, NamespacedObjectKindReference } from "../types"; 7 | 8 | export interface GitCheckoutSpec { 9 | ref: GitRepositoryRef; 10 | } 11 | 12 | export interface CommitUser { 13 | name?: string; 14 | email: string; 15 | } 16 | 17 | export interface SigningKey { 18 | secretRef?: LocalObjectReference; 19 | } 20 | 21 | export interface CommitSpec { 22 | author?: CommitUser; 23 | signingKey?: SigningKey; 24 | messageTemplate?: string; 25 | } 26 | 27 | export interface PushSpec { 28 | branch?: string; 29 | refspec?: string; 30 | options?: Record; 31 | } 32 | 33 | export interface GitSpec { 34 | checkout?: GitCheckoutSpec; 35 | commit?: CommitSpec; 36 | push?: PushSpec; 37 | } 38 | 39 | export interface UpdateStrategy { 40 | strategy: string; 41 | path?: string; 42 | } 43 | 44 | export interface ImageRef { 45 | name: string; 46 | tag: string; 47 | digest?: string; 48 | } 49 | 50 | export interface ImageUpdateAutomationSpec extends FluxCDKubeObjectSpecWithSuspend { 51 | sourceRef: NamespacedObjectKindReference; 52 | git?: GitSpec; 53 | interval: string; 54 | update?: UpdateStrategy; 55 | suspend?: boolean; 56 | } 57 | 58 | export interface ImageUpdateAutomationStatus extends FluxCDKubeObjectStatus { 59 | lastAutomationRunTime?: string; 60 | lastPushCommit?: string; 61 | lastPushTime?: string; 62 | observedPolicies?: Record; 63 | } 64 | 65 | export class ImageUpdateAutomation extends Renderer.K8sApi.LensExtensionKubeObject< 66 | Renderer.K8sApi.KubeObjectMetadata, 67 | ImageUpdateAutomationStatus, 68 | ImageUpdateAutomationSpec 69 | > { 70 | static readonly kind = "ImageUpdateAutomation"; 71 | static readonly namespaced = true; 72 | static readonly apiBase = "/apis/image.toolkit.fluxcd.io/v1beta2/imageupdateautomations"; 73 | 74 | static readonly crd = { 75 | apiVersions: ["image.toolkit.fluxcd.io/v1beta2"], 76 | plural: "imageupdateautomations", 77 | singular: "imageupdateautomation", 78 | shortNames: [], 79 | title: "Image Update Automations", 80 | }; 81 | 82 | static getCommitAuthor(object: ImageUpdateAutomation): string | undefined { 83 | const { email, name } = object.spec.git?.commit?.author ?? {}; 84 | if (!email) return; 85 | return name ? `${name} <${email}>` : email; 86 | } 87 | } 88 | 89 | export class ImageUpdateAutomationApi extends Renderer.K8sApi.KubeApi {} 90 | export class ImageUpdateAutomationStore extends Renderer.K8sApi.KubeObjectStore {} 91 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/gitrepository-v1beta1.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface GitRepositoryRef { 8 | branch?: string; 9 | tag?: string; 10 | semver?: string; 11 | commit?: string; 12 | name?: string; 13 | } 14 | 15 | export interface GitRepositoryInclude { 16 | repository: LocalObjectReference; 17 | fromPath: string; 18 | toPath: string; 19 | } 20 | 21 | export interface GitRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 22 | url: string; 23 | secretRef?: LocalObjectReference; 24 | interval: string; 25 | timeout?: string; 26 | ref?: GitRepositoryRef; 27 | verify?: { mode?: string; secretRef?: LocalObjectReference }; 28 | ignore?: string; 29 | suspend?: boolean; 30 | gitImplementation?: "go-git" | "libgit2"; 31 | recurseSubmodules?: boolean; 32 | include?: GitRepositoryInclude[]; 33 | accessFrom?: AccessFrom; 34 | } 35 | 36 | export interface GitRepositoryStatus extends FluxCDKubeObjectStatus { 37 | url?: string; 38 | artifact?: Artifact; 39 | includedArtifacts?: Artifact[]; 40 | } 41 | 42 | export class GitRepository extends Renderer.K8sApi.LensExtensionKubeObject< 43 | Renderer.K8sApi.KubeObjectMetadata, 44 | GitRepositoryStatus, 45 | GitRepositorySpec 46 | > { 47 | static readonly kind = "GitRepository"; 48 | static readonly namespaced = true; 49 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta1/gitrepositories"; 50 | 51 | static readonly crd = { 52 | apiVersions: ["source.toolkit.fluxcd.io/v1beta1"], 53 | plural: "gitrepositories", 54 | singular: "gitrepository", 55 | shortNames: ["gitrepo"], 56 | title: "Git Repositories", 57 | }; 58 | 59 | static getGitRef(ref?: GitRepositoryRef): string | undefined { 60 | if (!ref) return; 61 | return ref.name?.replace(/^refs\/(heads|tags)\//, "") ?? ref.branch ?? ref.tag ?? ref.semver ?? ref.commit; 62 | } 63 | 64 | static getGitRefFull(ref?: GitRepositoryRef): string | undefined { 65 | if (!ref) return; 66 | if (ref.name) return `name: ${ref.name}`; 67 | if (ref.branch) return `branch: ${ref.branch}`; 68 | if (ref.tag) return `tag: ${ref.tag}`; 69 | if (ref.semver) return `semver: ${ref.semver}`; 70 | if (ref.commit) return `commit: ${ref.commit}`; 71 | return; 72 | } 73 | 74 | static getGitRevision(object: GitRepository): string | undefined { 75 | return object.status?.artifact?.revision?.replace(/^refs\/(heads|tags)\//, ""); 76 | } 77 | } 78 | 79 | export class GitRepositoryApi extends Renderer.K8sApi.KubeApi {} 80 | export class GitRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 81 | -------------------------------------------------------------------------------- /src/renderer/k8s/fluxcd/source/gitrepository-v1beta2.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "@freelensapp/extensions"; 2 | 3 | import type { LocalObjectReference } from "@freelensapp/kube-object"; 4 | 5 | import type { AccessFrom, Artifact, FluxCDKubeObjectSpecWithSuspend, FluxCDKubeObjectStatus } from "../types"; 6 | 7 | export interface GitRepositoryRef { 8 | branch?: string; 9 | tag?: string; 10 | semver?: string; 11 | commit?: string; 12 | name?: string; 13 | } 14 | 15 | export interface GitRepositoryInclude { 16 | repository: LocalObjectReference; 17 | fromPath: string; 18 | toPath: string; 19 | } 20 | 21 | export interface GitRepositorySpec extends FluxCDKubeObjectSpecWithSuspend { 22 | url: string; 23 | secretRef?: LocalObjectReference; 24 | interval: string; 25 | timeout?: string; 26 | ref?: GitRepositoryRef; 27 | verify?: { mode?: string; secretRef?: LocalObjectReference }; 28 | ignore?: string; 29 | suspend?: boolean; 30 | gitImplementation?: "go-git" | "libgit2"; 31 | recurseSubmodules?: boolean; 32 | include?: GitRepositoryInclude[]; 33 | accessFrom?: AccessFrom; 34 | } 35 | 36 | export interface GitRepositoryStatus extends FluxCDKubeObjectStatus { 37 | url?: string; 38 | artifact?: Artifact; 39 | includedArtifacts?: Artifact[]; 40 | } 41 | 42 | export class GitRepository extends Renderer.K8sApi.LensExtensionKubeObject< 43 | Renderer.K8sApi.KubeObjectMetadata, 44 | GitRepositoryStatus, 45 | GitRepositorySpec 46 | > { 47 | static readonly kind = "GitRepository"; 48 | static readonly namespaced = true; 49 | static readonly apiBase = "/apis/source.toolkit.fluxcd.io/v1beta2/gitrepositories"; 50 | 51 | static readonly crd = { 52 | apiVersions: ["source.toolkit.fluxcd.io/v1beta2"], 53 | plural: "gitrepositories", 54 | singular: "gitrepository", 55 | shortNames: ["gitrepo"], 56 | title: "Git Repositories", 57 | }; 58 | 59 | static getGitRef(ref?: GitRepositoryRef): string | undefined { 60 | if (!ref) return; 61 | return ref.name?.replace(/^refs\/(heads|tags)\//, "") ?? ref.branch ?? ref.tag ?? ref.semver ?? ref.commit; 62 | } 63 | 64 | static getGitRefFull(ref?: GitRepositoryRef): string | undefined { 65 | if (!ref) return; 66 | if (ref.name) return `name: ${ref.name}`; 67 | if (ref.branch) return `branch: ${ref.branch}`; 68 | if (ref.tag) return `tag: ${ref.tag}`; 69 | if (ref.semver) return `semver: ${ref.semver}`; 70 | if (ref.commit) return `commit: ${ref.commit}`; 71 | return; 72 | } 73 | 74 | static getGitRevision(object: GitRepository): string | undefined { 75 | return object.status?.artifact?.revision?.replace(/^refs\/(heads|tags)\//, ""); 76 | } 77 | } 78 | 79 | export class GitRepositoryApi extends Renderer.K8sApi.KubeApi {} 80 | export class GitRepositoryStore extends Renderer.K8sApi.KubeObjectStore {} 81 | -------------------------------------------------------------------------------- /.trunk/trunk.yaml: -------------------------------------------------------------------------------- 1 | # This file controls the behavior of Trunk: https://docs.trunk.io/cli 2 | # To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml 3 | version: 0.1 4 | cli: 5 | version: 1.25.0 6 | # Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) 7 | plugins: 8 | sources: 9 | - id: trunk 10 | ref: v1.7.4 11 | uri: https://github.com/trunk-io/plugins 12 | # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) 13 | runtimes: 14 | enabled: 15 | - go@1.21.0 16 | - node@22.16.0! # datasource=node-version depName=node 17 | - python@3.10.8 18 | # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) 19 | lint: 20 | definitions: 21 | # See https://github.com/trunk-io/plugins/pull/1063 22 | - name: biome 23 | files: 24 | - astro 25 | - css 26 | - graphql 27 | - html 28 | - javascript 29 | - json 30 | - typescript 31 | commands: 32 | - output: regex 33 | success_codes: 34 | - 0 35 | - 1 36 | batch: true 37 | cache_results: false 38 | name: lint 39 | parse_regex: ^::(?P.*) title=(?P[^,]+),file=(?P[^,]+),line=(?P[^,]+),endLine=[^,]+,col=(?P[^,]+),endColumn=[^:]+::(?P.*) 40 | read_output_from: stdout 41 | run: biome check --config-path=${workspace}/biome.jsonc --reporter=github ${target} 42 | run_from: ${root_or_parent_with(biome.jsonc)} 43 | - output: regex 44 | success_codes: 45 | - 0 46 | batch: true 47 | cache_results: false 48 | formatter: true 49 | name: fmt 50 | parse_regex: ^::(?P.*) title=(?P[^,]+),file=(?P[^,]+),line=(?P[^,]+),endLine=[^,]+,col=(?P[^,]+),endColumn=[^:]+::(?P.*) 51 | read_output_from: stdout 52 | run: biome format --config-path=${workspace}/biome.jsonc --reporter=github --write ${target} 53 | run_from: ${root_or_parent_with(biome.jsonc)} 54 | run_timeout: 1m 55 | 56 | # Prettier checks only *.scss files 57 | - name: prettier 58 | files: 59 | - sass 60 | enabled: 61 | - oxipng@9.1.5 62 | - actionlint@1.7.9 63 | - biome@2.1.1! # datasource=npm depName=@biomejs/biome 64 | - git-diff-check 65 | - markdownlint@0.46.0 66 | - prettier@3.6.2! # datasource=npm depName=prettier 67 | - svgo@4.0.0 68 | - yamlfmt@0.20.0 69 | - yamllint@1.37.1 70 | disabled: 71 | - checkov 72 | - eslint 73 | - osv-scanner 74 | - renovate 75 | - trufflehog 76 | actions: 77 | enabled: 78 | - trunk-announce 79 | - trunk-check-pre-push 80 | - trunk-fmt-pre-commit 81 | - trunk-upgrade-available 82 | --------------------------------------------------------------------------------