Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 模板文件支持 Helm 语法模式 #3494

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
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)
}
35 changes: 35 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,18 @@ func (t *TemplateAction) PreviewTemplateFile(ctx context.Context, req *clusterRe
return nil, err
}

// helm 语法模式 模板文件内容进行helm template 渲染, 简单语法模式自动跳过
content, errRender := renderHelmTemplate(templates, req.GetValues())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

非 helm 语法模式为什么也要用 helm 渲染

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)
if _, ok := content[helmPath]; ok {
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 +598,18 @@ 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)
if _, ok := content[helmPath]; ok {
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
Loading