Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions agent/app/api/v2/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,24 @@ func (b *BaseApi) GetSettingByKey(c *gin.Context) {
value := settingService.GetSettingByKey(key)
helper.SuccessWithData(c, value)
}

// @Tags System Setting
// @Summary Save common description
// @Accept json
// @Param request body dto.CommonDescription true "request"
// @Success 200
// @Security ApiKeyAuth
// @Security Timestamp
// @Router /settings/description/save [post]
func (b *BaseApi) SaveDescription(c *gin.Context) {
var req dto.CommonDescription
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}

if err := settingService.SaveDescription(req); err != nil {
helper.InternalServer(c, err)
return
}
helper.Success(c)
}
3 changes: 3 additions & 0 deletions agent/app/dto/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type ContainerInfo struct {
AppName string `json:"appName"`
AppInstallName string `json:"appInstallName"`
Websites []string `json:"websites"`

IsPinned bool `json:"isPinned"`
Description string `json:"description"`
}

type ContainerOptions struct {
Expand Down
3 changes: 3 additions & 0 deletions agent/app/dto/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ type ImageInfo struct {
IsUsed bool `json:"isUsed"`
Tags []string `json:"tags"`
Size int64 `json:"size"`

IsPinned bool `json:"isPinned"`
Description string `json:"description"`
}

type ImageLoad struct {
Expand Down
8 changes: 8 additions & 0 deletions agent/app/dto/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,11 @@ type SystemProxy struct {
User string `json:"user"`
Password string `json:"password"`
}

type CommonDescription struct {
ID string `json:"id" validate:"required"`
Type string `json:"type" validate:"required"`
DetailType string `json:"detailType"`
IsPinned bool `json:"isPinned"`
Description string `json:"description"`
}
8 changes: 8 additions & 0 deletions agent/app/model/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ type Setting struct {
About string `json:"about"`
}

type CommonDescription struct {
ID string `json:"id"`
Type string `json:"type"`
DetailType string `json:"detailType"`
IsPinned bool `json:"isPinned"`
Description string `json:"description"`
}

type NodeInfo struct {
Scope string `json:"scope"`
BaseDir string `json:"baseDir"`
Expand Down
5 changes: 5 additions & 0 deletions agent/app/repo/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ func WithByType(tp string) DBOption {
return g.Where("`type` = ?", tp)
}
}
func WithByDetailType(tp string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("`detail_type` = ?", tp)
}
}

func WithTypes(types []string) DBOption {
return func(db *gorm.DB) *gorm.DB {
Expand Down
40 changes: 40 additions & 0 deletions agent/app/repo/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
DelMonitorIO(timeForDelete time.Time) error
DelMonitorNet(timeForDelete time.Time) error
UpdateOrCreate(key, value string) error

GetDescription(opts ...DBOption) (model.CommonDescription, error)
GetDescriptionList(opts ...DBOption) ([]model.CommonDescription, error)
CreateDescription(data *model.CommonDescription) error
UpdateDescription(id string, val map[string]interface{}) error
DelDescription(id string) error
WithByDescriptionID(id string) DBOption
}

func NewISettingRepo() ISettingRepo {
Expand Down Expand Up @@ -108,3 +115,36 @@
}
return global.DB.Model(&setting).UpdateColumn("value", value).Error
}

func (s *SettingRepo) GetDescriptionList(opts ...DBOption) ([]model.CommonDescription, error) {
var lists []model.CommonDescription
db := global.DB.Model(&model.CommonDescription{})
for _, opt := range opts {
db = opt(db)
}
err := db.Find(&lists).Error
return lists, err
}
func (s *SettingRepo) GetDescription(opts ...DBOption) (model.CommonDescription, error) {
var data model.CommonDescription
db := global.DB.Model(&model.CommonDescription{})
for _, opt := range opts {
db = opt(db)
}
err := db.First(&data).Error
return data, err
}
func (s *SettingRepo) CreateDescription(data *model.CommonDescription) error {
return global.DB.Create(data).Error
}
func (s *SettingRepo) UpdateDescription(id string, val map[string]interface{}) error {
return global.DB.Model(&model.CommonDescription{}).Where("id = ?", id).Updates(val).Error

Check failure on line 141 in agent/app/repo/setting.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of duplicating this literal "id = ?" 3 times.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZq019CDyR7fdKXDJBnr&open=AZq019CDyR7fdKXDJBnr&pullRequest=11049
}
func (s *SettingRepo) DelDescription(id string) error {
return global.DB.Where("id = ?", id).Delete(&model.CommonDescription{}).Error
}
func (s *SettingRepo) WithByDescriptionID(id string) DBOption {
return func(g *gorm.DB) *gorm.DB {
return g.Where("id = ?", id)
}
}
215 changes: 118 additions & 97 deletions agent/app/service/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@
}

