mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
YAML Templates in Create Resource dock tab
Signed-off-by: Pavel Ashevskiy <pavel.ashevskiy@ifellow.ru>
This commit is contained in:
parent
b852384e85
commit
f74d365ee4
@ -1,2 +1,25 @@
|
|||||||
.CreateResource {
|
.CreateResource {
|
||||||
|
.Select {
|
||||||
|
.Select__single-value {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
&.TemplateSelect {
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.select-template-item{
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: baseline;
|
||||||
|
|
||||||
|
.select-template-badge {
|
||||||
|
text-transform: none;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-template-group {
|
||||||
|
span {
|
||||||
|
font-size: 13px
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,14 +1,99 @@
|
|||||||
|
import fs from "fs-extra";
|
||||||
|
import path from "path";
|
||||||
|
import os from "os"
|
||||||
|
import chokidar from "chokidar"
|
||||||
|
import filehound from "filehound"
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { DockTabStore } from "./dock-tab.store";
|
import { DockTabStore } from "./dock-tab.store";
|
||||||
import { dockStore, IDockTab, TabKind } from "./dock.store";
|
import { dockStore, IDockTab, TabKind } from "./dock.store";
|
||||||
|
import { GroupSelectOption, SelectOption} from "../select";
|
||||||
|
|
||||||
|
export interface BadgedSelectOption extends SelectOption {
|
||||||
|
badge?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BadgedGroupSelectOption extends GroupSelectOption<BadgedSelectOption> {
|
||||||
|
badge?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
export class CreateResourceStore extends DockTabStore<string> {
|
export class CreateResourceStore extends DockTabStore<string> {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
storageKey: "create_resource"
|
storageKey: "create_resource"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get lensTemplatesFolder():string {
|
||||||
|
return path.resolve(__static, "../templates/create-resource");
|
||||||
|
}
|
||||||
|
|
||||||
|
get userTemplatesFolder():string {
|
||||||
|
return path.join(os.homedir(), ".k8slens", "templates");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getTemplates(templatesPath: string):Promise<GroupSelectOption[]>{
|
||||||
|
const ungroupedTemplates:SelectOption[] = [];
|
||||||
|
const templates:GroupSelectOption[] = [];
|
||||||
|
let groups = await fs.readdir(templatesPath);
|
||||||
|
await Promise.all(groups.map(async (group) =>{
|
||||||
|
const groupAbsPath = path.join(templatesPath, group);
|
||||||
|
if((await fs.stat(groupAbsPath)).isDirectory()){
|
||||||
|
const files = await fs.readdir(groupAbsPath);
|
||||||
|
const templateSelectOptions = await Promise.all(files.map(
|
||||||
|
(template) => ({
|
||||||
|
value: path.join(groupAbsPath,template),
|
||||||
|
label: path.parse(template).name
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
templates.push({label: group.replace("-", " "), options: templateSelectOptions});
|
||||||
|
} else {
|
||||||
|
ungroupedTemplates.push({ value: groupAbsPath, label: path.parse(group).name});
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
if (ungroupedTemplates.length > 0){
|
||||||
|
templates.push({label: "ungrouped", options: ungroupedTemplates})
|
||||||
|
}
|
||||||
|
return templates;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getMergedTemplates():Promise<BadgedGroupSelectOption[]> {
|
||||||
|
const lensTemplates = await this.getTemplates(this.lensTemplatesFolder);
|
||||||
|
const userTemplates = await this.getTemplates(this.userTemplatesFolder);
|
||||||
|
const userGroupOptions:BadgedGroupSelectOption[] = userTemplates.filter(
|
||||||
|
({label}) => !lensTemplates.map(({label}) => label.toString().toLowerCase()).includes(label.toString().toLowerCase())
|
||||||
|
).map(({label,options}) => ({label, badge:"user", options}));
|
||||||
|
// merge lens and user templates within lens groups, then merge lens and user groups
|
||||||
|
const badgedTemplates:BadgedGroupSelectOption[] = lensTemplates.map( ({label, options}) => {
|
||||||
|
const userOptions = userTemplates.find(userTemplate => userTemplate.label.toString().toLowerCase() == label.toString().toLowerCase())
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
options: userOptions ? options.concat(userOptions.options.map((userOption) => ({label: userOption.label, badge: "user", value: userOption.value}))) : options
|
||||||
|
};
|
||||||
|
})
|
||||||
|
return this.orderTemplatesGroups(userGroupOptions).concat(this.orderTemplatesGroups(badgedTemplates));
|
||||||
|
}
|
||||||
|
|
||||||
|
async watchUserTemplates(calback: ()=> void){
|
||||||
|
|
||||||
|
chokidar.watch(this.userTemplatesFolder).on('all', () => {
|
||||||
|
calback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
orderTemplatesGroups(templates:BadgedGroupSelectOption[]): BadgedGroupSelectOption[] {
|
||||||
|
const compare = (a:BadgedGroupSelectOption|BadgedSelectOption, b:BadgedGroupSelectOption|BadgedSelectOption) => {
|
||||||
|
return a.label.toString() > b.label.toString() ? 1 : a.label.toString() < b.label.toString() ? -1 : 0
|
||||||
|
}
|
||||||
|
return templates.map( group => {
|
||||||
|
group.options = group.options.sort((a, b) => compare(a,b));
|
||||||
|
return group;
|
||||||
|
}).sort((a, b) => compare(a,b));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createResourceStore = new CreateResourceStore();
|
export const createResourceStore = new CreateResourceStore();
|
||||||
|
|||||||
@ -1,17 +1,20 @@
|
|||||||
import "./create-resource.scss";
|
import "./create-resource.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import fs from "fs-extra";
|
||||||
|
import {Select, GroupSelectOption, SelectOption} from "../select";
|
||||||
import jsYaml from "js-yaml";
|
import jsYaml from "js-yaml";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import { createResourceStore } from "./create-resource.store";
|
import { createResourceStore, BadgedGroupSelectOption } from "./create-resource.store";
|
||||||
import { IDockTab } from "./dock.store";
|
import { IDockTab } from "./dock.store";
|
||||||
import { EditorPanel } from "./editor-panel";
|
import { EditorPanel } from "./editor-panel";
|
||||||
import { InfoPanel } from "./info-panel";
|
import { InfoPanel } from "./info-panel";
|
||||||
import { resourceApplierApi } from "../../api/endpoints/resource-applier.api";
|
import { resourceApplierApi } from "../../api/endpoints/resource-applier.api";
|
||||||
import { JsonApiErrorParsed } from "../../api/json-api";
|
import { JsonApiErrorParsed } from "../../api/json-api";
|
||||||
import { Notifications } from "../notifications";
|
import { Notifications } from "../notifications";
|
||||||
|
import { Badge } from "../badge";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -21,6 +24,31 @@ interface Props {
|
|||||||
@observer
|
@observer
|
||||||
export class CreateResource extends React.Component<Props> {
|
export class CreateResource extends React.Component<Props> {
|
||||||
@observable error = "";
|
@observable error = "";
|
||||||
|
@observable templates:GroupSelectOption<SelectOption>[] = [];
|
||||||
|
|
||||||
|
async componentDidMount(){
|
||||||
|
createResourceStore.watchUserTemplates(()=> {
|
||||||
|
this.templates = [];
|
||||||
|
createResourceStore.getMergedTemplates().then(
|
||||||
|
badgedTemplates => {
|
||||||
|
badgedTemplates.map((group) => {
|
||||||
|
this.templates.push(this.convertBadgedGroup(group));
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
convertBadgedGroup(badgedGroup: BadgedGroupSelectOption):GroupSelectOption {
|
||||||
|
const options = badgedGroup.options.map(({label, badge, value }) => ({
|
||||||
|
label: this.renderSelectOption(label.toString(), badge),
|
||||||
|
value,
|
||||||
|
}));
|
||||||
|
return ({
|
||||||
|
label: this.renderSelectGroup(badgedGroup.label.toString(), badgedGroup.badge),
|
||||||
|
options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
get tabId() {
|
get tabId() {
|
||||||
return this.props.tab.id;
|
return this.props.tab.id;
|
||||||
@ -35,6 +63,10 @@ export class CreateResource extends React.Component<Props> {
|
|||||||
this.error = error;
|
this.error = error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onSelectTemplate = (item: SelectOption) => {
|
||||||
|
fs.readFile(item.value,"utf8").then(v => createResourceStore.setData(this.tabId,v));
|
||||||
|
};
|
||||||
|
|
||||||
create = async () => {
|
create = async () => {
|
||||||
if (this.error) return;
|
if (this.error) return;
|
||||||
if (!this.data.trim()) return; // do not save when field is empty
|
if (!this.data.trim()) return; // do not save when field is empty
|
||||||
@ -67,6 +99,40 @@ export class CreateResource extends React.Component<Props> {
|
|||||||
return successMessage;
|
return successMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
renderSelectOption(label: string, badge?: string){
|
||||||
|
return this.renderSelectItem(label,"select-template-option", badge );
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSelectGroup(label: string, badge?: string){
|
||||||
|
return this.renderSelectItem(label,"select-template-group", badge );
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSelectItem(label: string, className: string, badge?: string) {
|
||||||
|
return(
|
||||||
|
<div className={cssNames("flex select-template-item", className)}>
|
||||||
|
<span>{label}</span>
|
||||||
|
{badge && <Badge className="select-template-badge" label={badge} />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { tabId, data, error, create, onChange } = this;
|
const { tabId, data, error, create, onChange } = this;
|
||||||
const { className } = this.props;
|
const { className } = this.props;
|
||||||
@ -76,6 +142,7 @@ export class CreateResource extends React.Component<Props> {
|
|||||||
<InfoPanel
|
<InfoPanel
|
||||||
tabId={tabId}
|
tabId={tabId}
|
||||||
error={error}
|
error={error}
|
||||||
|
controls={this.renderControls()}
|
||||||
submit={create}
|
submit={create}
|
||||||
submitLabel="Create"
|
submitLabel="Create"
|
||||||
showNotifications={false}
|
showNotifications={false}
|
||||||
|
|||||||
12
templates/create-resource/access-control/ClusterRole.yaml
Normal file
12
templates/create-resource/access-control/ClusterRole.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
# "namespace" omitted since ClusterRoles are not namespaced
|
||||||
|
name: secret-reader
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
#
|
||||||
|
# at the HTTP level, the name of the resource for accessing Secret
|
||||||
|
# objects is "secrets"
|
||||||
|
resources: ["secrets"]
|
||||||
|
verbs: ["get", "watch", "list"]
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: read-secrets-global
|
||||||
|
subjects:
|
||||||
|
- kind: Group
|
||||||
|
name: manager # Name is case sensitive
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: secret-reader
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
9
templates/create-resource/access-control/Role.yaml
Normal file
9
templates/create-resource/access-control/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/access-control/RoleBinding.yaml
Normal file
17
templates/create-resource/access-control/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
|
||||||
17
templates/create-resource/configuration/ConfigMap.yaml
Normal file
17
templates/create-resource/configuration/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
|
||||||
8
templates/create-resource/configuration/Secret.yaml
Normal file
8
templates/create-resource/configuration/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
|
||||||
19
templates/create-resource/k8s-workloads/CronJob.yaml
Normal file
19
templates/create-resource/k8s-workloads/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/k8s-workloads/DeamonSet.yaml
Normal file
44
templates/create-resource/k8s-workloads/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/k8s-workloads/Deployment.yaml
Normal file
21
templates/create-resource/k8s-workloads/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
|
||||||
13
templates/create-resource/k8s-workloads/Job.yaml
Normal file
13
templates/create-resource/k8s-workloads/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
|
||||||
21
templates/create-resource/k8s-workloads/ReplicaSet.yaml
Normal file
21
templates/create-resource/k8s-workloads/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
|
||||||
@ -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
|
||||||
34
templates/create-resource/k8s-workloads/StatefulSet.yaml
Normal file
34
templates/create-resource/k8s-workloads/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
|
||||||
17
templates/create-resource/networking/Ingress.yaml
Normal file
17
templates/create-resource/networking/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
|
||||||
34
templates/create-resource/networking/NetworkPolicy.yaml
Normal file
34
templates/create-resource/networking/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
|
||||||
11
templates/create-resource/networking/Service.yaml
Normal file
11
templates/create-resource/networking/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
|
||||||
18
templates/create-resource/storage/PersistentVolume.yaml
Normal file
18
templates/create-resource/storage/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/storage/PersistentVolumeClaim.yaml
Normal file
17
templates/create-resource/storage/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]}
|
||||||
Loading…
Reference in New Issue
Block a user