Skip to content

Commit

Permalink
Merge pull request #126 from kubeshop/olelensmar/docs/validator-docs-…
Browse files Browse the repository at this point in the history
…and-templates

Improved docs and added templates to create-monokle-plugin
  • Loading branch information
olensmar authored Jan 3, 2023
2 parents 299b653 + fd8986f commit 6727611
Show file tree
Hide file tree
Showing 41 changed files with 3,806 additions and 451 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# dependencies
node_modules
__generated__
/.pnp
.idea
.pnp.js
Expand Down Expand Up @@ -27,4 +28,4 @@ yarn-error.log*

.vscode

electron/env.ts
electron/env.ts
8 changes: 4 additions & 4 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

Monokle CLI is a command-line interface for static analysis of Kubernetes resources.

Use it to prevent misconfigurations within Kustomize, Helm or default Kubernetes resources. The output is available as a SARIF file which you can upload to GitHub CodeScan.
Use it to prevent misconfigurations within Kustomize, Helm or default Kubernetes resources. The output is available as a SARIF file
which you can upload to GitHub CodeScan.

Monokle CLI includes built-in validators for
- YAML Syntax
Expand Down Expand Up @@ -100,8 +101,7 @@ You can use `--help` to access help information directly from the CLI.
The Monokle CLI looks for a Monokle Validation configuration file
at `./monokle.validation.yaml`. You can change this by using the `--config` flag.

All rules are enabled by default and are
described in the [Monokle Validation configuration][monokle-validation-docs] documentation.
All rules are enabled by default and are described in the [Monokle Validation configuration][monokle-validation-docs] documentation.

**Example**

Expand All @@ -123,7 +123,7 @@ settings:
### Custom validators
It is easy to extend the Monokle CLI with custom validators that can be shared with others using
It is easy to extend the Monokle CLI with [custom validators](../validation/docs/custom-plugins.md) that can be shared with others using
our [Monokle Community Plugins][monokle-community-plugins] repository.
## GitHub Action
Expand Down
1 change: 1 addition & 0 deletions packages/cli/test/custom/.monokle-plugins/argo-plugin.js

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

7 changes: 7 additions & 0 deletions packages/cli/test/custom/argo-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocds
4 changes: 4 additions & 0 deletions packages/cli/test/custom/monokle.validation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
plugins:
argo: true
rules:
argo/argo-config-maps: "warn"
57 changes: 36 additions & 21 deletions packages/create-monokle-plugin/README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,63 @@
<p align="center">
<img src="docs/images/large-icon-256.png" alt="Monokle Logo" width="128" height="128"/>
</p>

<p align="center">
<a href="https://github.com/kubeshop/monokle-core/tree/main/packages/validation">
<img title="mit licence" src="https://img.shields.io/badge/License-MIT-yellow.svg"/>
</a>
</p>

# Welcome to Create Monokle Plugin

