mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Merge branch 'master' into upgrade-typedoc-to-0.20
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
commit
defa828fa1
33
.github/workflows/test.yml
vendored
33
.github/workflows/test.yml
vendored
@ -1,6 +1,11 @@
|
||||
name: Test
|
||||
on:
|
||||
- pull_request
|
||||
pull_request:
|
||||
branches:
|
||||
- "*"
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
build:
|
||||
name: Test
|
||||
@ -20,14 +25,36 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- run: make node_modules
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- uses: actions/cache@v2
|
||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-
|
||||
|
||||
- uses: nick-invision/retry@v2
|
||||
name: Install dependencies
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_on: error
|
||||
command: make node_modules
|
||||
|
||||
- run: make build-npm
|
||||
name: Generate npm package
|
||||
|
||||
- run: make -j2 build-extensions
|
||||
- uses: nick-invision/retry@v2
|
||||
name: Build bundled extensions
|
||||
with:
|
||||
timeout_minutes: 15
|
||||
max_attempts: 3
|
||||
retry_on: error
|
||||
command: make -j2 build-extensions
|
||||
|
||||
- run: make test
|
||||
name: Run tests
|
||||
|
||||
2
Makefile
2
Makefile
@ -18,7 +18,7 @@ binaries/client: node_modules
|
||||
yarn download-bins
|
||||
|
||||
node_modules: yarn.lock
|
||||
yarn install --frozen-lockfile
|
||||
yarn install --frozen-lockfile --network-timeout=100000
|
||||
yarn check --verify-tree --integrity
|
||||
|
||||
static/build/LensDev.html: node_modules
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Lens | The Kubernetes IDE
|
||||
|
||||
[](https://dev.azure.com/lensapp/lensapp/_build/latest?definitionId=1&branchName=master)
|
||||
[](https://github.com/lensapp/lens/actions/workflows/test.yml)
|
||||
[](https://github.com/lensapp/lens/releases?label=Downloads)
|
||||
[](https://join.slack.com/t/k8slens/shared_invite/enQtOTc5NjAyNjYyOTk4LWU1NDQ0ZGFkOWJkNTRhYTc2YjVmZDdkM2FkNGM5MjhiYTRhMDU2NDQ1MzIyMDA4ZGZlNmExOTc0N2JmY2M3ZGI)
|
||||
|
||||
@ -25,7 +25,7 @@ The Lens open source project is backed by a number of Kubernetes and cloud nativ
|
||||
* Lens Extensions are used to add custom visualizations and functionality to accelerate development workflows for all the technologies and services that integrate with Kubernetes
|
||||
* Port forwarding
|
||||
* Helm package deployment: Browse and deploy Helm charts with one click-Install
|
||||
* Extensions via Lens Extensions API
|
||||
* Extensions via Lens Extensions API
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@ -387,10 +387,11 @@ describe("Lens cluster pages", () => {
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}
|
||||
}
|
||||
await new Promise(r => setTimeout(r, 500)); // Give some extra time to prepare extensions
|
||||
|
||||
// Open logs tab in dock
|
||||
await app.client.click(".list .TableRow:first-child");
|
||||
await app.client.waitForVisible(".Drawer");
|
||||
await app.client.waitForVisible(`ul.KubeObjectMenu li.MenuItem i[title="Logs"]`);
|
||||
await app.client.click(".drawer-title .Menu li:nth-child(2)");
|
||||
// Check if controls are available
|
||||
await app.client.waitForVisible(".LogList .VirtualList");
|
||||
|
||||
@ -39,7 +39,10 @@ export function minikubeReady(testNamespace: string): boolean {
|
||||
}
|
||||
|
||||
export async function addMinikubeCluster(app: Application) {
|
||||
await app.client.click("button.add-button");
|
||||
await app.client.waitForVisible("button.MuiSpeedDial-fab");
|
||||
await app.client.click("button.MuiSpeedDial-fab");
|
||||
await app.client.waitForVisible(`button[title="Add from kubeconfig"]`);
|
||||
await app.client.click(`button[title="Add from kubeconfig"]`);
|
||||
await app.client.waitUntilTextExists("div", "Select kubeconfig file");
|
||||
await app.client.click("div.Select__control"); // show the context drop-down list
|
||||
await app.client.waitUntilTextExists("div", "minikube");
|
||||
|
||||
@ -206,6 +206,7 @@
|
||||
"electron-devtools-installer": "^3.1.1",
|
||||
"electron-updater": "^4.3.1",
|
||||
"electron-window-state": "^5.0.3",
|
||||
"filehound": "^1.17.4",
|
||||
"filenamify": "^4.1.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"handlebars": "^4.7.6",
|
||||
@ -216,7 +217,7 @@
|
||||
"jsonpath": "^1.0.2",
|
||||
"lodash": "^4.17.15",
|
||||
"mac-ca": "^1.0.4",
|
||||
"marked": "^1.2.7",
|
||||
"marked": "^2.0.3",
|
||||
"md5-file": "^5.0.0",
|
||||
"mobx": "^5.15.7",
|
||||
"mobx-observable-history": "^1.0.3",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { EventEmitter } from "events";
|
||||
import { observable } from "mobx";
|
||||
import { catalogCategoryRegistry } from "../catalog-category-registry";
|
||||
import { CatalogCategory, CatalogEntity, CatalogEntityActionContext, CatalogEntityContextMenuContext, CatalogEntityData, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog-entity";
|
||||
import { CatalogCategory, CatalogEntity, CatalogEntityActionContext, CatalogEntityAddMenuContext, CatalogEntityContextMenuContext, CatalogEntityData, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog-entity";
|
||||
import { clusterDisconnectHandler } from "../cluster-ipc";
|
||||
import { clusterStore } from "../cluster-store";
|
||||
import { requestMain } from "../ipc";
|
||||
@ -49,11 +49,13 @@ export class KubernetesCluster implements CatalogEntity {
|
||||
{
|
||||
icon: "settings",
|
||||
title: "Settings",
|
||||
onlyVisibleForSource: "local",
|
||||
onClick: async () => context.navigate(`/cluster/${this.metadata.uid}/settings`)
|
||||
},
|
||||
{
|
||||
icon: "delete",
|
||||
title: "Delete",
|
||||
onlyVisibleForSource: "local",
|
||||
onClick: async () => clusterStore.removeById(this.metadata.uid),
|
||||
confirm: {
|
||||
message: `Remove Kubernetes Cluster "${this.metadata.name} from Lens?`
|
||||
@ -97,6 +99,20 @@ export class KubernetesClusterCategory extends EventEmitter implements CatalogCa
|
||||
}
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.on("onCatalogAddMenu", (ctx: CatalogEntityAddMenuContext) => {
|
||||
ctx.menuItems.push({
|
||||
icon: "text_snippet",
|
||||
title: "Add from kubeconfig",
|
||||
onClick: async () => {
|
||||
ctx.navigate("/add-cluster");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getId() {
|
||||
return `${this.spec.group}/${this.spec.names.kind}`;
|
||||
}
|
||||
|
||||
@ -45,6 +45,7 @@ export interface CatalogEntityActionContext {
|
||||
export type CatalogEntityContextMenu = {
|
||||
icon: string;
|
||||
title: string;
|
||||
onlyVisibleForSource?: string; // show only if empty or if matches with entity source
|
||||
onClick: () => Promise<void>;
|
||||
confirm?: {
|
||||
message: string;
|
||||
@ -56,6 +57,11 @@ export interface CatalogEntityContextMenuContext {
|
||||
menuItems: CatalogEntityContextMenu[];
|
||||
}
|
||||
|
||||
export interface CatalogEntityAddMenuContext {
|
||||
navigate: (url: string) => void;
|
||||
menuItems: CatalogEntityContextMenu[];
|
||||
}
|
||||
|
||||
export type CatalogEntityData = {
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
// Common UI components
|
||||
export * from "../../renderer/components/layout/sub-title";
|
||||
export * from "../../renderer/components/input/search-input";
|
||||
|
||||
// layouts
|
||||
export * from "../../renderer/components/layout/page-layout";
|
||||
|
||||
@ -84,7 +84,9 @@ describe("kubeconfig manager tests", () => {
|
||||
|
||||
expect(logger.error).not.toBeCalled();
|
||||
expect(await kubeConfManager.getPath()).toBe(`tmp${path.sep}kubeconfig-foo`);
|
||||
const file = await fse.readFile(await kubeConfManager.getPath());
|
||||
// this causes an intermittent "ENXIO: no such device or address, read" error
|
||||
// const file = await fse.readFile(await kubeConfManager.getPath());
|
||||
const file = fse.readFileSync(await kubeConfManager.getPath());
|
||||
const yml = loadYaml<any>(file.toString());
|
||||
|
||||
expect(yml["current-context"]).toBe("minikube");
|
||||
|
||||
@ -2,7 +2,15 @@ import { navigate } from "../navigation";
|
||||
import { commandRegistry } from "../../extensions/registries";
|
||||
import { CatalogEntity } from "../../common/catalog-entity";
|
||||
|
||||
export { CatalogEntity, CatalogEntityData, CatalogEntityActionContext, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../common/catalog-entity";
|
||||
export {
|
||||
CatalogCategory,
|
||||
CatalogEntity,
|
||||
CatalogEntityData,
|
||||
CatalogEntityActionContext,
|
||||
CatalogEntityAddMenuContext,
|
||||
CatalogEntityContextMenu,
|
||||
CatalogEntityContextMenuContext
|
||||
} from "../../common/catalog-entity";
|
||||
|
||||
export const catalogEntityRunContext = {
|
||||
navigate: (url: string) => navigate(url),
|
||||
|
||||
9
src/renderer/components/+catalog/catalog-add-button.scss
Normal file
9
src/renderer/components/+catalog/catalog-add-button.scss
Normal file
@ -0,0 +1,9 @@
|
||||
.CatalogAddButton {
|
||||
position: absolute;
|
||||
right: 40px;
|
||||
bottom: 30px;
|
||||
|
||||
.MuiFab-primary {
|
||||
background-color: var(--blue);
|
||||
}
|
||||
}
|
||||
74
src/renderer/components/+catalog/catalog-add-button.tsx
Normal file
74
src/renderer/components/+catalog/catalog-add-button.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
import "./catalog-add-button.scss";
|
||||
import React from "react";
|
||||
import { SpeedDial, SpeedDialAction } from "@material-ui/lab";
|
||||
import { Icon } from "../icon";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { autobind } from "../../../common/utils";
|
||||
import { CatalogCategory, CatalogEntityAddMenuContext, CatalogEntityContextMenu } from "../../api/catalog-entity";
|
||||
import { EventEmitter } from "events";
|
||||
import { navigate } from "../../navigation";
|
||||
|
||||
export type CatalogAddButtonProps = {
|
||||
category: CatalogCategory
|
||||
};
|
||||
|
||||
@observer
|
||||
export class CatalogAddButton extends React.Component<CatalogAddButtonProps> {
|
||||
@observable protected isOpen = false;
|
||||
protected menuItems = observable.array<CatalogEntityContextMenu>([]);
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => this.props.category, (category) => {
|
||||
this.menuItems.clear();
|
||||
|
||||
if (category && category instanceof EventEmitter) {
|
||||
const context: CatalogEntityAddMenuContext = {
|
||||
navigate: (url: string) => navigate(url),
|
||||
menuItems: this.menuItems
|
||||
};
|
||||
|
||||
category.emit("onCatalogAddMenu", context);
|
||||
}
|
||||
}, { fireImmediately: true })
|
||||
]);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
onOpen() {
|
||||
this.isOpen = true;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
onClose() {
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.menuItems.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SpeedDial
|
||||
className="CatalogAddButton"
|
||||
ariaLabel="SpeedDial CatalogAddButton"
|
||||
open={this.isOpen}
|
||||
onOpen={this.onOpen}
|
||||
onClose={this.onClose}
|
||||
icon={<Icon material="add" />}
|
||||
direction="up"
|
||||
>
|
||||
{ this.menuItems.map((menuItem, index) => {
|
||||
return <SpeedDialAction
|
||||
key={index}
|
||||
icon={<Icon material={menuItem.icon} />}
|
||||
tooltipTitle={menuItem.title}
|
||||
onClick={() => menuItem.onClick()}
|
||||
/>;
|
||||
})}
|
||||
</SpeedDial>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -61,8 +61,6 @@ export class CatalogEntityStore extends ItemStore<CatalogEntityItem> {
|
||||
@computed get entities() {
|
||||
if (!this.activeCategory) return [];
|
||||
|
||||
console.log("computing entities", this.activeCategory);
|
||||
|
||||
return catalogEntityRegistry.getItemsForCategory(this.activeCategory).map(entity => new CatalogEntityItem(entity));
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
> .sidebar {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
|
||||
.sidebarTabs {
|
||||
margin-top: 5px;
|
||||
|
||||
@ -2,7 +2,7 @@ import "./catalog.scss";
|
||||
import React from "react";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { ItemListLayout } from "../item-object-list";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { action, observable, reaction } from "mobx";
|
||||
import { CatalogEntityItem, CatalogEntityStore } from "./catalog-entity.store";
|
||||
import { navigate } from "../../navigation";
|
||||
import { kebabCase } from "lodash";
|
||||
@ -12,12 +12,12 @@ import { Icon } from "../icon";
|
||||
import { CatalogEntityContextMenu, CatalogEntityContextMenuContext, catalogEntityRunContext } from "../../api/catalog-entity";
|
||||
import { Badge } from "../badge";
|
||||
import { hotbarStore } from "../../../common/hotbar-store";
|
||||
import { addClusterURL } from "../+add-cluster";
|
||||
import { autobind } from "../../utils";
|
||||
import { Notifications } from "../notifications";
|
||||
import { ConfirmDialog } from "../confirm-dialog";
|
||||
import { Tab, Tabs } from "../tabs";
|
||||
import { catalogCategoryRegistry } from "../../../common/catalog-category-registry";
|
||||
import { CatalogAddButton } from "./catalog-add-button";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -101,6 +101,7 @@ export class Catalog extends React.Component {
|
||||
return catalogCategoryRegistry.items;
|
||||
}
|
||||
|
||||
@action
|
||||
onTabChange = (tabId: string) => {
|
||||
this.activeTab = tabId;
|
||||
|
||||
@ -126,6 +127,7 @@ export class Catalog extends React.Component {
|
||||
|
||||
@autobind()
|
||||
renderItemMenu(item: CatalogEntityItem) {
|
||||
const menuItems = this.contextMenu.menuItems.filter((menuItem) => !menuItem.onlyVisibleForSource || menuItem.onlyVisibleForSource === item.entity.metadata.source);
|
||||
const onOpen = async () => {
|
||||
await item.onContextMenuOpen(this.contextMenu);
|
||||
};
|
||||
@ -138,7 +140,7 @@ export class Catalog extends React.Component {
|
||||
<MenuItem key="remove-from-hotbar" onClick={() => this.removeFromHotbar(item) }>
|
||||
<Icon material="clear" small interactive={true} title="Remove from hotbar"/> Remove from Hotbar
|
||||
</MenuItem>
|
||||
{ this.contextMenu.menuItems.map((menuItem, index) => {
|
||||
{ menuItems.map((menuItem, index) => {
|
||||
return (
|
||||
<MenuItem key={index} onClick={() => this.onMenuItemClick(menuItem)}>
|
||||
<Icon material={menuItem.icon} small interactive={true} title={menuItem.title}/> {menuItem.title}
|
||||
@ -149,6 +151,7 @@ export class Catalog extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
if (!this.catalogEntityStore) {
|
||||
return null;
|
||||
@ -161,6 +164,7 @@ export class Catalog extends React.Component {
|
||||
provideBackButtonNavigation={false}
|
||||
contentGaps={false}>
|
||||
<ItemListLayout
|
||||
renderHeaderTitle={this.catalogEntityStore.activeCategory?.metadata.name}
|
||||
isClusterScoped
|
||||
isSearchable={true}
|
||||
isSelectable={false}
|
||||
@ -186,11 +190,8 @@ export class Catalog extends React.Component {
|
||||
]}
|
||||
onDetails={(item: CatalogEntityItem) => this.onDetails(item) }
|
||||
renderItemMenu={this.renderItemMenu}
|
||||
addRemoveButtons={{
|
||||
addTooltip: "Add Kubernetes Cluster",
|
||||
onAdd: () => navigate(addClusterURL()),
|
||||
}}
|
||||
/>
|
||||
<CatalogAddButton category={this.catalogEntityStore.activeCategory} />
|
||||
</PageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
.CreateResource {
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,61 @@
|
||||
import fs from "fs-extra";
|
||||
import path from "path";
|
||||
import os from "os";
|
||||
import groupBy from "lodash/groupBy";
|
||||
import filehound from "filehound";
|
||||
import { watch } from "chokidar";
|
||||
import { autobind } from "../../utils";
|
||||
import { DockTabStore } from "./dock-tab.store";
|
||||
import { dockStore, IDockTab, TabKind } from "./dock.store";
|
||||
|
||||
@autobind()
|
||||
export class CreateResourceStore extends DockTabStore<string> {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
storageKey: "create_resource"
|
||||
});
|
||||
fs.ensureDirSync(this.userTemplatesFolder);
|
||||
}
|
||||
|
||||
get lensTemplatesFolder():string {
|
||||
return path.resolve(__static, "../templates/create-resource");
|
||||
}
|
||||
|
||||
get userTemplatesFolder():string {
|
||||
return path.join(os.homedir(), ".k8slens", "templates");
|
||||
}
|
||||
|
||||
async getTemplates(templatesPath: string, defaultGroup: string) {
|
||||
const templates = await filehound.create().path(templatesPath).ext(["yaml", "json"]).depth(1).find();
|
||||
|
||||
return templates ? this.groupTemplates(templates, templatesPath, defaultGroup) : {};
|
||||
}
|
||||
|
||||
groupTemplates(templates: string[], templatesPath: string, defaultGroup: string) {
|
||||
return groupBy(templates,(v:string) =>
|
||||
path.relative(templatesPath,v).split(path.sep).length>1
|
||||
? path.parse(path.relative(templatesPath,v)).dir
|
||||
: defaultGroup);
|
||||
}
|
||||
|
||||
async getMergedTemplates() {
|
||||
const userTemplates = await this.getTemplates(this.userTemplatesFolder, "ungrouped");
|
||||
const lensTemplates = await this.getTemplates(this.lensTemplatesFolder, "lens");
|
||||
|
||||
return {...userTemplates,...lensTemplates};
|
||||
}
|
||||
|
||||
async watchUserTemplates(callback: ()=> void){
|
||||
watch(this.userTemplatesFolder, {
|
||||
depth: 1,
|
||||
ignoreInitial: true,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 500
|
||||
}
|
||||
}).on("all", () => {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import "./create-resource.scss";
|
||||
|
||||
import React from "react";
|
||||
import path from "path";
|
||||
import fs from "fs-extra";
|
||||
import {Select, GroupSelectOption, SelectOption} from "../select";
|
||||
import jsYaml from "js-yaml";
|
||||
import { observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
@ -20,7 +23,25 @@ interface Props {
|
||||
|
||||
@observer
|
||||
export class CreateResource extends React.Component<Props> {
|
||||
@observable currentTemplates:Map<string,SelectOption> = new Map();
|
||||
@observable error = "";
|
||||
@observable templates:GroupSelectOption<SelectOption>[] = [];
|
||||
|
||||
componentDidMount() {
|
||||
createResourceStore.getMergedTemplates().then(v => this.updateGroupSelectOptions(v));
|
||||
createResourceStore.watchUserTemplates(() => createResourceStore.getMergedTemplates().then(v => this.updateGroupSelectOptions(v)));
|
||||
}
|
||||
|
||||
updateGroupSelectOptions(templates :Record<string, string[]>) {
|
||||
this.templates = Object.entries(templates)
|
||||
.map(([name, grouping]) => this.convertToGroup(name, grouping));
|
||||
}
|
||||
|
||||
convertToGroup(group:string, items:string[]):GroupSelectOption {
|
||||
const options = items.map(v => ({label: path.parse(v).name, value: v}));
|
||||
|
||||
return {label: group, options};
|
||||
}
|
||||
|
||||
get tabId() {
|
||||
return this.props.tab.id;
|
||||
@ -30,11 +51,20 @@ export class CreateResource extends React.Component<Props> {
|
||||
return createResourceStore.getData(this.tabId);
|
||||
}
|
||||
|
||||
get currentTemplate() {
|
||||
return this.currentTemplates.get(this.tabId) ?? null;
|
||||
}
|
||||
|
||||
onChange = (value: string, error?: string) => {
|
||||
createResourceStore.setData(this.tabId, value);
|
||||
this.error = error;
|
||||
};
|
||||
|
||||
onSelectTemplate = (item: SelectOption) => {
|
||||
this.currentTemplates.set(this.tabId, item);
|
||||
fs.readFile(item.value,"utf8").then(v => createResourceStore.setData(this.tabId,v));
|
||||
};
|
||||
|
||||
create = async () => {
|
||||
if (this.error) return;
|
||||
if (!this.data.trim()) return; // do not save when field is empty
|
||||
@ -67,6 +97,24 @@ export class CreateResource extends React.Component<Props> {
|
||||
return successMessage;
|
||||
};
|
||||
|
||||
renderControls(){
|
||||
return (
|
||||
<div className="flex gaps align-center">
|
||||
<Select
|
||||
autoConvertOptions = {false}
|
||||
className="TemplateSelect"
|
||||
placeholder="Select Template ..."
|
||||
options={this.templates}
|
||||
menuPlacement="top"
|
||||
themeName="outlined"
|
||||
onChange={v => this.onSelectTemplate(v)}
|
||||
value = {this.currentTemplate}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { tabId, data, error, create, onChange } = this;
|
||||
const { className } = this.props;
|
||||
@ -76,6 +124,7 @@ export class CreateResource extends React.Component<Props> {
|
||||
<InfoPanel
|
||||
tabId={tabId}
|
||||
error={error}
|
||||
controls={this.renderControls()}
|
||||
submit={create}
|
||||
submitLabel="Create"
|
||||
showNotifications={false}
|
||||
|
||||
@ -100,6 +100,7 @@ export class HotbarIcon extends React.Component<Props> {
|
||||
await entity.onContextMenuOpen(this.contextMenu);
|
||||
this.toggleMenu();
|
||||
};
|
||||
const menuItems = this.contextMenu?.menuItems.filter((menuItem) => !menuItem.onlyVisibleForSource || menuItem.onlyVisibleForSource === entity.metadata.source);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
@ -117,7 +118,7 @@ export class HotbarIcon extends React.Component<Props> {
|
||||
<MenuItem key="remove-from-hotbar" onClick={() => this.removeFromHotbar(entity) }>
|
||||
<Icon material="clear" small interactive={true} title="Remove from hotbar"/> Remove from Hotbar
|
||||
</MenuItem>
|
||||
{ this.contextMenu && this.contextMenu.menuItems.map((menuItem) => {
|
||||
{ this.contextMenu && menuItems.map((menuItem) => {
|
||||
return (
|
||||
<MenuItem key={menuItem.title} onClick={() => this.onMenuItemClick(menuItem) }>
|
||||
<Icon material={menuItem.icon} small interactive={true} title={menuItem.title}/> {menuItem.title}
|
||||
|
||||
198
templates/create-resource/ClusterRole.yaml
Normal file
198
templates/create-resource/ClusterRole.yaml
Normal file
@ -0,0 +1,198 @@
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: read-all-clusterrole
|
||||
rules:
|
||||
- nonResourceURLs:
|
||||
- /metrics
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- bindings
|
||||
- componentstatuses
|
||||
- configmaps
|
||||
- endpoints
|
||||
- events
|
||||
- limitranges
|
||||
- namespaces
|
||||
- namespaces/finalize
|
||||
- namespaces/status
|
||||
- nodes
|
||||
- nodes/proxy
|
||||
- nodes/status
|
||||
- persistentvolumeclaims
|
||||
- persistentvolumeclaims/status
|
||||
- persistentvolumes
|
||||
- persistentvolumes/status
|
||||
- pods
|
||||
- pods/attach
|
||||
- pods/binding
|
||||
- pods/eviction
|
||||
- pods/exec
|
||||
- pods/log
|
||||
- pods/proxy
|
||||
- pods/status
|
||||
- podtemplates
|
||||
- replicationcontrollers
|
||||
- replicationcontrollers/scale
|
||||
- replicationcontrollers/status
|
||||
- resourcequotas
|
||||
- resourcequotas/status
|
||||
- serviceaccounts
|
||||
- services
|
||||
- services/proxy
|
||||
- services/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- controllerrevisions
|
||||
- daemonsets
|
||||
- daemonsets/status
|
||||
- deployments
|
||||
- deployments/scale
|
||||
- deployments/status
|
||||
- replicasets
|
||||
- replicasets/scale
|
||||
- replicasets/status
|
||||
- statefulsets
|
||||
- statefulsets/scale
|
||||
- statefulsets/status
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- watch
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- jobs
|
||||
- jobs/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- autoscaling
|
||||
resources:
|
||||
- horizontalpodautoscalers
|
||||
- horizontalpodautoscalers/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- csidrivers
|
||||
- csinodes
|
||||
- storageclasses
|
||||
- volumeattachments
|
||||
- volumeattachments/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
resources:
|
||||
- networkpolicies
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- scheduling.k8s.io
|
||||
resources:
|
||||
- priorityclasses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- node.k8s.io
|
||||
resources:
|
||||
- runtimeclasses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- ingresses
|
||||
- ingresses/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- events.k8s.io
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
- customresourcedefinitions/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apiregistration.k8s.io
|
||||
resources:
|
||||
- apiservices
|
||||
- apiservices/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- discovery.k8s.io
|
||||
resources:
|
||||
- endpointslices
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- metrics.k8s.io
|
||||
resources:
|
||||
- pods
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- policy
|
||||
resources:
|
||||
- poddisruptionbudgets
|
||||
- poddisruptionbudgets/status
|
||||
- podsecuritypolicies
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- clusterrolebindings
|
||||
- clusterroles
|
||||
- rolebindings
|
||||
- roles
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
12
templates/create-resource/ClusterRoleBinding.yaml
Normal file
12
templates/create-resource/ClusterRoleBinding.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: developer-read-all
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: developer
|
||||
namespace: default
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: read-all-clusterrole
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
17
templates/create-resource/ConfigMap.yaml
Normal file
17
templates/create-resource/ConfigMap.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: game-demo
|
||||
data:
|
||||
# property-like keys; each key maps to a simple value
|
||||
player_initial_lives: "3"
|
||||
ui_properties_file_name: "user-interface.properties"
|
||||
|
||||
# file-like keys
|
||||
game.properties: |
|
||||
enemy.types=aliens,monsters
|
||||
player.maximum-lives=5
|
||||
user-interface.properties: |
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
||||
19
templates/create-resource/CronJob.yaml
Normal file
19
templates/create-resource/CronJob.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
apiVersion: batch/v1beta1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: hello
|
||||
spec:
|
||||
schedule: "*/1 * * * *"
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: hello
|
||||
image: busybox
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- date; echo Hello from the Kubernetes cluster
|
||||
restartPolicy: OnFailure
|
||||
44
templates/create-resource/DeamonSet.yaml
Normal file
44
templates/create-resource/DeamonSet.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: fluentd-elasticsearch
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: fluentd-logging
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
name: fluentd-elasticsearch
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: fluentd-elasticsearch
|
||||
spec:
|
||||
tolerations:
|
||||
# this toleration is to have the daemonset runnable on master nodes
|
||||
# remove it if your masters can't run pods
|
||||
- key: node-role.kubernetes.io/master
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: fluentd-elasticsearch
|
||||
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
|
||||
resources:
|
||||
limits:
|
||||
memory: 200Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 200Mi
|
||||
volumeMounts:
|
||||
- name: varlog
|
||||
mountPath: /var/log
|
||||
- name: varlibdockercontainers
|
||||
mountPath: /var/lib/docker/containers
|
||||
readOnly: true
|
||||
terminationGracePeriodSeconds: 30
|
||||
volumes:
|
||||
- name: varlog
|
||||
hostPath:
|
||||
path: /var/log
|
||||
- name: varlibdockercontainers
|
||||
hostPath:
|
||||
path: /var/lib/docker/containers
|
||||
21
templates/create-resource/Deployment.yaml
Normal file
21
templates/create-resource/Deployment.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
||||
17
templates/create-resource/Ingress.yaml
Normal file
17
templates/create-resource/Ingress.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: minimal-ingress
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||
spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /testpath
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: test
|
||||
port:
|
||||
number: 80
|
||||
13
templates/create-resource/Job.yaml
Normal file
13
templates/create-resource/Job.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: pi
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: pi
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
restartPolicy: Never
|
||||
backoffLimit: 4
|
||||
34
templates/create-resource/NetworkPolicy.yaml
Normal file
34
templates/create-resource/NetworkPolicy.yaml
Normal file
@ -0,0 +1,34 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: test-network-policy
|
||||
namespace: default
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
role: db
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
ingress:
|
||||
- from:
|
||||
- ipBlock:
|
||||
cidr: 172.17.0.0/16
|
||||
except:
|
||||
- 172.17.1.0/24
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
project: myproject
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
role: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 6379
|
||||
egress:
|
||||
- to:
|
||||
- ipBlock:
|
||||
cidr: 10.0.0.0/24
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5978
|
||||
18
templates/create-resource/PersistentVolume.yaml
Normal file
18
templates/create-resource/PersistentVolume.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: pv0003
|
||||
spec:
|
||||
capacity:
|
||||
storage: 5Gi
|
||||
volumeMode: Filesystem
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Recycle
|
||||
storageClassName: slow
|
||||
mountOptions:
|
||||
- hard
|
||||
- nfsvers=4.1
|
||||
nfs:
|
||||
path: /tmp
|
||||
server: 172.17.0.2
|
||||
17
templates/create-resource/PersistentVolumeClaim.yaml
Normal file
17
templates/create-resource/PersistentVolumeClaim.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: myclaim
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
volumeMode: Filesystem
|
||||
resources:
|
||||
requests:
|
||||
storage: 8Gi
|
||||
storageClassName: slow
|
||||
selector:
|
||||
matchLabels:
|
||||
release: "stable"
|
||||
matchExpressions:
|
||||
- {key: environment, operator: In, values: [dev]}
|
||||
21
templates/create-resource/ReplicaSet.yaml
Normal file
21
templates/create-resource/ReplicaSet.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
apiVersion: apps/v1
|
||||
kind: ReplicaSet
|
||||
metadata:
|
||||
name: frontend
|
||||
labels:
|
||||
app: guestbook
|
||||
tier: frontend
|
||||
spec:
|
||||
# modify replicas according to your case
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
tier: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
tier: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: php-redis
|
||||
image: gcr.io/google_samples/gb-frontend:v3
|
||||
19
templates/create-resource/ReplicationController.yaml
Normal file
19
templates/create-resource/ReplicationController.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
9
templates/create-resource/Role.yaml
Normal file
9
templates/create-resource/Role.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
namespace: default
|
||||
name: pod-reader
|
||||
rules:
|
||||
- apiGroups: [""] # "" indicates the core API group
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
17
templates/create-resource/RoleBinding.yaml
Normal file
17
templates/create-resource/RoleBinding.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
# This role binding allows "jane" to read pods in the "default" namespace.
|
||||
# You need to already have a Role named "pod-reader" in that namespace.
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: read-pods
|
||||
namespace: default
|
||||
subjects:
|
||||
# You can specify more than one "subject"
|
||||
- kind: User
|
||||
name: jane # "name" is case sensitive
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
roleRef:
|
||||
# "roleRef" specifies the binding to a Role / ClusterRole
|
||||
kind: Role #this must be Role or ClusterRole
|
||||
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
8
templates/create-resource/Secret.yaml
Normal file
8
templates/create-resource/Secret.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: secret-basic-auth
|
||||
type: kubernetes.io/basic-auth
|
||||
stringData:
|
||||
username: admin
|
||||
password: t0p-Secret
|
||||
11
templates/create-resource/Service.yaml
Normal file
11
templates/create-resource/Service.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: my-service
|
||||
spec:
|
||||
selector:
|
||||
app: MyApp
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 9376
|
||||
34
templates/create-resource/StatefulSet.yaml
Normal file
34
templates/create-resource/StatefulSet.yaml
Normal file
@ -0,0 +1,34 @@
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: web
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx # has to match .spec.template.metadata.labels
|
||||
serviceName: "nginx"
|
||||
replicas: 3 # by default is 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx # has to match .spec.selector.matchLabels
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 10
|
||||
containers:
|
||||
- name: nginx
|
||||
image: k8s.gcr.io/nginx-slim:0.8
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
volumeMounts:
|
||||
- name: www
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: www
|
||||
spec:
|
||||
accessModes: [ "ReadWriteOnce" ]
|
||||
storageClassName: "my-storage-class"
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
56
yarn.lock
56
yarn.lock
@ -2917,7 +2917,7 @@ bluebird-lst@^1.0.9:
|
||||
dependencies:
|
||||
bluebird "^3.5.5"
|
||||
|
||||
bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5:
|
||||
bluebird@^3.4.7, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||
@ -5683,7 +5683,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
|
||||
assign-symbols "^1.0.0"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
extend@~3.0.2:
|
||||
extend@^3.0.0, extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
@ -5833,6 +5833,15 @@ file-entry-cache@^5.0.1:
|
||||
dependencies:
|
||||
flat-cache "^2.0.1"
|
||||
|
||||
file-js@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/file-js/-/file-js-0.3.0.tgz#fab46bf782346c9294499f1f0d2ad07d838f25d1"
|
||||
integrity sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=
|
||||
dependencies:
|
||||
bluebird "^3.4.7"
|
||||
minimatch "^3.0.3"
|
||||
proper-lockfile "^1.2.0"
|
||||
|
||||
file-loader@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f"
|
||||
@ -5846,6 +5855,18 @@ file-uri-to-path@1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
|
||||
|
||||
filehound@^1.17.4:
|
||||
version "1.17.4"
|
||||
resolved "https://registry.yarnpkg.com/filehound/-/filehound-1.17.4.tgz#3f5b76c5b3edc1080311ba802e1ad43179e4291e"
|
||||
integrity sha512-A74hiTADH20bpFbXBNyKtpqN4Guffa+ROmdGJWNnuCRhaD45UVSVoI6McLcpHYmuaOERrzD3gMV3v9VZq/SHeA==
|
||||
dependencies:
|
||||
bluebird "^3.5.1"
|
||||
file-js "0.3.0"
|
||||
lodash "^4.17.10"
|
||||
minimatch "^3.0.4"
|
||||
moment "^2.22.1"
|
||||
unit-compare "^1.0.1"
|
||||
|
||||
filelist@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.1.tgz#f10d1a3ae86c1694808e8f20906f43d4c9132dbb"
|
||||
@ -9113,12 +9134,7 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
marked@^1.2.7:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.7.tgz#6e14b595581d2319cdcf033a24caaf41455a01fb"
|
||||
integrity sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA==
|
||||
|
||||
marked@^2.0.1:
|
||||
marked@^2.0.1, marked@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.3.tgz#3551c4958c4da36897bda2a16812ef1399c8d6b0"
|
||||
integrity sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==
|
||||
@ -9364,7 +9380,7 @@ minimalistic-crypto-utils@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
||||
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
|
||||
|
||||
minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.4, minimatch@~3.0.2:
|
||||
minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
@ -9522,6 +9538,11 @@ moment@^2.10.2, moment@^2.26.0:
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a"
|
||||
integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==
|
||||
|
||||
moment@^2.14.1, moment@^2.22.1:
|
||||
version "2.29.1"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
||||
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
||||
|
||||
moo-color@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/moo-color/-/moo-color-1.0.2.tgz#837c40758d2d58763825d1359a84e330531eca64"
|
||||
@ -11252,6 +11273,16 @@ prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
proper-lockfile@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-1.2.0.tgz#ceff5dd89d3e5f10fb75e1e8e76bc75801a59c34"
|
||||
integrity sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=
|
||||
dependencies:
|
||||
err-code "^1.0.0"
|
||||
extend "^3.0.0"
|
||||
graceful-fs "^4.1.2"
|
||||
retry "^0.10.0"
|
||||
|
||||
proper-lockfile@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.1.tgz#284cf9db9e30a90e647afad69deb7cb06881262c"
|
||||
@ -13991,6 +14022,13 @@ unique-string@^2.0.0:
|
||||
dependencies:
|
||||
crypto-random-string "^2.0.0"
|
||||
|
||||
unit-compare@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/unit-compare/-/unit-compare-1.0.1.tgz#0c7459f0e5bf53637ea873ca3cee18de2eeca386"
|
||||
integrity sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=
|
||||
dependencies:
|
||||
moment "^2.14.1"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user