* Add apps
Add redis&postgres operator and gui entryoint at cloud.

Signed-off-by: zzjin <tczzjin@gmail.com>

* Update apps
1. update session store support get kubeconfig token.
2. add redisinsight and pgadmin shown at desktop

Signed-off-by: zzjin <tczzjin@gmail.com>

Signed-off-by: zzjin <tczzjin@gmail.com>
This commit is contained in:
zzjin
2022-10-17 17:39:05 +08:00
committed by GitHub
parent 5287945312
commit 86f82bbf1f
13 changed files with 554 additions and 425 deletions
@@ -18,6 +18,10 @@ metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/configuration-snippet: |
more_clear_headers "X-Frame-Options:";
more_set_headers "Content-Security-Policy: default-src * blob: data: *.cloud.sealos.io cloud.sealos.io; img-src * data: blob: resource: *.cloud.sealos.io cloud.sealos.io; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.cloud.sealos.io cloud.sealos.io resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.cloud.sealos.io cloud.sealos.io resource: *.baidu.com *.bdstatic.com; frame-src 'self' cloud.sealos.io mailto: tel: weixin: mtt: *.baidu.com; frame-ancestors 'self' https://cloud.sealos.io https://*.cloud.sealos.io";
more_set_headers "X-Xss-Protection: 1; mode=block";
name: pgadmin-service
namespace: pgadmin-service
spec:
@@ -58,13 +58,13 @@ metadata:
name: pgadmin-service
namespace: pgadmin-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: http
selector:
app: pgadmin
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: http
selector:
app: pgadmin
type: ClusterIP
---
apiVersion: storage.k8s.io/v1
@@ -128,28 +128,28 @@ spec:
image: dpage/pgadmin4:latest
imagePullPolicy: IfNotPresent
env:
- name: PGADMIN_DEFAULT_EMAIL
value: user@domain.com
- name: PGADMIN_DEFAULT_PASSWORD
valueFrom:
secretKeyRef:
name: pgadmin
key: pgadmin-password
- name: PGADMIN_DEFAULT_EMAIL
value: user@domain.com
- name: PGADMIN_DEFAULT_PASSWORD
valueFrom:
secretKeyRef:
name: pgadmin
key: pgadmin-password
ports:
- name: http
containerPort: 80
protocol: TCP
- name: http
containerPort: 80
protocol: TCP
volumeMounts:
- name: pgadmin-config
mountPath: /pgadmin4/servers.json
subPath: servers.json
readOnly: true
- name: pgadmin-data
mountPath: /var/lib/pgadmin
- name: pgadmin-config
mountPath: /pgadmin4/servers.json
subPath: servers.json
readOnly: true
- name: pgadmin-data
mountPath: /var/lib/pgadmin
volumes:
- name: pgadmin-config
configMap:
name: pgadmin-config
- name: pgadmin-data
persistentVolumeClaim:
claimName: pgadmin-data-pv-claim
- name: pgadmin-config
configMap:
name: pgadmin-config
- name: pgadmin-data
persistentVolumeClaim:
claimName: pgadmin-data-pv-claim
@@ -18,6 +18,10 @@ metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/configuration-snippet: |
more_clear_headers "X-Frame-Options:";
more_set_headers "Content-Security-Policy: default-src * blob: data: *.cloud.sealos.io cloud.sealos.io; img-src * data: blob: resource: *.cloud.sealos.io cloud.sealos.io; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.cloud.sealos.io cloud.sealos.io resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.cloud.sealos.io cloud.sealos.io resource: *.baidu.com *.bdstatic.com; frame-src 'self' cloud.sealos.io mailto: tel: weixin: mtt: *.baidu.com; frame-ancestors 'self' https://cloud.sealos.io https://*.cloud.sealos.io";
more_set_headers "X-Xss-Protection: 1; mode=block";
name: redisinsight-service
namespace: redisinsight-service
spec:
@@ -105,9 +105,9 @@ spec:
image: busybox
command:
- /bin/sh
- '-c'
- "-c"
- |
chown -R 1001 /db
chown -R 1001 /db
resources: {}
volumeMounts:
- name: db
@@ -115,7 +115,7 @@ spec:
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
containers:
- name: redisinsight #Container name (DNS_LABEL, unique)
- name: redisinsight #Container name (DNS_LABEL, unique)
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
@@ -126,11 +126,11 @@ spec:
image: redislabs/redisinsight:hotfix-sentinel-probe #repo/image
imagePullPolicy: IfNotPresent #Always pull image
volumeMounts:
- name: db #Pod volumes to mount into the container's filesystem. Cannot be updated.
mountPath: /db
- name: db #Pod volumes to mount into the container's filesystem. Cannot be updated.
mountPath: /db
ports:
- containerPort: 8001 #exposed container port and protocol
protocol: TCP
- containerPort: 8001 #exposed container port and protocol
protocol: TCP
env:
- name: RITRUSTEDORIGINS
value: "https://redisinsight.cloud.sealos.io"
- name: RITRUSTEDORIGINS
value: "https://redisinsight.cloud.sealos.io"
+6 -6
View File
@@ -15,15 +15,14 @@
],
"dependencies": {
"@ctrl/golang-template": "^1.4.1",
"@fluentui/react-components": "^9.4.0",
"@fluentui/react-components": "^9.5.1",
"@fortawesome/fontawesome-svg-core": "^6.2.0",
"@fortawesome/free-regular-svg-icons": "^6.2.0",
"@fortawesome/free-solid-svg-icons": "^6.2.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@kubernetes/client-node": "0.17.1",
"@tanstack/react-query": "^4.10.3",
"@types/js-yaml": "^4.0.5",
"axios": "1.1.2",
"@tanstack/react-query": "^4.12.0",
"axios": "1.1.3",
"clsx": "^1.2.1",
"dayjs": "^1.11.5",
"immer": "^9.0.15",
@@ -41,11 +40,12 @@
"zustand": "^4.1.2"
},
"devDependencies": {
"@svgr/webpack": "^6.4.0",
"@types/node": "18.8.5",
"@svgr/webpack": "^6.5.0",
"@types/node": "18.11.0",
"@types/react": "18.0.21",
"@types/react-dom": "18.0.6",
"@types/uuid": "^8.3.4",
"@types/js-yaml": "^4.0.5",
"autoprefixer": "^10.4.12",
"eslint": "8.25.0",
"eslint-config-next": "12.3.1",
+374 -352
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.9 KiB

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
<style type="text/css">
.st0{fill:#A32422;}
.st1{fill:#DC382D;}
</style>
<g id="Layer_2">
<polygon class="st0" points="76.1,11.2 76.1,108.5 60,116.1 2.2,90.3 2.2,75.1 60,101.4 60,92.5 2.2,66.4 2.2,51.4 60,77.4
60,68.7 2.2,42.3 2.2,27.6 60,53.9 60,18.8 "/>
<polygon class="st0" points="97.2,30.6 97.2,99.2 80.4,106.9 80.4,37.9 "/>
<polygon class="st0" points="118,49.9 118,89.4 101.2,97 101.2,57.2 "/>
</g>
<g id="Layer_3">
<polygon class="st1" points="76.1,11.2 60,4.5 2.2,27.6 60,53.9 60,18.8 "/>
<polygon class="st1" points="60,68.7 60,77.4 2.2,51.4 12.3,46.9 "/>
<polygon class="st1" points="60,92.5 60,101.4 2.2,75.1 11.5,70.6 "/>
<polygon class="st1" points="80.4,37.9 97.2,30.6 80.4,23.8 "/>
<polygon class="st1" points="101.2,57.2 118,49.9 101.2,43.1 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+20
View File
@@ -0,0 +1,20 @@
import * as k8s from '@kubernetes/client-node';
import { ApplicationType, RunApplication, StartResp } from 'interfaces/kubernetes';
const PostgresAdminApplication: RunApplication = {
name: 'Postgres Admin',
description: 'Postgres Admin',
icon: '/images/pgadmin.svg',
application_type: ApplicationType.IFrame,
startTemplate: '',
doStart: async (kc: k8s.KubeConfig): Promise<StartResp> => {
return Promise.resolve({
status: 200,
application_type: ApplicationType.IFrame,
// iframe_page: 'https://pgadmin.cloud.sealos.io/browser'
iframe_page: 'https://pgadmin.cloud.sealos.io/'
});
}
};
export { PostgresAdminApplication };
@@ -0,0 +1,19 @@
import * as k8s from '@kubernetes/client-node';
import { ApplicationType, RunApplication, StartResp } from 'interfaces/kubernetes';
const RedisInsightApplication: RunApplication = {
name: 'Redis Insight',
description: 'Redis Insight',
icon: '/images/redisinsight.svg',
application_type: ApplicationType.IFrame,
startTemplate: '',
doStart: async (kc: k8s.KubeConfig): Promise<StartResp> => {
return Promise.resolve({
status: 200,
application_type: ApplicationType.IFrame,
iframe_page: 'https://redisinsight.cloud.sealos.io/'
});
}
};
export { RedisInsightApplication };
+42 -28
View File
@@ -87,34 +87,34 @@ const installedApps: TApp[] = [
],
size: 'maximize'
},
{
name: 'Prometheus',
icon: '/images/prometheus.svg',
type: 'iframe',
data: {
url: '',
desc: 'From metrics to insight'
},
gallery: [
'https://cdn.programiz.com/cdn/farfuture/IwFGGPqycIxTfzLl7mPdcaqUaircnStXfipaHd4EBik/mtime:1605833048/sites/all/themes/programiz/assets/compiler.png',
'https://www.programiz.com/blog/content/images/2020/07/programiz-online-compiler.png'
],
size: 'maximize'
},
{
name: 'Mysql',
icon: '/images/mysql.svg',
type: 'iframe',
data: {
url: '',
desc: 'mysql operator'
},
gallery: [
'https://cdn.programiz.com/cdn/farfuture/IwFGGPqycIxTfzLl7mPdcaqUaircnStXfipaHd4EBik/mtime:1605833048/sites/all/themes/programiz/assets/compiler.png',
'https://www.programiz.com/blog/content/images/2020/07/programiz-online-compiler.png'
],
size: 'maximize'
},
// {
// name: 'Prometheus',
// icon: '/images/prometheus.svg',
// type: 'iframe',
// data: {
// url: '',
// desc: 'From metrics to insight'
// },
// gallery: [
// 'https://cdn.programiz.com/cdn/farfuture/IwFGGPqycIxTfzLl7mPdcaqUaircnStXfipaHd4EBik/mtime:1605833048/sites/all/themes/programiz/assets/compiler.png',
// 'https://www.programiz.com/blog/content/images/2020/07/programiz-online-compiler.png'
// ],
// size: 'maximize'
// },
// {
// name: 'Mysql',
// icon: '/images/mysql.svg',
// type: 'iframe',
// data: {
// url: '',
// desc: 'mysql operator'
// },
// gallery: [
// 'https://cdn.programiz.com/cdn/farfuture/IwFGGPqycIxTfzLl7mPdcaqUaircnStXfipaHd4EBik/mtime:1605833048/sites/all/themes/programiz/assets/compiler.png',
// 'https://www.programiz.com/blog/content/images/2020/07/programiz-online-compiler.png'
// ],
// size: 'maximize'
// },
{
name: 'Redis',
icon: '/images/redis.svg',
@@ -129,6 +129,20 @@ const installedApps: TApp[] = [
],
size: 'maximize'
},
{
name: 'Postgres',
icon: '/images/pgadmin.svg',
type: 'iframe',
data: {
url: '',
desc: 'postgres operator'
},
gallery: [
'https://cdn.programiz.com/cdn/farfuture/IwFGGPqycIxTfzLl7mPdcaqUaircnStXfipaHd4EBik/mtime:1605833048/sites/all/themes/programiz/assets/compiler.png',
'https://www.programiz.com/blog/content/images/2020/07/programiz-online-compiler.png'
],
size: 'maximize'
},
{
name: 'SDK-DEMO',
icon: '/images/mysql.svg',
@@ -1,5 +1,8 @@
import { resetIdsForTests } from '@fluentui/react-components';
import { KubernetesDashboardApplication } from 'mock/hub/kubernetes_dashboard';
import { KuBoardApplication } from 'mock/hub/kuboard';
import { PostgresAdminApplication } from 'mock/hub/pgadmin';
import { RedisInsightApplication } from 'mock/hub/redisinsight';
import { TerminalApplication } from 'mock/hub/terminal';
import type { NextApiRequest, NextApiResponse } from 'next';
import { K8sApi } from 'services/backend/kubernetes';
@@ -57,6 +60,14 @@ export default async function handler(req: NextApiRequest, resp: NextApiResponse
// call apply to start terminal pod
const kb = await KuBoardApplication.doStart(kc);
return JsonResp(kb, resp);
case 'redis':
// call apply to start redis insight pod
const ri = await RedisInsightApplication.doStart(kc);
return JsonResp(ri, resp);
case 'postgres':
// call apply to start postgres admin pod
const pga = await PostgresAdminApplication.doStart(kc);
return JsonResp(pga, resp);
}
} catch (err) {
return InternalErrorResp(String(err), resp);
+10 -1
View File
@@ -3,6 +3,7 @@ import { devtools, persist } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
import type { Session } from '../interfaces/session';
import { sessionKey } from '../interfaces/session';
const yaml = require('js-yaml');
type SessionState = {
session: Session;
@@ -11,6 +12,7 @@ type SessionState = {
getSession: () => Session;
delSession: () => void;
isUserLogin: () => boolean;
getKubeconfigToken: () => string;
};
const useSessionStore = create<SessionState>()(
@@ -28,7 +30,14 @@ const useSessionStore = create<SessionState>()(
delSession: () => {
set({ session: undefined });
},
isUserLogin: () => get().session?.user?.id !== undefined
isUserLogin: () => get().session?.user?.id !== undefined,
getKubeconfigToken: () => {
if (get().session?.kubeconfig === '') {
return '';
}
const doc = yaml.load(get().session.kubeconfig);
return doc?.users[0]?.user?.token;
}
})),
{ name: sessionKey }
)