func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, error) {
var (
records []container.Summary
list []container.Summary
)
client, err := docker.NewDockerClient()
if err != nil {
return 0, nil, err
Expand All @@ -117,114 +113,32 @@
if err != nil {
return 0, nil, err
}
if req.ExcludeAppStore {
for _, item := range containers {
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
continue
}
list = append(list, item)
}
} else {
list = containers
}

if len(req.Name) != 0 {
length, count := len(list), 0
for count < length {
if !strings.Contains(list[count].Names[0][1:], req.Name) && !strings.Contains(list[count].Image, req.Name) {
list = append(list[:count], list[(count+1):]...)
length--
} else {
count++
}
}
}
if req.State != "all" {
length, count := len(list), 0
for count < length {
if list[count].State != req.State {
list = append(list[:count], list[(count+1):]...)
length--
} else {
count++
}
}
}
switch req.OrderBy {
case "name":
sort.Slice(list, func(i, j int) bool {
if req.Order == constant.OrderAsc {
return list[i].Names[0][1:] < list[j].Names[0][1:]
}
return list[i].Names[0][1:] > list[j].Names[0][1:]
})
default:
sort.Slice(list, func(i, j int) bool {
if req.Order == constant.OrderAsc {
return list[i].Created < list[j].Created
}
return list[i].Created > list[j].Created
})
}
records := searchWithFilter(req, containers)

total, start, end := len(list), (req.Page-1)*req.PageSize, req.Page*req.PageSize
var backData []dto.ContainerInfo
total, start, end := len(records), (req.Page-1)*req.PageSize, req.Page*req.PageSize
if start > total {
records = make([]container.Summary, 0)
backData = make([]dto.ContainerInfo, 0)
} else {
if end >= total {
end = total
}
records = list[start:end]
backData = records[start:end]
}

backDatas := make([]dto.ContainerInfo, len(records))
for i := 0; i < len(records); i++ {
item := records[i]
IsFromCompose := false
if _, ok := item.Labels[composeProjectLabel]; ok {
IsFromCompose = true
}
IsFromApp := false
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
IsFromApp = true
}

exposePorts := transPortToStr(records[i].Ports)
info := dto.ContainerInfo{
ContainerID: item.ID,
CreateTime: time.Unix(item.Created, 0).Format(constant.DateTimeLayout),
Name: item.Names[0][1:],
ImageId: strings.Split(item.ImageID, ":")[1],
ImageName: item.Image,
State: item.State,
RunTime: item.Status,
Ports: exposePorts,
IsFromApp: IsFromApp,
IsFromCompose: IsFromCompose,
SizeRw: item.SizeRw,
SizeRootFs: item.SizeRootFs,
}
install, _ := appInstallRepo.GetFirst(appInstallRepo.WithContainerName(info.Name))
for i := 0; i < len(backData); i++ {
install, _ := appInstallRepo.GetFirst(appInstallRepo.WithContainerName(backData[i].Name))
if install.ID > 0 {
info.AppInstallName = install.Name
info.AppName = install.App.Name
backData[i].AppInstallName = install.Name
backData[i].AppName = install.App.Name
websites, _ := websiteRepo.GetBy(websiteRepo.WithAppInstallId(install.ID))
for _, website := range websites {
info.Websites = append(info.Websites, website.PrimaryDomain)
}
}
backDatas[i] = info
if item.NetworkSettings != nil && len(item.NetworkSettings.Networks) > 0 {
networks := make([]string, 0, len(item.NetworkSettings.Networks))
for key := range item.NetworkSettings.Networks {
networks = append(networks, item.NetworkSettings.Networks[key].IPAddress)
backData[i].Websites = append(backData[i].Websites, website.PrimaryDomain)
}
sort.Strings(networks)
backDatas[i].Network = networks
}
}

return int64(total), backDatas, nil
return int64(total), backData, nil
}