Use this library to scaffold your custom Monokle validation plugin in seconds - which can then
be used locally or contributed to our [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repository.

## Table of contents

- [Usage](#usage)
- [Interactive](#interactive)
- [Create a TypeScript validation plugin](#create-a-typescript-validation-plugin)
- [Example](#example)
- [Acknowledgements](#acknowledgements)
Read more about custom plugins in the [Custom Validator documentation](../validation/docs/custom-plugins.md)

## Usage

Prerequisite: it's recommended to use NodeJs LTS or higher and NPM 7+.

### Interactive

```
Running in interactive mode:

```shell
npm create monokle-plugin@latest
```

will prompt for:

```shell
✔ Plugin name: … my-validation-plugin
✔ Select a plugin type: › validation
✔ Select a variant: › validation-ts
✔ Select a template: › basic

Scaffolding plugin in /Users/olensmar/WebstormProjects/monokle-core/packages/create-monokle-plugin/my-validation-plugin...

Done. Now run:

cd my-validation-plugin
npm install
npm run dev
```

Now you're all set to implement your [Custom Plugin](../validation/docs/custom-plugins.md)

### Create a TypeScript validation plugin

```
npm create monokle-plugin@latest my-validator -- --template validation-ts
```

### Example
### Sharing plugins

Head over to the [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repo for an
example on how to get started with your own plugin.
Head over to the [Monokle Community Plugins](https://github.com/kubeshop/monokle-community-plugins) repo to see existing
community plugins and learn how you can create and share your own.

## Acknowledgements

This project is a modified version of [create-vite](https://github.com/vitejs/vite/tree/main/packages/create-vite) and
most credits go to them.

<p align="center">
<img src="docs/images/large-icon-256.png" alt="Monokle Logo" width="128" height="128"/>
</p>

<p align="center">
<a href="https://github.com/kubeshop/monokle-core/tree/main/packages/validation">
<img title="mit licence" src="https://img.shields.io/badge/License-MIT-yellow.svg"/>
</a>
</p>
85 changes: 58 additions & 27 deletions packages/create-monokle-plugin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,23 @@ const PLUGIN_TYPES = [
{
name: "validation-ts",
display: "TypeScript",
description: "Validation plugin written in Typescript",
color: blue,
},
],
},
templates: [
{
name: "basic",
description: "A sample typescript plugin with a single sample rule",
path: "validation-ts/basic-template"
},
{
name: "with-custom-crd",
description: "A sample typescript plugin using a custom resource definition (CRD)",
path: "validation-ts/crd-template"
}
]
}
]
}
];

const TEMPLATES = PLUGIN_TYPES.map(
Expand All @@ -33,21 +46,21 @@ const TEMPLATES = PLUGIN_TYPES.map(

const renameFiles = {
_gitignore: ".gitignore",
_npmrc: ".npmrc",
_npmrc: ".npmrc"
};

async function init() {
const defaultTargetDir = "monokle-plugin";
let targetDir = formatTargetDir(argv._[0]);
let template = argv.template || argv.t;
let projectName;
let pluginName;

const hasTemplateArg = template !== undefined;
const communityPath = path.join(cwd, ".community");
const isMonokleCommunityRepository = fs.existsSync(communityPath);

const getProjectName = () =>
targetDir === "." ? path.basename(path.resolve()) : projectName;
targetDir === "." ? path.basename(path.resolve()) : pluginName;

let result = {};

Expand All @@ -56,37 +69,37 @@ async function init() {
[
{
type: targetDir ? null : "text",
name: "projectName",
message: reset("Project name:"),
name: "pluginName",
message: reset("Plugin name:"),
initial: defaultTargetDir,
onState: (state) => {
projectName = state.value ?? defaultTargetDir;
pluginName = state.value ?? defaultTargetDir;
targetDir = formatTargetDir(state.value) || defaultTargetDir;
},
}
},
{
type: () => (isValidPackageName(getProjectName()) ? null : "text"),
name: "packageName",
message: reset("Package name:"),
initial: () => toValidPackageName(getProjectName()),
validate: (dir) =>
isValidPackageName(dir) || "Invalid package.json name",
isValidPackageName(dir) || "Invalid package.json name"
},
{
type: template && TEMPLATES.includes(template) ? null : "select",
name: "pluginType",
message:
typeof template === "string" && !TEMPLATES.includes(template)
? reset(
`"${template}" isn't a valid template. Please choose from below: `
)
`"${template}" isn't a valid template. Please choose from below: `
)
: reset("Select a plugin type:"),
initial: 0,
choices: PLUGIN_TYPES.map((pluginTypes) => {
const pluginTypeColor = pluginTypes.color;
return {
title: pluginTypeColor(pluginTypes.name),
value: pluginTypes,
value: pluginTypes
};
}),
onState: (state) => {
Expand All @@ -95,22 +108,40 @@ async function init() {
}

targetDir = `${state.value.name}/${targetDir}`;
},
}
},
{
type: (pluginType) =>
pluginType && pluginType.variants ? "select" : null,
name: "variant",
message: reset("Select a variant:"),
// @ts-ignore
choices: (framework) =>
framework.variants.map((variant) => {
choices: (pluginType) =>
pluginType.variants.map((variant) => {
const variantColor = variant.color;
return {
title: variantColor(variant.name),
value: variant.name,
description: variant.description,
value: variant.name
};
}),
})
},
{
type: (variant, values) => {
return values.pluginType && variant &&
values.pluginType.variants.find(elm => elm.name === variant) ? "select" : null;
},
name: "variantTemplate",
message: reset("Select a template:"),
// @ts-ignore
choices: (variant, values) =>
values.pluginType.variants.find(elm => elm.name === variant)?.templates.map(template => {
return {
title: template.name,
description: template.description,
value: template.path
};
})
},
{
type: () =>
Expand All @@ -120,7 +151,7 @@ async function init() {
(targetDir === "."
? "Current directory"
: `Target directory "${targetDir}"`) +
` is not empty. Remove existing files and continue?`,
` is not empty. Remove existing files and continue?`
},
{
type: (_, { overwrite } = {}) => {
Expand All @@ -129,14 +160,14 @@ async function init() {
}
return null;
},
name: "overwriteChecker",
},
name: "overwriteChecker"
}
],

{
onCancel: () => {
throw new Error(red("✖") + " Operation cancelled");
},
}
}
);
} catch (cancelled) {
Expand All @@ -145,7 +176,7 @@ async function init() {
}

// user choice associated with prompts
const { pluginType, overwrite, packageName, variant } = result;
const { pluginType, overwrite, packageName, variant, variantTemplate } = result;

if (hasTemplateArg && isMonokleCommunityRepository) {
if (template.startsWith("validation")) {
Expand All @@ -162,14 +193,14 @@ async function init() {
}

// determine template
template = variant || pluginType || template;
template = variantTemplate ? path.join( "templates", variantTemplate ) : variant || pluginType || template;

console.log(`\nScaffolding plugin in ${root}...`);

const templateDir = path.resolve(
fileURLToPath(import.meta.url),
"..",
`template-${template}`
template
);

const write = (file, content) => {
Expand Down Expand Up @@ -296,7 +327,7 @@ function pkgFromUserAgent(userAgent) {
const pkgSpecArr = pkgSpec.split("/");
return {
name: pkgSpecArr[0],
version: pkgSpecArr[1],
version: pkgSpecArr[1]
};
}

Expand Down
4 changes: 2 additions & 2 deletions packages/create-monokle-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-monokle-plugin",
"version": "0.3.1",
"version": "0.4.0",
"type": "module",
"license": "MIT",
"author": "Kubeshop",
Expand All @@ -9,7 +9,7 @@
},
"files": [
"index.js",
"template-*"
"templates/**/*"
],
"main": "index.js",
"engines": {
Expand Down
Loading

0 comments on commit 6727611

Please sign in to comment.