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

enhance: remote slack attachment #56

Merged
merged 12 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
28 changes: 25 additions & 3 deletions cmd/vela-slack/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"

"time"
Expand All @@ -24,7 +23,7 @@ import (
_ "github.com/joho/godotenv/autoload"
)

// nolint: funlen // ignore length for main
//nolint:funlen // ignore length for main
func main() {
// capture application version information
v := version.New()
Expand Down Expand Up @@ -92,6 +91,12 @@ func main() {
Name: "webhook",
Usage: "slack webhook used to post log messages to channel",
},
&cli.BoolFlag{
EnvVars: []string{"PARAMETER_REMOTE", "SLACK_REMOTE"},
FilePath: "/vela/parameters/slack/remote,/vela/secrets/slack/remote",
Name: "remote",
Usage: "if filepath is remote or not",
},

// Webhook Flags

Expand Down Expand Up @@ -289,6 +294,14 @@ func main() {
Usage: "environment variable reference for reading in repository trusted",
},

// Registry
&cli.StringFlag{
EnvVars: []string{"PARAMETER_REGISTRY", "REGISTRY_URL"},
FilePath: "/vela/parameters/slack/registry-url,/vela/secrets/slack/registry-url",
Name: "registry-url",
Usage: "registry url",
},

// Optional LDAP config flags

&cli.StringFlag{
Expand Down Expand Up @@ -321,6 +334,12 @@ func main() {
Name: "ldap-search-base",
Usage: "environment variable for enterprise LDAP search base",
},
&cli.StringFlag{
EnvVars: []string{"PARAMETER_TOKEN", "GITHUB_TOKEN"},
FilePath: "/vela/parameters/slack/token,/vela/secrets/slack/token",
Name: "token",
Usage: "github token from user",
},
}

err = app.Run(os.Args)
Expand Down Expand Up @@ -370,6 +389,7 @@ func run(c *cli.Context) error {
Text: c.String("text"),
Parse: c.String("parse"),
},
Remote: c.Bool("remote"),
Env: &Env{
BuildAuthor: c.String("build-author"),
BuildAuthorEmail: c.String("build-author-email"),
Expand All @@ -392,6 +412,7 @@ func run(c *cli.Context) error {
BuildTag: c.String("build-tag"),
BuildTitle: c.String("build-title"),
BuildWorkspace: c.String("build-workspace"),
RegistryURL: c.String("registry-url"),
RepositoryBranch: c.String("repo-branch"),
RepoBranch: c.String("repo-branch"),
RepositoryClone: c.String("repo-clone"),
Expand All @@ -410,6 +431,7 @@ func run(c *cli.Context) error {
RepoTimeout: c.Int("repo-timeout"),
RepositoryTrusted: c.String("repo-trusted"),
RepoTrusted: c.String("repo-trusted"),
Token: c.String("token"),
},
}

Expand Down Expand Up @@ -440,7 +462,7 @@ func getSAMAccountName(c *cli.Context) string {

// create LDAP client
roots := x509.NewCertPool()
caCerts, err := ioutil.ReadFile(c.String("sslcert.path"))
caCerts, err := os.ReadFile(c.String("sslcert.path"))

if err != nil {
logrus.Errorf("%s", err)
Expand Down
83 changes: 76 additions & 7 deletions cmd/vela-slack/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"io"
"os"
"regexp"
"strconv"
"strings"
"text/template"

registry "github.com/go-vela/server/compiler/registry/github"

"github.com/Masterminds/sprig/v3"
"github.com/sirupsen/logrus"
"github.com/slack-go/slack"
Expand All @@ -26,6 +28,7 @@ type (
Env *Env
Path string
WebhookMsg *slack.WebhookMessage
Remote bool
}

// Env struct represents the environment variables the Vela injects
Expand All @@ -52,6 +55,7 @@ type (
BuildTag string
BuildTitle string
BuildWorkspace string
RegistryURL string
RepositoryBranch string
RepoBranch string
RepositoryClone string
Expand All @@ -70,11 +74,17 @@ type (
RepoTimeout int
RepositoryTrusted string
RepoTrusted string
Token string
}
)

// Exec formats and runs the commands for sending a message via Slack.
func (p *Plugin) Exec() error {
var (
attachments []slack.Attachment
err error
)

logrus.Debug("running plugin with provided configuration")
claire1618 marked this conversation as resolved.
Show resolved Hide resolved

// clean up newlines that could invalidate JSON
Expand All @@ -95,8 +105,13 @@ func (p *Plugin) Exec() error {

// parse the slack message file
if len(p.Path) != 0 {
logrus.Infof("Parsing provided template file %s, ", p.Path)
attachments, err := getAttachmentFromFile(p)
logrus.Infof("Parsing provided template file, %s", p.Path)

if p.Remote {
claire1618 marked this conversation as resolved.
Show resolved Hide resolved
attachments, err = getRemoteAttachment(p)
} else {
claire1618 marked this conversation as resolved.
Show resolved Hide resolved
attachments, err = getAttachmentFromFile(p)
}

if err != nil {
return fmt.Errorf("unable to parse attachment file: %w", err)
Expand Down Expand Up @@ -201,7 +216,7 @@ func getAttachmentFromFile(p *Plugin) ([]slack.Attachment, error) {
defer jsonFile.Close()

// read the contents of the json template
bytes, err := ioutil.ReadAll(jsonFile)
bytes, err := io.ReadAll(jsonFile)
if err != nil {
return nil, fmt.Errorf("unable to read json file: %w", err)
}
Expand All @@ -219,9 +234,63 @@ func getAttachmentFromFile(p *Plugin) ([]slack.Attachment, error) {
bStr = strings.Replace(bStr, "{{ .RepositoryTimeout }}", strconv.Itoa(p.Env.RepositoryTimeout), -1)
bytes = []byte(bStr)

logrus.Info("pip")
logrus.Info(bStr)
logrus.Info("pip")
// create a variable to hold our message
var msg slack.WebhookMessage

// cast bytes to go struct
err = json.Unmarshal(bytes, &msg)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal json file: %w", err)
}

return msg.Attachments, err
}

// getRemoteAttachment function to open and parse slack attachment json file into
// slack webhook message payload.
func getRemoteAttachment(p *Plugin) ([]slack.Attachment, error) {
var (
bytes []byte
err error
)

reg, err := registry.New(p.Env.RegistryURL, p.Env.Token)
if err != nil {
return nil, err
}

// parse source from slack attachment
src, err := reg.Parse(p.Path)
if err != nil {
return nil, fmt.Errorf("invalid slack attachment source provided: %w", err)
}

logrus.WithFields(logrus.Fields{
"org": src.Org,
"repo": src.Repo,
"path": src.Name,
"host": src.Host,
}).Tracef("Using authenticated GitHub client to pull template")

// use private (authenticated) github instance to pull from
bytes, err = reg.Template(nil, src)
if err != nil {
return nil, err
}

// Converts bytes into string and replaces {{ .BuildCreated }}
// with a timestamp before returning it back into bytes again.
bStr := string(bytes)
// x := strconv.Itoa(p.Env.BuildCreated)
bStr = strings.Replace(bStr, "{{ .BuildCreated }}", strconv.Itoa(p.Env.BuildCreated), -1)
bStr = strings.Replace(bStr, "{{ .BuildEnqueued }}", strconv.Itoa(p.Env.BuildEnqueued), -1)
bStr = strings.Replace(bStr, "{{ .BuildFinished }}", strconv.Itoa(p.Env.BuildFinished), -1)
bStr = strings.Replace(bStr, "{{ .BuildNumber }}", strconv.Itoa(p.Env.BuildNumber), -1)
bStr = strings.Replace(bStr, "{{ .BuildParent }}", strconv.Itoa(p.Env.BuildParent), -1)
bStr = strings.Replace(bStr, "{{ .BuildStarted }}", strconv.Itoa(p.Env.BuildStarted), -1)
bStr = strings.Replace(bStr, "{{ .RepositoryTimeout }}", strconv.Itoa(p.Env.RepositoryTimeout), -1)
claire1618 marked this conversation as resolved.
Show resolved Hide resolved
bytes = []byte(bStr)

// create a variable to hold our message
var msg slack.WebhookMessage

Expand Down
Loading
Loading