func (u *ContainerService) List() []dto.ContainerOptions {
Expand Down Expand Up @@ -1771,3 +1685,110 @@
}
return exposedPorts
}

func searchWithFilter(req dto.PageContainer, containers []container.Summary) []dto.ContainerInfo {

Check failure on line 1689 in agent/app/service/container.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 50 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1Panel-dev_1Panel&issues=AZq019CbyR7fdKXDJBns&open=AZq019CbyR7fdKXDJBns&pullRequest=11049
var (
records []dto.ContainerInfo
list []container.Summary
)

if req.ExcludeAppStore {
for _, item := range containers {
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
continue
}
list = append(list, item)
}
} else {
list = containers
}

if len(req.Name) != 0 {
length, count := len(list), 0
for count < length {
if !strings.Contains(list[count].Names[0][1:], req.Name) && !strings.Contains(list[count].Image, req.Name) {
list = append(list[:count], list[(count+1):]...)
length--
} else {
count++
}
}
}
if req.State != "all" {
length, count := len(list), 0
for count < length {
if list[count].State != req.State {
list = append(list[:count], list[(count+1):]...)
length--
} else {
count++
}
}
}
switch req.OrderBy {
case "name":
sort.Slice(list, func(i, j int) bool {
if req.Order == constant.OrderAsc {
return list[i].Names[0][1:] < list[j].Names[0][1:]
}
return list[i].Names[0][1:] > list[j].Names[0][1:]
})
default:
sort.Slice(list, func(i, j int) bool {
if req.Order == constant.OrderAsc {
return list[i].Created < list[j].Created
}
return list[i].Created > list[j].Created
})
}
for _, item := range list {
IsFromCompose := false
if _, ok := item.Labels[composeProjectLabel]; ok {
IsFromCompose = true
}
IsFromApp := false
if created, ok := item.Labels[composeCreatedBy]; ok && created == "Apps" {
IsFromApp = true
}
exposePorts := transPortToStr(item.Ports)
info := dto.ContainerInfo{
ContainerID: item.ID,
CreateTime: time.Unix(item.Created, 0).Format(constant.DateTimeLayout),
Name: item.Names[0][1:],
Ports: exposePorts,
ImageId: strings.Split(item.ImageID, ":")[1],
ImageName: item.Image,
State: item.State,
RunTime: item.Status,
SizeRw: item.SizeRw,
SizeRootFs: item.SizeRootFs,
IsFromApp: IsFromApp,
IsFromCompose: IsFromCompose,
}
if item.NetworkSettings != nil && len(item.NetworkSettings.Networks) > 0 {
networks := make([]string, 0, len(item.NetworkSettings.Networks))
for key := range item.NetworkSettings.Networks {
networks = append(networks, item.NetworkSettings.Networks[key].IPAddress)
}
sort.Strings(networks)
info.Network = networks
}
records = append(records, info)
}
dscriptions, _ := settingRepo.GetDescriptionList(repo.WithByType("container"))
for i := 0; i < len(records); i++ {
for _, desc := range dscriptions {
if desc.ID == records[i].ContainerID {
records[i].Description = desc.Description
records[i].IsPinned = desc.IsPinned
}
}
}
sort.Slice(records, func(i, j int) bool {
if records[i].IsPinned == records[j].IsPinned {
return list[i].Created > list[j].Created
}
return records[i].IsPinned
})
return records
}
Loading
Loading