first commit
This commit is contained in:
commit
57e5c736c0
60
app/cpcc.py
Normal file
60
app/cpcc.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from appPublic.registerfunction import RegisterFunction
|
||||||
|
from ahserver.webapp import webapp
|
||||||
|
from ahserver.serverenv import ServerEnv
|
||||||
|
from appbase.init import load_appbase
|
||||||
|
from rbac.check_perm import load_rbac
|
||||||
|
|
||||||
|
def UiError(title="出错", message="出错啦", timeout=5):
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"author":"tr",
|
||||||
|
"timeout":timeout,
|
||||||
|
"cwidth":15,
|
||||||
|
"cheight":10,
|
||||||
|
"title":title,
|
||||||
|
"message":message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def UiMessage(title="消息", message="后台消息", timeout=5):
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"author":"tr",
|
||||||
|
"timeout":timeout,
|
||||||
|
"cwidth":15,
|
||||||
|
"cheight":10,
|
||||||
|
"title":title,
|
||||||
|
"message":message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_module_dbname(mname):
|
||||||
|
return 'cpcc'
|
||||||
|
|
||||||
|
rf = RegisterFunction()
|
||||||
|
rf.register('get_module_dbname', get_module_dbname)
|
||||||
|
|
||||||
|
def init():
|
||||||
|
g = ServerEnv()
|
||||||
|
g.get_module_dbname = get_module_dbname
|
||||||
|
load_appbase()
|
||||||
|
load_rbac()
|
||||||
|
g.UiError = UiError
|
||||||
|
g.UiMessage = UiMessage
|
||||||
|
|
||||||
|
# k8sAPI远程指令(目前放到.dspy文件中)
|
||||||
|
# 看样子cpcc.py文件中没有使用到数据库函数
|
||||||
|
# g.cluster_kubeconfig = cluster_kubeconfig
|
||||||
|
|
||||||
|
g.result_dict = {
|
||||||
|
"status": False,
|
||||||
|
"info": "failed",
|
||||||
|
"data": None
|
||||||
|
}
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
webapp(init)
|
||||||
|
|
||||||
|
# sword/111111
|
||||||
81
conf/config.json
Executable file
81
conf/config.json
Executable file
@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"password_key":"!@#$%^&*(*&^%$QWERTYUIqwertyui234567",
|
||||||
|
"logger":{
|
||||||
|
"name":"cpcc",
|
||||||
|
"levelname":"clientinfo",
|
||||||
|
"logfile":"$[workdir]$/logs/cpcc.log"
|
||||||
|
},
|
||||||
|
"filesroot":"$[workdir]$/files",
|
||||||
|
"databases":{
|
||||||
|
"cpcc":{
|
||||||
|
"driver":"aiomysql",
|
||||||
|
"async_mode":true,
|
||||||
|
"coding":"utf8",
|
||||||
|
"maxconn":100,
|
||||||
|
"dbname":"cpcc",
|
||||||
|
"kwargs":{
|
||||||
|
"user":"test",
|
||||||
|
"db":"cpcc",
|
||||||
|
"password":"QUZVcXg5V1p1STMybG5Ia6mX9D0v7+g=",
|
||||||
|
"host":"localhost"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"website":{
|
||||||
|
"paths":[
|
||||||
|
["$[workdir]$/wwwroot",""]
|
||||||
|
],
|
||||||
|
"client_max_size":10000,
|
||||||
|
"host":"0.0.0.0",
|
||||||
|
"port":9203,
|
||||||
|
"coding":"utf-8",
|
||||||
|
"ssl_gg":{
|
||||||
|
"crtfile":"$[workdir]$/conf/www.bsppo.com.pem",
|
||||||
|
"keyfile":"$[workdir]$/conf/www.bsppo.com.key"
|
||||||
|
},
|
||||||
|
"indexes":[
|
||||||
|
"index.html",
|
||||||
|
"index.tmpl",
|
||||||
|
"index.ui",
|
||||||
|
"index.dspy",
|
||||||
|
"index.md"
|
||||||
|
],
|
||||||
|
"startswiths":[
|
||||||
|
{
|
||||||
|
"leading":"/idfile",
|
||||||
|
"registerfunction":"idFileDownload"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"processors":[
|
||||||
|
[".ws","ws"],
|
||||||
|
[".xterm","xterm"],
|
||||||
|
[".proxy","proxy"],
|
||||||
|
[".llm", "llm"],
|
||||||
|
[".llms", "llms"],
|
||||||
|
[".llma", "llma"],
|
||||||
|
[".xlsxds","xlsxds"],
|
||||||
|
[".sqlds","sqlds"],
|
||||||
|
[".tmpl.js","tmpl"],
|
||||||
|
[".tmpl.css","tmpl"],
|
||||||
|
[".html.tmpl","tmpl"],
|
||||||
|
[".bcrud", "bricks_crud"],
|
||||||
|
[".tmpl","tmpl"],
|
||||||
|
[".app","app"],
|
||||||
|
[".bui","bui"],
|
||||||
|
[".ui","bui"],
|
||||||
|
[".dspy","dspy"],
|
||||||
|
[".md","md"]
|
||||||
|
],
|
||||||
|
"session_max_time":3000,
|
||||||
|
"session_issue_time":2500,
|
||||||
|
"session_redis_rrrr":{
|
||||||
|
"url":"redis://127.0.0.1:6379"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"langMapping":{
|
||||||
|
"zh-Hans-CN":"zh-cn",
|
||||||
|
"zh-CN":"zh-cn",
|
||||||
|
"en-us":"en",
|
||||||
|
"en-US":"en"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
docs/cpc数据表.xlsx
Normal file
BIN
docs/cpc数据表.xlsx
Normal file
Binary file not shown.
3
json/build.sh
Executable file
3
json/build.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
xls2ui -m ../models -o ../wwwroot cpcc *.json
|
||||||
13
json/components.json
Normal file
13
json/components.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"tblname":"components",
|
||||||
|
"params":{
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["id"],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
13
json/cpccluster.json
Normal file
13
json/cpccluster.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"tblname":"cpccluster",
|
||||||
|
"params":{
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["id", "cpcid"],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id", "cpcid"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
58
json/cpclist.json
Normal file
58
json/cpclist.json
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"tblname":"cpclist",
|
||||||
|
"params":{
|
||||||
|
"toolbar":{
|
||||||
|
"tools":[
|
||||||
|
{
|
||||||
|
"name":"newcluster",
|
||||||
|
"selected_row":true,
|
||||||
|
"label":"新建集群"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"newcluster",
|
||||||
|
"actiontype":"urlwidget",
|
||||||
|
"target":"PopupWindow",
|
||||||
|
"popup_options":{
|
||||||
|
"width":"80%",
|
||||||
|
"height":"80%"
|
||||||
|
},
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('../handy/new_cluster.ui')}}",
|
||||||
|
"params":{
|
||||||
|
"id":"{{params_kw.id}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"logined_userorgid":"orgid",
|
||||||
|
"confidential_fields":[
|
||||||
|
"api_pwd"
|
||||||
|
],
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"id","orgid", "pcapi_url","pcapi_user", "pcapi_pwd"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id", "orgid"
|
||||||
|
],
|
||||||
|
"subtables":[
|
||||||
|
{
|
||||||
|
"subtable":"cpccluster",
|
||||||
|
"field":"cpcid",
|
||||||
|
"title":"集群"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtable":"cpcnode",
|
||||||
|
"field":"cpcid",
|
||||||
|
"title":"节点"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
16
json/cpcnode.json
Normal file
16
json/cpcnode.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"tblname":"cpcnode",
|
||||||
|
"params":{
|
||||||
|
"confidential_fields":["adminpwd"],
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"id", "cpcid"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id", "cpcid", "clusterid"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BIN
models/components.xlsx
Normal file
BIN
models/components.xlsx
Normal file
Binary file not shown.
BIN
models/cpccluster.xlsx
Normal file
BIN
models/cpccluster.xlsx
Normal file
Binary file not shown.
BIN
models/cpclist.xlsx
Normal file
BIN
models/cpclist.xlsx
Normal file
Binary file not shown.
BIN
models/cpcnode.xlsx
Normal file
BIN
models/cpcnode.xlsx
Normal file
Binary file not shown.
BIN
models/cpcnode_config.xlsx
Normal file
BIN
models/cpcnode_config.xlsx
Normal file
Binary file not shown.
BIN
models/cpcnode_config_detail.xlsx
Normal file
BIN
models/cpcnode_config_detail.xlsx
Normal file
Binary file not shown.
BIN
models/cpvalue.xlsx
Normal file
BIN
models/cpvalue.xlsx
Normal file
Binary file not shown.
201
models/mysql.ddl.sql
Normal file
201
models/mysql.ddl.sql
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
|
||||||
|
-- ./cpcnode_config.xlsx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop table if exists cpcnode_config;
|
||||||
|
CREATE TABLE cpcnode_config
|
||||||
|
(
|
||||||
|
|
||||||
|
`id` VARCHAR(32) comment 'id',
|
||||||
|
`nodeid` VARCHAR(32) comment '节点名称',
|
||||||
|
`name` VARCHAR(255) comment '名称',
|
||||||
|
`description` VARCHAR(3000) comment '描述'
|
||||||
|
|
||||||
|
|
||||||
|
,primary key(id)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
engine=innodb
|
||||||
|
default charset=utf8
|
||||||
|
comment '节点配置表'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
-- ./cpccluster.xlsx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop table if exists cpccluster;
|
||||||
|
CREATE TABLE cpccluster
|
||||||
|
(
|
||||||
|
|
||||||
|
`id` VARCHAR(32) comment 'id',
|
||||||
|
`name` VARCHAR(255) comment '名称',
|
||||||
|
`cpcid` VARCHAR(32) NOT NULL comment '算力中心id',
|
||||||
|
`clustertype` VARCHAR(1) comment '集群类型',
|
||||||
|
`controllerid` VARCHAR(32) comment '控制节点id',
|
||||||
|
`enable_date` date comment '启用日期',
|
||||||
|
`export_date` date comment '停用日期'
|
||||||
|
|
||||||
|
|
||||||
|
,primary key(id)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
engine=innodb
|
||||||
|
default charset=utf8
|
||||||
|
comment '算力集群'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
-- ./cpcnode.xlsx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop table if exists cpcnode;
|
||||||
|
CREATE TABLE cpcnode
|
||||||
|
(
|
||||||
|
|
||||||
|
`id` VARCHAR(32) comment 'id',
|
||||||
|
`name` VARCHAR(255) comment '名称',
|
||||||
|
`ip` VARCHAR(90) comment '内网ip',
|
||||||
|
`sshport` int comment 'ssh端口号',
|
||||||
|
`adminuser` VARCHAR(99) comment '管理账号',
|
||||||
|
`adminpwd` VARCHAR(99) comment '管理密码',
|
||||||
|
`cpcid` VARCHAR(32) NOT NULL comment '算力中心id',
|
||||||
|
`node_status` VARCHAR(1) comment '节点状态',
|
||||||
|
`clusterid` int comment '所属集群',
|
||||||
|
`enable_date` date comment '启用日期',
|
||||||
|
`export_date` date comment '停用日期'
|
||||||
|
|
||||||
|
|
||||||
|
,primary key(id)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
engine=innodb
|
||||||
|
default charset=utf8
|
||||||
|
comment '算力节点'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
-- ./cpvalue.xlsx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop table if exists cpvalue;
|
||||||
|
CREATE TABLE cpvalue
|
||||||
|
(
|
||||||
|
|
||||||
|
`id` VARCHAR(32) comment 'id',
|
||||||
|
`comid` VARCHAR(255) comment '部件id',
|
||||||
|
`cpval` double(18,3) comment '算力值',
|
||||||
|
`cpunit` VARCHAR(1) comment '算力单位'
|
||||||
|
|
||||||
|
|
||||||
|
,primary key(id)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
engine=innodb
|
||||||
|
default charset=utf8
|
||||||
|
comment '算力值'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
-- ./cpclist.xlsx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop table if exists cpclist;
|
||||||
|
CREATE TABLE cpclist
|
||||||
|
(
|
||||||
|
|
||||||
|
`id` VARCHAR(32) comment 'id',
|
||||||
|
`name` VARCHAR(255) comment '名称',
|
||||||
|
`orgid` VARCHAR(32) comment '属主机构id',
|
||||||
|
`pcapi_url` VARCHAR(500) comment 'pcapi网址',
|
||||||
|
`api_user` VARCHAR(100) comment '接口用户',
|
||||||
|
`api_pwd` VARCHAR(100) comment '接口密码',
|
||||||
|
`enable_date` date comment '启用日期',
|
||||||
|
`expire_date` date comment '停用日期',
|
||||||
|
`contactname` VARCHAR(100) comment '联系人',
|
||||||
|
`contactphone` VARCHAR(100) comment '联系电话'
|
||||||
|
|
||||||
|
|
||||||
|
,primary key(id)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
engine=innodb
|
||||||
|
default charset=utf8
|
||||||
|
comment '算力中心列表'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
-- ./components.xlsx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop table if exists components;
|
||||||
|
CREATE TABLE components
|
||||||
|
(
|
||||||
|
|
||||||
|
`id` VARCHAR(32) comment 'id',
|
||||||
|
`name` VARCHAR(255) comment '名称',
|
||||||
|
`ccatelogid` VARCHAR(255) comment '部件分类',
|
||||||
|
`cmodel` VARCHAR(255) comment '型号',
|
||||||
|
`unitname` VARCHAR(32) comment '计量名',
|
||||||
|
`unitvalue` int comment '计量值'
|
||||||
|
|
||||||
|
|
||||||
|
,primary key(id)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
engine=innodb
|
||||||
|
default charset=utf8
|
||||||
|
comment '部件表'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
-- ./cpcnode_config_detail.xlsx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
drop table if exists cpcnode_config_detail;
|
||||||
|
CREATE TABLE cpcnode_config_detail
|
||||||
|
(
|
||||||
|
|
||||||
|
`id` VARCHAR(32) comment 'id',
|
||||||
|
`nodeconfigid` VARCHAR(32) comment '节点配置id',
|
||||||
|
`comid` VARCHAR(32) comment '部件id',
|
||||||
|
`comcnt` int comment '部件数量'
|
||||||
|
|
||||||
|
|
||||||
|
,primary key(id)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
engine=innodb
|
||||||
|
default charset=utf8
|
||||||
|
comment '节点配置明细项'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
3
script/cpcc_roleperm.sh
Normal file
3
script/cpcc_roleperm.sh
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
python ~/py/rbac/script/roleperm.py sage cpcc reseller operator cpclist cpcnode cpccluster components
|
||||||
40
wwwroot/app_panel.ui
Normal file
40
wwwroot/app_panel.ui
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"HBox",
|
||||||
|
"options":{
|
||||||
|
"css":"filler"
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"Text",
|
||||||
|
"options":{
|
||||||
|
"text":"主菜单",
|
||||||
|
"tip":"进入主菜单",
|
||||||
|
"css":"clickable"
|
||||||
|
},
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"click",
|
||||||
|
"actiontype":"urlwidget",
|
||||||
|
"target":"Popup",
|
||||||
|
"popup_options":{
|
||||||
|
"eventpos":true,
|
||||||
|
"dismiss_events":["command"]
|
||||||
|
},
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('menu.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype":"Title4",
|
||||||
|
"options":{
|
||||||
|
"i18n":true,
|
||||||
|
"otext":"大模型应用平台",
|
||||||
|
"wrap":true,
|
||||||
|
"halign":"left"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
17
wwwroot/bottom.ui
Normal file
17
wwwroot/bottom.ui
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"HBox",
|
||||||
|
"options":{
|
||||||
|
"cheight":2,
|
||||||
|
"bgcolor":"#e5e5e5"
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"Text",
|
||||||
|
"options":{
|
||||||
|
"otext":"© 2024 版权所有, 开元云(北京)科技有限公司",
|
||||||
|
"i18n":true,
|
||||||
|
"wrap":true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
15
wwwroot/center.ui
Normal file
15
wwwroot/center.ui
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"VBox",
|
||||||
|
"id":"page_center",
|
||||||
|
"options":{
|
||||||
|
"css":"filler"
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('/appbase/appcodes')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
35
wwwroot/components/add_components.dspy
Normal file
35
wwwroot/components/add_components.dspy
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
id = params_kw.id
|
||||||
|
if not id or len(id) > 32:
|
||||||
|
id = uuid()
|
||||||
|
ns['id'] = id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.C('components', ns.copy())
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"user_data":ns,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"title":"Add Success",
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Add Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
33
wwwroot/components/delete_components.dspy
Normal file
33
wwwroot/components/delete_components.dspy
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
ns = {
|
||||||
|
'id':params_kw['id'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.D('components', ns)
|
||||||
|
debug('delete success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Success",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('Delete failed');
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
83
wwwroot/components/get_components.dspy
Normal file
83
wwwroot/components/get_components.dspy
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
debug(f'get_components.dspy:{ns=}')
|
||||||
|
if not ns.get('page'):
|
||||||
|
ns['page'] = 1
|
||||||
|
if not ns.get('sort'):
|
||||||
|
|
||||||
|
ns['sort'] = 'id'
|
||||||
|
|
||||||
|
|
||||||
|
sql = '''select a.*, b.ccatelogid_text
|
||||||
|
from (select * from components where 1=1 [[filterstr]]) a left join (select k as ccatelogid,
|
||||||
|
v as ccatelogid_text from appcodes_kv where parentid='ccatelog') b on a.ccatelogid = b.ccatelogid'''
|
||||||
|
|
||||||
|
filterjson = params_kw.get('data_filter')
|
||||||
|
if not filterjson:
|
||||||
|
fields = [ f['name'] for f in [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ccatelogid",
|
||||||
|
"title": "部件分类",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cmodel",
|
||||||
|
"title": "型号",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unitname",
|
||||||
|
"title": "计量名",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unitvalue",
|
||||||
|
"title": "计量值",
|
||||||
|
"type": "short"
|
||||||
|
}
|
||||||
|
] ]
|
||||||
|
filterjson = default_filterjson(fields, ns)
|
||||||
|
filterdic = ns.copy()
|
||||||
|
filterdic['filterstr'] = ''
|
||||||
|
filterdic['userorgid'] = '${userorgid}$'
|
||||||
|
filterdic['userid'] = '${userid}$'
|
||||||
|
if filterjson:
|
||||||
|
dbf = DBFilter(filterjson)
|
||||||
|
conds = dbf.gen(ns)
|
||||||
|
if conds:
|
||||||
|
ns.update(dbf.consts)
|
||||||
|
conds = f' and {conds}'
|
||||||
|
filterdic['filterstr'] = conds
|
||||||
|
ac = ArgsConvert('[[', ']]')
|
||||||
|
vars = ac.findAllVariables(sql)
|
||||||
|
NameSpace = {v:'${' + v + '}$' for v in vars if v != 'filterstr' }
|
||||||
|
filterdic.update(NameSpace)
|
||||||
|
sql = ac.convert(sql, filterdic)
|
||||||
|
|
||||||
|
debug(f'{sql=}')
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.sqlPaging(sql, ns)
|
||||||
|
return r
|
||||||
|
return {
|
||||||
|
"total":0,
|
||||||
|
"rows":[]
|
||||||
|
}
|
||||||
122
wwwroot/components/index.ui
Normal file
122
wwwroot/components/index.ui
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
{
|
||||||
|
"id":"components_tbl",
|
||||||
|
"widgettype":"Tabular",
|
||||||
|
"options":{
|
||||||
|
|
||||||
|
|
||||||
|
"title":"部件表",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"css":"card",
|
||||||
|
|
||||||
|
"editable":{
|
||||||
|
"new_data_url":"{{entire_url('add_components.dspy')}}",
|
||||||
|
"delete_data_url":"{{entire_url('delete_components.dspy')}}",
|
||||||
|
"update_data_url":"{{entire_url('update_components.dspy')}}"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
"data_url":"{{entire_url('./get_components.dspy')}}",
|
||||||
|
"data_method":"GET",
|
||||||
|
"data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}},
|
||||||
|
"row_options":{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
"editexclouded":[
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
|
||||||
|
"fields":[
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ccatelogid",
|
||||||
|
"title": "部件分类",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"label": "部件分类",
|
||||||
|
"uitype": "code",
|
||||||
|
"valueField": "ccatelogid",
|
||||||
|
"textField": "ccatelogid_text",
|
||||||
|
"params": {
|
||||||
|
"dbname": "{{rfexe('get_module_dbname', 'cpcc')}}",
|
||||||
|
"table": "appcodes_kv",
|
||||||
|
"tblvalue": "k",
|
||||||
|
"tbltext": "v",
|
||||||
|
"valueField": "ccatelogid",
|
||||||
|
"textField": "ccatelogid_text",
|
||||||
|
"cond": "parentid='ccatelog'"
|
||||||
|
},
|
||||||
|
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cmodel",
|
||||||
|
"title": "型号",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "型号"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unitname",
|
||||||
|
"title": "计量名",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "计量名"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unitvalue",
|
||||||
|
"title": "计量值",
|
||||||
|
"type": "short",
|
||||||
|
"length": 0,
|
||||||
|
"uitype": "int",
|
||||||
|
"datatype": "short",
|
||||||
|
"label": "计量值"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"page_rows":160,
|
||||||
|
"cache_limit":5
|
||||||
|
}
|
||||||
|
|
||||||
|
,"binds":[]
|
||||||
|
|
||||||
|
}
|
||||||
32
wwwroot/components/update_components.dspy
Normal file
32
wwwroot/components/update_components.dspy
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.U('components', ns)
|
||||||
|
debug('update success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Success",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
35
wwwroot/cpccluster/add_cpccluster.dspy
Normal file
35
wwwroot/cpccluster/add_cpccluster.dspy
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
id = params_kw.id
|
||||||
|
if not id or len(id) > 32:
|
||||||
|
id = uuid()
|
||||||
|
ns['id'] = id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.C('cpccluster', ns.copy())
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"user_data":ns,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"title":"Add Success",
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Add Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
33
wwwroot/cpccluster/delete_cpccluster.dspy
Normal file
33
wwwroot/cpccluster/delete_cpccluster.dspy
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
ns = {
|
||||||
|
'id':params_kw['id'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.D('cpccluster', ns)
|
||||||
|
debug('delete success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Success",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"ok,记得把关联的节点都解除占用状态 ~"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('Delete failed');
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
91
wwwroot/cpccluster/get_cpccluster.dspy
Normal file
91
wwwroot/cpccluster/get_cpccluster.dspy
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
debug(f'get_cpccluster.dspy:{ns=}')
|
||||||
|
if not ns.get('page'):
|
||||||
|
ns['page'] = 1
|
||||||
|
if not ns.get('sort'):
|
||||||
|
|
||||||
|
ns['sort'] = 'id'
|
||||||
|
|
||||||
|
sql = '''select a.*, b.clustertype_text, c.controllerid_text
|
||||||
|
from (select * from cpccluster where 1=1 [[filterstr]]) a left join (select k as clustertype,
|
||||||
|
v as clustertype_text from appcodes_kv where parentid='clustertype') b on a.clustertype = b.clustertype left join (select id as controllerid,
|
||||||
|
ip as controllerid_text from cpcnode where 1 = 1) c on a.controllerid = c.controllerid'''
|
||||||
|
|
||||||
|
filterjson = params_kw.get('data_filter')
|
||||||
|
if not filterjson:
|
||||||
|
fields = [ f['name'] for f in [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcid",
|
||||||
|
"title": "算力中心id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clustertype",
|
||||||
|
"title": "集群类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "controllerid",
|
||||||
|
"title": "控制节点id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_date",
|
||||||
|
"title": "启用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "export_date",
|
||||||
|
"title": "停用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 255
|
||||||
|
}
|
||||||
|
] ]
|
||||||
|
filterjson = default_filterjson(fields, ns)
|
||||||
|
filterdic = ns.copy()
|
||||||
|
filterdic['filterstr'] = ''
|
||||||
|
filterdic['userorgid'] = '${userorgid}$'
|
||||||
|
filterdic['userid'] = '${userid}$'
|
||||||
|
if filterjson:
|
||||||
|
dbf = DBFilter(filterjson)
|
||||||
|
conds = dbf.gen(ns)
|
||||||
|
if conds:
|
||||||
|
ns.update(dbf.consts)
|
||||||
|
conds = f' and {conds}'
|
||||||
|
filterdic['filterstr'] = conds
|
||||||
|
ac = ArgsConvert('[[', ']]')
|
||||||
|
vars = ac.findAllVariables(sql)
|
||||||
|
NameSpace = {v:'${' + v + '}$' for v in vars if v != 'filterstr' }
|
||||||
|
filterdic.update(NameSpace)
|
||||||
|
sql = ac.convert(sql, filterdic)
|
||||||
|
|
||||||
|
debug(f'{sql=}')
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.sqlPaging(sql, ns)
|
||||||
|
return r
|
||||||
|
return {
|
||||||
|
"total":0,
|
||||||
|
"rows":[]
|
||||||
|
}
|
||||||
239
wwwroot/cpccluster/index.ui
Normal file
239
wwwroot/cpccluster/index.ui
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
{
|
||||||
|
"id": "cpccluster_tbl",
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
"title": "算力集群",
|
||||||
|
"css": "card",
|
||||||
|
"toolbar": {
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"name": "newworker",
|
||||||
|
"selected_row": true,
|
||||||
|
"label": "新增工作节点"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "newpodyaml",
|
||||||
|
"selected_row": true,
|
||||||
|
"label": "新建资源YAML"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"css": "float-right"
|
||||||
|
},
|
||||||
|
"editable": {
|
||||||
|
"new_data_url": "{{entire_url('add_cpccluster.dspy')}}",
|
||||||
|
"delete_data_url": "{{entire_url('delete_cpccluster.dspy')}}",
|
||||||
|
"update_data_url": "{{entire_url('update_cpccluster.dspy')}}"
|
||||||
|
},
|
||||||
|
"data_url": "{{entire_url('./get_cpccluster.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"data_params": {{json.dumps(params_kw, indent=4, ensure_ascii=False)}},
|
||||||
|
"row_options": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "集群名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 14,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "集群名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "controllerid",
|
||||||
|
"title": "控制节点IP",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 12,
|
||||||
|
"label": "控制节点IP",
|
||||||
|
"uitype": "code",
|
||||||
|
"valueField": "controllerid",
|
||||||
|
"textField": "controllerid_text",
|
||||||
|
"params": {
|
||||||
|
"dbname": "{{rfexe('get_module_dbname', 'cpcc')}}",
|
||||||
|
"table": "cpcnode",
|
||||||
|
"tblvalue": "id",
|
||||||
|
"tbltext": "name",
|
||||||
|
"valueField": "controllerid",
|
||||||
|
"textField": "controllerid_text"
|
||||||
|
},
|
||||||
|
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcid",
|
||||||
|
"title": "算力中心id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no",
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "算力中心id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clustertype",
|
||||||
|
"title": "集群类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
|
"cwidth": 8,
|
||||||
|
"label": "集群类型",
|
||||||
|
"uitype": "code",
|
||||||
|
"valueField": "clustertype",
|
||||||
|
"textField": "clustertype_text",
|
||||||
|
"params": {
|
||||||
|
"dbname": "{{rfexe('get_module_dbname', 'cpcc')}}",
|
||||||
|
"table": "appcodes_kv",
|
||||||
|
"tblvalue": "k",
|
||||||
|
"tbltext": "v",
|
||||||
|
"valueField": "clustertype",
|
||||||
|
"textField": "clustertype_text",
|
||||||
|
"cond": "parentid='clustertype'"
|
||||||
|
},
|
||||||
|
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clusterjoin",
|
||||||
|
"title": "加入集群凭证",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 45,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "加入集群凭证"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_date",
|
||||||
|
"title": "启用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 0,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "date",
|
||||||
|
"datatype": "date",
|
||||||
|
"label": "启用日期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "export_date",
|
||||||
|
"title": "停用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 0,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "date",
|
||||||
|
"datatype": "date",
|
||||||
|
"label": "停用日期"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"content_view": {
|
||||||
|
"widgettype": "TabPanel",
|
||||||
|
"options": {
|
||||||
|
"tab_wide": "auto",
|
||||||
|
"height": "100%",
|
||||||
|
"width": "100%",
|
||||||
|
"tab_pos": "top",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "cpcpod",
|
||||||
|
"label": "实时资源实例",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"params": {
|
||||||
|
"clusterid": "${id}",
|
||||||
|
"cpcid": "${cpcid}"
|
||||||
|
},
|
||||||
|
"url": "{{entire_url('..\/cpcpod')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcworker",
|
||||||
|
"label": "实时集群节点",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"params": {
|
||||||
|
"clusterid": "${id}",
|
||||||
|
"cpcid": "${cpcid}"
|
||||||
|
},
|
||||||
|
"url": "{{entire_url('..\/cpcworker')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcyamlconfig",
|
||||||
|
"label": "资源实例配置",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"params": {
|
||||||
|
"clusterid": "${id}",
|
||||||
|
"cpcid": "${cpcid}"
|
||||||
|
},
|
||||||
|
"url": "{{entire_url('..\/cpcpodyaml')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"page_rows": 160,
|
||||||
|
"cache_limit": 5
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "newworker",
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"target": "PopupWindow",
|
||||||
|
"popup_options": {
|
||||||
|
"width": "80%",
|
||||||
|
"height": "80%"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('../cpcworker/new_worker.ui')}}",
|
||||||
|
"params": {
|
||||||
|
"id": "{{params_kw.id}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "newpodyaml",
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"target": "PopupWindow",
|
||||||
|
"popup_options": {
|
||||||
|
"width": "80%",
|
||||||
|
"height": "80%"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('../cpcpod/new_podyaml.ui')}}",
|
||||||
|
"params": {
|
||||||
|
"id": "{{params_kw.id}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
32
wwwroot/cpccluster/update_cpccluster.dspy
Normal file
32
wwwroot/cpccluster/update_cpccluster.dspy
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.U('cpccluster', ns)
|
||||||
|
debug('update success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Success",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
52
wwwroot/cpclist/add_cpclist.dspy
Normal file
52
wwwroot/cpclist/add_cpclist.dspy
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
id = params_kw.id
|
||||||
|
if not id or len(id) > 32:
|
||||||
|
id = uuid()
|
||||||
|
ns['id'] = id
|
||||||
|
|
||||||
|
if params_kw.get('api_pwd'):
|
||||||
|
ns['api_pwd'] = password_encode(params_kw.get('api_pwd'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
userorgid = await get_userorgid()
|
||||||
|
if not userorgid:
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Authorization Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"Please login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns['orgid'] = userorgid
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.C('cpclist', ns.copy())
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"user_data":ns,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"title":"Add Success",
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Add Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
47
wwwroot/cpclist/delete_cpclist.dspy
Normal file
47
wwwroot/cpclist/delete_cpclist.dspy
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
ns = {
|
||||||
|
'id':params_kw['id'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
userorgid = await get_userorgid()
|
||||||
|
if not userorgid:
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Authorization Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"Please login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns['orgid'] = userorgid
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.D('cpclist', ns)
|
||||||
|
debug('delete success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Success",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('Delete failed');
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
123
wwwroot/cpclist/get_cpclist.dspy
Normal file
123
wwwroot/cpclist/get_cpclist.dspy
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
userorgid = await get_userorgid()
|
||||||
|
if not userorgid:
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Authorization Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"Please login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns['orgid'] = userorgid
|
||||||
|
ns['userorgid'] = userorgid
|
||||||
|
|
||||||
|
debug(f'get_cpclist.dspy:{ns=}')
|
||||||
|
if not ns.get('page'):
|
||||||
|
ns['page'] = 1
|
||||||
|
if not ns.get('sort'):
|
||||||
|
|
||||||
|
ns['sort'] = 'id'
|
||||||
|
|
||||||
|
|
||||||
|
sql = '''select a.*, b.orgid_text
|
||||||
|
from (select * from cpclist where 1=1 [[filterstr]]) a left join (select id as orgid,
|
||||||
|
orgname as orgid_text from organization where 1 = 1) b on a.orgid = b.orgid'''
|
||||||
|
|
||||||
|
filterjson = params_kw.get('data_filter')
|
||||||
|
if not filterjson:
|
||||||
|
fields = [ f['name'] for f in [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "orgid",
|
||||||
|
"title": "属主机构id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pcapi_url",
|
||||||
|
"title": "pcapi网址",
|
||||||
|
"type": "str",
|
||||||
|
"length": 500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "api_user",
|
||||||
|
"title": "接口用户",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "api_pwd",
|
||||||
|
"title": "接口密码",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_date",
|
||||||
|
"title": "启用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "expire_date",
|
||||||
|
"title": "停用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "contactname",
|
||||||
|
"title": "联系人",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "contactphone",
|
||||||
|
"title": "联系电话",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100
|
||||||
|
}
|
||||||
|
] ]
|
||||||
|
filterjson = default_filterjson(fields, ns)
|
||||||
|
filterdic = ns.copy()
|
||||||
|
filterdic['filterstr'] = ''
|
||||||
|
filterdic['userorgid'] = '${userorgid}$'
|
||||||
|
filterdic['userid'] = '${userid}$'
|
||||||
|
if filterjson:
|
||||||
|
dbf = DBFilter(filterjson)
|
||||||
|
conds = dbf.gen(ns)
|
||||||
|
if conds:
|
||||||
|
ns.update(dbf.consts)
|
||||||
|
conds = f' and {conds}'
|
||||||
|
filterdic['filterstr'] = conds
|
||||||
|
ac = ArgsConvert('[[', ']]')
|
||||||
|
vars = ac.findAllVariables(sql)
|
||||||
|
NameSpace = {v:'${' + v + '}$' for v in vars if v != 'filterstr' }
|
||||||
|
filterdic.update(NameSpace)
|
||||||
|
sql = ac.convert(sql, filterdic)
|
||||||
|
|
||||||
|
debug(f'{sql=}')
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.sqlPaging(sql, ns)
|
||||||
|
return r
|
||||||
|
return {
|
||||||
|
"total":0,
|
||||||
|
"rows":[]
|
||||||
|
}
|
||||||
209
wwwroot/cpclist/index.ui
Normal file
209
wwwroot/cpclist/index.ui
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
{
|
||||||
|
"id": "cpclist_tbl",
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
"title": "算力中心列表",
|
||||||
|
"toolbar": {
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"name": "newcluster",
|
||||||
|
"selected_row": true,
|
||||||
|
"label": "新建集群"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"css": "card",
|
||||||
|
"editable": {
|
||||||
|
"new_data_url": "{{entire_url('add_cpclist.dspy')}}",
|
||||||
|
"delete_data_url": "{{entire_url('delete_cpclist.dspy')}}",
|
||||||
|
"update_data_url": "{{entire_url('update_cpclist.dspy')}}"
|
||||||
|
},
|
||||||
|
"data_url": "{{entire_url('./get_cpclist.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"data_params": {{json.dumps(params_kw, indent=4, ensure_ascii=False)}},
|
||||||
|
"row_options": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"id",
|
||||||
|
"orgid",
|
||||||
|
"pcapi_url",
|
||||||
|
"pcapi_user",
|
||||||
|
"pcapi_pwd"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id",
|
||||||
|
"orgid"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "orgid",
|
||||||
|
"title": "属主机构id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"label": "属主机构id",
|
||||||
|
"uitype": "code",
|
||||||
|
"valueField": "orgid",
|
||||||
|
"textField": "orgid_text",
|
||||||
|
"params": {
|
||||||
|
"dbname": "{{rfexe('get_module_dbname', 'cpcc')}}",
|
||||||
|
"table": "organization",
|
||||||
|
"tblvalue": "id",
|
||||||
|
"tbltext": "orgname",
|
||||||
|
"valueField": "orgid",
|
||||||
|
"textField": "orgid_text"
|
||||||
|
},
|
||||||
|
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pcapi_url",
|
||||||
|
"title": "pcapi网址",
|
||||||
|
"type": "str",
|
||||||
|
"length": 500,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "pcapi网址"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "api_user",
|
||||||
|
"title": "接口用户",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "接口用户"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "api_pwd",
|
||||||
|
"title": "接口密码",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "接口密码"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_date",
|
||||||
|
"title": "启用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 0,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "date",
|
||||||
|
"datatype": "date",
|
||||||
|
"label": "启用日期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "expire_date",
|
||||||
|
"title": "停用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 0,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "date",
|
||||||
|
"datatype": "date",
|
||||||
|
"label": "停用日期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "contactname",
|
||||||
|
"title": "联系人",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "联系人"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "contactphone",
|
||||||
|
"title": "联系电话",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "联系电话"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"content_view": {
|
||||||
|
"widgettype": "TabPanel",
|
||||||
|
"options": {
|
||||||
|
"tab_wide": "auto",
|
||||||
|
"height": "100%",
|
||||||
|
"width": "100%",
|
||||||
|
"tab_pos": "top",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "cpccluster",
|
||||||
|
"label": "集群",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"params": {
|
||||||
|
"cpcid": "${id}"
|
||||||
|
},
|
||||||
|
"url": "{{entire_url('..\/cpccluster')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcnode",
|
||||||
|
"label": "节点",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"params": {
|
||||||
|
"cpcid": "${id}"
|
||||||
|
},
|
||||||
|
"url": "{{entire_url('..\/cpcnode')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"page_rows": 160,
|
||||||
|
"cache_limit": 5
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "newcluster",
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"target": "PopupWindow",
|
||||||
|
"popup_options": {
|
||||||
|
"width": "80%",
|
||||||
|
"height": "80%"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('../handy/new_cluster.ui')}}",
|
||||||
|
"params": {
|
||||||
|
"id": "{{params_kw.id}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
49
wwwroot/cpclist/update_cpclist.dspy
Normal file
49
wwwroot/cpclist/update_cpclist.dspy
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
userorgid = await get_userorgid()
|
||||||
|
if not userorgid:
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Authorization Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"Please login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ns['orgid'] = userorgid
|
||||||
|
|
||||||
|
|
||||||
|
if params_kw.get('api_pwd'):
|
||||||
|
ns['api_pwd'] = password_encode(params_kw.get('api_pwd'))
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.U('cpclist', ns)
|
||||||
|
debug('update success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Success",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
38
wwwroot/cpcnode/add_cpcnode.dspy
Normal file
38
wwwroot/cpcnode/add_cpcnode.dspy
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
id = params_kw.id
|
||||||
|
if not id or len(id) > 32:
|
||||||
|
id = uuid()
|
||||||
|
ns['id'] = id
|
||||||
|
|
||||||
|
if params_kw.get('adminpwd'):
|
||||||
|
ns['adminpwd'] = password_encode(params_kw.get('adminpwd'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.C('cpcnode', ns.copy())
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"user_data":ns,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"title":"Add Success",
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Add Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
33
wwwroot/cpcnode/delete_cpcnode.dspy
Normal file
33
wwwroot/cpcnode/delete_cpcnode.dspy
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
ns = {
|
||||||
|
'id':params_kw['id'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.D('cpcnode', ns)
|
||||||
|
debug('delete success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Success",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('Delete failed');
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
126
wwwroot/cpcnode/get_cpcnode.dspy
Normal file
126
wwwroot/cpcnode/get_cpcnode.dspy
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
debug(f'get_cpcnode.dspy:{ns=}')
|
||||||
|
if not ns.get('page'):
|
||||||
|
ns['page'] = 1
|
||||||
|
if not ns.get('sort'):
|
||||||
|
|
||||||
|
ns['sort'] = 'id'
|
||||||
|
|
||||||
|
|
||||||
|
sql = '''select a.*, b.node_status_text,d.devicetype_text
|
||||||
|
from (select * from cpcnode where 1=1 [[filterstr]])
|
||||||
|
a left join (select k as node_status, v as node_status_text from appcodes_kv where parentid='node_status')
|
||||||
|
b on a.node_status = b.node_status
|
||||||
|
left join (select k as devicetype, v as devicetype_text from appcodes_kv where parentid = 'devicetype')
|
||||||
|
d on a.devicetype = d.devicetype'''
|
||||||
|
|
||||||
|
|
||||||
|
filterjson = params_kw.get('data_filter')
|
||||||
|
if not filterjson:
|
||||||
|
fields = [ f['name'] for f in [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "devicetype",
|
||||||
|
"title": "设备类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ip",
|
||||||
|
"title": "内网ip",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sshport",
|
||||||
|
"title": "ssh端口号",
|
||||||
|
"type": "short"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "adminuser",
|
||||||
|
"title": "管理账号",
|
||||||
|
"type": "str",
|
||||||
|
"length": 99
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "adminpwd",
|
||||||
|
"title": "管理密码",
|
||||||
|
"type": "str",
|
||||||
|
"length": 99
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcid",
|
||||||
|
"title": "算力中心id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_status",
|
||||||
|
"title": "节点状态",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
|
"nullable": "yes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clusterid",
|
||||||
|
"title": "所属集群",
|
||||||
|
"type": "long",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "yes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_date",
|
||||||
|
"title": "启用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "export_date",
|
||||||
|
"title": "停用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 255
|
||||||
|
}
|
||||||
|
] ]
|
||||||
|
filterjson = default_filterjson(fields, ns)
|
||||||
|
filterdic = ns.copy()
|
||||||
|
filterdic['filterstr'] = ''
|
||||||
|
filterdic['userorgid'] = '${userorgid}$'
|
||||||
|
filterdic['userid'] = '${userid}$'
|
||||||
|
if filterjson:
|
||||||
|
dbf = DBFilter(filterjson)
|
||||||
|
conds = dbf.gen(ns)
|
||||||
|
if conds:
|
||||||
|
ns.update(dbf.consts)
|
||||||
|
conds = f' and {conds}'
|
||||||
|
filterdic['filterstr'] = conds
|
||||||
|
ac = ArgsConvert('[[', ']]')
|
||||||
|
vars = ac.findAllVariables(sql)
|
||||||
|
NameSpace = {v:'${' + v + '}$' for v in vars if v != 'filterstr' }
|
||||||
|
filterdic.update(NameSpace)
|
||||||
|
sql = ac.convert(sql, filterdic)
|
||||||
|
|
||||||
|
debug(f'{sql=}')
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.sqlPaging(sql, ns)
|
||||||
|
return r
|
||||||
|
return {
|
||||||
|
"total":0,
|
||||||
|
"rows":[]
|
||||||
|
}
|
||||||
179
wwwroot/cpcnode/index.ui
Normal file
179
wwwroot/cpcnode/index.ui
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
{
|
||||||
|
"id": "cpcnode_tbl",
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
"title": "入网算力节点",
|
||||||
|
"css": "card",
|
||||||
|
"editable": {
|
||||||
|
"new_data_url": "{{entire_url('add_cpcnode.dspy')}}",
|
||||||
|
"delete_data_url": "{{entire_url('delete_cpcnode.dspy')}}",
|
||||||
|
"update_data_url": "{{entire_url('update_cpcnode.dspy')}}"
|
||||||
|
},
|
||||||
|
"data_url": "{{entire_url('./get_cpcnode.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"data_params": {{json.dumps(params_kw, indent=4, ensure_ascii=False)}},
|
||||||
|
"row_options": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ip",
|
||||||
|
"title": "内网ip",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "内网ip"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 16,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "devicetype",
|
||||||
|
"title": "设备类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
|
"cwidth": 8,
|
||||||
|
"label": "设备类型",
|
||||||
|
"uitype": "code",
|
||||||
|
"valueField": "devicetype",
|
||||||
|
"textField": "devicetype_text",
|
||||||
|
"params": {
|
||||||
|
"dbname": "{{rfexe('get_module_dbname', 'cpcc')}}",
|
||||||
|
"table": "appcodes_kv",
|
||||||
|
"tblvalue": "k",
|
||||||
|
"tbltext": "v",
|
||||||
|
"valueField": "devicetype",
|
||||||
|
"textField": "devicetype_text",
|
||||||
|
"cond": "parentid='devicetype'"
|
||||||
|
},
|
||||||
|
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sshport",
|
||||||
|
"title": "ssh端口号",
|
||||||
|
"type": "short",
|
||||||
|
"length": 0,
|
||||||
|
"uitype": "int",
|
||||||
|
"datatype": "short",
|
||||||
|
"label": "ssh端口号"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "adminuser",
|
||||||
|
"title": "管理账号",
|
||||||
|
"type": "str",
|
||||||
|
"length": 99,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "管理账号"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "adminpwd",
|
||||||
|
"title": "管理密码",
|
||||||
|
"type": "str",
|
||||||
|
"length": 99,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "管理密码"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcid",
|
||||||
|
"title": "算力中心id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no",
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "算力中心id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_status",
|
||||||
|
"title": "节点状态",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
|
"nullable": "yes",
|
||||||
|
"label": "节点状态",
|
||||||
|
"uitype": "code",
|
||||||
|
"valueField": "node_status",
|
||||||
|
"textField": "node_status_text",
|
||||||
|
"params": {
|
||||||
|
"dbname": "{{rfexe('get_module_dbname', 'cpcc')}}",
|
||||||
|
"table": "appcodes_kv",
|
||||||
|
"tblvalue": "k",
|
||||||
|
"tbltext": "v",
|
||||||
|
"valueField": "node_status",
|
||||||
|
"textField": "node_status_text",
|
||||||
|
"cond": "parentid='node_status'"
|
||||||
|
},
|
||||||
|
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clusterid",
|
||||||
|
"title": "所属集群",
|
||||||
|
"type": "long",
|
||||||
|
"length": 0,
|
||||||
|
"nullable": "yes",
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "int",
|
||||||
|
"datatype": "long",
|
||||||
|
"label": "所属集群"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_date",
|
||||||
|
"title": "启用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 0,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "date",
|
||||||
|
"datatype": "date",
|
||||||
|
"label": "启用日期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "export_date",
|
||||||
|
"title": "停用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 0,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "date",
|
||||||
|
"datatype": "date",
|
||||||
|
"label": "停用日期"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"page_rows": 160,
|
||||||
|
"cache_limit": 5
|
||||||
|
},
|
||||||
|
"binds": []
|
||||||
|
}
|
||||||
35
wwwroot/cpcnode/update_cpcnode.dspy
Normal file
35
wwwroot/cpcnode/update_cpcnode.dspy
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if params_kw.get('adminpwd'):
|
||||||
|
ns['adminpwd'] = password_encode(params_kw.get('adminpwd'))
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.U('cpcnode', ns)
|
||||||
|
debug('update success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Success",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
76
wwwroot/cpcpod/get_cpcpod.dspy
Normal file
76
wwwroot/cpcpod/get_cpcpod.dspy
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
debug(f'get_cpcworker.dspy:{ns=}')
|
||||||
|
#{'_webbricks_': '1', 'width': '1139', 'height': '940', '_is_mobile': '0',
|
||||||
|
#'clusterid': '4hBm8atruISOU2bs24t_N', 'cpcid': 'AROU9udKtPNyh0AZtO_WY', 'page': '1', 'rows': '160'}
|
||||||
|
|
||||||
|
cpcid = params_kw.cpcid
|
||||||
|
clusterid = params_kw.clusterid
|
||||||
|
|
||||||
|
# 写数据库的步骤先pass
|
||||||
|
dbname = get_module_dbname('cpcc')
|
||||||
|
db = DBPools()
|
||||||
|
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
# 通过算力中心ID,获取算力中心部署所在设备的http(s)协议信息
|
||||||
|
cpcs = await sor.R('cpclist', {'id':cpcid})
|
||||||
|
if len(cpcs) < 1:
|
||||||
|
e = Exception(f'cpclist {cpcid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpc = cpcs[0]
|
||||||
|
# 通过集群ID,获取算力集群控制节点所在设备的ssh协议参数
|
||||||
|
cpclusters = await sor.R('cpccluster', {'id':clusterid})
|
||||||
|
if len(cpclusters) < 1:
|
||||||
|
e = Exception(f'cpclist {clusterid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpcluster = cpclusters[0]
|
||||||
|
nodeid = cpcluster.get("controllerid")
|
||||||
|
kubeconfig = cpcluster.get("kubeconfig")
|
||||||
|
nodes = await sor.R('cpcnode', {'id':nodeid})
|
||||||
|
# 这里有问题:没有匹配到节点信息!!!
|
||||||
|
if len(nodes) < 1:
|
||||||
|
e = Exception(f'cpcnode {nodeid=} 节点基础信息不匹配')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
node = nodes[0]
|
||||||
|
url = cpc.pcapi_url + "/pcapi/api/v1/cluster/common/get_cluster_pods"
|
||||||
|
debug(f"请求url: {url=}")
|
||||||
|
debug(f"目标IP认证信息: {node.ip=} {node.sshport=} {node.adminuser=} {password_decode(node.adminpwd)=}")
|
||||||
|
# 请求方式待定,取决于获取参数值方式
|
||||||
|
|
||||||
|
headers = basic_auth_headers(cpc.api_user, password_decode(cpc.api_pwd))
|
||||||
|
|
||||||
|
hc = HttpClient()
|
||||||
|
|
||||||
|
import requests
|
||||||
|
params = {
|
||||||
|
'host':node.ip,
|
||||||
|
'port':node.sshport,
|
||||||
|
'user':node.adminuser,
|
||||||
|
'psssword':password_decode(node.adminpwd),
|
||||||
|
'kubeconfig':kubeconfig
|
||||||
|
}
|
||||||
|
debug(f'请求参数{params=}')
|
||||||
|
|
||||||
|
#resp = await hc.request(url, method='GET',
|
||||||
|
# headers = headers,
|
||||||
|
# data=params
|
||||||
|
#)
|
||||||
|
# 框架不支持超时时间
|
||||||
|
resp = requests.post(url,
|
||||||
|
headers = headers,
|
||||||
|
data=params,
|
||||||
|
timeout=500
|
||||||
|
)
|
||||||
|
resp = json.dumps(resp.json()) #这里模拟hc.request返回的结果写后续逻辑
|
||||||
|
#debug(f'{type(resp)=}->{resp=}')
|
||||||
|
debug(f"pcapi返回值: {json.loads(resp)=}")
|
||||||
|
data = json.loads(resp).get('data')
|
||||||
|
if json.loads(resp).get("status") == True:
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
return UiError(title='get cluster nodes', message='failed')
|
||||||
|
|
||||||
|
return UiError(title='get cluster nodes', message='uncatched error')
|
||||||
11
wwwroot/cpcpod/get_node_labels.dspy
Normal file
11
wwwroot/cpcpod/get_node_labels.dspy
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
db = DBPools()
|
||||||
|
dbname = get_module_dbname('cpcc')
|
||||||
|
ns = {
|
||||||
|
"clusterid":params_kw.clusterid
|
||||||
|
}
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
sql = "select cpcid,id,ip,node_status from cpcnode where cpcid = (select cpcid from cpccluster where id = ${clusterid}$) and node_status = '0';"
|
||||||
|
recs = await sor.sqlExe(sql, ns.copy())
|
||||||
|
return recs
|
||||||
|
exception(f'{sql=},{ns=}')
|
||||||
|
return []
|
||||||
179
wwwroot/cpcpod/index.ui
Normal file
179
wwwroot/cpcpod/index.ui
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
{
|
||||||
|
"id": "cpcpod_tbl",
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
"title": "集群实时资源实例",
|
||||||
|
"description":"显示非系统命名空间下实时资源实例",
|
||||||
|
"css": "card",
|
||||||
|
"editable": {
|
||||||
|
"new_data_url": "{{entire_url('add_cpcpod.dspy')}}",
|
||||||
|
"delete_data_url": "{{entire_url('delete_cpcpod.dspy')}}",
|
||||||
|
"update_data_url": "{{entire_url('update_cpcpod.dspy')}}"
|
||||||
|
},
|
||||||
|
"data_url": "{{entire_url('./get_cpcpod.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"data_params": {{json.dumps(params_kw, indent=4, ensure_ascii=False)}},
|
||||||
|
"row_options": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "pod_namespace",
|
||||||
|
"title": "命名空间",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 14,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "命名空间"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_name",
|
||||||
|
"title": "资源实例名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 20,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源实例名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_ready",
|
||||||
|
"title": "就绪状态",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "就绪状态"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcid",
|
||||||
|
"title": "算力中心id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no",
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "算力中心id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_running",
|
||||||
|
"title": "运行状态",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no",
|
||||||
|
"cwidth": 10 ,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "运行状态"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_restart",
|
||||||
|
"title": "重启次数",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "重启次数"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_age",
|
||||||
|
"title": "运行时长",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "运行时长"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_ip",
|
||||||
|
"title": "集群内部IP",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "集群内部IP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_node",
|
||||||
|
"title": "Pod节点主机名",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 16,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "Pod节点主机名"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_nominated_node",
|
||||||
|
"title": "Pod指定节点",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "Pod指定节点"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_cpurate",
|
||||||
|
"title": "cpu占用率",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "cpu占用率"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_memrate",
|
||||||
|
"title": "内存占用率",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "内存占用率"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_readiness_gates",
|
||||||
|
"title": "盖茨准备",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "盖茨准备"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"page_rows": 160,
|
||||||
|
"cache_limit": 5
|
||||||
|
},
|
||||||
|
"binds": []
|
||||||
|
}
|
||||||
101
wwwroot/cpcpod/new_cpcpodyaml.dspy
Normal file
101
wwwroot/cpcpod/new_cpcpodyaml.dspy
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
# params_kw:
|
||||||
|
# clusterid
|
||||||
|
debug(f'Web参数:{params_kw=}')
|
||||||
|
dbname = get_module_dbname('cpcc')
|
||||||
|
db = DBPools()
|
||||||
|
clusterid = params_kw.clusterid
|
||||||
|
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
# clusterid -> nodeid
|
||||||
|
cpclusters = await sor.R('cpccluster', {'id':clusterid})
|
||||||
|
if len(cpclusters) < 1:
|
||||||
|
e = Exception(f'cpclist {clusterid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpcluster = cpclusters[0]
|
||||||
|
# 此处的nodeid即控制节点id
|
||||||
|
kubeconfig = cpcluster.get("kubeconfig")
|
||||||
|
nodeid = cpcluster.get("controllerid")
|
||||||
|
cpcid = cpcluster.get("cpcid")
|
||||||
|
cpcs = await sor.R('cpclist', {'id':cpcid})
|
||||||
|
if len(cpcs) < 1:
|
||||||
|
e = Exception(f'cpclist {cpcid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpc = cpcs[0]
|
||||||
|
nodes = await sor.R('cpcnode', {'id':nodeid})
|
||||||
|
# 这里有问题:没有匹配到节点信息!!!
|
||||||
|
if len(nodes) < 1:
|
||||||
|
e = Exception(f'cpcnode {nodeid=} 节点基础信息不匹配')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
node = nodes[0]
|
||||||
|
url = cpc.pcapi_url + "/pcapi/api/v1/cluster/common/yaml_apply"
|
||||||
|
debug(f"请求url: {url=}")
|
||||||
|
debug(f"目标IP认证信息: {node.ip=} {node.sshport=} {node.adminuser=} {password_decode(node.adminpwd)=}")
|
||||||
|
# 请求方式待定,取决于获取参数值方式
|
||||||
|
|
||||||
|
userorgid = await get_userorgid()
|
||||||
|
debug(f'当前组织ID:{userorgid}')
|
||||||
|
if not userorgid:
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Authorization Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"Please login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
headers = basic_auth_headers(cpc.api_user, password_decode(cpc.api_pwd))
|
||||||
|
ns_name = clusterid.replace("_","-") + "-" + userorgid # 集群信息+组织信息合成命名空间
|
||||||
|
ns_name = ns_name.lower()
|
||||||
|
hc = HttpClient()
|
||||||
|
# type参数:更新和新增都是为apply,删除为delete
|
||||||
|
yamlconfig_id = uuid().replace("_","-").lower()
|
||||||
|
import requests
|
||||||
|
params = {
|
||||||
|
'cluster_type': "k8s",
|
||||||
|
'host':node.ip,
|
||||||
|
'port':node.sshport,
|
||||||
|
'user':node.adminuser,
|
||||||
|
'psssword':password_decode(node.adminpwd),
|
||||||
|
'kubeconfig':kubeconfig,
|
||||||
|
'action':'apply',
|
||||||
|
'namespace_name': ns_name,
|
||||||
|
'serviceaccount_name': ns_name + "-serviceaccount",
|
||||||
|
'podcd_name': yamlconfig_id + "-" + params_kw.get("source_podengine").lower(),
|
||||||
|
'service_name': yamlconfig_id + "-service",
|
||||||
|
'instance_type': params_kw.get("instance_type") #目前仅支持RelationalDB和LinuxOS
|
||||||
|
}
|
||||||
|
params.update(params_kw)
|
||||||
|
|
||||||
|
keys_to_remove = ['_webbricks_', 'width', 'height', '_is_mobile']
|
||||||
|
for key in keys_to_remove:
|
||||||
|
if key in params:
|
||||||
|
del params[key]
|
||||||
|
|
||||||
|
resp = requests.post(url,
|
||||||
|
headers = headers,
|
||||||
|
data=params,
|
||||||
|
timeout=500
|
||||||
|
)
|
||||||
|
if resp.status_code != 200:
|
||||||
|
return UiError(title='新增YAML参数', message=f'算力中心服务异常 {resp.status_code}')
|
||||||
|
debug(f'{type(resp)=}->{resp=}')
|
||||||
|
resp = json.dumps(resp.json()) #这里模拟hc.request返回的结果写后续逻辑
|
||||||
|
keys_to_remove = ['cluster_type', 'host', 'port', 'user', 'psssword', 'kubeconfig']
|
||||||
|
for key in keys_to_remove:
|
||||||
|
if key in params:
|
||||||
|
del params[key]
|
||||||
|
params['id'] = yamlconfig_id
|
||||||
|
params['cpcid'] = cpcid
|
||||||
|
if json.loads(resp).get("status") == True:
|
||||||
|
debug(f"更新资源yaml配置元数据: {params=}")
|
||||||
|
await sor.C('yaml_config', params)
|
||||||
|
return UiMessage(title='新增YAML参数', message='资源实例参数更新成功,请10秒后查看实时资源实例面板')
|
||||||
|
else:
|
||||||
|
return UiError(title='新增YAML参数', message='资源实例数据写入数据库失败')
|
||||||
|
|
||||||
|
return UiError(title='新增YAML参数', message='全局未知异常')
|
||||||
265
wwwroot/cpcpod/new_podyaml.ui
Normal file
265
wwwroot/cpcpod/new_podyaml.ui
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"Form",
|
||||||
|
"options":{
|
||||||
|
"title":"新建资源YAML模板",
|
||||||
|
"description":"通过实例化资源YAML,为算力中心的kubernetes集群新增资源实例(注意:kubernetes部分参数值只允许小写,若拼接请以'-'间隔)",
|
||||||
|
"fields":[
|
||||||
|
{
|
||||||
|
"name":"clusterid",
|
||||||
|
"value":"{{params_kw.id}}",
|
||||||
|
"uitype":"hide"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_name",
|
||||||
|
"title": "资源容器名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源容器名称(可以-分隔)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_authuser",
|
||||||
|
"title": "资源初始账号",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源初始账号"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_authpasswd",
|
||||||
|
"title": "资源初始密码",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源初始密码"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_podengine",
|
||||||
|
"label":"资源实例控制器",
|
||||||
|
"data":[
|
||||||
|
{
|
||||||
|
"value":"Deployment",
|
||||||
|
"text":"Deployment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"Job",
|
||||||
|
"text":"Job"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"CronJob",
|
||||||
|
"text":"CronJob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"DaemonSet",
|
||||||
|
"text":"DaemonSet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"StatefulSet",
|
||||||
|
"text":"StatefulSet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"standalone",
|
||||||
|
"text":"standalone"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"value":"StatefulSet",
|
||||||
|
"uitype":"code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_replicasetnum",
|
||||||
|
"title": "资源副本个数",
|
||||||
|
"type": "short",
|
||||||
|
"length": 0,
|
||||||
|
"uitype": "int",
|
||||||
|
"cwidth": 18,
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源副本个数"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"instance_type",
|
||||||
|
"label":"资源实例类型",
|
||||||
|
"data":[
|
||||||
|
{
|
||||||
|
"value":"RelationalDB",
|
||||||
|
"text":"关系型数据库"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"LinuxOS",
|
||||||
|
"text":"Linux操作系统"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"value":"LinuxOS",
|
||||||
|
"uitype":"code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"pod_imagepath",
|
||||||
|
"label":"基础镜像",
|
||||||
|
"data":[
|
||||||
|
{
|
||||||
|
"value":"docker.io/library/mysql:8.0",
|
||||||
|
"text":"docker.io/library/mysql:8.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"docker.io/library/nginx:latest",
|
||||||
|
"text":"docker.io/library/nginx:latest"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"docker.io/library/ubuntu:22.04",
|
||||||
|
"text":"docker.io/library/ubuntu:22.04"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"docker.io/jupyter/base-notebook:latest",
|
||||||
|
"text":"docker.io/jupyter/base-notebook:latest"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"value":"docker.io/library/ubuntu:22.04",
|
||||||
|
"uitype":"code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_memrate",
|
||||||
|
"title": "资源内存限制",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源内存限制(示例:100Mi)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_cpurate",
|
||||||
|
"title": "资源cpu限制",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源cpu限制(示例:100m)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_selflabel",
|
||||||
|
"title": "资源自身标签",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源自身标签(service代理)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"source_portmode",
|
||||||
|
"label":"端口映射模式",
|
||||||
|
"data":[
|
||||||
|
{
|
||||||
|
"value":"NodePort",
|
||||||
|
"text":"NodePort"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"LoadBalancer",
|
||||||
|
"text":"LoadBalancer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"Ingress",
|
||||||
|
"text":"Ingress"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"value":"NodePort",
|
||||||
|
"uitype":"code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"source_restartpolicy",
|
||||||
|
"label":"重启策略",
|
||||||
|
"data":[
|
||||||
|
{
|
||||||
|
"value":"Always",
|
||||||
|
"text":"Always"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"OnFailure",
|
||||||
|
"text":"OnFailure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"Never",
|
||||||
|
"text":"Never"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"value":"Always",
|
||||||
|
"uitype":"code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_apiport",
|
||||||
|
"title": "集群内部映射端口",
|
||||||
|
"type": "short",
|
||||||
|
"length": 0,
|
||||||
|
"uitype": "int",
|
||||||
|
"cwidth": 18,
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "集群内部映射端口"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_insideport",
|
||||||
|
"title": "容器默认监听端口",
|
||||||
|
"type": "short",
|
||||||
|
"length": 0,
|
||||||
|
"uitype": "int",
|
||||||
|
"cwidth": 18,
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "容器默认监听端口"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_outsideport",
|
||||||
|
"title": "集群外部映射端口",
|
||||||
|
"type": "short",
|
||||||
|
"length": 0,
|
||||||
|
"uitype": "int",
|
||||||
|
"cwidth": 18,
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "集群外部映射端口(必须是30000-32767之间的整数)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"source_nodeSelector",
|
||||||
|
"label":"节点标签(指定节点运行)",
|
||||||
|
"uitype":"code",
|
||||||
|
"textField":"ip",
|
||||||
|
"valueField":"id",
|
||||||
|
"dataurl":"{{entire_url('get_node_labels.dspy')}}?clusterid={{params_kw.id}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"source_mountpath",
|
||||||
|
"title":"容器内挂载点",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label":"容器内挂载点"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_storagelimits",
|
||||||
|
"title": "定义存储盘容量(单位:Gi)",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "定义存储盘容量(单位:Gi)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"submit",
|
||||||
|
"actiontype":"urlwidget",
|
||||||
|
"target":"PopupWindow",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('new_cpcpodyaml.dspy')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
138
wwwroot/cpcpodyaml/delete_cpcpodyaml.dspy
Normal file
138
wwwroot/cpcpodyaml/delete_cpcpodyaml.dspy
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
ns = {
|
||||||
|
'id':params_kw['id'],
|
||||||
|
}
|
||||||
|
|
||||||
|
yamlconfig_id = params_kw.get("id")
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
|
||||||
|
# 成功完成k8s资源级联删除后才可以删除数据库记录
|
||||||
|
yaml_configs = await sor.R('yaml_config', {'id':yamlconfig_id})
|
||||||
|
if len(yaml_configs) < 1:
|
||||||
|
e = Exception(f'yaml_config {yamlconfig_id=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
yaml_config = yaml_configs[0]
|
||||||
|
|
||||||
|
source_podengine = yaml_config.get("source_podengine")
|
||||||
|
clusterid = yaml_config.get("clusterid")
|
||||||
|
cpcid = yaml_config.get("cpcid")
|
||||||
|
debug(f'===== delete yamlconfig_id: {yamlconfig_id}')
|
||||||
|
|
||||||
|
cpclusters = await sor.R('cpccluster', {'id':clusterid})
|
||||||
|
if len(cpclusters) < 1:
|
||||||
|
e = Exception(f'cpclist {clusterid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpcluster = cpclusters[0]
|
||||||
|
# 此处的nodeid即控制节点id
|
||||||
|
kubeconfig = cpcluster.get("kubeconfig")
|
||||||
|
nodeid = cpcluster.get("controllerid")
|
||||||
|
|
||||||
|
cpcs = await sor.R('cpclist', {'id':cpcid})
|
||||||
|
if len(cpcs) < 1:
|
||||||
|
e = Exception(f'cpclist {cpcid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpc = cpcs[0]
|
||||||
|
nodes = await sor.R('cpcnode', {'id':nodeid})
|
||||||
|
# 这里有问题:没有匹配到节点信息!!!
|
||||||
|
if len(nodes) < 1:
|
||||||
|
e = Exception(f'cpcnode {nodeid=} 节点基础信息不匹配')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
node = nodes[0]
|
||||||
|
url = cpc.pcapi_url + "/pcapi/api/v1/cluster/common/delete_cpcpod"
|
||||||
|
debug(f"请求url: {url=}")
|
||||||
|
debug(f"目标IP认证信息: {node.ip=} {node.sshport=} {node.adminuser=} {password_decode(node.adminpwd)=}")
|
||||||
|
# 请求方式待定,取决于获取参数值方式
|
||||||
|
|
||||||
|
userorgid = await get_userorgid()
|
||||||
|
debug(f'当前组织ID:{userorgid}')
|
||||||
|
if not userorgid:
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Authorization Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"Please login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = basic_auth_headers(cpc.api_user, password_decode(cpc.api_pwd))
|
||||||
|
ns_name = clusterid.replace("_","-") + "-" + userorgid # 集群信息+组织信息合成命名空间
|
||||||
|
ns_name = ns_name.lower()
|
||||||
|
hc = HttpClient()
|
||||||
|
|
||||||
|
# type参数:更新和新增都是为apply,删除为delete
|
||||||
|
yamlconfig_id = params_kw.get('id')
|
||||||
|
|
||||||
|
import requests
|
||||||
|
params = {
|
||||||
|
'host':node.ip,
|
||||||
|
'port':node.sshport,
|
||||||
|
'user':node.adminuser,
|
||||||
|
'psssword':password_decode(node.adminpwd),
|
||||||
|
'kubeconfig':kubeconfig,
|
||||||
|
'action':'delete',
|
||||||
|
'namespace_name': ns_name,
|
||||||
|
'serviceaccount_name': ns_name + "-serviceaccount",
|
||||||
|
'podcd_name': yamlconfig_id + "-" + source_podengine.lower(),
|
||||||
|
'service_name': yamlconfig_id + "-service", #取代+ "-" + source_name
|
||||||
|
}
|
||||||
|
params.update(yaml_config)
|
||||||
|
|
||||||
|
keys_to_remove = ['_webbricks_', 'width', 'height', '_is_mobile']
|
||||||
|
for key in keys_to_remove:
|
||||||
|
if key in params:
|
||||||
|
del params[key]
|
||||||
|
|
||||||
|
debug(f'请求pcapi参数: {params}')
|
||||||
|
|
||||||
|
# 框架不支持超时时间
|
||||||
|
resp = requests.post(url,
|
||||||
|
headers = headers,
|
||||||
|
data = params,
|
||||||
|
timeout = 500
|
||||||
|
)
|
||||||
|
|
||||||
|
debug(f'{type(resp)}->{resp}')
|
||||||
|
resp = json.dumps(resp.json()) #这里模拟hc.request返回的结果写后续逻辑
|
||||||
|
data = json.loads(resp).get('data')
|
||||||
|
keys_to_remove = ['host', 'port', 'user', 'psssword', 'kubeconfig']
|
||||||
|
for key in keys_to_remove:
|
||||||
|
if key in params:
|
||||||
|
del params[key]
|
||||||
|
params['id'] = yamlconfig_id
|
||||||
|
|
||||||
|
if json.loads(resp).get("status") == True:
|
||||||
|
|
||||||
|
r = await sor.D('yaml_config', ns)
|
||||||
|
debug('级联删除集群资源成功');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"级联删除集群资源成功",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('级联删除集群资源失败');
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"级联删除集群资源失败",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
121
wwwroot/cpcpodyaml/get_cpcpodyaml.dspy
Normal file
121
wwwroot/cpcpodyaml/get_cpcpodyaml.dspy
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
debug(f'get_cpcnode.dspy:{ns=}')
|
||||||
|
if not ns.get('page'):
|
||||||
|
ns['page'] = 1
|
||||||
|
if not ns.get('sort'):
|
||||||
|
|
||||||
|
ns['sort'] = 'id'
|
||||||
|
|
||||||
|
|
||||||
|
sql = '''select * from yaml_config'''
|
||||||
|
|
||||||
|
|
||||||
|
filterjson = params_kw.get('data_filter')
|
||||||
|
if not filterjson:
|
||||||
|
fields = [ f['name'] for f in [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "devicetype",
|
||||||
|
"title": "设备类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ip",
|
||||||
|
"title": "内网ip",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sshport",
|
||||||
|
"title": "ssh端口号",
|
||||||
|
"type": "short"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "adminuser",
|
||||||
|
"title": "管理账号",
|
||||||
|
"type": "str",
|
||||||
|
"length": 99
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "adminpwd",
|
||||||
|
"title": "管理密码",
|
||||||
|
"type": "str",
|
||||||
|
"length": 99
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcid",
|
||||||
|
"title": "算力中心id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_status",
|
||||||
|
"title": "节点状态",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
|
"nullable": "yes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clusterid",
|
||||||
|
"title": "所属集群",
|
||||||
|
"type": "long",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "yes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_date",
|
||||||
|
"title": "启用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "export_date",
|
||||||
|
"title": "停用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 255
|
||||||
|
}
|
||||||
|
] ]
|
||||||
|
filterjson = default_filterjson(fields, ns)
|
||||||
|
filterdic = ns.copy()
|
||||||
|
filterdic['filterstr'] = ''
|
||||||
|
filterdic['userorgid'] = '${userorgid}$'
|
||||||
|
filterdic['userid'] = '${userid}$'
|
||||||
|
if filterjson:
|
||||||
|
dbf = DBFilter(filterjson)
|
||||||
|
conds = dbf.gen(ns)
|
||||||
|
if conds:
|
||||||
|
ns.update(dbf.consts)
|
||||||
|
conds = f' and {conds}'
|
||||||
|
filterdic['filterstr'] = conds
|
||||||
|
ac = ArgsConvert('[[', ']]')
|
||||||
|
vars = ac.findAllVariables(sql)
|
||||||
|
NameSpace = {v:'${' + v + '}$' for v in vars if v != 'filterstr' }
|
||||||
|
filterdic.update(NameSpace)
|
||||||
|
sql = ac.convert(sql, filterdic)
|
||||||
|
|
||||||
|
debug(f'{sql=}')
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.sqlPaging(sql, ns)
|
||||||
|
return r
|
||||||
|
return {
|
||||||
|
"total":0,
|
||||||
|
"rows":[]
|
||||||
|
}
|
||||||
278
wwwroot/cpcpodyaml/index.ui
Normal file
278
wwwroot/cpcpodyaml/index.ui
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
{
|
||||||
|
"id": "cpcnode_tbl",
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
"title": "集群资源实例YAML配置",
|
||||||
|
"description":"显示非系统命名空间下所有资源实例对应的静态YAML参数,更新资源YAML后,kubernetes集群会根据整体资源情况,自动调整资源实例",
|
||||||
|
"css": "card",
|
||||||
|
"editable": {
|
||||||
|
"new_data_url": "{{entire_url('add_cpcpodyaml.dspy')}}",
|
||||||
|
"delete_data_url": "{{entire_url('delete_cpcpodyaml.dspy')}}",
|
||||||
|
"update_data_url": "{{entire_url('update_cpcpodyaml.dspy')}}"
|
||||||
|
},
|
||||||
|
"data_url": "{{entire_url('./get_cpcpodyaml.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"data_params": {{json.dumps(params_kw, indent=4, ensure_ascii=False)}},
|
||||||
|
"row_options": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "资源级联标识",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 12,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源级联标识"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcid",
|
||||||
|
"title": "算力中心id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no",
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "算力中心id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "clusterid",
|
||||||
|
"title": "所属集群",
|
||||||
|
"type": "long",
|
||||||
|
"length": 0,
|
||||||
|
"nullable": "yes",
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "int",
|
||||||
|
"datatype": "long",
|
||||||
|
"label": "所属集群"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_name",
|
||||||
|
"title": "资源名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "namespace_name",
|
||||||
|
"title": "命名空间",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 14,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "命名空间"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "serviceaccount_name",
|
||||||
|
"title": "服务认证",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 16,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "服务认证"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "podcd_name",
|
||||||
|
"title": "资源控制器名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 16,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源控制器名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "instance_type",
|
||||||
|
"title": "资源实例类型",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源实例类型"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "service_name",
|
||||||
|
"title": "服务名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 16,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "服务名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_replicasetnum",
|
||||||
|
"title": "副本数量",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "副本数量"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_authuser",
|
||||||
|
"title": "默认账号",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "默认账号"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_authpasswd",
|
||||||
|
"title": "默认密码",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "默认密码"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_podengine",
|
||||||
|
"title": "资源控制器",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 7,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源控制器"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pod_imagepath",
|
||||||
|
"title": "基础镜像",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 16,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "基础镜像"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_memrate",
|
||||||
|
"title": "内存限制",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "内存限制"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_cpurate",
|
||||||
|
"title": "CPU限制",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "CPU限制"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_selflabel",
|
||||||
|
"title": "资源标签",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "资源标签"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_portmode",
|
||||||
|
"title": "端口映射模式",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 7,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "端口映射模式"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_restartpolicy",
|
||||||
|
"title": "重启策略",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "重启策略"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_apiport",
|
||||||
|
"title": "集群内部映射端口",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 9,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "集群内部映射端口"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_insideport",
|
||||||
|
"title": "容器默认监听端口",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 9,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "容器默认监听端口"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_outsideport",
|
||||||
|
"title": "集群外部映射端口",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 9,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "集群外部映射端口"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_mountpath",
|
||||||
|
"title": "容器内部挂载点",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "容器内部挂载点"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "source_storagelimits",
|
||||||
|
"title": "容器存储盘限制",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "容器存储盘限制"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"page_rows": 160,
|
||||||
|
"cache_limit": 5
|
||||||
|
},
|
||||||
|
"binds": []
|
||||||
|
}
|
||||||
110
wwwroot/cpcpodyaml/update_cpcpodyaml.dspy
Normal file
110
wwwroot/cpcpodyaml/update_cpcpodyaml.dspy
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
# cpcid
|
||||||
|
# clusterid
|
||||||
|
|
||||||
|
if params_kw.get('adminpwd'):
|
||||||
|
ns['adminpwd'] = password_encode(params_kw.get('adminpwd'))
|
||||||
|
|
||||||
|
clusterid = params_kw.get("clusterid")
|
||||||
|
cpcid = params_kw.get("cpcid")
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
|
||||||
|
# 补充['cluster_type', 'host', 'port', 'user', 'psssword', 'kubeconfig']
|
||||||
|
|
||||||
|
cpclusters = await sor.R('cpccluster', {'id':clusterid})
|
||||||
|
if len(cpclusters) < 1:
|
||||||
|
e = Exception(f'cpclist {clusterid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpcluster = cpclusters[0]
|
||||||
|
# 此处的nodeid即控制节点id
|
||||||
|
kubeconfig = cpcluster.get("kubeconfig")
|
||||||
|
nodeid = cpcluster.get("controllerid")
|
||||||
|
|
||||||
|
cpcs = await sor.R('cpclist', {'id':cpcid})
|
||||||
|
if len(cpcs) < 1:
|
||||||
|
e = Exception(f'cpclist {cpcid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpc = cpcs[0]
|
||||||
|
nodes = await sor.R('cpcnode', {'id':nodeid})
|
||||||
|
# 这里有问题:没有匹配到节点信息!!!
|
||||||
|
if len(nodes) < 1:
|
||||||
|
e = Exception(f'cpcnode {nodeid=} 节点基础信息不匹配')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
node = nodes[0]
|
||||||
|
url = cpc.pcapi_url + "/pcapi/api/v1/cluster/common/update_cpcpod"
|
||||||
|
debug(f"请求url: {url=}")
|
||||||
|
debug(f"目标IP认证信息: {node.ip=} {node.sshport=} {node.adminuser=} {password_decode(node.adminpwd)=}")
|
||||||
|
# 请求方式待定,取决于获取参数值方式
|
||||||
|
|
||||||
|
userorgid = await get_userorgid()
|
||||||
|
debug(f'当前组织ID:{userorgid}')
|
||||||
|
if not userorgid:
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Authorization Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"Please login"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = basic_auth_headers(cpc.api_user, password_decode(cpc.api_pwd))
|
||||||
|
ns_name = clusterid.replace("_","-") + "-" + userorgid # 集群信息+组织信息合成命名空间
|
||||||
|
ns_name = ns_name.lower()
|
||||||
|
hc = HttpClient()
|
||||||
|
# type参数:更新和新增都是为apply,删除为delete
|
||||||
|
yamlconfig_id = params_kw.get('id')
|
||||||
|
import requests
|
||||||
|
params = {
|
||||||
|
'cluster_type': cluster_type,
|
||||||
|
'host':node.ip,
|
||||||
|
'port':node.sshport,
|
||||||
|
'user':node.adminuser,
|
||||||
|
'psssword':password_decode(node.adminpwd),
|
||||||
|
'kubeconfig':kubeconfig,
|
||||||
|
'action':'apply',
|
||||||
|
'namespace_name': ns_name,
|
||||||
|
'serviceaccount_name': ns_name + "-serviceaccount",
|
||||||
|
'podcd_name': yamlconfig_id + "-" + params_kw.get("source_podengine").lower(),
|
||||||
|
'service_name': yamlconfig_id + "-service", #取代+ "-" + params_kw.get("source_name")
|
||||||
|
}
|
||||||
|
params.update(params_kw)
|
||||||
|
|
||||||
|
keys_to_remove = ['_webbricks_', 'width', 'height', '_is_mobile']
|
||||||
|
for key in keys_to_remove:
|
||||||
|
if key in params:
|
||||||
|
del params[key]
|
||||||
|
|
||||||
|
debug(f'请求pcapi参数: {params=}')
|
||||||
|
# 框架不支持超时时间
|
||||||
|
resp = requests.post(url,
|
||||||
|
headers = headers,
|
||||||
|
data=params,
|
||||||
|
timeout=500
|
||||||
|
)
|
||||||
|
resp = json.dumps(resp.json()) #这里模拟hc.request返回的结果写后续逻辑
|
||||||
|
debug(f'{type(resp)=}->{resp=}')
|
||||||
|
data = json.loads(resp).get('data')
|
||||||
|
keys_to_remove = ['cluster_type', 'host', 'port', 'user', 'psssword', 'kubeconfig']
|
||||||
|
for key in keys_to_remove:
|
||||||
|
if key in params:
|
||||||
|
del params[key]
|
||||||
|
params['id'] = yamlconfig_id
|
||||||
|
if json.loads(resp).get("status") == True:
|
||||||
|
|
||||||
|
r = await sor.U('yaml_config', ns)
|
||||||
|
debug('update success');
|
||||||
|
return UiMessage(title='更新YAML参数', message='资源参数更新成功,请10秒后查看实时资源实例面板')
|
||||||
|
else:
|
||||||
|
return UiError(title='更新YAML参数', message='资源实例更新失败')
|
||||||
|
|
||||||
|
return UiError(title='更新YAML参数', message='其他错误')
|
||||||
35
wwwroot/cpcworker/add_cpcworker.dspy
Normal file
35
wwwroot/cpcworker/add_cpcworker.dspy
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
id = params_kw.id
|
||||||
|
if not id or len(id) > 32:
|
||||||
|
id = uuid()
|
||||||
|
ns['id'] = id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.C('cpccluster', ns.copy())
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"user_data":ns,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"title":"Add Success",
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Add Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
33
wwwroot/cpcworker/delete_cpcworker.dspy
Normal file
33
wwwroot/cpcworker/delete_cpcworker.dspy
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
ns = {
|
||||||
|
'id':params_kw['id'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.D('cpccluster', ns)
|
||||||
|
debug('delete success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Success",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"ok,记得把关联的节点都解除占用状态 ~"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('Delete failed');
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Delete Error",
|
||||||
|
"timeout":3,
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
11
wwwroot/cpcworker/get_availableworker.dspy
Normal file
11
wwwroot/cpcworker/get_availableworker.dspy
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
db = DBPools()
|
||||||
|
dbname = get_module_dbname('cpcc')
|
||||||
|
ns = {
|
||||||
|
"clusterid":params_kw.clusterid
|
||||||
|
}
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
sql = "select cpcid,id,ip,node_status from cpcnode where cpcid = (select cpcid from cpccluster where id = ${clusterid}$) and node_status = '0';"
|
||||||
|
recs = await sor.sqlExe(sql, ns.copy())
|
||||||
|
return recs
|
||||||
|
exception(f'{sql=},{ns=}')
|
||||||
|
return []
|
||||||
84
wwwroot/cpcworker/get_cpcworker.dspy
Normal file
84
wwwroot/cpcworker/get_cpcworker.dspy
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
debug(f'get_cpcworker.dspy:{ns=}')
|
||||||
|
#{'_webbricks_': '1', 'width': '1139', 'height': '940', '_is_mobile': '0',
|
||||||
|
#'clusterid': '4hBm8atruISOU2bs24t_N', 'cpcid': 'AROU9udKtPNyh0AZtO_WY', 'page': '1', 'rows': '160'}
|
||||||
|
|
||||||
|
cpcid = params_kw.cpcid
|
||||||
|
clusterid = params_kw.clusterid
|
||||||
|
|
||||||
|
# 写数据库的步骤先pass
|
||||||
|
dbname = get_module_dbname('cpcc')
|
||||||
|
db = DBPools()
|
||||||
|
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
# 通过算力中心ID,获取算力中心部署所在设备的http(s)协议信息
|
||||||
|
cpcs = await sor.R('cpclist', {'id':cpcid})
|
||||||
|
if len(cpcs) < 1:
|
||||||
|
e = Exception(f'cpclist {cpcid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpc = cpcs[0]
|
||||||
|
# 通过集群ID,获取算力集群控制节点所在设备的ssh协议参数
|
||||||
|
cpclusters = await sor.R('cpccluster', {'id':clusterid})
|
||||||
|
if len(cpclusters) < 1:
|
||||||
|
e = Exception(f'cpclist {clusterid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpcluster = cpclusters[0]
|
||||||
|
nodeid = cpcluster.get("controllerid")
|
||||||
|
kubeconfig = cpcluster.get("kubeconfig")
|
||||||
|
nodes = await sor.R('cpcnode', {'id':nodeid})
|
||||||
|
# 这里有问题:没有匹配到节点信息!!!
|
||||||
|
if len(nodes) < 1:
|
||||||
|
e = Exception(f'cpcnode {nodeid=} 节点基础信息不匹配')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
node = nodes[0]
|
||||||
|
url = cpc.pcapi_url + "/pcapi/api/v1/cluster/common/get_cluster_nodes"
|
||||||
|
debug(f"请求url: {url=}")
|
||||||
|
debug(f"目标IP认证信息: {node.ip=} {node.sshport=} {node.adminuser=} {password_decode(node.adminpwd)=}")
|
||||||
|
# 请求方式待定,取决于获取参数值方式
|
||||||
|
|
||||||
|
headers = basic_auth_headers(cpc.api_user, password_decode(cpc.api_pwd))
|
||||||
|
|
||||||
|
hc = HttpClient()
|
||||||
|
|
||||||
|
import requests
|
||||||
|
params = {
|
||||||
|
'host':node.ip,
|
||||||
|
'port':node.sshport,
|
||||||
|
'user':node.adminuser,
|
||||||
|
'psssword':password_decode(node.adminpwd),
|
||||||
|
'kubeconfig':kubeconfig
|
||||||
|
}
|
||||||
|
debug(f'请求参数{params=}')
|
||||||
|
|
||||||
|
#resp = await hc.request(url, method='GET',
|
||||||
|
# headers = headers,
|
||||||
|
# data=params
|
||||||
|
#)
|
||||||
|
# 框架不支持超时时间
|
||||||
|
resp = requests.post(url,
|
||||||
|
headers = headers,
|
||||||
|
data=params,
|
||||||
|
timeout=500
|
||||||
|
)
|
||||||
|
resp = json.dumps(resp.json()) #这里模拟hc.request返回的结果写后续逻辑
|
||||||
|
#debug(f'{type(resp)=}->{resp=}')
|
||||||
|
debug(f"pcapi返回值: {json.loads(resp)=}")
|
||||||
|
data = json.loads(resp).get('data')
|
||||||
|
if json.loads(resp).get("status") == True:
|
||||||
|
#node_ns = {
|
||||||
|
# 'id':nodeid,
|
||||||
|
# 'node_status':'1',
|
||||||
|
# 'clusterid':clusterid,
|
||||||
|
# 'cpcid':cpcid
|
||||||
|
#}
|
||||||
|
#debug(f"更新新增工作节点元数据 {node_ns=}")
|
||||||
|
#await sor.U('cpcnode', node_ns)
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
return UiError(title='get cluster nodes', message='failed')
|
||||||
|
|
||||||
|
return UiError(title='get cluster nodes', message='uncatched error')
|
||||||
179
wwwroot/cpcworker/index.ui
Normal file
179
wwwroot/cpcworker/index.ui
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
{
|
||||||
|
"id": "cpcworker_tbl",
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"options": {
|
||||||
|
"title": "集群实时节点",
|
||||||
|
"description":"显示集群中所有实时节点信息",
|
||||||
|
"css": "card",
|
||||||
|
"editable": {
|
||||||
|
"new_data_url": "{{entire_url('add_cpcworker.dspy')}}",
|
||||||
|
"delete_data_url": "{{entire_url('delete_cpcworker.dspy')}}",
|
||||||
|
"update_data_url": "{{entire_url('update_cpcworker.dspy')}}"
|
||||||
|
},
|
||||||
|
"data_url": "{{entire_url('./get_cpcworker.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"data_params": {{json.dumps(params_kw, indent=4, ensure_ascii=False)}},
|
||||||
|
"row_options": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id",
|
||||||
|
"cpcid",
|
||||||
|
"clusterid"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "node_internalip",
|
||||||
|
"title": "内网IP",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 6,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "内网IP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_name",
|
||||||
|
"title": "主机名",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 15,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "主机名"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_status",
|
||||||
|
"title": "运行状态",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "运行状态"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cpcid",
|
||||||
|
"title": "算力中心id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no",
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "算力中心id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_role",
|
||||||
|
"title": "节点角色",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "no",
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "节点角色"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_age",
|
||||||
|
"title": "运行时长",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 5,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "运行时长"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_version",
|
||||||
|
"title": "kubernetes版本",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "kubernetes版本"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_cpurate",
|
||||||
|
"title": "CPU占用率",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 6,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "CPU占用率"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_memrate",
|
||||||
|
"title": "内存占用率",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 6,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "内存占用率"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_osversion",
|
||||||
|
"title": "操作系统",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "操作系统"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_containeruntime",
|
||||||
|
"title": "容器运行时版本",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "容器运行时"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_kernelversion",
|
||||||
|
"title": "内核版本",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 10,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "内核版本"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node_externalip",
|
||||||
|
"title": "外网IP",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"cwidth": 8,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "外网IP"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"page_rows": 160,
|
||||||
|
"cache_limit": 5
|
||||||
|
},
|
||||||
|
"binds": []
|
||||||
|
}
|
||||||
83
wwwroot/cpcworker/new_cpcworker.dspy
Normal file
83
wwwroot/cpcworker/new_cpcworker.dspy
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
# params_kw:
|
||||||
|
# clusterid
|
||||||
|
# worker_nodeid
|
||||||
|
debug(f'{params_kw=}')
|
||||||
|
dbname = get_module_dbname('cpcc')
|
||||||
|
db = DBPools()
|
||||||
|
clusterid = params_kw.clusterid
|
||||||
|
nodeid = params_kw.worker_nodeid
|
||||||
|
#debug(f"=====> {clusterid=} {worker_nodeid=}")
|
||||||
|
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
# clusterid -> cpcid
|
||||||
|
cpclusters = await sor.R('cpccluster', {'id':clusterid})
|
||||||
|
if len(cpclusters) < 1:
|
||||||
|
e = Exception(f'cpclist {clusterid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpcluster = cpclusters[0]
|
||||||
|
join_command = cpcluster.get("clusterjoin")
|
||||||
|
cpcid = cpcluster.get("cpcid")
|
||||||
|
cpcs = await sor.R('cpclist', {'id':cpcid})
|
||||||
|
if len(cpcs) < 1:
|
||||||
|
e = Exception(f'cpclist {cpcid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpc = cpcs[0]
|
||||||
|
debug(f'集群注册命令:{join_command=}')
|
||||||
|
nodes = await sor.R('cpcnode', {'id':nodeid})
|
||||||
|
# 这里有问题:没有匹配到节点信息!!!
|
||||||
|
if len(nodes) < 1:
|
||||||
|
e = Exception(f'cpcnode {nodeid=} 节点基础信息不匹配')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
node = nodes[0]
|
||||||
|
url = cpc.pcapi_url + "/pcapi/api/v1/cluster/common/new_worker"
|
||||||
|
debug(f"请求url: {url=}")
|
||||||
|
debug(f"目标IP认证信息: {node.ip=} {node.sshport=} {node.adminuser=} {password_decode(node.adminpwd)=}")
|
||||||
|
# 请求方式待定,取决于获取参数值方式
|
||||||
|
|
||||||
|
headers = basic_auth_headers(cpc.api_user, password_decode(cpc.api_pwd))
|
||||||
|
|
||||||
|
hc = HttpClient()
|
||||||
|
|
||||||
|
import requests
|
||||||
|
params = {
|
||||||
|
'cluster_type': cluster_type,
|
||||||
|
'host':node.ip,
|
||||||
|
'port':node.sshport,
|
||||||
|
'user':node.adminuser,
|
||||||
|
'psssword':password_decode(node.adminpwd),
|
||||||
|
'role':"worker",
|
||||||
|
'join_command':join_command
|
||||||
|
}
|
||||||
|
debug(f'{params=}')
|
||||||
|
|
||||||
|
#resp = await hc.request(url, method='POST',
|
||||||
|
# headers = headers,
|
||||||
|
# data=params
|
||||||
|
#)
|
||||||
|
# 框架不支持超时时间
|
||||||
|
resp = requests.post(url,
|
||||||
|
headers = headers,
|
||||||
|
data=params,
|
||||||
|
timeout=500
|
||||||
|
)
|
||||||
|
resp = json.dumps(resp.json()) #这里模拟hc.request返回的结果写后续逻辑
|
||||||
|
debug(f'{type(resp)=}->{resp=}')
|
||||||
|
debug(f"pcapi返回值: {json.loads(resp)=}")
|
||||||
|
data = json.loads(resp).get('data')
|
||||||
|
if json.loads(resp).get("status") == True:
|
||||||
|
node_ns = {
|
||||||
|
'id':nodeid,
|
||||||
|
'node_status':'1',
|
||||||
|
'clusterid':clusterid,
|
||||||
|
'cpcid':cpcid
|
||||||
|
}
|
||||||
|
debug(f"更新新增工作节点元数据 {node_ns=}")
|
||||||
|
await sor.U('cpcnode', node_ns)
|
||||||
|
return UiMessage(title='new cluster', message='操作成功!')
|
||||||
|
else:
|
||||||
|
return UiError(title='new cluster', message='failed')
|
||||||
|
|
||||||
|
return UiError(title='new cluster', message='uncatched error')
|
||||||
33
wwwroot/cpcworker/new_worker.ui
Normal file
33
wwwroot/cpcworker/new_worker.ui
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"Form",
|
||||||
|
"options":{
|
||||||
|
"title":"新增工作节点",
|
||||||
|
"description":"为算力中心的kubernetes集群新增工作节点,目前支持kubernetes工作模式",
|
||||||
|
"fields":[
|
||||||
|
{
|
||||||
|
"name":"clusterid",
|
||||||
|
"value":"{{params_kw.id}}",
|
||||||
|
"uitype":"hide"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"worker_nodeid",
|
||||||
|
"label":"请选择安装工作模式的节点",
|
||||||
|
"uitype":"code",
|
||||||
|
"textField":"ip",
|
||||||
|
"valueField":"id",
|
||||||
|
"dataurl":"{{entire_url('get_availableworker.dspy')}}?clusterid={{params_kw.id}}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"submit",
|
||||||
|
"actiontype":"urlwidget",
|
||||||
|
"target":"PopupWindow",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('new_cpcworker.dspy')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
32
wwwroot/cpcworker/update_cpcworker.dspy
Normal file
32
wwwroot/cpcworker/update_cpcworker.dspy
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
ns = params_kw.copy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
db = DBPools()
|
||||||
|
dbname = await rfexe('get_module_dbname', 'cpcc')
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
r = await sor.U('cpccluster', ns)
|
||||||
|
debug('update success');
|
||||||
|
return {
|
||||||
|
"widgettype":"Message",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Success",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"ok"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype":"Error",
|
||||||
|
"options":{
|
||||||
|
"title":"Update Error",
|
||||||
|
"cwidth":16,
|
||||||
|
"cheight":9,
|
||||||
|
"timeout":3,
|
||||||
|
"message":"failed"
|
||||||
|
}
|
||||||
|
}
|
||||||
12
wwwroot/handy/get_cpcnodes.dspy
Normal file
12
wwwroot/handy/get_cpcnodes.dspy
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
debug(f'{params_kw=}')
|
||||||
|
db = DBPools()
|
||||||
|
dbname = get_module_dbname('cpcc')
|
||||||
|
ns = {
|
||||||
|
"cpcid":params_kw.cpcid
|
||||||
|
}
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
sql = "select * from cpcnode where cpcid=${cpcid}$ and node_status = '0'"
|
||||||
|
recs = await sor.sqlExe(sql, ns.copy())
|
||||||
|
return recs
|
||||||
|
exception(f'{sql=},{ns=}')
|
||||||
|
return []
|
||||||
97
wwwroot/handy/new_cluster.dspy
Normal file
97
wwwroot/handy/new_cluster.dspy
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# params_kw:
|
||||||
|
# cpcid
|
||||||
|
# cluster_type
|
||||||
|
# ctl_nodeid
|
||||||
|
# cluster_name
|
||||||
|
debug(f'{params_kw=}')
|
||||||
|
dbname = get_module_dbname('cpcc')
|
||||||
|
db = DBPools()
|
||||||
|
cpcid = params_kw.cpcid
|
||||||
|
nodeid = params_kw.ctl_nodeid
|
||||||
|
cluster_type = params_kw.cluster_type
|
||||||
|
cluster_name = params_kw.cluster_name
|
||||||
|
enable_date = params_kw.enable_date
|
||||||
|
export_date = params_kw.export_date
|
||||||
|
# debug(f"=====> {cluster_type=} {cluster_name=} {nodeid=} {cpcid=}")
|
||||||
|
|
||||||
|
async with db.sqlorContext(dbname) as sor:
|
||||||
|
cpcs = await sor.R('cpclist', {'id':cpcid})
|
||||||
|
if len(cpcs) < 1:
|
||||||
|
e = Exception(f'cpclist {cpcid=} not exists')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
cpc = cpcs[0]
|
||||||
|
nodes = await sor.R('cpcnode', {'id':nodeid})
|
||||||
|
# 这里有问题:没有匹配到节点信息!!!
|
||||||
|
if len(nodes) < 1:
|
||||||
|
e = Exception(f'cpcnode {nodeid=} 节点基础信息不匹配')
|
||||||
|
exception(f'{e}')
|
||||||
|
raise e
|
||||||
|
node = nodes[0]
|
||||||
|
url = cpc.pcapi_url + "/pcapi/api/v1/cluster/common/new_cluster"
|
||||||
|
debug(f"请求url: {url=}")
|
||||||
|
debug(f"目标IP认证信息: {node.ip=} {node.sshport=} {node.adminuser=} {password_decode(node.adminpwd)=}")
|
||||||
|
# 请求方式待定,取决于获取参数值方式
|
||||||
|
debug(333)
|
||||||
|
headers = basic_auth_headers('ysh', 'Kyy@123456')
|
||||||
|
debug(22)
|
||||||
|
hc = HttpClient()
|
||||||
|
print(444)
|
||||||
|
import requests
|
||||||
|
params = {
|
||||||
|
'cluster_type': cluster_type,
|
||||||
|
'host':node.ip,
|
||||||
|
'port':node.sshport,
|
||||||
|
'user':node.adminuser,
|
||||||
|
'psssword':password_decode(node.adminpwd),
|
||||||
|
'role':"master"
|
||||||
|
}
|
||||||
|
debug(f'{params=}')
|
||||||
|
debug(1111111)
|
||||||
|
#resp = await hc.request(url, method='POST',
|
||||||
|
# headers = headers,
|
||||||
|
# data=params
|
||||||
|
#)
|
||||||
|
# 框架不支持超时时间
|
||||||
|
resp = requests.post(url,
|
||||||
|
headers = headers,
|
||||||
|
data=params,
|
||||||
|
timeout=500
|
||||||
|
)
|
||||||
|
resp = json.dumps(resp.json()) #这里模拟hc.request返回的结果写后续逻辑
|
||||||
|
debug(f'{type(resp)=}->{resp=}')
|
||||||
|
debug(f"pcapi返回值: {json.loads(resp)=}")
|
||||||
|
2datas = json.loads(resp).get('data')
|
||||||
|
2datas = 2datas.split("\n")
|
||||||
|
clusterjoin = 2datas[0]
|
||||||
|
kubeconfig_context = 2datas[1]
|
||||||
|
if json.loads(resp).get("status") == True:
|
||||||
|
# new cluster info write to database
|
||||||
|
# update node_status to '1' cpcnode record identify by ctl_nodeid ctl_node
|
||||||
|
clusterid = uuid()
|
||||||
|
ns = {
|
||||||
|
'id':clusterid,
|
||||||
|
'clustertype':cluster_type,
|
||||||
|
'cpcid':cpcid,
|
||||||
|
'controllerid':nodeid,
|
||||||
|
'name':cluster_name,
|
||||||
|
'enable_date':enable_date,
|
||||||
|
'export_date':export_date,
|
||||||
|
'clusterjoin':clusterjoin,
|
||||||
|
'kubeconfig':kubeconfig_context
|
||||||
|
}
|
||||||
|
debug(f"新集群元数据: {ns=}")
|
||||||
|
await sor.C('cpccluster', ns)
|
||||||
|
node_ns = {
|
||||||
|
'id':nodeid,
|
||||||
|
'node_status':'1',
|
||||||
|
'clusterid':clusterid,
|
||||||
|
'cpcid':cpcid
|
||||||
|
}
|
||||||
|
debug(f"更新控制节点元数据 {node_ns=}")
|
||||||
|
await sor.U('cpcnode', node_ns)
|
||||||
|
return UiMessage(title='new cluster', message='操作成功!\n加入集群凭证: %s' % clusterjoin)
|
||||||
|
else:
|
||||||
|
return UiError(title='new cluster', message='failed')
|
||||||
|
|
||||||
|
return UiError(title='new cluster', message='uncatched error')
|
||||||
79
wwwroot/handy/new_cluster.ui
Normal file
79
wwwroot/handy/new_cluster.ui
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"Form",
|
||||||
|
"options":{
|
||||||
|
"title":"创建集群",
|
||||||
|
"description":"为算力中心创建集群,目前支持kubernetes集群",
|
||||||
|
"fields":[
|
||||||
|
{
|
||||||
|
"name":"cpcid",
|
||||||
|
"value":"{{params_kw.id}}",
|
||||||
|
"uitype":"hide"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"cluster_type",
|
||||||
|
"label":"集群类型",
|
||||||
|
"data":[
|
||||||
|
{
|
||||||
|
"value":"0",
|
||||||
|
"text":"kubernetes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value":"1",
|
||||||
|
"text":"slurm"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"value":"0",
|
||||||
|
"uitype":"code"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cluster_name",
|
||||||
|
"title": "集群名称",
|
||||||
|
"type": "str",
|
||||||
|
"length": 90,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "str",
|
||||||
|
"datatype": "str",
|
||||||
|
"label": "集群名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"ctl_nodeid",
|
||||||
|
"label":"控制节点IP",
|
||||||
|
"uitype":"code",
|
||||||
|
"textField":"ip",
|
||||||
|
"valueField":"id",
|
||||||
|
"dataurl":"{{entire_url('get_cpcnodes.dspy')}}?cpcid={{params_kw.id}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_date",
|
||||||
|
"title": "启用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 0,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "date",
|
||||||
|
"datatype": "date",
|
||||||
|
"label": "启用日期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "export_date",
|
||||||
|
"title": "停用日期",
|
||||||
|
"type": "date",
|
||||||
|
"length": 0,
|
||||||
|
"cwidth": 18,
|
||||||
|
"uitype": "date",
|
||||||
|
"datatype": "date",
|
||||||
|
"label": "停用日期"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds":[
|
||||||
|
{
|
||||||
|
"wid":"self",
|
||||||
|
"event":"submit",
|
||||||
|
"actiontype":"urlwidget",
|
||||||
|
"target":"PopupWindow",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('new_cluster.dspy')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
27
wwwroot/index.ui
Normal file
27
wwwroot/index.ui
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"VBox",
|
||||||
|
"options":{
|
||||||
|
"width":"100%",
|
||||||
|
"height":"100%"
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('top.ui')}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('center.ui')}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('bottom.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
20
wwwroot/menu.ui
Normal file
20
wwwroot/menu.ui
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{% set roles = get_user_roles(get_user()) %}
|
||||||
|
{
|
||||||
|
"widgettype":"Menu",
|
||||||
|
"options":{
|
||||||
|
"target":"page_center",
|
||||||
|
"cwidth":10,
|
||||||
|
"items":[
|
||||||
|
{
|
||||||
|
"name":"home",
|
||||||
|
"label":"代码管理",
|
||||||
|
"url":"{{entire_url('/appbase/appcodes')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"home",
|
||||||
|
"label":"算力中心管理",
|
||||||
|
"url":"{{entire_url('cpclist')}}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
23
wwwroot/top.ui
Normal file
23
wwwroot/top.ui
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"id":"top_panel",
|
||||||
|
"widgettype":"HBox",
|
||||||
|
"options":{
|
||||||
|
"bgcolor":"#444444",
|
||||||
|
"cheight":2.5,
|
||||||
|
"color":"#eeeeee"
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('app_panel.ui')}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('/rbac/user/user_panel.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user