Argo CICD demo step6

很多情况下,在工作流结束之后,可能你需要通过邮件向相关用户发送通知,下面是一个例子

首先我们通过golang创建一个可以用来发送邮件的镜像

下面的golang代码接收几个参数分别是

标题、工作流的结束状态、失败的异常信息 和 提交的注释内容

另外还通过环境变量,配置了其他信息

stmp服务器地址、端口、用户名和密码、cc list、发件人等

package main

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strconv"
	"strings"

	"gopkg.in/gomail.v2"
)

func main() {
	projectname := os.Getenv("projectname")
	smtpHost := os.Getenv("smtphost")
	smtpPort, _ := strconv.Atoi(os.Getenv("smtpport")) // 端口
	smtpPass := os.Getenv("smtppass")                  // 密码
	smtpUser := os.Getenv("smtpuser")                  // 用户

	smtpCc := os.Getenv("smtpCc")

	sender := os.Getenv("sender") // 发送者

	subject := os.Getenv("subject")
	buildstatus := os.Getenv("message")
	commitidtxt := "commitid.txt"
	failures := "None"

	log.Println(len(os.Args))

	if len(os.Args) == 5 {
		subject = os.Args[1]
		buildstatus = os.Args[2]
		failures = os.Args[3]
		commitidtxt = os.Args[4]
		log.Println(subject + " " + os.Args[1])
		log.Println(buildstatus + " " + os.Args[2])
		log.Println(failures + " " + os.Args[3])
		log.Println(commitidtxt + " " + os.Args[4])
	}
	commitid, _ := exec_shell("cat " + commitidtxt)
	log.Println("commitid:" + commitid)

	git_receiver_str, _ := exec_shell("git log --no-merges --pretty=format:\"%ae\" -1 " + commitid)
	log.Println("git_receiver:" + git_receiver_str)

	comments, _ := exec_shell("git log --pretty=format:\"%s\" -1 " + commitid)
	log.Println("comments:" + comments)

	committer, _ := exec_shell("git log --pretty=format:\"%cn\" -1 " + commitid)
	log.Println("committer:" + committer)

	time, _ := exec_shell("git log --pretty=format:\"%ad\" -1 " + commitid)
	log.Println("time:" + time)

	os_receivers_str := os.Getenv("receivers")
	log.Println("os_receivers_str:" + os_receivers_str)

	receivers_str := ""
	if os_receivers_str == "" {
		receivers_str = git_receiver_str
	} else {
		receivers_str = os_receivers_str
	}

	receivers := strings.Split(receivers_str, ",")

	m := gomail.NewMessage()
	m.SetHeader("From", sender)
	m.SetHeader("To", receivers...)
	if smtpCc != "" {
		log.Println("ccs:" + smtpCc)
		ccs := strings.Split(smtpCc, ",")
		m.SetHeader("Cc", ccs...)
	}

	m.SetHeader("Subject", subject)
	m.SetBody("text/html",
		"<br/><br/>Project Name: "+projectname+
			"<br/>Build status: "+buildstatus+
			"<br/>Committer: "+committer+
			"<br/>Comments: "+comments+
			"<br/>Commitid: "+commitid+
			"<br/>Time: "+time+
			"<br/>Failures: "+failures)

	d := gomail.NewDialer(smtpHost, smtpPort, smtpUser, smtpPass)
	d.TLSConfig = &tls.Config{InsecureSkipVerify: true}

	if err := d.DialAndSend(m); err != nil {
		fmt.Println(err)
	}
}

//阻塞式的执行外部shell命令的函数,等待执行完毕并返回标准输出
func exec_shell(s string) (string, error) {
	//函数返回一个*Cmd,用于使用给出的参数执行name指定的程序
	cmd := exec.Command("/bin/bash", "-c", s)

	//读取io.Writer类型的cmd.Stdout,再通过bytes.Buffer(缓冲byte类型的缓冲器)将byte类型转化为string类型(out.String():这是bytes类型提供的接口)
	var out bytes.Buffer
	cmd.Stdout = &out

	//Run执行c包含的命令,并阻塞直到完成。  这里stdout被取出,cmd.Wait()无法正确获取stdin,stdout,stderr,则阻塞在那了
	err := cmd.Run()

	return out.String(), err
}

打包好镜像之后,可以使用下面的工作流

apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
  name: lizhegithub
  namespace: argo
