Skip to content

Commit

Permalink
feat: 模板文件支持 Helm 语法模式
Browse files Browse the repository at this point in the history
  • Loading branch information
LidolLxf committed Sep 20, 2024
1 parent c35a091 commit fce11ff
Show file tree
Hide file tree
Showing 10 changed files with 2,965 additions and 2,800 deletions.
2 changes: 2 additions & 0 deletions bcs-services/cluster-resources/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ require (
require (
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
Expand All @@ -247,6 +248,7 @@ require (
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-redis/redis/extra/rediscmd/v8 v8.11.5 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/golang-migrate/migrate/v4 v4.17.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/btree v1.0.1 // indirect
Expand Down
45 changes: 45 additions & 0 deletions bcs-services/cluster-resources/pkg/action/template/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ import (
"context"
"encoding/json"
"fmt"
"path"
"regexp"
"strings"

"gopkg.in/yaml.v2"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/engine"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"

res "github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource"
cli "github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/client"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/constants"
resCsts "github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/constants"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/store/entity"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/util/mapx"
Expand Down Expand Up @@ -238,3 +241,45 @@ func pruneResource(m map[string]interface{}) map[string]interface{} {

return m
}

// 校验chart helm语法是否正确,并自动填充Helm模板内容
func validAndFillChart(cht *chart.Chart, value string) (map[string]string, error) {
var m map[string]interface{}
err := yaml.Unmarshal([]byte(value), &m)
if err != nil {
return nil, err
}

var options chartutil.ReleaseOptions
valuesToRender, err := chartutil.ToRenderValues(cht, m, options, nil)
if err != nil {
return nil, err
}
var e engine.Engine
e.LintMode = true
result, err := e.Render(cht, valuesToRender)
if err != nil {
return nil, err
}
return result, nil
}

// 模板文件内容进行helm template 渲染
func renderHelmTemplate(td []entity.TemplateDeploy, value string) (map[string]string, error) {
cht := chart.Chart{
Raw: []*chart.File{},
Metadata: &chart.Metadata{},
Templates: []*chart.File{},
}

for _, v := range td {
// helm 模式才转
if v.RenderMode == string(constants.HelmRenderMode) {
cht.Templates = append(cht.Templates, &chart.File{
Name: path.Join(v.TemplateSpace, v.TemplateName),
Data: []byte(v.Content),
})
}
}
return validAndFillChart(&cht, value)
}
31 changes: 31 additions & 0 deletions bcs-services/cluster-resources/pkg/action/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package template

import (
"context"
"path"

"github.com/Tencent/bk-bcs/bcs-common/pkg/odm/operator"
"gopkg.in/yaml.v2"
Expand All @@ -32,6 +33,7 @@ import (
projectAuth "github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/iam/perm/resource/project"
res "github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource"
cli "github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/client"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/constants"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/form/parser"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/perm"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/store"
Expand Down Expand Up @@ -250,6 +252,7 @@ func (t *TemplateAction) Create(ctx context.Context, req *clusterRes.CreateTempl
// 非草稿状态下:创建模板文件版本
versionID := ""
if !req.GetIsDraft() {
renderMode := constants.RenderMode(req.GetRenderMode())
// 创建顺序:templateVersion -> template
templateVersion := &entity.TemplateVersion{
ProjectCode: p.Code,
Expand All @@ -260,6 +263,7 @@ func (t *TemplateAction) Create(ctx context.Context, req *clusterRes.CreateTempl
EditFormat: req.GetEditFormat(),
Content: req.GetContent(),
Creator: userName,
RenderMode: renderMode.GetRenderMode(),
}
versionID, err = t.model.CreateTemplateVersion(ctx, templateVersion)
if err != nil {
Expand Down Expand Up @@ -418,6 +422,12 @@ func (t *TemplateAction) CreateTemplateSet(ctx context.Context, req *clusterRes.
// 组装 chart
cht := buildChart(tmps, req, ctxkey.GetUsernameFromCtx(ctx))

// 校验chart helm语法是否正确
_, err = validAndFillChart(cht, req.GetValues())
if err != nil {
return err
}

// 上传 chart
err = helm.UploadChart(ctx, cht, p.Code, req.GetVersion(), req.GetForce())
if err != nil {
Expand All @@ -442,6 +452,7 @@ func getTemplateContents(ctx context.Context, model store.ClusterResourcesModel,
TemplateName: vv.TemplateName,
TemplateVersion: vv.Version,
Content: vv.Content,
RenderMode: vv.RenderMode,
})
}
return templates, nil
Expand Down Expand Up @@ -517,6 +528,16 @@ func (t *TemplateAction) PreviewTemplateFile(ctx context.Context, req *clusterRe
return nil, err
}

// helm 语法模式 模板文件内容进行helm template 渲染
content, errRender := renderHelmTemplate(templates, req.GetValues())
if errRender != nil {
return map[string]interface{}{"items": []string{}, "error": errRender.Error()}, nil
}
for k, v := range templates {
helmPath := path.Join(v.TemplateSpace, v.TemplateName)
templates[k].Content = content[helmPath]
}

// render templates
manifests, err := t.renderTemplates(ctx, templates, req.GetVariables(), req.GetNamespace())
if err != nil {
Expand Down Expand Up @@ -575,6 +596,16 @@ func (t *TemplateAction) DeployTemplateFile(ctx context.Context, req *clusterRes
return nil, err
}

// helm 语法模式 模板文件内容进行helm template 渲染
content, errRender := renderHelmTemplate(templates, req.GetValues())
if errRender != nil {
return map[string]interface{}{"items": []string{}, "error": errRender.Error()}, nil
}
for k, v := range templates {
helmPath := path.Join(v.TemplateSpace, v.TemplateName)
templates[k].Content = content[helmPath]
}

// render templates
manifests, err := t.renderTemplates(ctx, templates, req.GetVariables(), req.GetNamespace())
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/i18n"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/iam"
projectAuth "github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/iam/perm/resource/project"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/constants"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/resource/form/parser"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/store"
"github.com/Tencent/bk-bcs/bcs-services/cluster-resources/pkg/store/entity"
Expand Down Expand Up @@ -212,6 +213,7 @@ func (t *TemplateVersionAction) Create(ctx context.Context, req *clusterRes.Crea
}

userName := ctxkey.GetUsernameFromCtx(ctx)
renderMode := constants.RenderMode(req.GetRenderMode())
if len(templateVersions) > 0 {
// 版本存在且不允许覆盖的情况下直接返回
if !req.GetForce() {
Expand All @@ -224,6 +226,7 @@ func (t *TemplateVersionAction) Create(ctx context.Context, req *clusterRes.Crea
"version": req.GetVersion(),
"content": req.GetContent(),
"creator": userName,
"renderMode": renderMode.GetRenderMode(),
}
if err = t.model.UpdateTemplateVersion(ctx, templateVersions[0].ID.Hex(), updateTemplateVersion); err != nil {
return "", err
Expand All @@ -241,6 +244,7 @@ func (t *TemplateVersionAction) Create(ctx context.Context, req *clusterRes.Crea
EditFormat: req.GetEditFormat(),
Content: req.GetContent(),
Creator: userName,
RenderMode: renderMode.GetRenderMode(),
}
id, err := t.model.CreateTemplateVersion(ctx, templateVersion)
if err != nil {
Expand Down
18 changes: 18 additions & 0 deletions bcs-services/cluster-resources/pkg/resource/constants/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,21 @@ func GetResourceAttr(resource string) string {
}
return resource
}

// RenderMode 模板文件语法模式
type RenderMode string

const (
// HelmRenderMode helm 语法模式
HelmRenderMode RenderMode = "Helm"
// SimpleRenderMode 单一语法模式,默认
SimpleRenderMode RenderMode = "Simple"
)

// GetRenderMode 获取模板文件语法模式
func (r RenderMode) GetRenderMode() string {
if r == HelmRenderMode {
return string(HelmRenderMode)
}
return string(SimpleRenderMode)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type TemplateVersion struct {
Content string `json:"content" bson:"content"`
Creator string `json:"creator" bson:"creator"`
CreateAt int64 `json:"createAt" bson:"createAt"`
RenderMode string `json:"renderMode" bson:"renderMode"`
Latest bool `json:"latest" bson:"-"` // 是否是最新版本,不存储在数据库
Draft bool `json:"draft" bson:"-"`
}
Expand All @@ -53,6 +54,7 @@ func (t *TemplateVersion) ToMap() map[string]interface{} {
m["content"] = t.Content
m["creator"] = t.Creator
m["createAt"] = t.CreateAt
m["renderMode"] = t.RenderMode
m["latest"] = t.Latest
m["draft"] = t.Draft
return m
Expand Down Expand Up @@ -93,4 +95,5 @@ type TemplateDeploy struct {
TemplateName string `json:"templateName"`
TemplateVersion string `json:"templateVersion"`
Content string `json:"content"`
RenderMode string `json:"renderMode"`
}
Loading

0 comments on commit fce11ff

Please sign in to comment.