Browse Source

完成基本审批节点和流程

yjp 1 year ago
parent
commit
f76843aff4
5 changed files with 126 additions and 26 deletions
  1. 52 19
      approve_former/flow.go
  2. 7 3
      approve_former/node.go
  3. 64 0
      approve_former/sign.go
  4. 0 3
      approve_former/single.go
  5. 3 1
      test/approve_former_test.go

+ 52 - 19
approve_former/flow.go

@@ -1,21 +1,25 @@
 package approve_former
 
+import "strings"
+
 const flowTemplate = `apiVersion: argoproj.io/v1alpha1
 kind: WorkflowTemplate
 metadata:
-  name: {{ .name }}
+  name: [[ .name ]]
 spec:
   entrypoint: approve-flow
   templates:
     - name: approve-flow
       dag:
         tasks:
-          {{- if .nodeContent }}
-          {{ .nodeContent }}
-          {{- else }}
+          [[- if .childNodesContentLines ]]
+          [[- range .childNodesContentLines ]]
+          [[ . ]]
+          [[- end ]]
+          [[- else ]]
           - name: node
             template: approval
-          {{- end }}
+          [[- end ]]
           
     - name: approval
       suspend: {}
@@ -34,30 +38,59 @@ spec:
 `
 
 type Flow struct {
-	Name  string
-	Nodes []Node
+	Name       string
+	ChildNodes []Node
 }
 
-func NewFlow(name string, nodes ...Node) *Flow {
+func NewFlow(name string, childNodes ...Node) *Flow {
 	return &Flow{
-		Name:  name,
-		Nodes: nodes,
+		Name:       name,
+		ChildNodes: childNodes,
 	}
 }
 
-func (flow *Flow) Render() (string, error) {
-	nodeContents := make([]string, 0)
-	for _, node := range flow.Nodes {
-		nodeContent, err := node.Render()
-		if err != nil {
-			return "", err
+func (flow *Flow) GetName() string {
+	return flow.Name
+}
+
+func (flow *Flow) GetChildNodes() []Node {
+	return flow.ChildNodes
+}
+
+func (flow *Flow) Render(_ ...Node) (string, error) {
+	childNodesContents := make([]string, 0)
+	for i, childNode := range flow.ChildNodes {
+		var childNodeContent string
+
+		if i == 0 {
+			content, err := childNode.Render()
+			if err != nil {
+				return "", err
+			}
+
+			childNodeContent = content
+		} else {
+			upperNodes := make([]Node, 0)
+			upperChildNodes := flow.ChildNodes[i-1].GetChildNodes()
+			if len(upperChildNodes) == 0 {
+				upperNodes = append(upperNodes, flow.ChildNodes[i-1])
+			} else {
+				upperNodes = append(upperNodes, upperChildNodes...)
+			}
+
+			content, err := childNode.Render(upperNodes...)
+			if err != nil {
+				return "", err
+			}
+
+			childNodeContent = content
 		}
 
-		nodeContents = append(nodeContents, nodeContent)
+		childNodesContents = append(childNodesContents, strings.Split(childNodeContent, "\n")...)
 	}
 
 	return render("flow", flowTemplate, map[string]any{
-		"name":  flow.Name,
-		"nodes": nodeContents,
+		"name":                   flow.Name,
+		"childNodesContentLines": childNodesContents,
 	})
 }

+ 7 - 3
approve_former/node.go

@@ -2,25 +2,29 @@ package approve_former
 
 import (
 	"bytes"
+	"github.com/pkg/errors"
 	"text/template"
 )
 
 type Node interface {
-	Render() (string, error)
+	GetName() string
+	GetChildNodes() []Node
+	Render(upperNodes ...Node) (string, error)
 }
 
 func render(name string, templateStr string, templateParams map[string]any) (string, error) {
 	tpl := template.New(name)
+	tpl.Delims("[[", "]]")
 
 	tpl, err := tpl.Parse(templateStr)
 	if err != nil {
-		return "", err
+		return "", errors.New(err.Error())
 	}
 
 	buffer := &bytes.Buffer{}
 	err = tpl.Execute(buffer, templateParams)
 	if err != nil {
-		return "", err
+		return "", errors.New(err.Error())
 	}
 
 	return buffer.String(), nil

+ 64 - 0
approve_former/sign.go

@@ -0,0 +1,64 @@
+package approve_former
+
+const signTemplate = `
+[[- $name := .name -]]
+[[- $upperNodeNames := .upper_node_names -]]
+
+- name: [[ $name ]]
+  template: approval
+  [[- if $upperNodeNames ]]
+  [[- if eq (len $upperNodeNames) 1 ]]
+  depends: "[[ index $upperNodeNames 0 ]].Succeeded"
+  when: "{{ tasks.[[- index $upperNodeNames 0 -]].outputs.parameters.approve }} == 通过"
+  [[- else -]]
+  depends: "
+  [[- range $index, $upper_node_name := $upperNodeNames -]]
+  [[- if eq $index 0 -]]
+  [[ $upper_node_name ]].Succeeded
+  [[- else ]]
+   && [[ $upper_node_name ]].Succeeded
+  [[- end -]]
+  [[- end -]]
+  "
+  when: "
+  [[- range $index, $upper_node_name := $upperNodeNames -]]
+  [[- if eq $index 0 -]]
+  {{ tasks.[[ $upper_node_name ]].outputs.parameters.approve }} == 通过
+  [[- else -]]
+   && {{ tasks.[[ $upper_node_name ]].outputs.parameters.approve }} == 通过
+  [[- end -]]
+  [[- end -]]
+  "
+  [[- end -]]
+  [[- end -]]
+`
+
+type Sign struct {
+	Name string
+}
+
+func NewSign(name string) *Sign {
+	return &Sign{
+		Name: name,
+	}
+}
+
+func (sign *Sign) GetName() string {
+	return sign.Name
+}
+
+func (sign *Sign) GetChildNodes() []Node {
+	return make([]Node, 0)
+}
+
+func (sign *Sign) Render(upperNodes ...Node) (string, error) {
+	upperNodeNames := make([]string, 0)
+	for _, upperNode := range upperNodes {
+		upperNodeNames = append(upperNodeNames, upperNode.GetName())
+	}
+
+	return render("sign", signTemplate, map[string]any{
+		"name":             sign.Name,
+		"upper_node_names": upperNodeNames,
+	})
+}

+ 0 - 3
approve_former/single.go

@@ -1,3 +0,0 @@
-package approve_former
-
-const singleTemplate = ``

+ 3 - 1
test/approve_former_test.go

@@ -7,7 +7,9 @@ import (
 )
 
 func TestApproveFormer(t *testing.T) {
-	flow := approve_former.NewFlow("test")
+	flow := approve_former.NewFlow("flow",
+		approve_former.NewSign("sign1"),
+		approve_former.NewSign("sign2"))
 
 	flowDefinition, err := flow.Render()
 	if err != nil {