├── .nvmrc ├── packages ├── components │ ├── src │ │ ├── molecules │ │ │ ├── README.md │ │ │ ├── TitleBarCount │ │ │ │ ├── types.ts │ │ │ │ ├── index.ts │ │ │ │ ├── args.tsx │ │ │ │ ├── TitleBarCount.tsx │ │ │ │ └── TitleBarCount.stories.tsx │ │ │ ├── LearnCard │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ ├── args.tsx │ │ │ │ └── LeanCard.stories.tsx │ │ │ ├── TitleBar │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ └── TitleBar.stories.tsx │ │ │ ├── ProblemInfo │ │ │ │ ├── index.ts │ │ │ │ ├── utils.ts │ │ │ │ ├── types.ts │ │ │ │ └── ProblemInfo.stories.tsx │ │ │ ├── WalkThrough │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ ├── args.ts │ │ │ │ └── WalkThrough.tsx │ │ │ ├── ActionsMenu │ │ │ │ ├── index.ts │ │ │ │ ├── ActionsMenu.stories.args.tsx │ │ │ │ ├── types.ts │ │ │ │ ├── ActionsMenu.stories.tsx │ │ │ │ └── ActionsMenu.tsx │ │ │ ├── ActivityBar │ │ │ │ ├── index.ts │ │ │ │ └── ActivityBar.stories.tsx │ │ │ ├── WalkThroughCard │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ └── WalkThroughCard.stories.tsx │ │ │ ├── ValidationPopover │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ └── ValidationPopover.stories.tsx │ │ │ ├── LearnPage │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── ValidationOverview │ │ │ │ ├── index.ts │ │ │ │ ├── ValidationOverview.stories.tsx │ │ │ │ ├── constants.tsx │ │ │ │ └── useScroll.ts │ │ │ ├── Panels │ │ │ │ ├── index.ts │ │ │ │ ├── BarPanel.tsx │ │ │ │ ├── FullscreenPanel.tsx │ │ │ │ ├── ResizableRowsPanel.stories.tsx │ │ │ │ ├── types.ts │ │ │ │ ├── ResizableColumnsPanel.stories.tsx │ │ │ │ └── ResizableRowsPanel.tsx │ │ │ ├── index.ts │ │ │ └── stories │ │ │ │ └── ResizablePanels.stories.tsx │ │ ├── atoms │ │ │ ├── Dots │ │ │ │ ├── index.ts │ │ │ │ ├── Dots.stories.tsx │ │ │ │ ├── Dots.styled.tsx │ │ │ │ └── Dots.tsx │ │ │ ├── Spinner │ │ │ │ ├── index.ts │ │ │ │ ├── Spinner.styled.tsx │ │ │ │ ├── Spinner.tsx │ │ │ │ └── Spinner.stories.tsx │ │ │ ├── CopyButton │ │ │ │ ├── index.ts │ │ │ │ └── CopyButton.stories.tsx │ │ │ ├── SearchInput │ │ │ │ ├── index.ts │ │ │ │ └── SearchInput.tsx │ │ │ ├── TextEllipsis │ │ │ │ ├── index.ts │ │ │ │ ├── TextEllipsis.stories.tsx │ │ │ │ └── TextEllipsis.tsx │ │ │ ├── AppButtons │ │ │ │ ├── index.ts │ │ │ │ ├── AppButtons.stories.tsx │ │ │ │ ├── IconButton.stories.tsx │ │ │ │ ├── IconButton.tsx │ │ │ │ └── AppButtons.tsx │ │ │ ├── PaneCloseIcon │ │ │ │ ├── index.ts │ │ │ │ └── PaneCloseIcon.stories.tsx │ │ │ ├── Icon │ │ │ │ ├── index.ts │ │ │ │ └── Icons │ │ │ │ │ ├── ProblemIcon.tsx │ │ │ │ │ ├── Cluster.tsx │ │ │ │ │ ├── DefaultResource.tsx │ │ │ │ │ ├── ProblemSplit.tsx │ │ │ │ │ ├── Terminal.tsx │ │ │ │ │ ├── Validation.tsx │ │ │ │ │ ├── Compare.tsx │ │ │ │ │ ├── OPAStatus.tsx │ │ │ │ │ ├── Checked.tsx │ │ │ │ │ ├── ValidationOPA.tsx │ │ │ │ │ ├── SeverityLow.tsx │ │ │ │ │ ├── SeverityMedium.tsx │ │ │ │ │ ├── ClusterDashboard.tsx │ │ │ │ │ ├── PullRequest.tsx │ │ │ │ │ ├── CompactNodes.tsx │ │ │ │ │ ├── Collapse.tsx │ │ │ │ │ └── Warning.tsx │ │ │ ├── KeyValueInput │ │ │ │ ├── index.ts │ │ │ │ ├── NewKeyValueInput.stories.tsx │ │ │ │ ├── KeyValueInput.stories.tsx │ │ │ │ ├── KeyValueInput.styled.ts │ │ │ │ └── OperationSelect.tsx │ │ │ ├── ProblemIcon │ │ │ │ ├── index.ts │ │ │ │ ├── ProblemIcon.stories.tsx │ │ │ │ └── ProblemIcon.tsx │ │ │ ├── Filter │ │ │ │ ├── index.ts │ │ │ │ └── FilterForm.tsx │ │ │ └── index.ts │ │ ├── organisms │ │ │ ├── index.ts │ │ │ └── ResourceGraph │ │ │ │ ├── index.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── ResourceGraph.stories.tsx │ │ │ │ ├── MiniMap.tsx │ │ │ │ └── types.ts │ │ ├── styles │ │ │ ├── DebugStyles.ts │ │ │ ├── Animations.ts │ │ │ ├── index.ts │ │ │ ├── Borders.ts │ │ │ └── Device.ts │ │ ├── index.ts │ │ └── constants │ │ │ └── index.ts │ ├── vite-env.d.ts │ ├── .gitignore │ ├── .prettierignore │ ├── .storybook │ │ ├── preview-head.html │ │ ├── preview.js │ │ └── main.js │ ├── .eslintignore │ ├── README.md │ ├── tsconfig.node.json │ ├── .prettierrc.yml │ ├── tsconfig.json │ └── .prettierrc ├── parser │ ├── .gitignore │ ├── .prettierignore │ ├── .prettierrc │ ├── src │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── k8s.ts │ │ ├── parse.ts │ │ └── file.ts │ ├── tsconfig.build.json │ ├── .prettierrc.yml │ ├── tsconfig.json │ └── CHANGELOG.md ├── tree-navigator │ ├── src │ │ ├── components │ │ │ ├── index.ts │ │ │ ├── TreeNavigatorRenderer │ │ │ │ ├── index.ts │ │ │ │ └── styled.ts │ │ │ └── SectionRenderer │ │ │ │ ├── index.ts │ │ │ │ └── hooks.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ └── redux.ts │ │ ├── slice │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── types │ │ │ ├── index.ts │ │ │ ├── sliceState.ts │ │ │ ├── rootDispatch.ts │ │ │ ├── rootState.ts │ │ │ ├── rtk.ts │ │ │ └── instance.ts │ │ └── styles │ │ │ └── colors.ts │ ├── .gitignore │ ├── example │ │ ├── src │ │ │ ├── App.css │ │ │ ├── vite-env.d.ts │ │ │ ├── data │ │ │ │ ├── files.ts │ │ │ │ ├── fileEntries.ts │ │ │ │ ├── resources.ts │ │ │ │ └── slice.ts │ │ │ ├── main.tsx │ │ │ ├── App.tsx │ │ │ └── navigators │ │ │ │ ├── ResourceTreeNavigator.ts │ │ │ │ └── FileTreeNavigator.ts │ │ ├── vite.config.ts │ │ ├── tsconfig.node.json │ │ ├── .gitignore │ │ ├── index.html │ │ ├── tsconfig.json │ │ └── package.json │ ├── tsconfig.build.json │ ├── CHANGELOG.md │ └── tsconfig.json ├── validation │ ├── .gitignore │ ├── src │ │ ├── custom.ts │ │ ├── references │ │ │ ├── mappers │ │ │ │ ├── index.ts │ │ │ │ ├── ownerReference.ts │ │ │ │ ├── validatingAdmissionPolicyBinding.ts │ │ │ │ ├── endpoints.ts │ │ │ │ └── endpointSlice.ts │ │ │ ├── index.ts │ │ │ └── utils │ │ │ │ ├── refMatcher.ts │ │ │ │ └── getResourceKindsWithTargetingRefs.ts │ │ ├── validators │ │ │ ├── metadata │ │ │ │ └── index.ts │ │ │ ├── yaml-syntax │ │ │ │ └── index.ts │ │ │ ├── admission-policy │ │ │ │ ├── index.ts │ │ │ │ ├── loadWasm.ts │ │ │ │ ├── rules.ts │ │ │ │ └── types.ts │ │ │ ├── resource-links │ │ │ │ └── index.ts │ │ │ ├── custom │ │ │ │ ├── constants.ts │ │ │ │ └── schemas │ │ │ │ │ ├── pod.v1.ts │ │ │ │ │ ├── job.batch.v1.ts │ │ │ │ │ ├── secret.v1.ts │ │ │ │ │ ├── service.v1.ts │ │ │ │ │ ├── configmap.v1.ts │ │ │ │ │ ├── endpoints.v1.ts │ │ │ │ │ ├── namespace.v1.ts │ │ │ │ │ ├── cronjob.batch.v1.ts │ │ │ │ │ ├── daemonset.apps.v1.ts │ │ │ │ │ ├── limitrange.v1.ts │ │ │ │ │ ├── deployment.apps.v1.ts │ │ │ │ │ ├── replicaset.apps.v1.ts │ │ │ │ │ ├── resourcequota.v1.ts │ │ │ │ │ ├── role.rbac.authorization.k8s.io.v1.ts │ │ │ │ │ ├── statefulset.apps.v1.ts │ │ │ │ │ ├── serviceaccount.v1.ts │ │ │ │ │ ├── ingress.networking.k8s.io.v1.ts │ │ │ │ │ ├── persistentvolume.v1.ts │ │ │ │ │ ├── storageclass.storage.k8s.io.v1.ts │ │ │ │ │ ├── clusterrole.rbac.authorization.k8s.io.v1.ts │ │ │ │ │ ├── rolebinding.rbac.authorization.k8s.io.v1.ts │ │ │ │ │ ├── endpointslice.discovery.k8s.io.v1.ts │ │ │ │ │ ├── networkpolicy.networking.k8s.io.v1.ts │ │ │ │ │ ├── persistentvolumeclaim.v1.ts │ │ │ │ │ ├── replicationcontroller.v1.ts │ │ │ │ │ ├── volumeattachment.storage.k8s.io.v1.ts │ │ │ │ │ ├── clusterrolebinding.rbac.authorization.k8s.io.v1.ts │ │ │ │ │ ├── horizontalpodautoscaler.autoscaling.v2.ts │ │ │ │ │ └── customresourcedefinition.apiextensions.k8s.io.v1.ts │ │ │ ├── kubernetes-schema │ │ │ │ └── index.ts │ │ │ ├── open-policy-agent │ │ │ │ ├── index.ts │ │ │ │ ├── wasmLoader │ │ │ │ │ ├── WasmLoader.ts │ │ │ │ │ ├── FileWasmLoader.ts │ │ │ │ │ ├── RemoteWasmLoader.browser.ts │ │ │ │ │ └── RemoteWasmLoader.node.ts │ │ │ │ └── types.ts │ │ │ ├── index.ts │ │ │ ├── practices │ │ │ │ └── rules │ │ │ │ │ ├── KBP114-no-exposed-service.ts │ │ │ │ │ ├── KBP110-no-ssh-exposed.ts │ │ │ │ │ ├── KBP112-no-secret-mounted-as-env.ts │ │ │ │ │ ├── KBP113-privileged-ports.ts │ │ │ │ │ └── KBP111-no-secret-env.ts │ │ │ └── pod-security-standards │ │ │ │ └── rules │ │ │ │ └── PSS105-hostPath-volumes.ts │ │ ├── taxonomies │ │ │ └── index.ts │ │ ├── __tests__ │ │ │ └── resources │ │ │ │ ├── kustomize-5.0.0-patches-and-values-files │ │ │ │ ├── patches │ │ │ │ │ └── existing-patch.yaml │ │ │ │ ├── valuesFiles │ │ │ │ │ └── existing-values.yaml │ │ │ │ └── kustomization.yaml │ │ │ │ ├── kustomize-with-relative-path-resources │ │ │ │ └── ldap │ │ │ │ │ ├── base │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ └── service.yaml │ │ │ │ │ └── overlays │ │ │ │ │ ├── staging │ │ │ │ │ ├── deployment.yaml │ │ │ │ │ └── kustomization.yaml │ │ │ │ │ └── production │ │ │ │ │ ├── kustomization.yaml │ │ │ │ │ └── deployment.yaml │ │ │ │ ├── kustomize-with-relative-patch │ │ │ │ └── argocd │ │ │ │ │ ├── overlays │ │ │ │ │ └── production │ │ │ │ │ │ └── argocd-server-deploy-command.yaml │ │ │ │ │ └── kustomization.yaml │ │ │ │ ├── kustomize-components │ │ │ │ ├── components │ │ │ │ │ └── without-loadgenerator │ │ │ │ │ │ ├── delete-loadgenerator.patch.yaml │ │ │ │ │ │ └── kustomization.yaml │ │ │ │ └── kustomization.yaml │ │ │ │ ├── config1.yaml │ │ │ │ ├── config2.yaml │ │ │ │ ├── deprecations-4 │ │ │ │ └── resources.yaml │ │ │ │ ├── no-metadata │ │ │ │ └── replica-set.yaml │ │ │ │ ├── basic-deployment │ │ │ │ └── deployment.yaml │ │ │ │ ├── deprecations-1 │ │ │ │ └── replica-set.yaml │ │ │ │ ├── deprecations-3 │ │ │ │ └── replica-set.yaml │ │ │ │ ├── pss-1 │ │ │ │ ├── valid-volume-type.yaml │ │ │ │ └── invalid-volume-type.yaml │ │ │ │ ├── metadata │ │ │ │ └── replica-set.yaml │ │ │ │ └── no-apiversion │ │ │ │ └── resources.yaml │ │ ├── config │ │ │ ├── index.node.ts │ │ │ ├── index.browser.ts │ │ │ ├── read.browser.ts │ │ │ └── read.node.ts │ │ ├── sarif │ │ │ ├── index.ts │ │ │ ├── suppressions │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ └── plugins │ │ │ │ │ └── FakeSuppressor.ts │ │ │ └── fix │ │ │ │ ├── plugins │ │ │ │ └── DisabledSuppressor.ts │ │ │ │ └── index.ts │ │ ├── pluginLoaders │ │ │ ├── index.ts │ │ │ ├── index.node.ts │ │ │ ├── dynamicImportLoader.ts │ │ │ ├── requireFromStringLoader.node.ts │ │ │ └── types.ts │ │ ├── assets │ │ │ └── policies │ │ │ │ └── trivy.wasm │ │ ├── utils │ │ │ ├── isDefined.ts │ │ │ ├── findJsonPointerNode.ts │ │ │ ├── uriBase.ts │ │ │ ├── sarif.ts │ │ │ └── knownResourceKinds.ts │ │ ├── commonExports.ts │ │ ├── common │ │ │ └── NodeWrapper.ts │ │ └── constants.ts │ ├── .prettierignore │ ├── docs │ │ └── images │ │ │ ├── large-icon-256.png │ │ │ └── monokle-cloud-developer-mode.png │ ├── .prettierrc │ ├── tsconfig.build.json │ ├── .prettierrc.yml │ ├── CONTRIBUTING.md │ └── tsconfig.json ├── monaco-kubernetes │ ├── .gitignore │ ├── src │ │ ├── constants.ts │ │ ├── utils │ │ │ ├── typeHelpers.ts │ │ │ └── telemetry.ts │ │ ├── fillers │ │ │ ├── ajv.ts │ │ │ ├── schemaSelectionHandlers.ts │ │ │ └── vscode-nls.ts │ │ └── validation │ │ │ └── types.ts │ ├── docs │ │ └── images │ │ │ └── large-icon-256.png │ ├── tsconfig.json │ ├── index.d.ts │ ├── LICENSE.md │ └── README.md ├── synchronizer │ ├── .gitignore │ ├── .mocharc.json │ ├── CONTRIBUTING.md │ ├── .prettierignore │ ├── src │ │ ├── __tests__ │ │ │ └── fixtures │ │ │ │ ├── auth.token.yaml │ │ │ │ ├── github-kubeshop-monokle-core.policy.yaml │ │ │ │ └── auth.deviceflow.yaml │ │ ├── createDefaultMonokleFetcher.ts │ │ ├── constants.ts │ │ ├── handlers │ │ │ ├── storageHandlerJsonCache.ts │ │ │ └── storageHandlerPolicy.ts │ │ ├── createMonokleFetcher.ts │ │ ├── createDefaultMonokleSynchronizer.ts │ │ ├── createDefaultMonokleAuthenticator.ts │ │ ├── index.ts │ │ └── models │ │ │ └── user.ts │ ├── tsconfig.build.mjs.json │ ├── .prettierrc │ ├── .prettierrc.yml │ ├── tsconfig.build.cjs.json │ ├── scripts │ │ └── fixup.js │ └── tsconfig.json ├── types │ ├── README.md │ ├── package.json │ └── CHANGELOG.md ├── plugin-toolkit │ ├── src │ │ ├── config.ts │ │ └── cli │ │ │ └── build.cts │ ├── docs │ │ └── images │ │ │ └── large-icon-256.png │ ├── CHANGELOG.md │ ├── tsconfig.cli.json │ ├── tsconfig.json │ └── README.md └── create-monokle-plugin │ ├── templates │ └── validation-ts │ │ ├── crd-template │ │ ├── _gitignore │ │ ├── src │ │ │ ├── plugin.ts │ │ │ └── rules │ │ │ │ └── 1-exampleCrd.ts │ │ ├── tsconfig.json │ │ └── package.json │ │ └── basic-template │ │ ├── _gitignore │ │ ├── src │ │ ├── plugin.ts │ │ └── rules │ │ │ └── 1-example.ts │ │ ├── tsconfig.json │ │ └── package.json │ ├── docs │ └── images │ │ └── large-icon-256.png │ ├── CHANGELOG.md │ ├── package.json │ └── LICENSE ├── .github ├── CODEOWNERS └── workflows │ ├── release.yml │ └── test-build.yml ├── turbo.json ├── .changeset ├── config.json └── README.md ├── .gitignore ├── package.json ├── .npmrc ├── CONTRIBUTING.md └── LICENSE /.nvmrc: -------------------------------------------------------------------------------- 1 | 16.17.1 2 | -------------------------------------------------------------------------------- /packages/components/src/molecules/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/parser/.gitignore: -------------------------------------------------------------------------------- 1 | lib/** 2 | **.tgz 3 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/components/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/validation/.gitignore: -------------------------------------------------------------------------------- 1 | lib/** 2 | **.tgz 3 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /cjs 3 | -------------------------------------------------------------------------------- /packages/synchronizer/.gitignore: -------------------------------------------------------------------------------- 1 | lib/** 2 | **.tgz 3 | -------------------------------------------------------------------------------- /packages/tree-navigator/.gitignore: -------------------------------------------------------------------------------- 1 | lib/* 2 | node_modules/* 3 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Dots/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Dots"; 2 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/components/TreeNavigatorRenderer/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./redux"; 2 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/slice/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./slice"; 2 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Spinner/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Spinner"; 2 | -------------------------------------------------------------------------------- /packages/components/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/components/src/atoms/CopyButton/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./CopyButton"; 2 | -------------------------------------------------------------------------------- /packages/components/src/organisms/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ResourceGraph'; 2 | -------------------------------------------------------------------------------- /packages/synchronizer/.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec": "./lib/mjs/__tests__/" 3 | } -------------------------------------------------------------------------------- /packages/components/.gitignore: -------------------------------------------------------------------------------- 1 | storybook-static/** 2 | dist/** 3 | node_modules/** 4 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const LANGUAGE_ID = "kubernetes"; 2 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: black; 3 | } -------------------------------------------------------------------------------- /packages/validation/src/custom.ts: -------------------------------------------------------------------------------- 1 | export * from './validators/custom/config.js'; 2 | -------------------------------------------------------------------------------- /packages/validation/src/references/mappers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './mappers.js'; 2 | -------------------------------------------------------------------------------- /packages/validation/src/validators/metadata/index.ts: -------------------------------------------------------------------------------- 1 | export * from './validator.js'; 2 | -------------------------------------------------------------------------------- /packages/components/src/organisms/ResourceGraph/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ResourceGraph'; 2 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/validation/src/validators/yaml-syntax/index.ts: -------------------------------------------------------------------------------- 1 | export * from './validator.js'; 2 | -------------------------------------------------------------------------------- /packages/components/.prettierignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .git 3 | build 4 | dist 5 | node_modules 6 | 7 | -------------------------------------------------------------------------------- /packages/validation/src/validators/admission-policy/index.ts: -------------------------------------------------------------------------------- 1 | export * from './validator.js'; 2 | -------------------------------------------------------------------------------- /packages/validation/src/validators/resource-links/index.ts: -------------------------------------------------------------------------------- 1 | export * from './validator.js'; 2 | -------------------------------------------------------------------------------- /packages/components/.storybook/preview-head.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/validation/src/taxonomies/index.ts: -------------------------------------------------------------------------------- 1 | export * from './nsa.js'; 2 | export * from './pss.js'; 3 | -------------------------------------------------------------------------------- /packages/components/src/atoms/SearchInput/index.ts: -------------------------------------------------------------------------------- 1 | export {default as SearchInput} from './SearchInput'; 2 | -------------------------------------------------------------------------------- /packages/parser/.prettierignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .git 3 | .vscode 4 | build 5 | dist 6 | lib 7 | node_modules 8 | -------------------------------------------------------------------------------- /packages/synchronizer/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Development 4 | 5 | ## Publication 6 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/constants.ts: -------------------------------------------------------------------------------- 1 | export const DEV_MODE_TOKEN = '@@developer@@'; 2 | -------------------------------------------------------------------------------- /packages/components/src/atoms/TextEllipsis/index.ts: -------------------------------------------------------------------------------- 1 | export {default as TextEllipsis} from './TextEllipsis'; 2 | -------------------------------------------------------------------------------- /packages/synchronizer/.prettierignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .git 3 | .vscode 4 | build 5 | dist 6 | lib 7 | node_modules 8 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/components/SectionRenderer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./SectionRenderer"; 2 | -------------------------------------------------------------------------------- /packages/types/README.md: -------------------------------------------------------------------------------- 1 | # Monokle Types 2 | 3 | Package used to share common types between core packages. 4 | -------------------------------------------------------------------------------- /packages/validation/.prettierignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .git 3 | .vscode 4 | build 5 | dist 6 | lib 7 | node_modules 8 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-5.0.0-patches-and-values-files/patches/existing-patch.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/validation/src/config/index.node.ts: -------------------------------------------------------------------------------- 1 | export * from './parse.js'; 2 | export * from './read.node.js'; 3 | -------------------------------------------------------------------------------- /packages/components/src/atoms/AppButtons/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AppButtons'; 2 | export * from './IconButton'; 3 | -------------------------------------------------------------------------------- /packages/components/src/atoms/PaneCloseIcon/index.ts: -------------------------------------------------------------------------------- 1 | export {default as PaneCloseIcon} from './PaneCloseIcon'; 2 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-5.0.0-patches-and-values-files/valuesFiles/existing-values.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/validation/src/config/index.browser.ts: -------------------------------------------------------------------------------- 1 | export * from './parse.js'; 2 | export * from './read.browser.js'; 3 | -------------------------------------------------------------------------------- /packages/validation/src/references/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utils/helpers.js'; 2 | export * from './process.js'; 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | @devcatalin @WitoDelnat @topliceanurazvan @monojack @DzoQiEuoi @erdkse @yasarkubeshop @manoukyanmari 2 | -------------------------------------------------------------------------------- /packages/validation/src/sarif/index.ts: -------------------------------------------------------------------------------- 1 | export * from './fix/index.js'; 2 | export * from './suppressions/index.js'; 3 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/index.ts: -------------------------------------------------------------------------------- 1 | export {default as Icon} from './Icon'; 2 | export type {IconNames} from './types'; 3 | -------------------------------------------------------------------------------- /packages/components/src/atoms/KeyValueInput/index.ts: -------------------------------------------------------------------------------- 1 | export * from './KeyValueInput'; 2 | export * from './NewKeyValueInput'; 3 | -------------------------------------------------------------------------------- /packages/plugin-toolkit/src/config.ts: -------------------------------------------------------------------------------- 1 | export { 2 | definePlugin, 3 | defineRule, 4 | } from "@monokle/validation/custom"; 5 | -------------------------------------------------------------------------------- /packages/validation/src/pluginLoaders/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dynamicImportLoader.js'; 2 | export * from './PluginLoader.js'; 3 | -------------------------------------------------------------------------------- /packages/components/src/styles/DebugStyles.ts: -------------------------------------------------------------------------------- 1 | export const debugBorder = { 2 | border: '2px dashed rgba(255, 0, 0, 0.4)', 3 | }; 4 | -------------------------------------------------------------------------------- /packages/validation/src/validators/kubernetes-schema/index.ts: -------------------------------------------------------------------------------- 1 | export * from './validator.js'; 2 | export * from './schemaLoader.js'; 3 | -------------------------------------------------------------------------------- /packages/components/src/molecules/TitleBarCount/types.ts: -------------------------------------------------------------------------------- 1 | export type TitleBarCountType = { 2 | count: number; 3 | isActive: boolean; 4 | } 5 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/data/files.ts: -------------------------------------------------------------------------------- 1 | export const files = ["pod.yaml", "deployment.yaml", "configmap.yaml", "serviceaccount.yaml"]; 2 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/index.ts: -------------------------------------------------------------------------------- 1 | export { getTreeNavigatorReducer, setupTreeNavigators, createTreeNavigator } from "./core/treeNavigator"; 2 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/crd-template/_gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | dist 4 | node_modules 5 | **/__generated__/** 6 | -------------------------------------------------------------------------------- /packages/components/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './atoms'; 2 | export * from './molecules'; 3 | export * from './organisms'; 4 | export * from './styles'; 5 | -------------------------------------------------------------------------------- /packages/components/src/molecules/LearnCard/index.ts: -------------------------------------------------------------------------------- 1 | export {default as LearnCard} from './LearnCard'; 2 | export type {LearnCardType} from './types'; 3 | -------------------------------------------------------------------------------- /packages/components/src/molecules/TitleBar/index.ts: -------------------------------------------------------------------------------- 1 | export { default as TitleBar } from "./TitleBar"; 2 | export type { TitleBarType } from "./types"; 3 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/basic-template/_gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | dist 4 | node_modules 5 | **/__generated__/** 6 | -------------------------------------------------------------------------------- /packages/tree-navigator/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "lib"], 4 | "include": ["src"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/validation/docs/images/large-icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubeshop/monokle-core/HEAD/packages/validation/docs/images/large-icon-256.png -------------------------------------------------------------------------------- /packages/validation/src/assets/policies/trivy.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubeshop/monokle-core/HEAD/packages/validation/src/assets/policies/trivy.wasm -------------------------------------------------------------------------------- /packages/components/src/molecules/ProblemInfo/index.ts: -------------------------------------------------------------------------------- 1 | export {default as ProblemInfo} from './ProblemInfo'; 2 | export type {ProblemInfoType} from './types'; 3 | -------------------------------------------------------------------------------- /packages/components/src/molecules/WalkThrough/index.ts: -------------------------------------------------------------------------------- 1 | export {default as WalkThrough} from './WalkThrough'; 2 | export type {WalkThroughProps} from './types'; 3 | -------------------------------------------------------------------------------- /packages/validation/src/validators/open-policy-agent/index.ts: -------------------------------------------------------------------------------- 1 | export * from './rules.js'; 2 | export * from './validator.js'; 3 | export * from './types.js'; 4 | -------------------------------------------------------------------------------- /packages/components/src/atoms/ProblemIcon/index.ts: -------------------------------------------------------------------------------- 1 | export {default as ProblemIcon} from './ProblemIcon'; 2 | export type {ProblemIconType} from './ProblemIcon'; 3 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ActionsMenu/index.ts: -------------------------------------------------------------------------------- 1 | export {default as ActionsMenu} from './ActionsMenu'; 2 | export type {ActivityMenuProps} from './types'; 3 | -------------------------------------------------------------------------------- /packages/plugin-toolkit/docs/images/large-icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubeshop/monokle-core/HEAD/packages/plugin-toolkit/docs/images/large-icon-256.png -------------------------------------------------------------------------------- /packages/validation/src/validators/open-policy-agent/wasmLoader/WasmLoader.ts: -------------------------------------------------------------------------------- 1 | export interface WasmLoader { 2 | load(src: string): Promise; 3 | } 4 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/docs/images/large-icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubeshop/monokle-core/HEAD/packages/monaco-kubernetes/docs/images/large-icon-256.png -------------------------------------------------------------------------------- /packages/components/src/molecules/ActivityBar/index.ts: -------------------------------------------------------------------------------- 1 | export {default as ActivityBar} from './ActivityBar'; 2 | export type {ActivityBarProps, ActivityType} from './types'; 3 | -------------------------------------------------------------------------------- /packages/components/src/molecules/TitleBarCount/index.ts: -------------------------------------------------------------------------------- 1 | export { default as TitleBarCount } from "./TitleBarCount"; 2 | export type { TitleBarCountType } from "./types"; 3 | -------------------------------------------------------------------------------- /packages/components/src/styles/Animations.ts: -------------------------------------------------------------------------------- 1 | export enum AnimationDurations { 2 | fast = '150ms', 3 | base = '300ms', 4 | slow = '500ms', 5 | slower = '1000ms', 6 | } 7 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Filter/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Filter'; 2 | export * from './FilterHeader'; 3 | export * from './FilterForm'; 4 | export * from './FilterButton'; 5 | -------------------------------------------------------------------------------- /packages/components/src/molecules/WalkThroughCard/index.ts: -------------------------------------------------------------------------------- 1 | export {default as WalkThroughCard} from './WalkThroughCard'; 2 | export type {WalkThroughCardProps} from './types'; 3 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/docs/images/large-icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubeshop/monokle-core/HEAD/packages/create-monokle-plugin/docs/images/large-icon-256.png -------------------------------------------------------------------------------- /packages/components/src/molecules/ValidationPopover/index.ts: -------------------------------------------------------------------------------- 1 | export {default as ValidationPopover} from './ValidationPopover'; 2 | export type {ValidationPopoverProps} from './types'; 3 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/src/utils/typeHelpers.ts: -------------------------------------------------------------------------------- 1 | export function isDefined(value: T | null | undefined): value is T { 2 | return value !== null && value !== undefined; 3 | } 4 | -------------------------------------------------------------------------------- /packages/synchronizer/src/__tests__/fixtures/auth.token.yaml: -------------------------------------------------------------------------------- 1 | auth: 2 | email: user1@kubeshop.io 3 | token: 4 | access_token: 'USER1_ACCESS_TOKEN' 5 | token_type: ApiKey 6 | -------------------------------------------------------------------------------- /packages/validation/docs/images/monokle-cloud-developer-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubeshop/monokle-core/HEAD/packages/validation/docs/images/monokle-cloud-developer-mode.png -------------------------------------------------------------------------------- /packages/components/src/molecules/LearnCard/types.ts: -------------------------------------------------------------------------------- 1 | export type LearnCardType = { 2 | description: string; 3 | icon: JSX.Element; 4 | title: string; 5 | onClick: () => void; 6 | }; 7 | -------------------------------------------------------------------------------- /packages/components/src/molecules/WalkThrough/types.ts: -------------------------------------------------------------------------------- 1 | export interface WalkThroughProps { 2 | topic: string; 3 | dismissWalkThrough: () => void; 4 | children: React.ReactNode; 5 | } 6 | -------------------------------------------------------------------------------- /packages/validation/src/pluginLoaders/index.node.ts: -------------------------------------------------------------------------------- 1 | export * from './dynamicImportLoader.js'; 2 | export * from './requireFromStringLoader.node.js'; 3 | export * from './PluginLoader.js'; 4 | -------------------------------------------------------------------------------- /packages/components/src/molecules/LearnPage/index.ts: -------------------------------------------------------------------------------- 1 | export {default as LearnPage} from './LearnPage'; 2 | export type {HelpTopicType, HelpfulResourceCardType, LearnPageType} from './types'; 3 | -------------------------------------------------------------------------------- /packages/validation/src/sarif/suppressions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types.js'; 2 | export * from './plugins/AnnotationSuppressor.js'; 3 | export * from './plugins/FingerprintSuppressor.js'; 4 | -------------------------------------------------------------------------------- /packages/validation/src/utils/isDefined.ts: -------------------------------------------------------------------------------- 1 | import isNil from 'lodash/isNil.js'; 2 | 3 | export function isDefined(value: T | null | undefined): value is T { 4 | return !isNil(value); 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/src/styles/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Animations'; 2 | export * from './Borders'; 3 | export * from './Colors'; 4 | export * from './DebugStyles'; 5 | export * from './Device'; 6 | -------------------------------------------------------------------------------- /packages/parser/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "arrowParens": "avoid", 4 | "bracketSpacing": false, 5 | "semi": true, 6 | "trailingComma": "es5", 7 | "printWidth": 120 8 | } 9 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./blueprint"; 2 | export * from "./customization"; 3 | export * from "./instance"; 4 | export * from "./rtk"; 5 | export * from "./navigator"; 6 | -------------------------------------------------------------------------------- /packages/types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@monokle/types", 3 | "version": "0.3.2", 4 | "types": "./index.d.ts", 5 | "scripts": { 6 | "build": "echo 'Types only package' && exit 0" 7 | } 8 | } -------------------------------------------------------------------------------- /packages/validation/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "arrowParens": "avoid", 4 | "bracketSpacing": false, 5 | "semi": true, 6 | "trailingComma": "es5", 7 | "printWidth": 120 8 | } 9 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-with-relative-path-resources/ldap/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - deployment.yaml 3 | - service.yaml 4 | - crd.yaml 5 | - github.com/test 6 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/types/sliceState.ts: -------------------------------------------------------------------------------- 1 | import { TreeNavigatorState } from "./navigator"; 2 | 3 | export type SliceState = { 4 | stateByTreeNavigatorId: Record; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/validation/src/config/read.browser.ts: -------------------------------------------------------------------------------- 1 | import type {Config} from './parse.js'; 2 | 3 | export async function readConfig(path: string = ''): Promise { 4 | return undefined; 5 | } 6 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-with-relative-patch/argocd/overlays/production/argocd-server-deploy-command.yaml: -------------------------------------------------------------------------------- 1 | - {op: add, path: /spec/template/spec/containers/0/command/-, value: --insecure} 2 | 3 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-components/components/without-loadgenerator/delete-loadgenerator.patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: loadgenerator 5 | $patch: delete 6 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-with-relative-path-resources/ldap/overlays/staging/deployment.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: ldap 6 | spec: 7 | replicas: 2 8 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-with-relative-path-resources/ldap/overlays/staging/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - ../../base 3 | patchesStrategicMerge: 4 | - deployment.yaml 5 | namePrefix: staging- 6 | -------------------------------------------------------------------------------- /packages/components/src/molecules/WalkThrough/args.ts: -------------------------------------------------------------------------------- 1 | import { WalkThroughProps } from "./types"; 2 | 3 | export const WalkThoughArgs: Partial = { 4 | topic: "explore", 5 | dismissWalkThrough: () => {}, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()] 7 | }) 8 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/components/TreeNavigatorRenderer/styled.ts: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const BeforeInitializationContainer = styled.div` 4 | padding-top: 16px; 5 | margin-left: 16px; 6 | `; 7 | -------------------------------------------------------------------------------- /packages/components/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | cache 4 | lib 5 | dist 6 | .husky 7 | webpack.*.js 8 | server.js 9 | build.js 10 | init.js 11 | .eslintrc.js 12 | package.json 13 | antd.theme.ts 14 | src/__generated__ 15 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ValidationOverview/index.ts: -------------------------------------------------------------------------------- 1 | export {default as ValidationOverview} from './ValidationOverview'; 2 | export type {ValidationFiltersValueType, ValidationOverviewType, GroupByFilterOptionType} from './types'; 3 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-with-relative-path-resources/ldap/overlays/production/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - ../../base/ 3 | patchesStrategicMerge: 4 | - deployment.yaml 5 | namePrefix: production- 6 | -------------------------------------------------------------------------------- /packages/parser/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const KUSTOMIZATION_KIND = 'Kustomization'; 2 | export const KUSTOMIZATION_API_GROUP = 'kustomize.config.k8s.io'; 3 | 4 | export const RESOURCE_UUID_NAMESPACE = '6fa71997-8aa8-4b89-b987-cec4fd3de770'; 5 | -------------------------------------------------------------------------------- /packages/components/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export const TOOLTIP_DELAY = 1.0; 2 | export const FILTER_HEADER_HEIGHT = 50; 3 | 4 | export const LAYOUT = { 5 | zIndex: { 6 | low: 200, 7 | medium: 500, 8 | high: 1000, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/src/fillers/ajv.ts: -------------------------------------------------------------------------------- 1 | import { ValidateFunction } from "ajv"; 2 | 3 | export default class AJVStub { 4 | // eslint-disable-next-line class-methods-use-this 5 | compile(): ValidateFunction { 6 | return () => true; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/config1.yaml: -------------------------------------------------------------------------------- 1 | plugins: 2 | yaml-syntax: false 3 | open-policy-agent: false 4 | kubernetes-schema: true 5 | pod-security-standards: true 6 | settings: 7 | kubernetes-schema: 8 | schemaVersion: v1.27.1 9 | -------------------------------------------------------------------------------- /packages/parser/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants.js'; 2 | export * from './extract.js'; 3 | export * from './file.js'; 4 | export * from './k8s.js'; 5 | export * from './parse.js'; 6 | export * from './resource.js'; 7 | export * from './resourceRefs.js'; 8 | -------------------------------------------------------------------------------- /packages/parser/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "node_modules", 5 | "lib", 6 | "src/utils/testing/**", 7 | "src/__tests__/**", 8 | "**/*.test.ts" 9 | ], 10 | "include": ["src"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/types/rootDispatch.ts: -------------------------------------------------------------------------------- 1 | import { AnyAction, Dispatch, ThunkDispatch } from "@reduxjs/toolkit"; 2 | import { RootState } from "./rootState"; 3 | 4 | export type RootDispatch = Dispatch & ThunkDispatch; 5 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Spinner/Spinner.styled.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const SpinnerWrapper = styled.div` 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | 8 | height: inherit; 9 | `; 10 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ProblemInfo/utils.ts: -------------------------------------------------------------------------------- 1 | export function renderToolComponentName(name: string) { 2 | const words = name.split('-'); 3 | const result = words.map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '); 4 | return result; 5 | } 6 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/src/fillers/schemaSelectionHandlers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a stub for `monaco-yaml/lib/esm/schemaSelectionHandlers.js`. 3 | */ 4 | // eslint-disable-next-line @typescript-eslint/no-empty-function 5 | export function JSONSchemaSelection(): void {} 6 | -------------------------------------------------------------------------------- /packages/validation/src/sarif/fix/plugins/DisabledSuppressor.ts: -------------------------------------------------------------------------------- 1 | import type {Fixer} from '../index.js'; 2 | import type {Fix} from '../../../common/sarif.js'; 3 | 4 | export class DisabledFixer implements Fixer { 5 | createFix(): Fix[] { 6 | return []; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/validation/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "node_modules", 5 | "lib", 6 | "src/utils/testing/**", 7 | "src/__tests__/**", 8 | "**/*.test.ts" 9 | ], 10 | "include": ["src"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/components/src/molecules/Panels/index.ts: -------------------------------------------------------------------------------- 1 | export {default as ResizableColumnsPanel} from './ResizableColumnsPanel'; 2 | export {default as ResizableRowsPanel} from './ResizableRowsPanel'; 3 | export type {ResizableColumnsPanelType, ResizableRowsPanelType} from './types'; 4 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/components/README.md: -------------------------------------------------------------------------------- 1 | # @monokle/components 2 | 3 | Shared components between desktop/cloud projects 4 | 5 | # Notice 6 | 7 | In order to correctly use the resizable panes library ( allotment ), importing the css files ( 8 | 'allotment/dist/style.css' ) manually is required. -------------------------------------------------------------------------------- /packages/components/src/molecules/Panels/BarPanel.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import styled from 'styled-components'; 3 | 4 | const BarPanel = styled.div` 5 | width: 8px; 6 | background-color: ${Colors.grey10}; 7 | `; 8 | 9 | export default BarPanel; 10 | -------------------------------------------------------------------------------- /packages/synchronizer/src/__tests__/fixtures/github-kubeshop-monokle-core.policy.yaml: -------------------------------------------------------------------------------- 1 | plugins: 2 | open-policy-agent: false 3 | resource-links: true 4 | yaml-syntax: true 5 | kubernetes-schema: true 6 | pod-security-standards: true 7 | practices: true 8 | metadata: false 9 | -------------------------------------------------------------------------------- /packages/synchronizer/src/__tests__/fixtures/auth.deviceflow.yaml: -------------------------------------------------------------------------------- 1 | auth: 2 | email: user2@kubeshop.io 3 | token: 4 | access_token: 'USER2_ACCESS_TOKEN' 5 | token_type: Bearer 6 | expires_at: 1691579288 7 | id_token: 'USER2_ID_TOKEN' 8 | refresh_token: 'USER2_REFRESH_TOKEN' -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-with-relative-path-resources/ldap/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: ldap 6 | name: ldap-service 7 | spec: 8 | ports: 9 | - port: 389 10 | selector: 11 | app: ldap 12 | -------------------------------------------------------------------------------- /packages/plugin-toolkit/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @monokle/plugin-toolkit 2 | 3 | ## 0.1.0 4 | 5 | ### Minor Changes 6 | 7 | - 034573b: Add monokle-plugin-toolkit 8 | 9 | ### Patch Changes 10 | 11 | - Updated dependencies [034573b] 12 | - Updated dependencies [521529e] 13 | - @monokle/validation@0.10.0 14 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/data/fileEntries.ts: -------------------------------------------------------------------------------- 1 | import { files } from "./files"; 2 | 3 | export type FileEntry = { 4 | filePath: string; 5 | }; 6 | 7 | export const fileMap: Record = Object.fromEntries( 8 | files.map((filePath) => [filePath, { filePath }]) 9 | ); 10 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ActionsMenu/ActionsMenu.stories.args.tsx: -------------------------------------------------------------------------------- 1 | import {ActivityMenuProps} from './types'; 2 | 3 | export const MainActionsMenuArgs: ActivityMenuProps = { 4 | menuItems: [ 5 | { key: '1', label: 'View', onClick: () => console.log('View') }, 6 | ], 7 | show: 'always', 8 | }; 9 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/config2.yaml: -------------------------------------------------------------------------------- 1 | plugins: 2 | open-policy-agent: true 3 | yaml-syntax: true 4 | rules: 5 | open-policy-agent/no-elevated-process: false 6 | open-policy-agent/app-armor: false 7 | open-policy-agent/drop-capabilities: false 8 | open-policy-agent/no-sys-admin: true 9 | -------------------------------------------------------------------------------- /packages/synchronizer/tsconfig.build.mjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "node_modules", 5 | "lib", 6 | "src/utils/testing/**", 7 | "**/*.test.ts" 8 | ], 9 | "include": ["src"], 10 | "compilerOptions": { 11 | "outDir": "lib/mjs", 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/components/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "strict": true, 6 | "strictNullChecks": true, 7 | "moduleResolution": "node", 8 | "allowSyntheticDefaultImports": true 9 | }, 10 | "include": ["vite.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/tree-navigator/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @monokle/tree-navigator 2 | 3 | ## 1.0.4 4 | 5 | ### Patch Changes 6 | 7 | - 11e4eba: Replace useRef with useState in TreeNavigatorRenderer 8 | - 6fca94f: Improved generic types for tree-navigator 9 | 10 | ## 1.0.3 11 | 12 | ### Patch Changes 13 | 14 | - 73ad79a: Fix errors 15 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/types/rootState.ts: -------------------------------------------------------------------------------- 1 | import { SliceState } from "./sliceState"; 2 | 3 | /** 4 | * This is the redux store root state 5 | */ 6 | export interface RootState { 7 | treeNavigator: SliceState; // TODO: would it make sense to get the slice name from an env variable? 8 | [x: string]: any; 9 | } 10 | -------------------------------------------------------------------------------- /packages/components/.storybook/preview.js: -------------------------------------------------------------------------------- 1 | import 'antd/dist/antd.css'; 2 | import 'allotment/dist/style.css'; 3 | 4 | export const parameters = { 5 | actions: {argTypesRegex: '^on[A-Z].*'}, 6 | controls: { 7 | matchers: { 8 | color: /(background|color)$/i, 9 | date: /Date$/, 10 | }, 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/components/src/molecules/TitleBarCount/args.tsx: -------------------------------------------------------------------------------- 1 | import {TitleBarCountType} from './types'; 2 | 3 | export const ActiveTitleBarCountArgs: TitleBarCountType = { 4 | count: 123, 5 | isActive: true, 6 | }; 7 | 8 | export const InactiveTitleBarCountArgs: TitleBarCountType = { 9 | count: 123, 10 | isActive: false, 11 | }; 12 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ActionsMenu/types.ts: -------------------------------------------------------------------------------- 1 | import { DropDownProps } from 'antd'; 2 | import { ItemType } from 'antd/lib/menu/hooks/useItems'; 3 | 4 | export type ActivityMenuProps = { 5 | menuItems: ItemType[]; 6 | show?: 'onFileListHover' | 'always'; 7 | target?: React.FC; 8 | trigger?: DropDownProps['trigger']; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/parser/.prettierrc.yml: -------------------------------------------------------------------------------- 1 | # .prettierrc.yml 2 | # see: https://prettier.io/docs/en/options.html 3 | printWidth: 120 4 | semi: true 5 | singleQuote: true 6 | trailingComma: es5 7 | bracketSpacing: false 8 | jsxBracketSameLine: false 9 | arrowParens: avoid 10 | proseWrap: always 11 | quoteProps: as-needed 12 | tabWidth: 2 13 | useTabs: false 14 | -------------------------------------------------------------------------------- /packages/synchronizer/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "semi": true, 4 | "singleQuote": true, 5 | "trailingComma": "es5", 6 | "bracketSpacing": false, 7 | "jsxBracketSameLine": false, 8 | "arrowParens": "avoid", 9 | "proseWrap": "always", 10 | "quoteProps": "as-needed", 11 | "tabWidth": 2, 12 | "useTabs": false 13 | } 14 | -------------------------------------------------------------------------------- /packages/components/.prettierrc.yml: -------------------------------------------------------------------------------- 1 | # .prettierrc.yml 2 | # see: https://prettier.io/docs/en/options.html 3 | printWidth: 120 4 | semi: true 5 | singleQuote: true 6 | trailingComma: es5 7 | bracketSpacing: false 8 | jsxBracketSameLine: false 9 | arrowParens: avoid 10 | proseWrap: always 11 | quoteProps: as-needed 12 | tabWidth: 2 13 | useTabs: false 14 | -------------------------------------------------------------------------------- /packages/synchronizer/.prettierrc.yml: -------------------------------------------------------------------------------- 1 | # .prettierrc.yml 2 | # see: https://prettier.io/docs/en/options.html 3 | printWidth: 120 4 | semi: true 5 | singleQuote: true 6 | trailingComma: es5 7 | bracketSpacing: false 8 | jsxBracketSameLine: false 9 | arrowParens: avoid 10 | proseWrap: always 11 | quoteProps: as-needed 12 | tabWidth: 2 13 | useTabs: false 14 | -------------------------------------------------------------------------------- /packages/validation/.prettierrc.yml: -------------------------------------------------------------------------------- 1 | # .prettierrc.yml 2 | # see: https://prettier.io/docs/en/options.html 3 | printWidth: 120 4 | semi: true 5 | singleQuote: true 6 | trailingComma: es5 7 | bracketSpacing: false 8 | jsxBracketSameLine: false 9 | arrowParens: avoid 10 | proseWrap: always 11 | quoteProps: as-needed 12 | tabWidth: 2 13 | useTabs: false 14 | -------------------------------------------------------------------------------- /packages/validation/src/references/mappers/ownerReference.ts: -------------------------------------------------------------------------------- 1 | import {RefMapper} from './mappers.js'; 2 | 3 | export const ownerReferenceMapper: RefMapper = { 4 | source: { 5 | pathParts: ['metadata', 'ownerReferences', '*', 'uid'], 6 | }, 7 | target: { 8 | kind: '$.*', 9 | pathParts: ['metadata', 'uid'], 10 | }, 11 | type: 'owner', 12 | }; 13 | -------------------------------------------------------------------------------- /packages/components/src/molecules/WalkThroughCard/types.ts: -------------------------------------------------------------------------------- 1 | type NonEmptyArray = [T, ...T[]]; 2 | 3 | export interface WalkThroughCardProps { 4 | heading: string; 5 | items: NonEmptyArray; 6 | mediaItems: LearnMediaItem[]; 7 | onFinish: () => void; 8 | } 9 | 10 | interface LearnMediaItem { 11 | index: number; 12 | src: string; 13 | } 14 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/data/resources.ts: -------------------------------------------------------------------------------- 1 | import { files } from "./files"; 2 | 3 | export type Resource = { 4 | filePath: string; 5 | name: string; 6 | }; 7 | 8 | export const resourceMap: Record = Object.fromEntries( 9 | files.map((filePath) => [filePath, { name: filePath.substring(0, filePath.length - 4), filePath }]) 10 | ); 11 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/deprecations-4/resources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: node.k8s.io/v1alpha1 2 | kind: RuntimeClass 3 | metadata: 4 | name: class1 5 | handler: config1 6 | --- 7 | apiVersion: kubescheduler.config.k8s.io/v1beta3 8 | kind: KubeSchedulerConfiguration 9 | clientConnection: 10 | kubeconfig: /etc/srv/kubernetes/kube-scheduler/kubeconfig 11 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/hooks/redux.ts: -------------------------------------------------------------------------------- 1 | import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; 2 | import { RootDispatch } from "../types/rootDispatch"; 3 | import { RootState } from "../types/rootState"; 4 | 5 | export const useAppDispatch = () => useDispatch(); 6 | export const useAppSelector: TypedUseSelectorHook = useSelector; 7 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/pod.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Pod } from "kubernetes-types/core/v1.d.js"; 2 | export type { Pod } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isPod(resource: unknown): resource is Pod { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "Pod"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/components/src/molecules/Panels/FullscreenPanel.tsx: -------------------------------------------------------------------------------- 1 | import BarPanel from "./BarPanel"; 2 | 3 | type IProps = { 4 | children: React.ReactNode; 5 | }; 6 | 7 | const FullscreenPanel: React.FC = ({ children }) => { 8 | return ( 9 | <> 10 | 11 | {children} 12 | 13 | ); 14 | }; 15 | 16 | export default FullscreenPanel; 17 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Dots/Dots.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStoryObj } from "@storybook/react"; 2 | import { Dots } from "./Dots"; 3 | 4 | const meta: ComponentMeta = { 5 | title: "Atoms/Dots", 6 | component: Dots, 7 | }; 8 | export default meta; 9 | 10 | export const Default: ComponentStoryObj = { 11 | args: {}, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/validation/src/validators/open-policy-agent/wasmLoader/FileWasmLoader.ts: -------------------------------------------------------------------------------- 1 | import {readFile} from 'fs/promises'; 2 | import {WasmLoader} from './WasmLoader.js'; 3 | 4 | export class FileWasmLoader implements WasmLoader { 5 | async load(path: string): Promise { 6 | const response = await readFile(path, null); 7 | return response.buffer; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/validation/src/validators/open-policy-agent/wasmLoader/RemoteWasmLoader.browser.ts: -------------------------------------------------------------------------------- 1 | import {WasmLoader} from './WasmLoader.js'; 2 | 3 | export class RemoteWasmLoader implements WasmLoader { 4 | async load(url: string): Promise { 5 | const response = await fetch(url); 6 | const data = await response.arrayBuffer(); 7 | return data; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/synchronizer/tsconfig.build.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "node_modules", 5 | "lib", 6 | "src/utils/testing/**", 7 | "src/__tests__/**", 8 | "**/*.test.ts" 9 | ], 10 | "include": ["src"], 11 | "compilerOptions": { 12 | "module": "CommonJS", 13 | "outDir": "lib/cjs", 14 | "target": "ES2015" 15 | } 16 | } -------------------------------------------------------------------------------- /packages/validation/src/references/mappers/validatingAdmissionPolicyBinding.ts: -------------------------------------------------------------------------------- 1 | import {RefMapper} from './mappers.js'; 2 | 3 | export const validatingAdmissionPolicyBindingMappers: RefMapper[] = [ 4 | { 5 | type: 'name', 6 | source: { 7 | pathParts: ['policyName'], 8 | }, 9 | target: { 10 | kind: 'ValidatingAdmissionPolicy', 11 | }, 12 | }, 13 | ]; 14 | -------------------------------------------------------------------------------- /packages/validation/src/references/utils/refMatcher.ts: -------------------------------------------------------------------------------- 1 | import type {RefMapper} from '../mappers/mappers.js'; 2 | 3 | export function refMapperMatchesKind(refMapper: RefMapper, kind: string) { 4 | if (kind && refMapper.target.kind.startsWith('$')) { 5 | return kind.match(refMapper.target.kind.substring(1)) !== null; 6 | } 7 | 8 | return refMapper.target.kind === kind; 9 | } 10 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/job.batch.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Job } from "kubernetes-types/batch/v1.d.js"; 2 | export type { Job } from "kubernetes-types/batch/v1.d.js"; 3 | 4 | export function isJob(resource: unknown): resource is Job { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "batch/v1" && (resource as any)?.kind === "Job"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/synchronizer/scripts/fixup.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const packageMjs = path.join(__dirname, '../lib/mjs/package.json'); 5 | fs.writeFileSync(packageMjs, JSON.stringify({type: "module"}, null, 2)); 6 | 7 | const packageCjs = path.join(__dirname, '../lib/cjs/package.json'); 8 | fs.writeFileSync(packageCjs, JSON.stringify({type: "commonjs"}, null, 2)); -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/secret.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Secret } from "kubernetes-types/core/v1.d.js"; 2 | export type { Secret } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isSecret(resource: unknown): resource is Secret { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "Secret"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/service.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Service } from "kubernetes-types/core/v1.d.js"; 2 | export type { Service } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isService(resource: unknown): resource is Service { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "Service"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './custom/simpleValidator.js'; 2 | export * from './custom/devValidator.js'; 3 | export * from './custom/constants.js'; 4 | export * from './open-policy-agent/index.js'; 5 | export * from './kubernetes-schema/index.js'; 6 | export * from './yaml-syntax/index.js'; 7 | export * from './resource-links/index.js'; 8 | export * from './metadata/index.js'; 9 | -------------------------------------------------------------------------------- /packages/components/src/atoms/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AppButtons'; 2 | export * from './CopyButton'; 3 | export * from './Dots'; 4 | export * from './Filter'; 5 | export * from './Icon'; 6 | export * from './KeyValueInput'; 7 | export * from './PaneCloseIcon'; 8 | export * from './ProblemIcon'; 9 | export * from './SearchInput'; 10 | export * from './Spinner'; 11 | export * from './TextEllipsis'; 12 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/components/src/molecules/LearnPage/types.ts: -------------------------------------------------------------------------------- 1 | export type HelpTopicType = 'documentation' | 'video-tutorial' | 'discord'; 2 | 3 | export type HelpfulResourceCardType = { 4 | description: string; 5 | title: string; 6 | onClick: () => void; 7 | }; 8 | 9 | export type LearnPageType = { 10 | onHelpfulResourceCardClick: (topic: HelpTopicType) => void; 11 | children: React.ReactNode; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/configmap.v1.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigMap } from "kubernetes-types/core/v1.d.js"; 2 | export type { ConfigMap } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isConfigMap(resource: unknown): resource is ConfigMap { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "ConfigMap"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/endpoints.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Endpoints } from "kubernetes-types/core/v1.d.js"; 2 | export type { Endpoints } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isEndpoints(resource: unknown): resource is Endpoints { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "Endpoints"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/namespace.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Namespace } from "kubernetes-types/core/v1.d.js"; 2 | export type { Namespace } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isNamespace(resource: unknown): resource is Namespace { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "Namespace"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Development 4 | 5 | TODO 6 | 7 | ## Publication 8 | 9 | 1. First bump the version in package.json 10 | 11 | 2. Then create a build (i.e. JavaScript) **at the root of the repository:** 12 | 13 | ``` 14 | npm run build 15 | ``` 16 | 17 | 3. Finally publishon NPM 18 | 19 | ```bash 20 | cd packages/cli 21 | npm publish --access public 22 | ``` 23 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/no-metadata/replica-set.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta2 2 | kind: ReplicaSet 3 | spec: 4 | replicas: 3 5 | selector: 6 | matchLabels: 7 | tier: frontend 8 | template: 9 | metadata: 10 | labels: 11 | tier: frontend 12 | spec: 13 | containers: 14 | - name: php-redis 15 | image: gcr.io/google_samples/gb-frontend:v3 16 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/cronjob.batch.v1.ts: -------------------------------------------------------------------------------- 1 | import type { CronJob } from "kubernetes-types/batch/v1.d.js"; 2 | export type { CronJob } from "kubernetes-types/batch/v1.d.js"; 3 | 4 | export function isCronJob(resource: unknown): resource is CronJob { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "batch/v1" && (resource as any)?.kind === "CronJob"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/crd-template/src/plugin.ts: -------------------------------------------------------------------------------- 1 | import { definePlugin } from "@monokle/plugin-toolkit"; 2 | import { noAdminApi } from "./rules/1-exampleCrd.js"; 3 | 4 | export default definePlugin({ 5 | id: "YCP", 6 | name: "ycp", 7 | displayName: "Sample CRD plugin", 8 | description: "Welcome to your first plugin!", 9 | rules: { 10 | noAdminApi, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-with-relative-path-resources/ldap/overlays/production/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ldap 5 | spec: 6 | replicas: 6 7 | template: 8 | spec: 9 | volumes: 10 | - name: ldap-data 11 | emptyDir: null 12 | gcePersistentDisk: 13 | pdName: ldap-persistent-storage 14 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/daemonset.apps.v1.ts: -------------------------------------------------------------------------------- 1 | import type { DaemonSet } from "kubernetes-types/apps/v1.d.js"; 2 | export type { DaemonSet } from "kubernetes-types/apps/v1.d.js"; 3 | 4 | export function isDaemonSet(resource: unknown): resource is DaemonSet { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "apps/v1" && (resource as any)?.kind === "DaemonSet"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/limitrange.v1.ts: -------------------------------------------------------------------------------- 1 | import type { LimitRange } from "kubernetes-types/core/v1.d.js"; 2 | export type { LimitRange } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isLimitRange(resource: unknown): resource is LimitRange { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "LimitRange"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/open-policy-agent/wasmLoader/RemoteWasmLoader.node.ts: -------------------------------------------------------------------------------- 1 | import {WasmLoader} from './WasmLoader.js'; 2 | import fetch from 'node-fetch'; 3 | 4 | export class RemoteWasmLoader implements WasmLoader { 5 | async load(url: string): Promise { 6 | const response = await fetch(url); 7 | const data = await response.arrayBuffer(); 8 | return data; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/components/src/molecules/LearnCard/args.tsx: -------------------------------------------------------------------------------- 1 | import { UnorderedListOutlined } from "@ant-design/icons"; 2 | import { LearnCardType } from "./types"; 3 | 4 | export const LearnCardArgs: LearnCardType = { 5 | title: "Explore", 6 | description: "Configure your resources workspace, whereas it's local, on a Git, a cluster or from scratch.", 7 | icon: , 8 | onClick: () => {}, 9 | }; 10 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turborepo.org/schema.json", 3 | "pipeline": { 4 | "build": { 5 | "dependsOn": ["^build"], 6 | "outputs": ["dist/**", "build/**", "lib/**"] 7 | }, 8 | "@monokle/validation#test": { 9 | "dependsOn": ["@monokle/parser#build"] 10 | }, 11 | "test": { 12 | "dependsOn": ["^test"], 13 | "outputs": ["coverage/**"] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/deployment.apps.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Deployment } from "kubernetes-types/apps/v1.d.js"; 2 | export type { Deployment } from "kubernetes-types/apps/v1.d.js"; 3 | 4 | export function isDeployment(resource: unknown): resource is Deployment { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "apps/v1" && (resource as any)?.kind === "Deployment"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/replicaset.apps.v1.ts: -------------------------------------------------------------------------------- 1 | import type { ReplicaSet } from "kubernetes-types/apps/v1.d.js"; 2 | export type { ReplicaSet } from "kubernetes-types/apps/v1.d.js"; 3 | 4 | export function isReplicaSet(resource: unknown): resource is ReplicaSet { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "apps/v1" && (resource as any)?.kind === "ReplicaSet"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/components/src/molecules/TitleBar/types.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export type TitleBarType = { 4 | title: React.ReactNode; 5 | actions?: React.ReactNode; 6 | description?: React.ReactNode; 7 | expandable?: boolean; 8 | descriptionStyle?: React.CSSProperties; 9 | headerStyle?: React.CSSProperties; 10 | isOpen?: boolean; 11 | type?: 'primary' | 'secondary'; 12 | onExpand?: () => void; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/basic-template/src/plugin.ts: -------------------------------------------------------------------------------- 1 | import { definePlugin } from "@monokle/plugin-toolkit"; 2 | import { noEmptyAnnotations } from "./rules/1-example.js"; 3 | 4 | export default definePlugin({ 5 | id: "YCP", 6 | name: "ycp", 7 | displayName: "Your custom plugin", 8 | description: "Welcome to your first plugin!", 9 | rules: { 10 | noEmptyAnnotations 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/resourcequota.v1.ts: -------------------------------------------------------------------------------- 1 | import type { ResourceQuota } from "kubernetes-types/core/v1.d.js"; 2 | export type { ResourceQuota } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isResourceQuota(resource: unknown): resource is ResourceQuota { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "ResourceQuota"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/role.rbac.authorization.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Role } from "kubernetes-types/rbac/v1.d.js"; 2 | export type { Role } from "kubernetes-types/rbac/v1.d.js"; 3 | 4 | export function isRole(resource: unknown): resource is Role { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "rbac.authorization.k8s.io/v1" && (resource as any)?.kind === "Role"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/statefulset.apps.v1.ts: -------------------------------------------------------------------------------- 1 | import type { StatefulSet } from "kubernetes-types/apps/v1.d.js"; 2 | export type { StatefulSet } from "kubernetes-types/apps/v1.d.js"; 3 | 4 | export function isStatefulSet(resource: unknown): resource is StatefulSet { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "apps/v1" && (resource as any)?.kind === "StatefulSet"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/pluginLoaders/dynamicImportLoader.ts: -------------------------------------------------------------------------------- 1 | import {CustomPluginLoader} from './types.js'; 2 | import {SimpleCustomValidator} from '../validators/custom/simpleValidator.js'; 3 | 4 | export const dynamicImportCustomPluginLoader: CustomPluginLoader = async (url, parser, fixer) => { 5 | const customPlugin = await import(/* @vite-ignore */ url); 6 | return new SimpleCustomValidator(customPlugin.default, parser, fixer); 7 | }; 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/serviceaccount.v1.ts: -------------------------------------------------------------------------------- 1 | import type { ServiceAccount } from "kubernetes-types/core/v1.d.js"; 2 | export type { ServiceAccount } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isServiceAccount(resource: unknown): resource is ServiceAccount { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "ServiceAccount"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-5.0.0-patches-and-values-files/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | patches: 5 | - path: patches/existing-patch.yaml 6 | - path: patches/missing-patch.yaml 7 | 8 | helmCharts: 9 | - name: testChart 10 | additionalValuesFiles: 11 | - valuesFiles/existing-values.yaml 12 | - valuesFiles/missing-values.yaml 13 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/data/slice.ts: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | import { fileMap } from "./fileEntries"; 3 | import { resourceMap } from "./resources"; 4 | 5 | export const dataSlice = createSlice({ 6 | name: "data", 7 | initialState: { 8 | fileMap, 9 | resourceMap, 10 | }, 11 | reducers: {}, 12 | }); 13 | 14 | // export const {} = dataSlice.actions; 15 | export default dataSlice.reducer; 16 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/basic-deployment/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: demo 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app.kubernetes.io/name: demo 10 | template: 11 | metadata: 12 | labels: 13 | app.kubernetes.io/name: demo 14 | spec: 15 | containers: 16 | - name: demo 17 | image: demo:latest 18 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/ingress.networking.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { Ingress } from "kubernetes-types/networking/v1.d.js"; 2 | export type { Ingress } from "kubernetes-types/networking/v1.d.js"; 3 | 4 | export function isIngress(resource: unknown): resource is Ingress { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "networking.k8s.io/v1" && (resource as any)?.kind === "Ingress"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/persistentvolume.v1.ts: -------------------------------------------------------------------------------- 1 | import type { PersistentVolume } from "kubernetes-types/core/v1.d.js"; 2 | export type { PersistentVolume } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isPersistentVolume(resource: unknown): resource is PersistentVolume { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "PersistentVolume"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { store } from "./store"; 2 | 3 | import React from "react"; 4 | import ReactDOM from "react-dom/client"; 5 | import App from "./App"; 6 | 7 | import { Provider } from "react-redux"; 8 | 9 | ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [], 11 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { 12 | "onlyUpdatePeerDependentsWhenOutOfRange": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/components/src/atoms/CopyButton/CopyButton.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStoryObj } from "@storybook/react"; 2 | import { CopyButton } from "./CopyButton"; 3 | 4 | const meta: ComponentMeta = { 5 | title: "Atoms/CopyButton", 6 | component: CopyButton, 7 | }; 8 | export default meta; 9 | 10 | export const Primary: ComponentStoryObj = { 11 | args: { 12 | content: "Hello", 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/storageclass.storage.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { StorageClass } from "kubernetes-types/storage/v1.d.js"; 2 | export type { StorageClass } from "kubernetes-types/storage/v1.d.js"; 3 | 4 | export function isStorageClass(resource: unknown): resource is StorageClass { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "storage.k8s.io/v1" && (resource as any)?.kind === "StorageClass"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/components/src/molecules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ActivityBar'; 2 | export * from './ActionsMenu'; 3 | export * from './LearnCard'; 4 | export * from './LearnPage'; 5 | export * from './Panels'; 6 | export * from './ProblemInfo'; 7 | export * from './TitleBar'; 8 | export * from './TitleBarCount'; 9 | export * from './ValidationOverview'; 10 | export * from './ValidationPopover'; 11 | export * from './WalkThrough'; 12 | export * from './WalkThroughCard'; 13 | -------------------------------------------------------------------------------- /packages/parser/src/k8s.ts: -------------------------------------------------------------------------------- 1 | export type KubernetesLike = { 2 | apiVersion: string; 3 | kind: string; 4 | metadata?: { 5 | name: string; 6 | namespace?: string; 7 | }; 8 | spec?: { 9 | names?: { 10 | kind?: string; 11 | }; 12 | }; 13 | }; 14 | 15 | export function isKubernetesLike(content: any): content is KubernetesLike { 16 | return content && typeof content.apiVersion === 'string' && typeof content.kind === 'string'; 17 | } 18 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { FileTreeNavigator } from "./navigators/FileTreeNavigator"; 2 | import { ResourceTreeNavigator } from "./navigators/ResourceTreeNavigator"; 3 | 4 | import "./App.css"; 5 | 6 | function App() { 7 | return ( 8 |
9 | 10 | 11 |
12 | ); 13 | } 14 | 15 | export default App; 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | __generated__ 4 | /.pnp 5 | .idea 6 | .pnp.js 7 | *.iml 8 | .turbo 9 | 10 | # production 11 | /build 12 | /dist 13 | **/dist/** 14 | **/lib/** 15 | 16 | # misc 17 | .DS_Store 18 | .env 19 | .env.local 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | *.swp 28 | 29 | .vscode 30 | 31 | electron/env.ts 32 | 33 | coverage 34 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": false, 4 | "forceConsistentCasingInFileNames": true, 5 | "downlevelIteration": true, 6 | "lib": ["dom", "dom.iterable", "es2017"], 7 | "module": "esnext", 8 | "moduleResolution": "node", 9 | "noEmit": true, 10 | "skipLibCheck": true, 11 | "sourceMap": true, 12 | "target": "es6", 13 | "types": [], 14 | "strict": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/clusterrole.rbac.authorization.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { ClusterRole } from "kubernetes-types/rbac/v1.d.js"; 2 | export type { ClusterRole } from "kubernetes-types/rbac/v1.d.js"; 3 | 4 | export function isClusterRole(resource: unknown): resource is ClusterRole { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "rbac.authorization.k8s.io/v1" && (resource as any)?.kind === "ClusterRole"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/rolebinding.rbac.authorization.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { RoleBinding } from "kubernetes-types/rbac/v1.d.js"; 2 | export type { RoleBinding } from "kubernetes-types/rbac/v1.d.js"; 3 | 4 | export function isRoleBinding(resource: unknown): resource is RoleBinding { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "rbac.authorization.k8s.io/v1" && (resource as any)?.kind === "RoleBinding"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/endpointslice.discovery.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { EndpointSlice } from "kubernetes-types/discovery/v1.d.js"; 2 | export type { EndpointSlice } from "kubernetes-types/discovery/v1.d.js"; 3 | 4 | export function isEndpointSlice(resource: unknown): resource is EndpointSlice { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "discovery.k8s.io/v1" && (resource as any)?.kind === "EndpointSlice"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/networkpolicy.networking.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { NetworkPolicy } from "kubernetes-types/networking/v1.d.js"; 2 | export type { NetworkPolicy } from "kubernetes-types/networking/v1.d.js"; 3 | 4 | export function isNetworkPolicy(resource: unknown): resource is NetworkPolicy { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "networking.k8s.io/v1" && (resource as any)?.kind === "NetworkPolicy"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/persistentvolumeclaim.v1.ts: -------------------------------------------------------------------------------- 1 | import type { PersistentVolumeClaim } from "kubernetes-types/core/v1.d.js"; 2 | export type { PersistentVolumeClaim } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isPersistentVolumeClaim(resource: unknown): resource is PersistentVolumeClaim { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "PersistentVolumeClaim"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/replicationcontroller.v1.ts: -------------------------------------------------------------------------------- 1 | import type { ReplicationController } from "kubernetes-types/core/v1.d.js"; 2 | export type { ReplicationController } from "kubernetes-types/core/v1.d.js"; 3 | 4 | export function isReplicationController(resource: unknown): resource is ReplicationController { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "v1" && (resource as any)?.kind === "ReplicationController"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "monokle-core", 3 | "private": false, 4 | "scripts": { 5 | "build": "turbo run build", 6 | "test": "turbo run test", 7 | "release": "turbo run build && changeset publish" 8 | }, 9 | "workspaces": [ 10 | "packages/*" 11 | ], 12 | "devDependencies": { 13 | "prettier": "2.5.1", 14 | "pretty-quick": "3.1.3", 15 | "turbo": "1.10.13" 16 | }, 17 | "dependencies": { 18 | "@changesets/cli": "2.25.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/ProblemIcon.tsx: -------------------------------------------------------------------------------- 1 | const ProblemIcon = ({width, height}: {width?: number; height?: number}) => { 2 | const iconWidth = width || '8'; 3 | const iconHeight = height || '8'; 4 | 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | 12 | export default ProblemIcon; 13 | -------------------------------------------------------------------------------- /packages/validation/src/sarif/fix/index.ts: -------------------------------------------------------------------------------- 1 | import {ResourceParser} from '../../common/resourceParser.js'; 2 | import type {Resource} from '../../common/types.js'; 3 | import type {Fix} from '../../common/sarif.js'; 4 | import {FixMetadata} from '../../custom.js'; 5 | 6 | export * from './plugins/DisabledSuppressor.js'; 7 | 8 | export interface Fixer { 9 | createFix(resource: Resource, fixedContent: any, fixMetadata: FixMetadata | undefined, parser: ResourceParser): Fix[]; 10 | } 11 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/volumeattachment.storage.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { VolumeAttachment } from "kubernetes-types/storage/v1.d.js"; 2 | export type { VolumeAttachment } from "kubernetes-types/storage/v1.d.js"; 3 | 4 | export function isVolumeAttachment(resource: unknown): resource is VolumeAttachment { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "storage.k8s.io/v1" && (resource as any)?.kind === "VolumeAttachment"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/components/src/styles/Borders.ts: -------------------------------------------------------------------------------- 1 | import {Colors} from '../styles/Colors'; 2 | 3 | export enum BorderRadius { 4 | pill = '1000px', 5 | circle = '50%', 6 | large = '8px', 7 | medium = '4px', 8 | small = '2px', 9 | } 10 | 11 | export enum BorderWidth { 12 | thick = '3px', 13 | medium = '2px', 14 | thin = '1px', 15 | } 16 | 17 | export const AppBorders = { 18 | pageDivider: `1px solid ${Colors.grey3};`, 19 | sectionDivider: `1px solid ${Colors.grey3}`, 20 | }; 21 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/Cluster.tsx: -------------------------------------------------------------------------------- 1 | export default function Cluster() { 2 | return ( 3 | 10 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Spinner/Spinner.tsx: -------------------------------------------------------------------------------- 1 | import { Spin } from "antd"; 2 | 3 | import * as S from "./Spinner.styled"; 4 | 5 | interface Props { 6 | isSpinning?: boolean; 7 | size?: "small" | "default" | "large"; 8 | } 9 | 10 | export const Spinner: React.FC = (props) => { 11 | const { isSpinning = true, size = "small" } = props; 12 | 13 | return ( 14 | 15 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Dots/Dots.styled.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | import {Colors} from '../../styles/Colors'; 4 | 5 | export const Dot = styled.div<{$color: Colors}>` 6 | width: 6px; 7 | height: 6px; 8 | border-radius: 50%; 9 | background-color: ${props => props.$color}; 10 | `; 11 | 12 | export const DotsContainer = styled.div` 13 | display: flex; 14 | align-items: center; 15 | justify-content: space-between; 16 | gap: 3px; 17 | height: inherit; 18 | `; 19 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { JSONSchema4, JSONSchema6, JSONSchema7 } from "json-schema"; 2 | import type { IEvent } from "monaco-editor"; 3 | import type { Config } from "@monokle/validation"; 4 | 5 | /** 6 | * Configure `monaco-kubernetes` diagnostics options. 7 | * 8 | * @param options The options to set. 9 | */ 10 | export function configure(settings?: LanguageSettings): void; 11 | 12 | type LanguageSettings = { 13 | validation?: Config; 14 | telemetry?: boolean; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/DefaultResource.tsx: -------------------------------------------------------------------------------- 1 | export default function DefaultResource() { 2 | return ( 3 | 10 | 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/deprecations-1/replica-set.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta2 2 | kind: ReplicaSet 3 | metadata: 4 | name: frontend 5 | labels: 6 | app: guestbook 7 | tier: frontend 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | tier: frontend 13 | template: 14 | metadata: 15 | labels: 16 | tier: frontend 17 | spec: 18 | containers: 19 | - name: php-redis 20 | image: gcr.io/google_samples/gb-frontend:v3 21 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/deprecations-3/replica-set.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta2 2 | kind: ReplicaSet 3 | metadata: 4 | name: frontend 5 | labels: 6 | app: guestbook 7 | tier: frontend 8 | spec: 9 | replicas: 3 10 | selector: 11 | matchLabels: 12 | tier: frontend 13 | template: 14 | metadata: 15 | labels: 16 | tier: frontend 17 | spec: 18 | containers: 19 | - name: php-redis 20 | image: gcr.io/google_samples/gb-frontend:v3 21 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-with-relative-patch/argocd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | patchesStrategicMerge: 5 | - https://raw.githubusercontent.com/argoproj/argo-cd/master/notifications_catalog/install.yaml 6 | 7 | patchesJson6902: 8 | - path: overlays/production/argocd-server-deploy-command.yaml 9 | target: 10 | group: apps 11 | kind: Deployment 12 | name: argocd-server 13 | version: v1 14 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/clusterrolebinding.rbac.authorization.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { ClusterRoleBinding } from "kubernetes-types/rbac/v1.d.js"; 2 | export type { ClusterRoleBinding } from "kubernetes-types/rbac/v1.d.js"; 3 | 4 | export function isClusterRoleBinding(resource: unknown): resource is ClusterRoleBinding { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "rbac.authorization.k8s.io/v1" && (resource as any)?.kind === "ClusterRoleBinding"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/components/src/atoms/ProblemIcon/ProblemIcon.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import ProblemIcon from './ProblemIcon'; 3 | 4 | export default { 5 | title: 'Atoms/ProblemIcon', 6 | component: ProblemIcon, 7 | } as ComponentMeta; 8 | 9 | const Template: ComponentStory = args => ; 10 | 11 | export const DefaultComponent = Template.bind({}); 12 | DefaultComponent.args = { 13 | level: 'both', 14 | }; 15 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # create-monokle-plugin 2 | 3 | ## 0.3.1 4 | 5 | ### Patch Changes 6 | 7 | - 4a7a899: Add readme extension 8 | - d1e0ea0: Delete internals 9 | - 5f27e51: Fix gitignore 10 | 11 | ## 0.3.0 12 | 13 | ### Minor Changes 14 | 15 | - ab4d567: Add template with toolkit and fix minor bug 16 | 17 | ## 0.2.0 18 | 19 | ### Minor Changes 20 | 21 | - 8c476f9: Add typegen for known core resources 22 | 23 | ## 0.1.5 24 | 25 | ### Patch Changes 26 | 27 | - 23f8187: Fix install instruction 28 | -------------------------------------------------------------------------------- /packages/validation/src/pluginLoaders/requireFromStringLoader.node.ts: -------------------------------------------------------------------------------- 1 | import type {CustomPluginLoader} from './types.js'; 2 | import {loadCustomPlugin} from '../utils/loadCustomPlugin.node.js'; 3 | import {SimpleCustomValidator} from '../validators/custom/simpleValidator.js'; 4 | 5 | export const requireFromStringCustomPluginLoader: CustomPluginLoader = async (pluginNameOrUrl, parser, fixer) => { 6 | const customPlugin = await loadCustomPlugin(pluginNameOrUrl); 7 | return new SimpleCustomValidator(customPlugin, parser, fixer); 8 | }; 9 | -------------------------------------------------------------------------------- /packages/validation/src/pluginLoaders/types.ts: -------------------------------------------------------------------------------- 1 | import {ResourceParser} from '../common/resourceParser.js'; 2 | import type {Plugin} from '../common/types.js'; 3 | import {Fixer} from '../sarif/fix/index.js'; 4 | import {SchemaLoader} from '../validators/kubernetes-schema/index.js'; 5 | 6 | export type PluginContext = { 7 | parser: ResourceParser; 8 | fixer?: Fixer; 9 | schemaLoader?: SchemaLoader; 10 | }; 11 | 12 | export type CustomPluginLoader = (name: string, parser: ResourceParser, fixer?: Fixer) => Promise; 13 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/horizontalpodautoscaler.autoscaling.v2.ts: -------------------------------------------------------------------------------- 1 | import type { HorizontalPodAutoscaler } from "kubernetes-types/autoscaling/v2.d.js"; 2 | export type { HorizontalPodAutoscaler } from "kubernetes-types/autoscaling/v2.d.js"; 3 | 4 | export function isHorizontalPodAutoscaler(resource: unknown): resource is HorizontalPodAutoscaler { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "autoscaling/v2" && (resource as any)?.kind === "HorizontalPodAutoscaler"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ValidationPopover/types.ts: -------------------------------------------------------------------------------- 1 | import {RuleLevel, ValidationResult} from '@monokle/validation'; 2 | 3 | export type ValidationPopoverProps = { 4 | level: RuleLevel | 'both' | 'none'; 5 | results: ValidationResult[]; 6 | disabled?: boolean; 7 | popoverIconStyle?: React.CSSProperties; 8 | popoverRenderItem?: JSX.Element; 9 | style?: React.CSSProperties; 10 | onMessageClickHandler?: ((result: ValidationResult) => void); 11 | title?: string | JSX.Element; 12 | hideEmptyPopover?: boolean; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/validation/src/validators/custom/schemas/customresourcedefinition.apiextensions.k8s.io.v1.ts: -------------------------------------------------------------------------------- 1 | import type { CustomResourceDefinition } from "kubernetes-types/apiextensions/v1.d.js"; 2 | export type { CustomResourceDefinition } from "kubernetes-types/apiextensions/v1.d.js"; 3 | 4 | export function isCustomResourceDefinition(resource: unknown): resource is CustomResourceDefinition { 5 | return typeof resource === "object" && (resource as any)?.apiVersion === "apiextensions.k8s.io/v1" && (resource as any)?.kind === "CustomResourceDefinition"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /packages/plugin-toolkit/tsconfig.cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist/cli", 4 | "lib": ["ES2020"], 5 | "module": "CommonJS", 6 | "target": "es2022", 7 | "moduleResolution": "NodeNext", 8 | "allowSyntheticDefaultImports": true, 9 | "esModuleInterop": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "pretty": true, 12 | "skipLibCheck": true, 13 | "removeComments": true, 14 | "strict": true 15 | }, 16 | "include": ["src/cli/**/*"], 17 | "exclude": ["node_modules", "dist"] 18 | } 19 | -------------------------------------------------------------------------------- /packages/synchronizer/src/createDefaultMonokleFetcher.ts: -------------------------------------------------------------------------------- 1 | import {ApiHandler} from './handlers/apiHandler.js'; 2 | import {Fetcher} from './utils/fetcher.js'; 3 | 4 | /** 5 | * Creates default Monokle Fetcher instance. 6 | * 7 | * @deprecated Use createMonokleFetcherFromOrigin or createMonokleFetcherFromConfig instead which does not rely on hardcoded config. 8 | * 9 | * @param apiHandler 10 | * @returns Fetcher instance 11 | */ 12 | export function createDefaultMonokleFetcher(apiHandler: ApiHandler = new ApiHandler()) { 13 | return new Fetcher(apiHandler); 14 | } 15 | -------------------------------------------------------------------------------- /packages/plugin-toolkit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "lib": ["ES2020"], 5 | "module": "ES2022", 6 | "target": "ES2022", 7 | "moduleResolution": "NodeNext", 8 | "allowSyntheticDefaultImports": true, 9 | "esModuleInterop": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "pretty": true, 12 | "skipLibCheck": true, 13 | "removeComments": true, 14 | "strict": true, 15 | "declaration": true 16 | }, 17 | "include": ["src/config.ts"], 18 | "exclude": ["node_modules", "dist"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ActionsMenu/ActionsMenu.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import ActionsMenu from './ActionsMenu'; 3 | import {MainActionsMenuArgs} from './ActionsMenu.stories.args'; 4 | 5 | export default { 6 | title: 'Molecules/ActionsMenu', 7 | component: ActionsMenu, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ; 11 | 12 | export const MainActionsMenu = Template.bind({}); 13 | MainActionsMenu.args = MainActionsMenuArgs; 14 | -------------------------------------------------------------------------------- /packages/parser/src/parse.ts: -------------------------------------------------------------------------------- 1 | import {LineCounter, parseAllDocuments, parseDocument} from 'yaml'; 2 | 3 | export function parseYamlDocument(text: string, lineCounter?: LineCounter) { 4 | return parseDocument(text, {lineCounter, uniqueKeys: false, strict: false, logLevel: 'silent'}); 5 | } 6 | 7 | /** 8 | * Wrapper that ensures consistent options 9 | */ 10 | export function parseAllYamlDocuments(text: string, lineCounter?: LineCounter) { 11 | return parseAllDocuments(text, { 12 | lineCounter, 13 | uniqueKeys: false, 14 | strict: false, 15 | logLevel: 'silent', 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /packages/plugin-toolkit/src/cli/build.cts: -------------------------------------------------------------------------------- 1 | import { rollup } from "rollup"; 2 | import { DEBUG_CONFIG, DIST_CONFIG } from "./rollupConfig.cjs"; 3 | 4 | export type BuildArgs = { 5 | debug?: boolean; 6 | }; 7 | 8 | export async function build({ debug = false }: BuildArgs = {}) { 9 | try { 10 | const options = debug ? DEBUG_CONFIG : DIST_CONFIG; 11 | const [rollupOptions, generateOptions] = options; 12 | const bundle = await rollup(rollupOptions); 13 | await bundle.write(generateOptions); 14 | } catch (err) { 15 | console.error("build_failed"); 16 | throw err; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/synchronizer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "lib": ["ESNext", "DOM"], 5 | "module": "ESNext", 6 | "target": "ESNext", 7 | "moduleResolution": "node", 8 | "allowSyntheticDefaultImports": true, 9 | "declaration": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "esModuleInterop": true, 12 | "pretty": true, 13 | "resolveJsonModule": true, 14 | "skipLibCheck": true, 15 | "removeComments": false, 16 | "strict": true, 17 | }, 18 | "exclude": ["node_modules", "lib"], 19 | "include": ["src"] 20 | } 21 | -------------------------------------------------------------------------------- /packages/components/src/atoms/PaneCloseIcon/PaneCloseIcon.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import PaneCloseIcon from './PaneCloseIcon'; 3 | 4 | export default { 5 | title: 'Atoms/PaneCloseIcon', 6 | component: PaneCloseIcon, 7 | } as ComponentMeta; 8 | 9 | const Template: ComponentStory = args => ; 10 | 11 | export const DefaultComponent = Template.bind({}); 12 | DefaultComponent.args = { 13 | containerStyle: { 14 | backgroundColor: 'red', 15 | }, 16 | onClick: () => {}, 17 | }; 18 | -------------------------------------------------------------------------------- /packages/components/src/organisms/ResourceGraph/helpers.ts: -------------------------------------------------------------------------------- 1 | import { ValidationResult } from '@monokle/validation'; 2 | 3 | export const getValidationLevel = ( 4 | errors: ValidationResult[], 5 | warnings: ValidationResult[] 6 | ) => { 7 | if (errors.length && warnings.length) { 8 | return 'both'; 9 | } 10 | 11 | if (errors.length > 0) { 12 | return 'error'; 13 | } 14 | 15 | if (warnings.length > 0) { 16 | return 'warning'; 17 | } 18 | 19 | return 'none'; 20 | }; 21 | 22 | export const isDefined = (value: T | undefined): value is T => { 23 | return value !== undefined; 24 | } 25 | -------------------------------------------------------------------------------- /packages/components/src/atoms/KeyValueInput/NewKeyValueInput.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import {NewKeyValueInput} from './NewKeyValueInput'; 3 | 4 | export default { 5 | title: 'Atoms/NewKeyValueInput', 6 | component: NewKeyValueInput, 7 | } as ComponentMeta; 8 | 9 | const Template: ComponentStory = args => ; 10 | 11 | export const NewKeyValueComponent = Template.bind({}); 12 | NewKeyValueComponent.args = { 13 | keyOptions: [{value: 'demo'}, {value: 'api'}, {value: 'app'}], 14 | }; 15 | -------------------------------------------------------------------------------- /packages/components/src/molecules/LearnCard/LeanCard.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import { LearnCardArgs } from './args'; 3 | import LearnCard from './LearnCard'; 4 | 5 | export default { 6 | title: 'Molecules/LearnCard', 7 | component: LearnCard, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ( 11 |
12 | 13 |
14 | ); 15 | 16 | export const MainLearnCard = Template.bind({}); 17 | MainLearnCard.args = LearnCardArgs 18 | -------------------------------------------------------------------------------- /packages/parser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "outDir": "lib", 5 | "lib": ["ESNext", "DOM"], 6 | "module": "ESNext", 7 | "target": "ESNext", 8 | "moduleResolution": "node", 9 | "allowSyntheticDefaultImports": true, 10 | "declaration": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "esModuleInterop": true, 13 | "pretty": true, 14 | "resolveJsonModule": true, 15 | "skipLibCheck": true, 16 | "removeComments": false, 17 | "strict": true, 18 | }, 19 | "exclude": ["node_modules", "lib"], 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /packages/synchronizer/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_STORAGE_CONFIG_FOLDER = 'monokle'; 2 | export const DEFAULT_STORAGE_CONFIG_FILE_AUTH = 'auth.yaml'; 3 | 4 | export const DEFAULT_ORIGIN = 'https://app.monokle.com'; 5 | export const DEFAULT_API_URL = 'https://api.monokle.com'; 6 | 7 | export const DEFAULT_DEVICE_FLOW_IDP_URL = 'https://id.monokle.com/realms/monokle'; 8 | export const DEFAULT_DEVICE_FLOW_CLIENT_ID = 'mc-cli'; 9 | export const DEFAULT_DEVICE_FLOW_CLIENT_SECRET = ''; 10 | export const DEFAULT_DEVICE_FLOW_ALG = 'ES512'; 11 | export const DEFAULT_DEVICE_FLOW_CLIENT_SCOPE = 'openid profile offline_access'; 12 | -------------------------------------------------------------------------------- /packages/validation/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "outDir": "lib", 5 | "lib": ["ESNext", "DOM"], 6 | "module": "ESNext", 7 | "target": "ESNext", 8 | "moduleResolution": "node", 9 | "allowSyntheticDefaultImports": true, 10 | "declaration": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "esModuleInterop": true, 13 | "pretty": true, 14 | "resolveJsonModule": true, 15 | "skipLibCheck": true, 16 | "removeComments": false, 17 | "strict": true, 18 | }, 19 | "exclude": ["node_modules", "lib"], 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /packages/components/src/molecules/WalkThroughCard/WalkThroughCard.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import WalkThroughCard from './WalkThroughCard'; 3 | import { WalkThoughCardArgs } from './args'; 4 | 5 | export default { 6 | title: 'Molecules/WalkThroughCard', 7 | component: WalkThroughCard, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ( 11 | 14 | ); 15 | 16 | export const MainWalkThroughCard = Template.bind({}); 17 | MainWalkThroughCard.args = WalkThoughCardArgs; 18 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/basic-template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "outDir": "build", 5 | "lib": ["ESNext", "DOM"], 6 | "module": "ESNext", 7 | "target": "ESNext", 8 | "moduleResolution": "NodeNext", 9 | "allowSyntheticDefaultImports": true, 10 | "declaration": false, 11 | "forceConsistentCasingInFileNames": true, 12 | "esModuleInterop": true, 13 | "pretty": true, 14 | "resolveJsonModule": true, 15 | "skipLibCheck": true, 16 | "removeComments": false, 17 | "strict": true 18 | }, 19 | "include": [ 20 | "src" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/crd-template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "outDir": "build", 5 | "lib": ["ESNext", "DOM"], 6 | "module": "ESNext", 7 | "target": "ESNext", 8 | "moduleResolution": "NodeNext", 9 | "allowSyntheticDefaultImports": true, 10 | "declaration": false, 11 | "forceConsistentCasingInFileNames": true, 12 | "esModuleInterop": true, 13 | "pretty": true, 14 | "resolveJsonModule": true, 15 | "skipLibCheck": true, 16 | "removeComments": false, 17 | "strict": true 18 | }, 19 | "include": [ 20 | "src" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/basic-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "monokle-custom-validator", 3 | "author": "unknown", 4 | "description": "Validates with custom rules.", 5 | "license": "MIT", 6 | "version": "1.0.0", 7 | "main": "dist/plugin.js", 8 | "type": "module", 9 | "scripts": { 10 | "postinstall": "npm run codegen", 11 | "codegen": "monokle-plugin-toolkit codegen", 12 | "dev": "monokle-plugin-toolkit dev", 13 | "build": "monokle-plugin-toolkit build", 14 | "debug": "monokle-plugin-toolkit build --debug" 15 | }, 16 | "dependencies": { 17 | "@monokle/plugin-toolkit": "^0.1.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/crd-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "monokle-custom-validator", 3 | "author": "unknown", 4 | "description": "Validates with custom rules.", 5 | "license": "MIT", 6 | "version": "1.0.0", 7 | "main": "dist/plugin.js", 8 | "type": "module", 9 | "scripts": { 10 | "postinstall": "npm run codegen", 11 | "codegen": "monokle-plugin-toolkit codegen", 12 | "dev": "monokle-plugin-toolkit dev", 13 | "build": "monokle-plugin-toolkit build", 14 | "debug": "monokle-plugin-toolkit build --debug" 15 | }, 16 | "dependencies": { 17 | "@monokle/plugin-toolkit": "^0.1.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/validation/src/commonExports.ts: -------------------------------------------------------------------------------- 1 | // This file contains the common exports for both node and browser. 2 | 3 | export * from './common/sarif.js'; 4 | export * from './common/types.js'; 5 | export * from './common/NodeWrapper.js'; 6 | export * from './common/resourceParser.js'; 7 | 8 | export * from './types.js'; 9 | export * from './utils/getRule.js'; 10 | export * from './utils/sarif.js'; 11 | export {CORE_PLUGINS} from './constants.js'; 12 | 13 | export * from './MonokleValidator.js'; 14 | 15 | export * from './pluginLoaders/index.js'; 16 | export * from './references/index.js'; 17 | export * from './sarif/index.js'; 18 | export * from './validators/index.js'; 19 | -------------------------------------------------------------------------------- /packages/components/src/organisms/ResourceGraph/ResourceGraph.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import ResourceGraph from './ResourceGraph'; 3 | import {ResourceGraphArgs} from './ResourceGraph.stories.args'; 4 | 5 | export default { 6 | title: 'Organisms/ResourceGraph', 7 | component: ResourceGraph, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ( 11 |
12 | 13 |
14 | ); 15 | 16 | export const MainResourceGraph = Template.bind({}); 17 | MainResourceGraph.args = ResourceGraphArgs; 18 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ValidationOverview/ValidationOverview.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import ValidationOverview from './ValidationOverview'; 3 | import {MainValidationOverviewArgs} from './ValidationOverview.stories.args'; 4 | 5 | export default { 6 | title: 'Molecules/ValidationOverview', 7 | component: ValidationOverview, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ; 11 | 12 | export const MainValidationOverview = Template.bind({}); 13 | MainValidationOverview.args = MainValidationOverviewArgs; 14 | -------------------------------------------------------------------------------- /packages/types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @monokle/types 2 | 3 | ## 0.3.2 4 | 5 | ### Patch Changes 6 | 7 | - 0ce5665: added ScriptConfig dry-run type 8 | 9 | ## 0.3.1 10 | 11 | ### Patch Changes 12 | 13 | - 6201800: fix dry-run config `args` type 14 | 15 | ## 0.3.0 16 | 17 | ### Minor Changes 18 | 19 | - 367ef4a: add dry-run config types 20 | 21 | ## 0.2.2 22 | 23 | ### Patch Changes 24 | 25 | - 393090b: removed unallowed semicolon from types definitions 26 | 27 | ## 0.2.1 28 | 29 | ### Patch Changes 30 | 31 | - 8e49957: add get suppressions query in the synchronizer package 32 | 33 | ## 0.2.0 34 | 35 | ### Minor Changes 36 | 37 | - d085cd3: Introduced '@monokle/types' package 38 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/styles/colors.ts: -------------------------------------------------------------------------------- 1 | export enum Colors { 2 | grey700 = "#93989C", 3 | grey7 = "#7D7D7D", 4 | blue10 = "#B7E3FA", 5 | yellow7 = "#E8D639", 6 | cyan7 = "#33BCB7", 7 | 8 | whitePure = "#ffffff", 9 | blackPure = "#000000", 10 | blackPearl = "#111d2c", 11 | 12 | selectionGradient = "linear-gradient(90deg, #3C9AE8 0%, #84E2D8 100%)", 13 | selectionGradientHover = "linear-gradient(90deg, #3C9AE8 50%, #84E2D8 100%)", 14 | highlightGradient = "linear-gradient(90deg, #113536 0%, #000000 100%)", 15 | highlightGradientHover = "linear-gradient(90deg, #113536 50%, #000000 100%)", 16 | } 17 | 18 | export enum FontColors { 19 | grey = Colors.grey700, 20 | } 21 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # Supress wall of text on 'npm install' 2 | audit = false 3 | fund = false 4 | update-notifier = true 5 | # Lock versions of node and npm, when looking up engines. 6 | node-version = 16.17.1 7 | npm-version = 8.11.0 8 | # Default options for package-lock - package-lock=true package-lock-only=false 9 | # If set to false, then ignore package-lock.json files when installing. This will also prevent writing package-lock.json if save is true. 10 | # When package package-locks are disabled, automatic pruning of extraneous modules will also be disabled. 11 | package-lock = true 12 | package-lock-only = false 13 | # temporary added - should move it after craco 7 is released 14 | legacy-peer-deps = true 15 | -------------------------------------------------------------------------------- /packages/validation/src/validators/admission-policy/loadWasm.ts: -------------------------------------------------------------------------------- 1 | import Go, {loadGoGlueCode} from '../../assets/wasm_exec.js'; 2 | import pako from 'pako'; 3 | 4 | export async function loadWasm() { 5 | try { 6 | loadGoGlueCode(); 7 | const go = new Go(); 8 | 9 | let buffer = pako.ungzip(await (await fetch('https://plugins.monokle.com/validation/cel.wasm.gz')).arrayBuffer()); 10 | 11 | if (buffer[0] === 0x1f && buffer[1] === 0x8b) { 12 | buffer = pako.ungzip(buffer); 13 | } 14 | 15 | const result = await WebAssembly.instantiate(buffer.buffer, go.importObject); 16 | go.run(result.instance); 17 | } catch (err: any) { 18 | console.log(err); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/tree-navigator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "outDir": "lib", 5 | "lib": ["ESNext", "DOM"], 6 | "module": "ESNext", 7 | "target": "ESNext", 8 | "moduleResolution": "node", 9 | "allowSyntheticDefaultImports": true, 10 | "declaration": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "esModuleInterop": true, 13 | "pretty": true, 14 | "jsx": "react-jsx", 15 | "resolveJsonModule": true, 16 | "skipLibCheck": true, 17 | "removeComments": false, 18 | "strict": true, 19 | "noUncheckedIndexedAccess": true 20 | }, 21 | "exclude": ["node_modules", "lib"], 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Dots/Dots.tsx: -------------------------------------------------------------------------------- 1 | import {useMemo} from 'react'; 2 | 3 | import {Colors} from '@/styles/Colors'; 4 | 5 | import * as S from './Dots.styled'; 6 | 7 | interface DotsProps { 8 | color?: Colors; 9 | dotNumber?: number; 10 | } 11 | 12 | export const Dots: React.FC = props => { 13 | const {color = Colors.blue6, dotNumber = 3} = props; 14 | 15 | const dots = useMemo( 16 | () => 17 | Array.from({length: dotNumber}).map((_, index) => { 18 | const key = `dot_${index}`; 19 | 20 | return ; 21 | }), 22 | [color, dotNumber] 23 | ); 24 | 25 | return {dots}; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/pss-1/valid-volume-type.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: demo 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app.kubernetes.io/name: demo 10 | template: 11 | metadata: 12 | labels: 13 | app.kubernetes.io/name: demo 14 | spec: 15 | containers: 16 | - name: demo 17 | image: demo:latest 18 | volumeMounts: 19 | - name: configuration 20 | subPath: data.js 21 | mountPath: /usr/share/data.js 22 | volumes: 23 | - name: configuration 24 | configMap: 25 | name: demo-configuration 26 | -------------------------------------------------------------------------------- /packages/validation/src/utils/findJsonPointerNode.ts: -------------------------------------------------------------------------------- 1 | import {Document, isCollection, ParsedNode} from 'yaml'; 2 | 3 | export function findJsonPointerNode(valuesDoc: Document.Parsed, path: string[]) { 4 | if (!valuesDoc.contents) { 5 | return undefined; 6 | } 7 | 8 | let valueNode: any = valuesDoc.contents; 9 | 10 | for (let c = 0; valueNode && c < path.length; c += 1) { 11 | let node = path[c]; 12 | if (isCollection(valueNode)) { 13 | const nextNode = valueNode.get(node, true); 14 | if (nextNode) { 15 | valueNode = nextNode; 16 | } else { 17 | return valueNode; 18 | } 19 | } else break; 20 | } 21 | 22 | return valueNode; 23 | } 24 | -------------------------------------------------------------------------------- /packages/components/src/styles/Device.ts: -------------------------------------------------------------------------------- 1 | const size = { 2 | mobileS: '320px', 3 | mobileM: '375px', 4 | mobileL: '425px', 5 | tablet: '768px', 6 | laptop: '1024px', 7 | laptopM: '1270px', 8 | laptopL: '1440px', 9 | desktop: '2560px', 10 | }; 11 | 12 | export const Device = { 13 | mobileS: `(min-width: ${size.mobileS})`, 14 | mobileM: `(min-width: ${size.mobileM})`, 15 | mobileL: `(min-width: ${size.mobileL})`, 16 | tablet: `(min-width: ${size.tablet})`, 17 | laptopM: `(min-width: ${size.laptopM})`, 18 | laptop: `(min-width: ${size.laptop})`, 19 | laptopL: `(min-width: ${size.laptopL})`, 20 | desktop: `(min-width: ${size.desktop})`, 21 | desktopL: `(min-width: ${size.desktop})`, 22 | }; 23 | -------------------------------------------------------------------------------- /packages/parser/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @monokle/parser 2 | 3 | ## 0.3.2 4 | 5 | ### Patch Changes 6 | 7 | - 74c0a7c: Support Windows separator in helm path checks 8 | 9 | ## 0.3.1 10 | 11 | ### Patch Changes 12 | 13 | - 0f8d7c5: Improve helm files check 14 | 15 | ## 0.3.0 16 | 17 | ### Minor Changes 18 | 19 | - 333ea82: Add logic to guess resources if yaml invalid 20 | 21 | ## 0.2.0 22 | 23 | ### Minor Changes 24 | 25 | - 7357bdf: Added flag to filter helm template files during parsing 26 | 27 | ## 0.1.1 28 | 29 | ### Patch Changes 30 | 31 | - 8e49957: add get suppressions query in the synchronizer package 32 | 33 | ## 0.1.0 34 | 35 | ### Minor Changes 36 | 37 | - cf78c92: Introduced '@monokle/parser' package 38 | -------------------------------------------------------------------------------- /packages/validation/src/references/mappers/endpoints.ts: -------------------------------------------------------------------------------- 1 | import {optionalExplicitNamespaceMatcher, targetKindMatcher} from './core.js'; 2 | import {RefMapper} from './mappers.js'; 3 | 4 | export const endpointsMappers: RefMapper[] = [ 5 | { 6 | source: { 7 | pathParts: ['metadata', 'name'], 8 | }, 9 | target: { 10 | kind: 'Service', 11 | }, 12 | type: 'name', 13 | }, 14 | { 15 | source: { 16 | pathParts: ['targetRef', 'name'], 17 | siblingMatchers: { 18 | namespace: optionalExplicitNamespaceMatcher, 19 | kind: targetKindMatcher, 20 | }, 21 | }, 22 | target: { 23 | kind: '$.*', 24 | }, 25 | type: 'name', 26 | }, 27 | ]; 28 | -------------------------------------------------------------------------------- /packages/validation/src/utils/uriBase.ts: -------------------------------------------------------------------------------- 1 | import { OriginalUriBaseIds } from "../common/sarif.js"; 2 | 3 | type CreateOriginalUriBaseIdsParams = { 4 | srcroot?: string; 5 | } 6 | 7 | export function createOriginalUriBaseIds({ 8 | srcroot 9 | }: CreateOriginalUriBaseIdsParams) { 10 | const result: OriginalUriBaseIds = { 11 | "SRCROOT": { 12 | description: { 13 | text: "The path to the root of this project." 14 | } 15 | }, 16 | "RESOURCE": { 17 | description: { 18 | text:"A symbol which indicates the URI is a resource identifier." 19 | } 20 | } 21 | } 22 | 23 | if (srcroot) { 24 | result["SRCROOT"].uri = srcroot; 25 | } 26 | 27 | return result; 28 | } -------------------------------------------------------------------------------- /packages/components/src/atoms/KeyValueInput/KeyValueInput.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import {KeyValueInput} from './KeyValueInput'; 3 | 4 | export default { 5 | title: 'Atoms/KeyValueInput', 6 | component: KeyValueInput, 7 | } as ComponentMeta; 8 | 9 | const Template: ComponentStory = args => ; 10 | 11 | export const IsExistOperatorComponent = Template.bind({}); 12 | 13 | IsExistOperatorComponent.args = { 14 | pair: ['label', ''], 15 | }; 16 | 17 | export const IsEqualOperatorComponent = Template.bind({}); 18 | 19 | IsEqualOperatorComponent.args = { 20 | pair: ['label', 'demo'], 21 | }; 22 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ProblemInfo/types.ts: -------------------------------------------------------------------------------- 1 | import {Location, RuleMetadata, ValidationResult} from '@monokle/validation'; 2 | import React from 'react'; 3 | import {SuppressionBindings} from '../ValidationOverview/types'; 4 | 5 | export type ProblemInfoType = { 6 | problem: ValidationResult; 7 | rule: RuleMetadata; 8 | onHelpURLClick: (url: string) => void; 9 | onConfigureRule: () => void; 10 | containerClassName?: string; 11 | containerStyle?: React.CSSProperties; 12 | onLocationClick?: (location: Location) => void; 13 | suppressionBindings?: SuppressionBindings; 14 | onProblemAutofix?: (problem: ValidationResult) => void; 15 | onProblemShare?: (problem: ValidationResult) => void; 16 | }; 17 | -------------------------------------------------------------------------------- /packages/synchronizer/src/handlers/storageHandlerJsonCache.ts: -------------------------------------------------------------------------------- 1 | import {StorageHandler, getDefaultStorageConfigPaths} from './storageHandler.js'; 2 | 3 | export class StorageHandlerJsonCache extends StorageHandler> { 4 | constructor(storageFolderPath: string = getDefaultStorageConfigPaths().cache) { 5 | super(storageFolderPath); 6 | } 7 | 8 | async setStoreData(data: Record, fileName: string): Promise { 9 | const filePath = this.getStoreDataFilePath(fileName); 10 | await this.writeStoreData(filePath, JSON.stringify(data)); 11 | return filePath; 12 | } 13 | 14 | protected parseData(data: string) { 15 | return JSON.parse(data); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/validation/src/validators/admission-policy/rules.ts: -------------------------------------------------------------------------------- 1 | import {RuleMetadata} from '../../common/sarif.js'; 2 | 3 | export const ADMISSION_POLICY_RULES: RuleMetadata[] = [ 4 | { 5 | id: 'VAP001', 6 | name: 'admission-policy-violated', 7 | shortDescription: {text: 'Admission policy conditions violated'}, 8 | help: { 9 | text: 'Check whether the admission policy conditions are met.', 10 | }, 11 | }, 12 | { 13 | id: 'VAP002', 14 | name: 'admission-policy-failed-to-evaluate', 15 | shortDescription: {text: "Admission policy couldn't be evaluated"}, 16 | help: { 17 | text: 'Check whether the admission policy expression is properly written.', 18 | }, 19 | }, 20 | ]; 21 | -------------------------------------------------------------------------------- /packages/monaco-kubernetes/src/validation/types.ts: -------------------------------------------------------------------------------- 1 | import { Config } from "@monokle/validation"; 2 | import { TextDocument } from "vscode-languageserver-textdocument"; 3 | import { Diagnostic, DefinitionLink } from "vscode-languageserver-types"; 4 | import { DefinitionParams } from "vscode-languageserver-protocol/lib/common/protocol"; 5 | 6 | export type ValidationLanguageSettings = { 7 | validation?: Config; 8 | }; 9 | 10 | export interface MonokleLanguageService { 11 | configure(settings: ValidationLanguageSettings): void; 12 | doValidation(document: TextDocument): Promise; 13 | doDefinition( 14 | document: TextDocument, 15 | params: DefinitionParams 16 | ): DefinitionLink[] | undefined; 17 | } 18 | -------------------------------------------------------------------------------- /packages/validation/src/sarif/suppressions/types.ts: -------------------------------------------------------------------------------- 1 | import {Suppression, SuppressionKind, ValidationResult, ValidationRun} from '../../common/sarif.js'; 2 | import {Resource} from '../../common/types.js'; 3 | 4 | export type {AnnotationsSuppression, FingerprintSuppression} from '@monokle/types'; 5 | 6 | export type ResourceApi = { 7 | getResource: () => Resource | undefined; 8 | getAllResources: () => Resource[]; 9 | }; 10 | 11 | export interface Suppressor { 12 | kind: SuppressionKind; 13 | preload(suppressions?: S[]): Promise; 14 | suppress(problem: ValidationResult, run: ValidationRun, api: ResourceApi): Suppression[] | Promise; 15 | suppressions?: S[]; 16 | } 17 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/pss-1/invalid-volume-type.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: demo 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app.kubernetes.io/name: demo 10 | template: 11 | metadata: 12 | labels: 13 | app.kubernetes.io/name: demo 14 | spec: 15 | containers: 16 | - name: demo 17 | image: demo:latest 18 | volumeMounts: 19 | - name: configuration 20 | subPath: data.js 21 | mountPath: /usr/share/data.js 22 | volumes: 23 | - name: configuration 24 | azureFile: 25 | secretName: 'test' 26 | shareName: 'test' 27 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ProblemInfo/ProblemInfo.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import ProblemInfo from './ProblemInfo'; 3 | import {LocationClickProblemInfoArgs, MainProblemInfoArgs} from './ProblemInfo.stories.args'; 4 | 5 | export default { 6 | title: 'Molecules/ProblemInfo', 7 | component: ProblemInfo, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ; 11 | 12 | export const MainProblemInfo = Template.bind({}); 13 | MainProblemInfo.args = MainProblemInfoArgs; 14 | 15 | export const LocationClickProblemInfo = Template.bind({}); 16 | LocationClickProblemInfo.args = LocationClickProblemInfoArgs; 17 | -------------------------------------------------------------------------------- /packages/validation/src/config/read.node.ts: -------------------------------------------------------------------------------- 1 | import * as fsp from 'fs/promises'; 2 | import * as fs from 'fs'; 3 | import YAML from 'yaml'; 4 | import {Config, parseConfig} from './parse.js'; 5 | 6 | const DEFAULT_CONFIG_PATH = 'monokle.validation.yaml'; 7 | 8 | export async function readConfig(path: string = DEFAULT_CONFIG_PATH): Promise { 9 | if (!fs.existsSync(path)) { 10 | return undefined; 11 | } 12 | 13 | try { 14 | const data = await fsp.readFile(path, 'utf8'); 15 | const content = YAML.parse(data); 16 | const config = parseConfig(content); 17 | return config; 18 | } catch (err) { 19 | console.error('Failed to read configuration from ' + path); 20 | return undefined; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/src/atoms/TextEllipsis/TextEllipsis.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import TextEllipsis from './TextEllipsis'; 3 | 4 | export default { 5 | title: 'Atoms/TextEllipsis', 6 | component: TextEllipsis, 7 | } as ComponentMeta; 8 | 9 | const Template: ComponentStory = args => ; 10 | 11 | export const DefaultComponent = Template.bind({}); 12 | DefaultComponent.args = { 13 | text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', 14 | }; 15 | -------------------------------------------------------------------------------- /packages/components/src/organisms/ResourceGraph/MiniMap.tsx: -------------------------------------------------------------------------------- 1 | import { Colors } from '@/styles/Colors'; 2 | import { MiniMap as RFMniMap, Node } from 'reactflow'; 3 | import { backgroundColourByKind } from './styled'; 4 | import { ResourceNodeData } from './types'; 5 | 6 | const getNodeColor = (node: Node) => { 7 | const { kind } = node.data; 8 | return backgroundColourByKind[kind] || Colors.geekblue1; 9 | }; 10 | 11 | export function MiniMap() { 12 | return ( 13 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Spinner/Spinner.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStoryObj } from "@storybook/react"; 2 | import { Spinner } from "./Spinner"; 3 | 4 | const meta: ComponentMeta = { 5 | title: "Atoms/Spinner", 6 | component: Spinner, 7 | }; 8 | export default meta; 9 | 10 | export const Small: ComponentStoryObj = { 11 | args: { 12 | isSpinning: true, 13 | size: "small", 14 | }, 15 | }; 16 | 17 | export const Default: ComponentStoryObj = { 18 | args: { 19 | isSpinning: true, 20 | size: "default", 21 | }, 22 | }; 23 | 24 | export const Large: ComponentStoryObj = { 25 | args: { 26 | isSpinning: true, 27 | size: "large", 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/src/navigators/ResourceTreeNavigator.ts: -------------------------------------------------------------------------------- 1 | import { createTreeNavigator } from "@monokle/tree-navigator"; 2 | 3 | export const ResourceTreeNavigator = createTreeNavigator({ id: "ResourceNavigator" }); 4 | 5 | ResourceTreeNavigator.registerSection("files", { 6 | build: { 7 | label: "Resources", 8 | }, 9 | scope: (state) => { 10 | return { 11 | resourceMap: state.data.resourceMap, 12 | }; 13 | }, 14 | items: { 15 | build: (scope) => { 16 | const resources = Object.values(scope.resourceMap); 17 | return resources.map((resource: any) => { 18 | return { 19 | id: resource.filePath, 20 | label: resource.name, 21 | }; 22 | }); 23 | }, 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /packages/components/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "target": "ESNext", 5 | "useDefineForClassFields": true, 6 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 7 | "allowJs": false, 8 | "skipLibCheck": true, 9 | "esModuleInterop": false, 10 | "allowSyntheticDefaultImports": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "module": "ESNext", 14 | "moduleResolution": "Node", 15 | "resolveJsonModule": true, 16 | "isolatedModules": true, 17 | "noEmit": true, 18 | "jsx": "react-jsx", 19 | "paths": { 20 | "@/*": ["./src/*"] 21 | } 22 | }, 23 | "include": ["src"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/basic-template/src/rules/1-example.ts: -------------------------------------------------------------------------------- 1 | import { defineRule } from "@monokle/plugin-toolkit"; 2 | 3 | /** 4 | * A basic example that checks if a resource has annotations 5 | */ 6 | export const noEmptyAnnotations = defineRule({ 7 | id: 1, 8 | description: "Require annotations as metadata.", 9 | help: "Add any annotation to the Kubernetes resource.", 10 | validate({ resources }, { report }) { 11 | resources.forEach((resource) => { 12 | const annotations = Object.entries(resource.metadata?.annotations ?? {}); 13 | const hasAnnotations = annotations.length > 0; 14 | 15 | if (!hasAnnotations) { 16 | report(resource, { path: "metadata.annotations" }); 17 | } 18 | }); 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /packages/components/src/molecules/stories/ResizablePanels.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import {ResizableColumnsPanel, ResizableRowsPanel} from '../Panels'; 3 | import {AllColumnsArgs} from '../Panels/args'; 4 | 5 | export default { 6 | title: 'Organisms/ResizablePanels', 7 | component: ResizableRowsPanel, 8 | } as ComponentMeta; 9 | 10 | export const ResizablePanels: ComponentStory = () => ( 11 |
12 | } 15 | bottom={
Bottom Panel
} 16 | /> 17 |
18 | ); 19 | -------------------------------------------------------------------------------- /packages/components/src/atoms/SearchInput/SearchInput.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import {SearchOutlined} from '@ant-design/icons'; 3 | import {Input, InputProps} from 'antd'; 4 | import styled from 'styled-components'; 5 | 6 | const SearchInput = styled((props: InputProps) => ).attrs({ 7 | prefix: , 8 | })` 9 | border-radius: 4px; 10 | border: none; 11 | background-color: rgba(255, 255, 255, 0.1); 12 | width: 100%; 13 | 14 | .anticon-search { 15 | color: ${Colors.grey6}; 16 | font-size: 16px; 17 | } 18 | 19 | .ant-input-prefix { 20 | margin-right: 8px; 21 | } 22 | 23 | .ant-input { 24 | background-color: transparent; 25 | color: ${Colors.grey8}; 26 | } 27 | `; 28 | 29 | export default SearchInput; 30 | -------------------------------------------------------------------------------- /packages/components/src/molecules/Panels/ResizableRowsPanel.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import {AllRowsArgs, WithoutBottomRowArgs} from './args'; 3 | import ResizableRowsPanel from './ResizableRowsPanel'; 4 | 5 | export default { 6 | title: 'Molecules/ResizableRowsPanel', 7 | component: ResizableRowsPanel, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ( 11 |
12 | 13 |
14 | ); 15 | 16 | export const AllPanels = Template.bind({}); 17 | AllPanels.args = AllRowsArgs; 18 | 19 | export const WithoutBottomPanel = Template.bind({}); 20 | WithoutBottomPanel.args = WithoutBottomRowArgs; 21 | -------------------------------------------------------------------------------- /packages/components/src/atoms/KeyValueInput/KeyValueInput.styled.ts: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import styled from 'styled-components'; 3 | 4 | export const Box = styled.div` 5 | display: flex; 6 | border: solid ${Colors.grey5b} 1px; 7 | border-radius: 1px; 8 | align-items: center; 9 | `; 10 | 11 | export const KeySpacer = styled.div` 12 | flex: 1 1 50%; 13 | min-width: 80px; 14 | overflow: hidden; 15 | white-space: nowrap; 16 | text-overflow: clip; 17 | `; 18 | 19 | export const OperationSpacer = styled.div` 20 | color: ${Colors.grey7}; 21 | flex: 0 0 auto; 22 | padding: 0 4px; 23 | font-size: 12px; 24 | `; 25 | 26 | export const ValueSpacer = styled.div` 27 | flex: 1 3 120px; 28 | `; 29 | 30 | export const ActionSpacer = styled.div` 31 | flex: 0 0 20px; 32 | `; 33 | -------------------------------------------------------------------------------- /packages/components/src/molecules/WalkThrough/WalkThrough.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import styled from 'styled-components'; 3 | import {WalkThroughProps} from './types'; 4 | import {Modal as RawModal} from 'antd'; 5 | 6 | const WalkThrough: React.FC = ({topic, dismissWalkThrough, children}) => { 7 | return ( 8 | 9 | {children} 10 | 11 | ); 12 | }; 13 | 14 | export default WalkThrough; 15 | 16 | // Styled Components 17 | 18 | const Modal = styled(RawModal).attrs({ 19 | className: 'walkthrough-modal', 20 | })` 21 | min-width: 950px; 22 | 23 | .ant-modal-content { 24 | background-color: ${Colors.grey9} !important; 25 | border-radius: 4px; 26 | } 27 | `; 28 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/metadata/replica-set.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1beta2 2 | kind: ReplicaSet 3 | metadata: 4 | name: frontend 5 | labels: 6 | app: guestbook 7 | tier: frontend 8 | monokle.io/namespace: default 9 | monokle.io/group: local 10 | monokle.io/user: "" 11 | app.kubernetes.io/name: rs 12 | app.kubernetes.io/instance: rs-1 13 | app.kubernetes.io/version: "" 14 | annotations: 15 | revision: "1" 16 | hash: "123dsd3" 17 | monokle.io/namespace: default 18 | spec: 19 | replicas: 3 20 | selector: 21 | matchLabels: 22 | tier: frontend 23 | template: 24 | metadata: 25 | labels: 26 | tier: frontend 27 | spec: 28 | containers: 29 | - name: php-redis 30 | image: gcr.io/google_samples/gb-frontend:v3 31 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/templates/validation-ts/crd-template/src/rules/1-exampleCrd.ts: -------------------------------------------------------------------------------- 1 | import { defineRule } from "@monokle/plugin-toolkit"; 2 | import { isPrometheus } from "../schemas/__generated__/prometheus.monitoring.coreos.com.v1.js"; 3 | 4 | /** 5 | * Example with a CRD. 6 | * 7 | * @remark use `npm run codegen` to build the types 8 | */ 9 | export const noAdminApi = defineRule({ 10 | id: 1, 11 | description: "Disallow the admin API for Prometheus instances.", 12 | help: "Do not set enabledAdminAPI to true.", 13 | validate({ resources }, { report }) { 14 | resources.filter(isPrometheus).forEach((prometheus) => { 15 | const valid = prometheus.spec.enableAdminAPI !== true; 16 | if (valid) return; 17 | report(prometheus, { path: "spec.enableAdminAPI" }); 18 | }); 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /packages/validation/src/validators/open-policy-agent/types.ts: -------------------------------------------------------------------------------- 1 | import {loadPolicy} from '@open-policy-agent/opa-wasm'; 2 | import {RuleMetadata} from '../../common/sarif.js'; 3 | 4 | export type LoadedPolicy = Awaited>; 5 | export type PolicyError = {msg?: string}; 6 | 7 | export type PolicyConfig = { 8 | id: string; 9 | enabled: string; 10 | enabledRules: string[]; 11 | }; 12 | 13 | export type PolicyMetadata = { 14 | name: string; 15 | id: string; 16 | author: string; 17 | version: string; 18 | description: string; 19 | type: string; 20 | module: string; 21 | rules: RuleMetadata[]; 22 | }; 23 | 24 | /** 25 | * These are a rule's custom properties used by the OPA validator. 26 | */ 27 | export type OpaProperties = { 28 | entrypoint: string; 29 | path: string; 30 | }; 31 | -------------------------------------------------------------------------------- /packages/components/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "importOrder": [ 3 | "^@kubernetes?.+$", 4 | "^electron?.+$", 5 | "^react?.+$", 6 | "^antd?.+$", 7 | "^@ant-design?.+$", 8 | "^@reduxjs?.+$", 9 | "^@rjsf?.+$", 10 | "^(?![@\\.]).+$", 11 | "^@constants", 12 | "^@models", 13 | "^@redux", 14 | "^@organisms", 15 | "^@molecules", 16 | "^@atoms", 17 | "^@components", 18 | "^@hooks", 19 | "^@utils", 20 | "^@assets", 21 | "^@styles", 22 | "^@src", 23 | "^@.+$", 24 | "^(?!\\.+\\/styled)^[./]?.+$", 25 | "^\\.+\\/styled$" 26 | ], 27 | "importOrderSeparation": true, 28 | "importOrderSortSpecifiers": true, 29 | "singleQuote": true, 30 | "arrowParens": "avoid", 31 | "bracketSpacing": false, 32 | "semi": true, 33 | "trailingComma": "es5", 34 | "printWidth": 120 35 | } 36 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ValidationPopover/ValidationPopover.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import ValidationPopover from './ValidationPopover'; 3 | import {MainValidationPopoverArgs, MessageClickValidationPopoverArgs} from './ValidationPopover.stories.args'; 4 | 5 | export default { 6 | title: 'Molecules/ValidationPopover', 7 | component: ValidationPopover, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ; 11 | 12 | export const MainValidationPopover = Template.bind({}); 13 | MainValidationPopover.args = MainValidationPopoverArgs; 14 | 15 | export const MessageClickValidationPopover = Template.bind({}); 16 | MessageClickValidationPopover.args = MessageClickValidationPopoverArgs; 17 | -------------------------------------------------------------------------------- /packages/tree-navigator/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@reduxjs/toolkit": "^1.8.3", 13 | "@types/lodash.clonedeep": "^4.5.7", 14 | "lodash.clonedeep": "^4.5.0", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "react-redux": "^8.0.2", 18 | "redux-logger": "^3.0.6", 19 | "@monokle/tree-navigator": "*" 20 | }, 21 | "devDependencies": { 22 | "@types/react": "^18.0.15", 23 | "@types/react-dom": "^18.0.6", 24 | "@types/redux-logger": "^3.0.9", 25 | "@vitejs/plugin-react": "^2.0.0", 26 | "typescript": "^4.6.4", 27 | "vite": "^3.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-components/components/without-loadgenerator/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: kustomize.config.k8s.io/v1alpha1 16 | kind: Component 17 | patches: 18 | - delete-loadgenerator.patch.yaml 19 | -------------------------------------------------------------------------------- /packages/validation/src/__tests__/resources/kustomize-components/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: kustomize.config.k8s.io/v1beta1 16 | kind: Kustomization 17 | resources: 18 | - base 19 | components: 20 | - components/without-loadgenerator 21 | -------------------------------------------------------------------------------- /packages/validation/src/validators/admission-policy/types.ts: -------------------------------------------------------------------------------- 1 | import {Resource} from '../../common/types.js'; 2 | import {RuleLevel} from '../../commonExports.js'; 3 | 4 | export type Expression = { 5 | expression: string; 6 | message?: string; 7 | messageExpression?: string; 8 | }; 9 | 10 | export type PolicyExpressionsAndFilteredResources = Record< 11 | string, 12 | {expressions: Expression[]; resources: Resource[]; level: RuleLevel; params?: any} 13 | >; 14 | 15 | export type ParamRef = { 16 | name: string; 17 | namespace: string; 18 | }; 19 | 20 | export type PolicyBindingFilterResponse = Record< 21 | string, 22 | {resources: Resource[]; level: RuleLevel; paramRef?: ParamRef} 23 | >; 24 | 25 | // here the key of the record will be of type apiGroup/apiVersion#kind 26 | export type CRDExpressions = Record>; 27 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/ProblemSplit.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | 3 | const ProblemSplit = ({width, height}: {width?: number; height?: number}) => { 4 | const iconWidth = width || '8'; 5 | const iconHeight = height || '8'; 6 | 7 | return ( 8 | 9 | 13 | 17 | 18 | ); 19 | }; 20 | 21 | export default ProblemSplit; 22 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ActivityBar/ActivityBar.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import ActivityBar from './ActivityBar'; 3 | 4 | import {ExtraActivityBarArgs, HiddenOptionsActivityBarArgs, MainActivityBarArgs} from './args'; 5 | 6 | export default { 7 | title: 'Molecules/ActivityBar', 8 | component: ActivityBar, 9 | } as ComponentMeta; 10 | 11 | const Template: ComponentStory = args => ; 12 | 13 | export const MainActivityBar = Template.bind({}); 14 | MainActivityBar.args = MainActivityBarArgs; 15 | 16 | export const ExtraActivityBar = Template.bind({}); 17 | ExtraActivityBar.args = ExtraActivityBarArgs; 18 | 19 | export const HiddenOptionsActivityBar = Template.bind({}); 20 | HiddenOptionsActivityBar.args = HiddenOptionsActivityBarArgs; 21 | -------------------------------------------------------------------------------- /packages/validation/src/sarif/suppressions/plugins/FakeSuppressor.ts: -------------------------------------------------------------------------------- 1 | import {Suppression, SuppressionKind, ValidationResult} from '../../../common/sarif.js'; 2 | import {Suppressor} from '../types.js'; 3 | 4 | export class FakeSuppressor implements Suppressor { 5 | kind: SuppressionKind = 'external'; 6 | 7 | private _suppressions = new Set(); 8 | 9 | addSuppressionRequest(problem: ValidationResult) { 10 | this._suppressions.add(problem.fingerprints?.['monokleHash/v1']); 11 | } 12 | 13 | preload() { 14 | return Promise.resolve(); 15 | } 16 | 17 | suppress(problem: ValidationResult): Suppression[] { 18 | if (!this._suppressions.has(problem.fingerprints?.['monokleHash/v1'])) { 19 | return []; 20 | } 21 | 22 | return [{kind: 'external', status: 'accepted', justification: 'Suppressed by john.doe on 6th June.'}]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/components/src/atoms/TextEllipsis/TextEllipsis.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export type TextEllipsisProps = { 4 | text: string; 5 | style?: React.CSSProperties; 6 | }; 7 | 8 | const TextEllipsis: React.FC = props => { 9 | const {style = {}, text} = props; 10 | 11 | return ( 12 | 13 | {text} 14 | 15 | ); 16 | }; 17 | 18 | export default TextEllipsis; 19 | 20 | // Styled Components 21 | 22 | const Container = styled.div` 23 | width: 100%; 24 | position: relative; 25 | 26 | &:before { 27 | content: ' '; 28 | visibility: hidden; 29 | } 30 | 31 | & span { 32 | position: absolute; 33 | left: 0; 34 | right: 0; 35 | white-space: nowrap; 36 | overflow: hidden; 37 | text-overflow: ellipsis; 38 | } 39 | `; 40 | -------------------------------------------------------------------------------- /packages/validation/src/references/mappers/endpointSlice.ts: -------------------------------------------------------------------------------- 1 | import {implicitNamespaceMatcher, optionalExplicitNamespaceMatcher, targetKindMatcher} from './core.js'; 2 | import {RefMapper} from './mappers.js'; 3 | 4 | export const endpointSliceMappers: RefMapper[] = [ 5 | { 6 | source: { 7 | pathParts: ['metadata', 'labels', 'kubernetes.io/service-name'], 8 | siblingMatchers: { 9 | namespace: implicitNamespaceMatcher, 10 | }, 11 | }, 12 | target: { 13 | kind: 'Service', 14 | }, 15 | type: 'name', 16 | }, 17 | { 18 | source: { 19 | pathParts: ['targetRef', 'name'], 20 | siblingMatchers: { 21 | namespace: optionalExplicitNamespaceMatcher, 22 | kind: targetKindMatcher, 23 | }, 24 | }, 25 | target: { 26 | kind: '$.*', 27 | }, 28 | type: 'name', 29 | }, 30 | ]; 31 | -------------------------------------------------------------------------------- /packages/components/src/molecules/TitleBarCount/TitleBarCount.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import styled from 'styled-components'; 3 | import {TitleBarCountType} from './types'; 4 | 5 | const TitleBarCount: React.FC = ({count, isActive}) => { 6 | const Box = isActive ? ActiveBox : BaseBox; 7 | 8 | return {count}; 9 | }; 10 | 11 | export default TitleBarCount; 12 | 13 | // Styled Components 14 | 15 | const BaseBox = styled.div` 16 | font-size: 11px; 17 | line-height: 18px; 18 | padding: 0px 8px; 19 | background-color: ${Colors.blue3}; 20 | border: 1px solid ${Colors.blue4}; 21 | border-radius: 2px; 22 | color: ${Colors.blue7b}; 23 | `; 24 | 25 | const ActiveBox = styled(BaseBox)` 26 | background-color: ${Colors.geekblue7}; 27 | border: 1px solid ${Colors.grey9}; 28 | color: ${Colors.whitePure}; 29 | `; 30 | -------------------------------------------------------------------------------- /packages/tree-navigator/src/types/rtk.ts: -------------------------------------------------------------------------------- 1 | import { AnyAction, Dispatch } from "@reduxjs/toolkit"; 2 | import { 3 | AnyListenerPredicate, 4 | ListenerEffect, 5 | TypedStartListening, 6 | TypedStopListening, 7 | } from "@reduxjs/toolkit/dist/listenerMiddleware/types"; 8 | import { RootState } from "./rootState"; 9 | 10 | export type RtkListener = { 11 | predicate: AnyListenerPredicate; 12 | effect: ListenerEffect>; 13 | }; 14 | 15 | export type StartListening< 16 | AppState extends RootState = RootState, 17 | AppDispatch extends Dispatch = Dispatch 18 | > = TypedStartListening; 19 | 20 | export type StopListening< 21 | AppState extends RootState = RootState, 22 | AppDispatch extends Dispatch = Dispatch 23 | > = TypedStopListening; 24 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/Terminal.tsx: -------------------------------------------------------------------------------- 1 | const Terminal = ({ width, height }: { width?: number; height?: number }) => { 2 | const iconWidth = width || "22"; 3 | const iconHeight = height || "22"; 4 | 5 | return ( 6 | 7 | 14 | 21 | 22 | ); 23 | }; 24 | 25 | export default Terminal; 26 | -------------------------------------------------------------------------------- /packages/components/src/atoms/ProblemIcon/ProblemIcon.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import {Icon} from '../Icon'; 3 | 4 | export type ProblemIconType = { 5 | disabled?: boolean; 6 | level?: 'both' | 'error' | 'warning' | 'none'; 7 | style?: React.CSSProperties; 8 | }; 9 | 10 | const ProblemIcon: React.FC = props => { 11 | const {disabled, level, style = {}} = props; 12 | 13 | return ( 14 | 28 | ); 29 | }; 30 | 31 | export default ProblemIcon; 32 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | release: 12 | name: Release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout Repo 16 | uses: actions/checkout@v2 17 | 18 | - name: Setup Node.js 19 | uses: actions/setup-node@v2 20 | with: 21 | node-version: 16 22 | 23 | - name: Install Dependencies 24 | run: npm install 25 | 26 | - name: Create Release Pull Request or Publish to npm 27 | id: changesets 28 | uses: changesets/action@v1 29 | with: 30 | commit: "chore: release" 31 | publish: npm run release 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} 34 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 35 | -------------------------------------------------------------------------------- /packages/validation/src/utils/sarif.ts: -------------------------------------------------------------------------------- 1 | import {Location, ValidationResult} from '../common/sarif.js'; 2 | import invariant from './invariant.js'; 3 | 4 | export function getResourceId(result: ValidationResult): string | undefined { 5 | return getResourceLocation(result).physicalLocation?.artifactLocation.uri; 6 | } 7 | 8 | export function getFileId(result: ValidationResult): string | undefined { 9 | return getFileLocation(result).physicalLocation?.artifactLocation.uri; 10 | } 11 | 12 | export function getResourceLocation(result: ValidationResult): Location { 13 | const location = result.locations?.[1]; 14 | invariant(location, 'invalid SARIF result'); 15 | return location; 16 | } 17 | 18 | export function getFileLocation(result: ValidationResult): Location { 19 | const location = result.locations?.[0]; 20 | invariant(location, 'invalid SARIF result'); 21 | return location; 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/Validation.tsx: -------------------------------------------------------------------------------- 1 | const Validation = ({width, height}: {width?: number; height?: number}) => { 2 | const iconWidth = width || '18'; 3 | const iconHeight = height || '18'; 4 | return ( 5 | 6 | 11 | 18 | 19 | ); 20 | }; 21 | 22 | export default Validation; 23 | -------------------------------------------------------------------------------- /packages/create-monokle-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-monokle-plugin", 3 | "version": "0.4.0", 4 | "type": "module", 5 | "license": "MIT", 6 | "author": "Kubeshop", 7 | "bin": { 8 | "create-monokle": "index.js" 9 | }, 10 | "files": [ 11 | "index.js", 12 | "templates/**/*" 13 | ], 14 | "main": "index.js", 15 | "engines": { 16 | "node": "^14.18.0 || >=16.0.0" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/kubeshop/monokle-core.git", 21 | "directory": "packages/create-monokle-plugin" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/kubeshop/monokle-core/issues" 25 | }, 26 | "homepage": "https://github.com/kubeshop/monokle-core/tree/main/packages/create-monokle-plugin", 27 | "dependencies": { 28 | "kolorist": "1.5.1", 29 | "minimist": "1.2.6", 30 | "prompts": "2.4.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/validation/src/references/utils/getResourceKindsWithTargetingRefs.ts: -------------------------------------------------------------------------------- 1 | import {KNOWN_RESOURCE_KINDS} from '../../utils/knownResourceKinds.js'; 2 | import {getOutgoingRefMappers} from '../mappers/index.js'; 3 | import {refMapperMatchesKind} from './refMatcher.js'; 4 | 5 | const targetResourceKindCache = new Map(); 6 | 7 | /** 8 | * Returns all resource kinds that could potentially link to the specified kind. 9 | */ 10 | export function getResourceKindsWithTargetingRefs(kind: string): string[] { 11 | if (!targetResourceKindCache.has(kind)) { 12 | const resourceKinds = KNOWN_RESOURCE_KINDS.filter(knownKind => { 13 | const mappers = getOutgoingRefMappers(knownKind); 14 | return mappers.some(m => refMapperMatchesKind(m, kind)); 15 | }); 16 | 17 | targetResourceKindCache.set(kind, resourceKinds); 18 | } 19 | return targetResourceKindCache.get(kind) ?? []; 20 | } 21 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/Compare.tsx: -------------------------------------------------------------------------------- 1 | const Compare: React.FC = ({width, height}: {width?: number; height?: number}) => { 2 | const iconWidth = width || '18'; 3 | const iconHeight = height || '18'; 4 | 5 | return ( 6 | 7 | 14 | 21 | 22 | ); 23 | }; 24 | 25 | export default Compare; 26 | -------------------------------------------------------------------------------- /packages/validation/src/common/NodeWrapper.ts: -------------------------------------------------------------------------------- 1 | import {LineCounter, Scalar} from 'yaml'; 2 | import {RefPosition} from './types.js'; 3 | 4 | /** 5 | * Utility class used when parsing and creating refs 6 | */ 7 | export class NodeWrapper { 8 | node: Scalar; 9 | lineCounter?: LineCounter; 10 | 11 | constructor(node: Scalar, lineCounter?: LineCounter) { 12 | this.node = node; 13 | this.lineCounter = lineCounter; 14 | } 15 | 16 | nodeValue(): string { 17 | return this.node.value as string; 18 | } 19 | 20 | getNodePosition(): RefPosition { 21 | if (this.lineCounter && this.node.range) { 22 | const linePos = this.lineCounter.linePos(this.node.range[0]); 23 | return { 24 | line: linePos.line, 25 | column: linePos.col, 26 | length: this.node.range[1] - this.node.range[0], 27 | }; 28 | } 29 | 30 | return {line: 0, column: 0, length: 0}; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Filter/FilterForm.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import {PropsWithChildren} from 'react'; 3 | import styled from 'styled-components'; 4 | 5 | export const FilterForm = styled.div` 6 | display: flex; 7 | flex-direction: column; 8 | justify-items: flex-start; 9 | overflow-y: auto; 10 | gap: 6px; 11 | padding: 0 10px; 12 | `; 13 | 14 | type FieldProps = PropsWithChildren<{ 15 | name: string; 16 | }>; 17 | 18 | export function FilterField({name, children}: FieldProps) { 19 | return ( 20 | 21 | {name} 22 | {children} 23 | 24 | ); 25 | } 26 | 27 | const FieldItem = styled.div` 28 | display: flex; 29 | width: 100%; 30 | flex-direction: column; 31 | gap: 8px; 32 | color: ${Colors.grey9}; 33 | margin-bottom: 8px; 34 | 35 | & .ant-select-clear { 36 | border-radius: 50% !important; 37 | } 38 | `; 39 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/OPAStatus.tsx: -------------------------------------------------------------------------------- 1 | const OPAStatus = ({ width, height }: { width?: number; height?: number }) => { 2 | const iconWidth = width || "13"; 3 | const iconHeight = height || "14"; 4 | 5 | return ( 6 | 7 | 11 | 12 | ); 13 | }; 14 | 15 | export default OPAStatus; 16 | -------------------------------------------------------------------------------- /packages/components/src/molecules/TitleBarCount/TitleBarCount.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react"; 2 | import TitleBar from "../TitleBar/TitleBar"; 3 | import { ActiveTitleBarCountArgs, InactiveTitleBarCountArgs } from "./args"; 4 | import TitleBarCount from "./TitleBarCount"; 5 | 6 | export default { 7 | title: "Molecules/TitleBarCount", 8 | component: TitleBarCount, 9 | } as ComponentMeta; 10 | 11 | const Template: ComponentStory = (args) => ( 12 | } 17 | /> 18 | ); 19 | 20 | export const ActiveTitleBarCount = Template.bind({}); 21 | ActiveTitleBarCount.args = ActiveTitleBarCountArgs 22 | 23 | export const InactiveTitleBarCount = Template.bind({}); 24 | InactiveTitleBarCount.args = InactiveTitleBarCountArgs 25 | 26 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/Checked.tsx: -------------------------------------------------------------------------------- 1 | const Checked = ({width, height}: {width?: number; height?: number}) => { 2 | const iconWidth = width || '18'; 3 | const iconHeight = height || '18'; 4 | return ( 5 | 6 | 11 | 18 | 19 | ); 20 | }; 21 | 22 | export default Checked; 23 | -------------------------------------------------------------------------------- /packages/validation/src/validators/practices/rules/KBP114-no-exposed-service.ts: -------------------------------------------------------------------------------- 1 | import {defineRule} from '../../custom/config.js'; 2 | import {isService} from '../../custom/schemas/service.v1.js'; 3 | 4 | export const noExposedService = defineRule({ 5 | id: 114, 6 | description: 'Disallow exposing services publicly.', 7 | fullDescription: 8 | 'Exposed services are those who are not of the "ClusterIP" type. This practice hints that an ingress should be used instead.', 9 | help: 'Use ClusterIP services and expose it through an ingress.', 10 | advanced: { 11 | enabled: false, 12 | severity: 5, 13 | }, 14 | validate({resources}, {report}) { 15 | resources.filter(isService).forEach(service => { 16 | const valid = service.spec?.type === undefined || service.spec.type === 'ClusterIP'; 17 | if (valid) return; 18 | report(service, { 19 | path: 'spec.type', 20 | }); 21 | }); 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /packages/components/src/atoms/AppButtons/AppButtons.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import {AppButton} from './AppButtons'; 3 | import {EllipsisOutlined} from '@ant-design/icons'; 4 | 5 | export default { 6 | title: 'Atoms/AppButtons', 7 | component: AppButton, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ; 11 | 12 | export const PrimaryAppButton = Template.bind({}); 13 | PrimaryAppButton.args = { 14 | type: 'primary', 15 | children: 'Primary Button', 16 | }; 17 | 18 | export const SecondaryAppButton = Template.bind({}); 19 | SecondaryAppButton.args = { 20 | $disableHover: false, 21 | children: 'Secondary Button', 22 | }; 23 | 24 | export const DisabledSecondaryAppButton = Template.bind({}); 25 | DisabledSecondaryAppButton.args = { 26 | $disableHover: true, 27 | children: 'Secondary Button', 28 | }; 29 | -------------------------------------------------------------------------------- /packages/components/src/molecules/Panels/types.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export type ResizableColumnsPanelType = { 4 | right: React.ReactNode; 5 | middle?: React.ReactNode; 6 | defaultSizes?: number[]; 7 | isLeftActive?: boolean; 8 | isMiddleActive?: boolean; 9 | left?: React.ReactNode; 10 | leftPaneTooltipTitle?: string; 11 | middlePaneTooltipTitle?: string; 12 | leftClosable?: boolean; 13 | middleClosable?: boolean; 14 | minPaneWidth?: number; 15 | paneCloseIconStyle?: React.CSSProperties; 16 | onCloseLeftPane?: () => void; 17 | onCloseMiddlePane?: () => void; 18 | onDragEnd?: (sizes: number[]) => void; 19 | }; 20 | 21 | export type ResizableRowsPanelType = { 22 | top: React.ReactNode; 23 | bottom?: React.ReactNode; 24 | defaultSizes?: number[]; 25 | bottomPaneMinSize?: number; 26 | bottomPaneMaxSize?: number; 27 | isBottomVisible?: boolean; 28 | onDragEnd?: (sizes: number[]) => void; 29 | }; 30 | -------------------------------------------------------------------------------- /packages/components/src/atoms/Icon/Icons/ValidationOPA.tsx: -------------------------------------------------------------------------------- 1 | const ValidationOPA = ({ width, height }: { width?: number; height?: number }) => { 2 | const iconWidth = width || "12"; 3 | const iconHeight = height || "13"; 4 | 5 | return ( 6 | 7 | 11 | 12 | ); 13 | }; 14 | 15 | export default ValidationOPA; 16 | -------------------------------------------------------------------------------- /packages/synchronizer/src/createMonokleFetcher.ts: -------------------------------------------------------------------------------- 1 | import {DEFAULT_ORIGIN} from './constants.js'; 2 | import {ApiHandler, ClientConfig} from './handlers/apiHandler.js'; 3 | import {OriginConfig, fetchOriginConfig} from './handlers/configHandler.js'; 4 | import {Fetcher} from './utils/fetcher.js'; 5 | 6 | export async function createMonokleFetcherFromOrigin(clientConfig: ClientConfig, origin: string = DEFAULT_ORIGIN) { 7 | try { 8 | const originConfig = await fetchOriginConfig(origin); 9 | 10 | return createMonokleFetcherFromConfig(clientConfig, originConfig); 11 | } catch (err: any) { 12 | throw err; 13 | } 14 | } 15 | 16 | export function createMonokleFetcherFromConfig(clientConfig: ClientConfig, originConfig: OriginConfig) { 17 | if (!originConfig?.apiOrigin) { 18 | throw new Error(`No api origin found in origin config from ${origin}.`); 19 | } 20 | 21 | return new Fetcher(new ApiHandler(originConfig, clientConfig)); 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/src/organisms/ResourceGraph/types.ts: -------------------------------------------------------------------------------- 1 | import {Resource, ResourceMapType, RuleLevel, ValidationResult} from '@monokle/validation'; 2 | import {KnownResourceKinds} from '@monokle/validation/lib/utils/knownResourceKinds'; 3 | 4 | export type ResourceGraphProps = { 5 | resources: Resource[]; 6 | resourceMap: ResourceMapType; 7 | getProblemsForResource: (id: string, level: RuleLevel) => ValidationResult[]; 8 | onSelectResource?: (resource: Resource) => void; 9 | onSelectImage?: (imageId: string) => void; 10 | elkWorker: Worker; 11 | defaultNamespace?: string; 12 | }; 13 | 14 | export enum NodeType { 15 | Compact = 'compact', 16 | Expanded = 'expanded', 17 | None = 'none', 18 | } 19 | 20 | export type ResourceNodeKind = KnownResourceKinds | 'Kustomization' | 'Image'; 21 | export type ResourceNodeData = { 22 | name: string; 23 | kind: ResourceNodeKind; 24 | errors: ValidationResult[]; 25 | warnings: ValidationResult[]; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/synchronizer/src/createDefaultMonokleSynchronizer.ts: -------------------------------------------------------------------------------- 1 | import {ApiHandler} from './handlers/apiHandler.js'; 2 | import {GitHandler} from './handlers/gitHandler.js'; 3 | import {StorageHandlerPolicy} from './handlers/storageHandlerPolicy.js'; 4 | import {Synchronizer} from './utils/synchronizer.js'; 5 | 6 | /** 7 | * Creates default Monokle Synchronizer instance. 8 | * 9 | * @deprecated Use createMonokleSynchronizerFromOrigin or createMonokleSynchronizerFromConfig instead which does not rely on hardcoded config. 10 | * 11 | * @param storageHandler 12 | * @param apiHandler 13 | * @param gitHandler 14 | * @returns Synchronizer instance 15 | */ 16 | export function createDefaultMonokleSynchronizer( 17 | storageHandler: StorageHandlerPolicy = new StorageHandlerPolicy(), 18 | apiHandler: ApiHandler = new ApiHandler(), 19 | gitHandler: GitHandler = new GitHandler() 20 | ) { 21 | return new Synchronizer(storageHandler, apiHandler, gitHandler); 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/src/atoms/AppButtons/IconButton.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import {IconButton} from './IconButton'; 3 | import {EllipsisOutlined} from '@ant-design/icons'; 4 | 5 | export default { 6 | title: 'Atoms/IconButton', 7 | component: IconButton, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ; 11 | 12 | export const LargeEllipsisIconButton = Template.bind({}); 13 | LargeEllipsisIconButton.args = { 14 | $size: 'large', 15 | children: , 16 | }; 17 | 18 | export const MediumEllipsisIconButton = Template.bind({}); 19 | MediumEllipsisIconButton.args = { 20 | $size: 'medium', 21 | children: , 22 | }; 23 | 24 | export const SmallEllipsisIconButton = Template.bind({}); 25 | SmallEllipsisIconButton.args = { 26 | $size: 'small', 27 | children: , 28 | }; 29 | -------------------------------------------------------------------------------- /packages/components/src/molecules/ValidationOverview/constants.tsx: -------------------------------------------------------------------------------- 1 | import {Icon} from '@/atoms'; 2 | import {Colors} from '@/styles/Colors'; 3 | import {ValidationFiltersValueType} from './types'; 4 | 5 | export const DEFAULT_FILTERS_VALUE: ValidationFiltersValueType = { 6 | showSuppressed: true, 7 | showUnsuppressed: true, 8 | 'tool-component': undefined, 9 | type: undefined, 10 | }; 11 | 12 | export const iconMap: Record = { 13 | 'kubernetes-schema': , 14 | 'open-policy-agent': , 15 | 'resource-links': , 16 | 'yaml-syntax': , 17 | }; 18 | 19 | export const newErrorsTextMap: Record = { 20 | 'k8s-schema': 'K8s Schema changed.', 21 | rule: 'Rule changed.', 22 | }; 23 | -------------------------------------------------------------------------------- /packages/components/src/atoms/KeyValueInput/OperationSelect.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import {Select} from 'antd'; 3 | 4 | export enum Operation { 5 | IS = 'is', 6 | EXISTS = 'exists', 7 | } 8 | 9 | type Props = { 10 | value: Operation; 11 | onChange: (newOperation: Operation) => void; 12 | noFocus?: boolean; 13 | }; 14 | 15 | export function OperationSelect({value, onChange, noFocus = false}: Props) { 16 | return ( 17 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /packages/components/src/molecules/Panels/ResizableColumnsPanel.stories.tsx: -------------------------------------------------------------------------------- 1 | import {ComponentMeta, ComponentStory} from '@storybook/react'; 2 | import ResizableColumnsPanel from './ResizableColumnsPanel'; 3 | import {AllColumnsArgs, ClosableLeftColumnArgs, WithoutLeftColumnArgs} from './args'; 4 | 5 | export default { 6 | title: 'Molecules/ResizableColumnsPanel', 7 | component: ResizableColumnsPanel, 8 | } as ComponentMeta; 9 | 10 | const Template: ComponentStory = args => ( 11 |
12 | {' '} 13 |
14 | ); 15 | 16 | export const AllColumns = Template.bind({}); 17 | AllColumns.args = AllColumnsArgs; 18 | 19 | export const WithoutLeftColumn = Template.bind({}); 20 | WithoutLeftColumn.args = WithoutLeftColumnArgs; 21 | 22 | export const ClosableLeftColumn = Template.bind({}); 23 | ClosableLeftColumn.args = ClosableLeftColumnArgs; 24 | -------------------------------------------------------------------------------- /packages/components/src/atoms/AppButtons/IconButton.tsx: -------------------------------------------------------------------------------- 1 | import {Colors} from '@/styles/Colors'; 2 | import {Button, ButtonProps} from 'antd'; 3 | 4 | import styled from 'styled-components'; 5 | 6 | export const IconButton = styled((props: ButtonProps) =>