cube-studio/myapp/views/view_images.py

228 lines
7.5 KiB
Python
Raw Normal View History

2021-08-17 17:00:34 +08:00
from flask import render_template,redirect
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder import ModelView, ModelRestApi
from flask_appbuilder import ModelView,AppBuilder,expose,BaseView,has_access
from importlib import reload
from flask_babel import gettext as __
from flask_babel import lazy_gettext as _
from flask_appbuilder.forms import GeneralModelConverter
import uuid
import re
from kfp import compiler
from sqlalchemy.exc import InvalidRequestError
from myapp.models.model_job import Repository,Images
from myapp.views.view_team import Project_Filter
from myapp import app, appbuilder,db,event_logger
2022-08-04 14:58:08 +08:00
from wtforms.validators import DataRequired, Length, NumberRange, Optional,Regexp
2021-08-17 17:00:34 +08:00
from wtforms import BooleanField, IntegerField,StringField, SelectField,FloatField,DateField,DateTimeField,SelectMultipleField,FormField,FieldList
from flask_appbuilder.fieldwidgets import BS3TextFieldWidget,BS3PasswordFieldWidget,DatePickerWidget,DateTimePickerWidget,Select2ManyWidget,Select2Widget
from myapp.forms import MyBS3TextAreaFieldWidget,MySelect2Widget,MyCodeArea,MyLineSeparatedListField,MyJSONField,MyBS3TextFieldWidget,MySelectMultipleField
from .baseApi import (
MyappModelRestApi
)
from flask import (
current_app,
abort,
flash,
g,
Markup,
make_response,
redirect,
render_template,
request,
send_from_directory,
Response,
url_for,
)
from myapp import security_manager
from werkzeug.datastructures import FileStorage
from .base import (
api,
BaseMyappView,
check_ownership,
data_payload_response,
DeleteMixin,
generate_download_headers,
get_error_msg,
get_user_roles,
handle_api_exception,
json_error_response,
json_success,
MyappFilter,
MyappModelView,
)
from flask_appbuilder import CompactCRUDMixin, expose
import pysnooper,datetime,time,json
conf = app.config
logging = app.logger
2022-08-08 20:11:53 +08:00
2021-08-17 17:00:34 +08:00
class Repository_ModelView_Base():
datamodel = SQLAInterface(Repository)
label_title='仓库'
check_redirect_list_url = conf.get('MODEL_URLS',{}).get('repository','')
2022-08-08 20:11:53 +08:00
base_permissions = ['can_add', 'can_edit', 'can_delete', 'can_list', 'can_show']
2021-08-17 17:00:34 +08:00
base_order = ('id', 'desc')
order_columns = ['id']
list_columns = ['name','hubsecret','creator','modified']
cols_width = {
"name":{"type": "ellip2", "width": 250},
"hubsecret": {"type": "ellip2", "width": 250},
}
2021-08-17 17:00:34 +08:00
show_exclude_columns = ['password']
add_columns = ['name','server','user','password','hubsecret']
edit_columns = add_columns
add_form_extra_fields = {
2022-08-04 14:58:08 +08:00
"server": StringField(
_(datamodel.obj.lab('server')),
widget=BS3TextFieldWidget(),
default='harbor.oa.com',
description="镜像仓库服务地址"
),
"user": StringField(
_(datamodel.obj.lab('user')),
2022-08-16 11:09:52 +08:00
default='',
2022-08-04 14:58:08 +08:00
widget=BS3TextFieldWidget(),
description="镜像仓库的用户名"
),
2021-08-17 17:00:34 +08:00
"password": StringField(
_(datamodel.obj.lab('password')),
2022-08-16 11:09:52 +08:00
default='',
2022-08-04 14:58:08 +08:00
widget=BS3TextFieldWidget(),
description="镜像仓库的链接密码"
2021-08-17 17:00:34 +08:00
)
}
2022-07-26 20:47:49 +08:00
2021-08-17 17:00:34 +08:00
edit_form_extra_fields = add_form_extra_fields
# @pysnooper.snoop()
def set_column(self):
self.add_form_extra_fields['name'] = StringField(
_(self.datamodel.obj.lab('name')),
default=g.user.username+"-",
2022-08-08 20:11:53 +08:00
widget=BS3TextFieldWidget(),
2022-08-04 14:58:08 +08:00
description = "仓库名称"
2021-08-17 17:00:34 +08:00
)
self.add_form_extra_fields['hubsecret'] = StringField(
_(self.datamodel.obj.lab('hubsecret')),
2022-08-04 14:58:08 +08:00
default=g.user.username + "-hubsecret",
2022-08-08 20:11:53 +08:00
widget=BS3TextFieldWidget(),
2022-08-04 14:58:08 +08:00
description="在k8s中创建的hub secret",
validators=[Regexp("^[a-z][a-z0-9\-]*[a-z0-9]$"), Length(1, 54),DataRequired()]
2021-08-17 17:00:34 +08:00
)
pre_add_get = set_column
2022-08-08 20:11:53 +08:00
# create hubsecret
2021-09-07 18:09:47 +08:00
# @pysnooper.snoop()
2021-08-17 17:00:34 +08:00
def apply_hubsecret(self,hubsecret):
from myapp.utils.py.py_k8s import K8s
all_cluster=conf.get('CLUSTERS',{})
2022-05-27 11:50:05 +08:00
all_kubeconfig = [all_cluster[cluster].get('KUBECONFIG','') for cluster in all_cluster]+['']
2021-08-17 17:00:34 +08:00
all_kubeconfig = list(set(all_kubeconfig))
for kubeconfig in all_kubeconfig:
k8s = K8s(kubeconfig)
namespaces = conf.get('HUBSECRET_NAMESPACE')
for namespace in namespaces:
k8s.apply_hubsecret(namespace=namespace,
name=hubsecret.hubsecret,
user=hubsecret.user,
password=hubsecret.password,
server=hubsecret.server
)
def post_add(self, item):
self.apply_hubsecret(item)
def post_update(self, item):
self.apply_hubsecret(item)
# class Repository_ModelView(Repository_ModelView_Base,MyappModelView,DeleteMixin):
# datamodel = SQLAInterface(Repository)
#
# appbuilder.add_view(Repository_ModelView,"仓库",icon = 'fa-shopping-basket',category = '训练',category_icon = 'fa-sitemap')
2021-08-17 17:00:34 +08:00
2022-08-08 20:11:53 +08:00
2021-08-17 17:00:34 +08:00
class Repository_ModelView_Api(Repository_ModelView_Base,MyappModelRestApi):
datamodel = SQLAInterface(Repository)
route_base = '/repository_modelview/api'
appbuilder.add_api(Repository_ModelView_Api)
2021-09-07 18:09:47 +08:00
2021-08-17 17:00:34 +08:00
# 只能查看到自己归属的项目组的镜像
class Images_Filter(MyappFilter):
# @pysnooper.snoop(watch_explode=('result'))
def apply(self, query, func):
user_roles = [role.name.lower() for role in list(self.get_user_roles())]
if "admin" in user_roles:
2022-08-16 11:09:52 +08:00
return query.order_by(self.model.id.desc())
2021-08-17 17:00:34 +08:00
result = query.order_by(self.model.id.desc())
return result
class Images_ModelView_Base():
label_title='镜像'
datamodel = SQLAInterface(Images)
check_redirect_list_url = conf.get('MODEL_URLS',{}).get('images','')
2021-08-17 17:00:34 +08:00
list_columns = ['images_url','creator','modified']
cols_width = {
"images_url":{"type": "ellip2", "width": 500},
}
2021-08-17 17:00:34 +08:00
base_order = ('id', 'desc')
order_columns = ['id']
2021-09-07 18:09:47 +08:00
add_columns = ['repository', 'name', 'describe', 'dockerfile', 'gitpath']
2021-08-17 17:00:34 +08:00
edit_columns = add_columns
add_form_extra_fields = {
"dockerfile": StringField(
_(datamodel.obj.lab('dockerfile')),
description='镜像的构建Dockerfile全部内容',
2022-08-16 11:09:52 +08:00
default='',
2022-08-08 20:11:53 +08:00
widget=MyBS3TextAreaFieldWidget(rows=10),
2021-08-17 17:00:34 +08:00
),
"name": StringField(
_(datamodel.obj.lab('name')),
description='镜像名称全称例如ubuntu:20.04',
2022-08-16 11:09:52 +08:00
default='',
2022-08-08 20:11:53 +08:00
widget=BS3TextFieldWidget(),
2021-08-17 17:00:34 +08:00
),
"entrypoint": StringField(
_(datamodel.obj.lab('entrypoint')),
description='镜像的入口命令直接写成单行字符串例如python xx.py无需添加[]',
2022-08-16 11:09:52 +08:00
default='',
2022-08-08 20:11:53 +08:00
widget=BS3TextFieldWidget(),
2021-08-17 17:00:34 +08:00
)
}
edit_form_extra_fields = add_form_extra_fields
2022-08-08 20:11:53 +08:00
base_filters = [["id", Images_Filter, lambda: []]]
2021-08-17 17:00:34 +08:00
class Images_ModelView(Images_ModelView_Base,MyappModelView,DeleteMixin):
datamodel = SQLAInterface(Images)
2022-02-26 22:36:57 +08:00
appbuilder.add_view(Images_ModelView,"模板镜像",href="/images_modelview/list/?_flt_2_name=",icon = 'fa-file-image-o',category = '训练')
2021-08-17 17:00:34 +08:00
class Images_ModelView_Api(Images_ModelView_Base,MyappModelRestApi):
datamodel = SQLAInterface(Images)
route_base = '/images_modelview/api'
list_columns = ['images_url', 'modified','creator']
2021-08-17 17:00:34 +08:00
appbuilder.add_api(Images_ModelView_Api)