Skip to content

Commit

Permalink
feat: add monaco-kubernetes for editing IntelliSense (argoproj#12778)
Browse files Browse the repository at this point in the history
Signed-off-by: Delnat Wito <wito.delnat@gmail.com>
Signed-off-by: Remington Breeze <remington@breeze.software>
Co-authored-by: Remington Breeze <remington@breeze.software>
  • Loading branch information
WitoDelnat and rbreeze authored May 17, 2023
1 parent ea3a67a commit f8e016d
Show file tree
Hide file tree
Showing 8 changed files with 349 additions and 20 deletions.
1 change: 1 addition & 0 deletions test/container/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ FROM docker.io/library/redis:7.0.11@sha256:f50031a49f41e493087fb95f96fdb3523bb25
# architecture, so we create a symlink here to facilitate copying.
RUN ln -s /usr/lib/$(uname -m)-linux-gnu /usr/lib/linux-gnu


# Please make sure to also check the contained yarn version and update the references below when upgrading this image's version
FROM docker.io/library/node:18.15.0@sha256:8d9a875ee427897ef245302e31e2319385b092f1c3368b497e89790f240368f5 as node

Expand Down
2 changes: 1 addition & 1 deletion ui/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testEnvironment: 'jsdom',
reporters: ['default', 'jest-junit'],
collectCoverage: true,
transformIgnorePatterns: ['node_modules/(?!(argo-ui)/)'],
Expand Down
6 changes: 4 additions & 2 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"scripts": {
"start": "webpack-dev-server --config ./src/app/webpack.config.js --mode development",
"docker": "./scripts/build_docker.sh",
"build": "find ./dist -type f -not -name gitkeep -delete && webpack --config ./src/app/webpack.config.js --mode production",
"build": "find ./dist -type f -not -name gitkeep -delete && webpack --config ./src/app/webpack.config.js --mode production --stats-children",
"lint": "tsc --noEmit --project ./src/app && tslint -p ./src/app",
"lint:fix": "tslint -p ./src/app --fix",
"test": "jest"
Expand All @@ -28,6 +28,7 @@
"minimatch": "^3.1.2",
"moment": "^2.29.4",
"monaco-editor": "^0.33.0",
"monaco-kubernetes": "0.2.2",
"path": "^0.12.7",
"prop-types": "^15.8.1",
"react": "^16.9.3",
Expand Down Expand Up @@ -74,6 +75,7 @@
"@types/js-yaml": "^3.11.2",
"@types/lodash-es": "^4.17.6",
"@types/minimatch": "^3.0.3",
"@types/node": "18.15.3",
"@types/prop-types": "^15.7.5",
"@types/react": "^16.8.5",
"@types/react-autocomplete": "^1.8.4",
Expand Down Expand Up @@ -110,7 +112,7 @@
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-react": "^5.0.0",
"typescript": "^4.0.3",
"typescript": "^4.9.5",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4",
Expand Down
10 changes: 7 additions & 3 deletions ui/src/app/shared/components/monaco-editor.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';

import * as monacoEditor from 'monaco-editor';
import {configure, LanguageSettings} from 'monaco-kubernetes';

export interface EditorInput {
text: string;
Expand All @@ -11,7 +12,7 @@ export interface MonacoProps {
minHeight?: number;
vScrollBar: boolean;
editor?: {
options?: monacoEditor.editor.IEditorOptions;
options?: monacoEditor.editor.IEditorOptions & {settings?: LanguageSettings};
input: EditorInput;
getApi?: (api: monacoEditor.editor.IEditor) => any;
};
Expand All @@ -25,11 +26,13 @@ const DEFAULT_LINE_HEIGHT = 18;

const MonacoEditorLazy = React.lazy(() =>
import('monaco-editor').then(monaco => {
require('monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution.js');

const component = (props: MonacoProps) => {
const [height, setHeight] = React.useState(0);

React.useEffect(() => {
configure(props.editor.options.settings);
}, [props.editor.options.settings]);

return (
<div
style={{
Expand All @@ -47,6 +50,7 @@ const MonacoEditorLazy = React.lazy(() =>
const editor = monaco.editor.create(el, {
...props.editor.options,
scrollBeyondLastLine: props.vScrollBar,
renderValidationDecorations: 'on',
scrollbar: {
handleMouseWheel: false,
vertical: props.vScrollBar ? 'visible' : 'hidden'
Expand Down
54 changes: 54 additions & 0 deletions ui/src/app/shared/components/yaml-editor/yaml-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {LanguageSettings} from 'monaco-kubernetes';

/**
* The configuration of the editor.
*/
export type EditorConfig = {
/**
* Whether to use monaco-kubernetes in the editor.
*
* Enhancements
*
* - Schema validation for both well-known resources
* (e.g. Deployment, Ingress, etc) and Argo CRDs. This
* includes autocomplete and other common IntelliSense.
* - Adds semantical validation which includes the most
* prevalent Kubernetes hardening guidelines and additional
* rules to prevent misconfigurations in Argo CD CRDs.
*
* @remark All heavy lifting is done in a web worker which
* leaves the main thread free for rendering the UI.
*/
useKubernetesEditor: boolean;

/**
* Configuration of monaco-kubernetes.
*/

settings?: LanguageSettings;
};

export const DEFAULT_EDITOR_CONFIG: EditorConfig = {
useKubernetesEditor: true,
settings: {
// @see https://github.com/kubeshop/monokle-core/blob/main/packages/validation/docs/configuration.md
validation: {
plugins: {
'yaml-syntax': true,
'kubernetes-schema': true,
'open-policy-agent': true,
'argo': true
},
rules: {
// @see https://github.com/kubeshop/monokle-core/blob/main/packages/validation/docs/core-plugins.md#open-policy-agent
'open-policy-agent/no-latest-image': 'warn',
'open-policy-agent/no-low-user-id': 'warn',
'open-policy-agent/no-low-group-id': 'warn',
'open-policy-agent/no-elevated-process': 'err',
'open-policy-agent/no-sys-admin': 'err',
'open-policy-agent/no-host-mounted-path': 'err',
'open-policy-agent/no-host-port-access': 'err'
}
}
}
};
7 changes: 5 additions & 2 deletions ui/src/app/shared/components/yaml-editor/yaml-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as React from 'react';

import {Consumer} from '../../context';
import {MonacoEditor} from '../monaco-editor';
import {DEFAULT_EDITOR_CONFIG, EditorConfig} from './yaml-config';

const jsonMergePatch = require('json-merge-patch');
require('./yaml-editor.scss');
Expand All @@ -18,6 +19,7 @@ export class YamlEditor<T> extends React.Component<
onSave?: (patch: string, patchType: string) => Promise<any>;
onCancel?: () => any;
minHeight?: number;
config?: EditorConfig;
},
{
editing: boolean;
Expand All @@ -33,6 +35,7 @@ export class YamlEditor<T> extends React.Component<
public render() {
const props = this.props;
const yaml = props.input ? jsYaml.safeDump(props.input) : '';
const config = props.config ?? DEFAULT_EDITOR_CONFIG;

return (
<div className='yaml-editor'>
Expand Down Expand Up @@ -97,8 +100,8 @@ export class YamlEditor<T> extends React.Component<
minHeight={props.minHeight}
vScrollBar={props.vScrollbar}
editor={{
input: {text: yaml, language: 'yaml'},
options: {readOnly: !this.state.editing, minimap: {enabled: false}},
input: {text: yaml, language: config.useKubernetesEditor ? 'kubernetes' : 'yaml'},
options: {readOnly: !this.state.editing, minimap: {enabled: false}, settings: config.settings},
getApi: api => {
this.model = api.getModel() as monacoEditor.editor.ITextModel;
}
Expand Down
12 changes: 11 additions & 1 deletion ui/src/app/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,17 @@ const config = {
}),
new MonacoWebpackPlugin({
// https://github.com/microsoft/monaco-editor-webpack-plugin#options
languages: ['yaml']
languages: ['yaml'],
customLanguages: [
{
label: 'kubernetes',
entry: 'monaco-kubernetes',
worker: {
id: 'monaco-kubernetes/kubernetesWorker',
entry: 'monaco-kubernetes/worker'
}
}
]
})
],
devServer: {
Expand Down
Loading

0 comments on commit f8e016d

Please sign in to comment.