spec:
  template:
    serviceAccountName: operate-workflow-sa
  dependencies:
    - name: fe-dep
      eventSourceName: lizhegithub
      eventName: lizhegitwebhook
  triggers:
    - template:
        name: lizhe-workflow-trigger
        argoWorkflow:
          group: argoproj.io
          version: v1alpha1
          resource: workflows
          operation: submit
          source:
            resource:
              apiVersion: argoproj.io/v1alpha1
              kind: WorkflowTemplate
              metadata:
                generateName: lizhebuildkit-
                namespace: argo
              spec:
                templates:
                  - name: main
                    dag:
                      tasks:
                        - name: clean
                          template: clean
                          arguments: {}
                        - name: clone
                          template: clone
                          arguments:
                            parameters:
                              - name: repo
                                value: '{{workflow.parameters.repo}}'
                              - name: branch
                                value: '{{workflow.parameters.branch}}'
                          depends: clean
                        - name: getcommitid
                          template: getcommitid
                          arguments: {}
                          depends: clone
                        - name: mountcommitid
                          template: mountcommitid
                          arguments: {}
                          depends: getcommitid
                        - name: build
                          template: build
                          arguments: {}
                          depends: mountcommitid
                        - name: image
                          template: image
                          arguments:
                            parameters:
                              - name: image
                                value: '{{workflow.parameters.image}}'
                              - name: commitid
                                value: '{{tasks.mountcommitid.outputs.parameters.commitid}}'
                          depends: build
                        - name: deploy
                          template: deploy
                          arguments: {}
                          depends: image
                          onExit: deploy-exit-handler  
                  - name: clean
                    container:
                      name: ''
                      image: k8s.gcr.io/busybox
                      command:
                        - /bin/sh
                      args:
                        - '-c'
                        - 'rm -rf /work/*'
                      workingDir: /work
                      volumeMounts:
                        - name: work
                          mountPath: /work
                  - name: clone
                    inputs:
                      artifacts:
                      - name: argo-source
                        path: /src
                        git:
                          repo: '{{workflow.parameters.repo}}'
                          revision: '{{workflow.parameters.branch}}'
                          usernameSecret:
                            name: github-creds
                            key: username
                          passwordSecret:
                            name: github-creds
                            key: password
                    container:
                      image: k8s.gcr.io/busybox
                      command:
                        - /bin/sh
                      args:
                        - '-c'
                        - cp -rf /src/. /work/ && ls /work
                      workingDir: /src
                      volumeMounts:
                        - name: work
                          mountPath: /work
                  - name: getcommitid
                    inputs: {}
                    outputs: {}
                    metadata: {}
                    container:
                      name: ''
                      image: libaibai/getcommitid
                      command:
                        - /bin/bash
                      args:
                        - '-c'
                        - /getcommitid.sh
                      workingDir: /work
                      volumeMounts:
                        - name: work
                          mountPath: /work
                  - name: mountcommitid
                    outputs:
                      parameters:
                        - name: commitid
                          valueFrom:
                            path: /work/commitid.txt
                            default: mockup_commitid
                    metadata: {}
                    container:
                      name: ''
                      image: k8s.gcr.io/busybox
                      command:
                        - /bin/sh
                      args:
                        - '-c'
                        - ls /work
                      workingDir: /work
                      resources: {}
                      volumeMounts:
                        - name: work
                          mountPath: /work
                  - name: build
                    container:
                      name: ''
                      image: 'node-alpine-3.13'
                      command:
                        - sh
                      args:
                        - -c
                        - 'yarn install && yarn build-storybook'
                      workingDir: /work/packages/components
                      env:
                        - name: ENVTEST
                          value: helloworld
                      volumeMounts:
                        - name: work
                          mountPath: /work
                  - name: image
                    inputs:
                      parameters:
                        - name: image
                        - name: commitid
                    container:
                      name: ''
                      image: gcr.io/kaniko-project/executor@sha256:f652f28537fa76e8f4f9393de13a064f0206003c451ce2ad6e4359fd5a21acbc
                      args:
                        - '-f'
                        - /work/packages/components/Dockerfile
                        - '-c'
                        - /work/packages/components
                        - --destination={{inputs.parameters.image}}:{{inputs.parameters.commitid}}
                      workingDir: /work
                      env:
                        - name: envkey
                          value: envvalue
                      resources: {}
                      volumeMounts:
                      - name: docker-config
                        mountPath: /kaniko/.docker/
                      - name: aws-secret
                        mountPath: /root/.aws/
                      - name: work
                        mountPath: /work
                    volumes:
                    - name: docker-config
                      configMap:
                        name: docker-config
                    - name: aws-secret
                      secret:
                        secretName: aws-secret
                  - name: deploy
                    container:
                      name: ''
                      image: 'libaibai/sedcommitid:latest'
                      command:
                        - /main.sh
                      args:
                        - weblizheponents/weblizheponents_dep.yaml
                      workingDir: /
                      env:
                        - name: GIT_URL
                          valueFrom:
                            secretKeyRef:
                              key: lizhe
                              name: giturl
                        - name: REPO
                          value: devops
                        - name: BRANCH
                          value: main
                        - name: USER_NAME
                          value: lizhe
                        - name: USER_EMAIL
                          value: xxxxx@email.com
                      volumeMounts:
                        - name: work
                          mountPath: /work
                  - name: deploy-exit-handler
                    container:
                      image: docker/whalesay
                      command: [cowsay]
                      args: ["task cleanup"]
                  - name: exit-handler
                    container:
                      image: xxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/mailsender
                      command:
                        - /bin/bash
                      args: 
                      - -c
                      - "/main {{workflow.name}} {{workflow.status}} {{workflow.failures}} /work/commitid.txt"
                      workingDir: /work
                      env:
                        - name: projectname
                          value: YOURPROJECTNAME
                        - name: smtppass
                          valueFrom:
                            secretKeyRef:
                              key: password
                              name: smtpaccount
                        - name: smtpuser
                          valueFrom:
                            secretKeyRef:
                              key: username
                              name: smtpaccount
                        - name: smtphost
                          value: smtp.gmail.com
                        - name: smtpport
                          value: "587"
                        - name: sender
                          value: sender@email.com
                        - name: smtpCc
                          value: xxx@email.com,xxxx@email.com
                        - name: subject
                          value: mockup_subject
                        - name: body
                          value: mockup_body
                      volumeMounts:
                        - name: work
                          mountPath: /work
                entrypoint: main 
                onExit: exit-handler  
                imagePullSecrets:
                - name: regcred
                arguments:
                  parameters:
                    - name: repo
                      value: https://github.com/xxxxx/xxxxxx.git
                    - name: branch
                      value: develop
                    - name: image
                      value: xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/weblizheponents
                volumeClaimTemplates:
                  - metadata:
                      name: work
                      creationTimestamp: null
                    spec:
                      accessModes:
                        - ReadWriteOnce
                      resources:
                        requests:
                          storage: 2Gi
                      storageClassName: gp2
                    status: {}
                ttlStrategy:
                  secondsAfterCompletion: 1800
                  secondsAfterSuccess: 1800
                  secondsAfterFailure: 1800
Send a Message