Skip to content
This repository has been archived by the owner on May 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #81 from rcousineau-xandr/notify-chart-version
Browse files Browse the repository at this point in the history
ensure chart version appears in notification messages
  • Loading branch information
John Esmet authored Jul 11, 2019
2 parents 2dbeea1 + 486c920 commit 3b54788
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 47 deletions.
4 changes: 2 additions & 2 deletions ankh/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,13 +407,13 @@ func execute(ctx *ankh.ExecutionContext) {
}

if ctx.SlackChannel != "" {
if err := slack.PingSlackChannel(ctx); err != nil {
if err := slack.PingSlackChannel(ctx, &rootAnkhFile); err != nil {
ctx.Logger.Errorf("Slack message failed with error: %v", err)
}
}

if ctx.CreateJiraTicket {
if err := jira.CreateJiraTicket(ctx); err != nil {
if err := jira.CreateJiraTicket(ctx, &rootAnkhFile); err != nil {
ctx.Logger.Errorf("Unable to create JIRA ticket. %v", err)
}
}
Expand Down
73 changes: 51 additions & 22 deletions jira/jira.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package jira
import (
"fmt"
"log"
"strings"

jira "github.com/andygrunwald/go-jira"
ankh "github.com/appnexus/ankh/context"
"github.com/appnexus/ankh/util"
)

func CreateJiraTicket(ctx *ankh.ExecutionContext) error {
func CreateJiraTicket(ctx *ankh.ExecutionContext, ankhFile *ankh.AnkhFile) error {
base := ctx.AnkhConfig.Jira.BaseUrl
if base == "" {
return fmt.Errorf("No Jira base url provided. Unable to create ticket.")
Expand All @@ -29,9 +30,27 @@ func CreateJiraTicket(ctx *ankh.ExecutionContext) error {
Password: password,
}

deploymentEnvironment := util.GetEnvironmentOrContext(ctx.Environment, ctx.Context)
summary, err := getSummary(ctx, deploymentEnvironment)
description, err := getDescription(ctx, deploymentEnvironment)
envOrContext := util.GetEnvironmentOrContext(ctx.Environment, ctx.Context)

var summaries []string
var descriptions []string
for i := 0; i < len(ankhFile.Charts); i++ {
chart := &ankhFile.Charts[i]
summary, err := getSummary(ctx, chart, envOrContext)
if err != nil {
log.Fatal(err)
} else {
summaries = append(summaries, summary)
}
description, err := getDescription(ctx, chart, envOrContext)
if err != nil {
log.Fatal(err)
} else {
descriptions = append(descriptions, description)
}
}
summaryText := strings.Join(summaries, ", ")
descriptionText := strings.Join(descriptions, "\n")

jiraClient, err := jira.NewClient(tp.Client(), base)
if err != nil {
Expand All @@ -45,15 +64,15 @@ func CreateJiraTicket(ctx *ankh.ExecutionContext) error {
Reporter: &jira.User{
Name: username,
},
Summary: summary,
Summary: summaryText,
// TODO: Should this be defined in ankh config?
Type: jira.IssueType{
Name: "Task",
},
Project: jira.Project{
Key: queue,
},
Description: description,
Description: descriptionText,
},
}

Expand All @@ -74,7 +93,7 @@ func CreateJiraTicket(ctx *ankh.ExecutionContext) error {
ctx.Logger.Infof("Created JIRA Ticket: %v", issue.Key)
return nil
} else {
ctx.Logger.Infof("--dry-run set, not creating JIRA Ticket for %v queue with summary '%v' and description '%v'", queue, summary, description)
ctx.Logger.Infof("--dry-run set, not creating JIRA Ticket for %v queue with summary '%v' and description '%v'", queue, summaryText, descriptionText)
return nil
}
}
Expand Down Expand Up @@ -123,15 +142,20 @@ func promptForAuth(ctx *ankh.ExecutionContext, retryCount int) (string, string,
return providedUsername, providedPassword, nil
}

func getSummary(ctx *ankh.ExecutionContext, env string) (string, error) {
func getSummary(ctx *ankh.ExecutionContext, chart *ankh.Chart, envOrContext string) (string, error) {
// If format is set, use that
format := ctx.AnkhConfig.Jira.SummaryFormat
if ctx.Mode == ankh.Rollback {
format = ctx.AnkhConfig.Jira.RollbackSummaryFormat
}

chartString, err := util.GetChartString(chart)
if err != nil {
return "", err
}

if format != "" {
message, err := util.ReplaceFormatVariables(format, ctx.Chart, ctx.DeploymentTag, env)
message, err := util.ReplaceFormatVariables(format, chartString, *chart.Tag, envOrContext)
if err != nil {
ctx.Logger.Infof("Unable to use format: '%v'. Will prompt for subject", format)
} else {
Expand All @@ -140,23 +164,28 @@ func getSummary(ctx *ankh.ExecutionContext, env string) (string, error) {
}

// Otherwise, prompt for message
message, err := promptForSummary(ctx.Chart, ctx.DeploymentTag, env)
message, err := promptForSummary(chartString, *chart.Tag, envOrContext)
if err != nil {
ctx.Logger.Infof("Unable to prompt for subject. Will use default subject")
}

return message, nil
}

func getDescription(ctx *ankh.ExecutionContext, env string) (string, error) {
func getDescription(ctx *ankh.ExecutionContext, chart *ankh.Chart, envOrContext string) (string, error) {
// If format is set, use that
format := ctx.AnkhConfig.Jira.DescriptionFormat
if ctx.DeploymentTag == "rollback" {
if *chart.Tag == "rollback" {
format = ctx.AnkhConfig.Jira.RollbackDescriptionFormat
}

chartString, err := util.GetChartString(chart)
if err != nil {
return "", err
}

if format != "" {
message, err := util.ReplaceFormatVariables(format, ctx.Chart, ctx.DeploymentTag, env)
message, err := util.ReplaceFormatVariables(format, chartString, *chart.Tag, envOrContext)
if err != nil {
ctx.Logger.Infof("Unable to use format: '%v'. Will prompt for description", format)
} else {
Expand All @@ -165,18 +194,18 @@ func getDescription(ctx *ankh.ExecutionContext, env string) (string, error) {
}

// Otherwise, prompt for message
message, err := promptForDescription(ctx.Chart, ctx.DeploymentTag, env)
message, err := promptForDescription(chartString, *chart.Tag, envOrContext)
if err != nil {
ctx.Logger.Infof("Unable to prompt for description. Will use default description")
}

return message, nil
}

func promptForSummary(chart string, version string, env string) (string, error) {
defaultSubject := fmt.Sprintf("Deployment of %v verson:%v to *%v*", chart, version, env)
if env == "rollback" {
defaultSubject = fmt.Sprintf("Rollback of %v in *%v*", chart, env)
func promptForSummary(chart string, version string, envOrContext string) (string, error) {
defaultSubject := fmt.Sprintf("Deployment of %v verson:%v to *%v*", chart, version, envOrContext)
if envOrContext == "rollback" {
defaultSubject = fmt.Sprintf("Rollback of %v in *%v*", chart, envOrContext)
}

message, err := util.PromptForInput(defaultSubject, "Jira Summary")
Expand All @@ -187,10 +216,10 @@ func promptForSummary(chart string, version string, env string) (string, error)
return message, nil
}

func promptForDescription(chart string, version string, env string) (string, error) {
defaultSubject := fmt.Sprintf("Ticket to track the deployment of %v verson:%v to *%v*", chart, version, env)
if env == "rollback" {
defaultSubject = fmt.Sprintf("Ticket to track the rollback of %v in *%v*", chart, env)
func promptForDescription(chart string, version string, envOrContext string) (string, error) {
defaultSubject := fmt.Sprintf("Ticket to track the deployment of %v verson:%v to *%v*", chart, version, envOrContext)
if envOrContext == "rollback" {
defaultSubject = fmt.Sprintf("Ticket to track the rollback of %v in *%v*", chart, envOrContext)
}

message, err := util.PromptForInput(defaultSubject, "Jira Description")
Expand Down
51 changes: 33 additions & 18 deletions slack/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package slack
import (
"fmt"
"os/user"
"strings"

ankh "github.com/appnexus/ankh/context"
"github.com/appnexus/ankh/util"
Expand All @@ -14,17 +15,25 @@ const DEFAULT_USERNAME = "ankh"

// Send out a release message based on the chart, version and environment
// supplied by the user
func PingSlackChannel(ctx *ankh.ExecutionContext) error {
func PingSlackChannel(ctx *ankh.ExecutionContext, ankhFile *ankh.AnkhFile) error {

// attempt the connection
api := slack.New(ctx.AnkhConfig.Slack.Token)

// get environment from env vs. context
deploymentEnvironment := util.GetEnvironmentOrContext(ctx.Environment, ctx.Context)
messageText, err := getMessageText(ctx, deploymentEnvironment)
if err != nil {
ctx.Logger.Infof("Unable to prompt for slack message. Using default value. Error: %v", err)
envOrContext := util.GetEnvironmentOrContext(ctx.Environment, ctx.Context)

var messages []string
for i := 0; i < len(ankhFile.Charts); i++ {
chart := &ankhFile.Charts[i]
message, err := getMessageText(ctx, chart, envOrContext)
if err != nil {
return fmt.Errorf("Unable to prompt for slack message. Using default value. Error: %v", err)
} else {
messages = append(messages, message)
}
}
messageText := strings.Join(messages, "\n")

pretext := ctx.AnkhConfig.Slack.Pretext
if pretext == "" {
Expand Down Expand Up @@ -52,18 +61,19 @@ func PingSlackChannel(ctx *ankh.ExecutionContext) error {
Username: username,
}

channelId, err := getSlackChannelIDByName(api, ctx.SlackChannel)
if err != nil {
return err
}

if !ctx.DryRun {
channelId, err := getSlackChannelIDByName(api, ctx.SlackChannel)
if err != nil {
return err
}

_, _, err = api.PostMessage(channelId, slack.MsgOptionAttachments(attachment), slack.MsgOptionPostMessageParameters(messageParams))
return err
} else {
ctx.Logger.Infof("--dry-run set so not sending message '%v' to slack channel %v", messageText, ctx.SlackChannel)
}

return err
return nil
}

func getSlackChannelIDByName(api *slack.Client, channelName string) (string, error) {
Expand Down Expand Up @@ -101,7 +111,7 @@ func getSlackChannelIDByName(api *slack.Client, channelName string) (string, err
return "", fmt.Errorf("channel %v not found", channelName)
}

func getMessageText(ctx *ankh.ExecutionContext, env string) (string, error) {
func getMessageText(ctx *ankh.ExecutionContext, chart *ankh.Chart, envOrContext string) (string, error) {

// Override takes precedence
if ctx.SlackMessageOverride != "" {
Expand All @@ -114,8 +124,13 @@ func getMessageText(ctx *ankh.ExecutionContext, env string) (string, error) {
format = ctx.AnkhConfig.Slack.RollbackFormat
}

chartString, err := util.GetChartString(chart)
if err != nil {
return "", err
}

if format != "" {
message, err := util.ReplaceFormatVariables(format, ctx.Chart, ctx.DeploymentTag, env)
message, err := util.ReplaceFormatVariables(format, chartString, *chart.Tag, envOrContext)
if err != nil {
ctx.Logger.Infof("Unable to use format: '%v'. Will prompt for message", format)
} else {
Expand All @@ -124,22 +139,22 @@ func getMessageText(ctx *ankh.ExecutionContext, env string) (string, error) {
}

// Otherwise, prompt for message
message, err := promptForMessageText(ctx.Chart, ctx.DeploymentTag, env)
message, err := promptForMessageText(chartString, *chart.Tag, envOrContext)
if err != nil {
ctx.Logger.Infof("Unable to prompt for message. Will use default message")
}

return message, nil
}

func promptForMessageText(chart string, version string, env string) (string, error) {
func promptForMessageText(chart string, version string, envOrContext string) (string, error) {
currentUser, err := user.Current()
if err != nil {
return "", err
}
defaultMessage := fmt.Sprintf("%v is releasing %v@%v to *%v*", currentUser.Username, chart, version, env)
if env == "rollback" {
defaultMessage = fmt.Sprintf("%v is rolling back %v in *%v*", currentUser, chart, env)
defaultMessage := fmt.Sprintf("%v is releasing %v@%v to *%v*", currentUser.Username, chart, version, envOrContext)
if envOrContext == "rollback" {
defaultMessage = fmt.Sprintf("%v is rolling back %v in *%v*", currentUser, chart, envOrContext)
}

message, err := util.PromptForInput(defaultMessage, "Slack Message")
Expand Down
15 changes: 10 additions & 5 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,11 +621,16 @@ func GetEnvironmentOrContext(environment string, context string) string {
return ""
}

func GetAppVersion(ctx *ankh.ExecutionContext, ankhFile *ankh.AnkhFile) string {

chart := &ankhFile.Charts[0]

return *chart.Tag
func GetChartString(chart *ankh.Chart) (string, error) {
if chart.Path != "" {
absChartPath, err := filepath.Abs(chart.Path)
if err != nil {
return "", nil
}
return fmt.Sprintf("%v (local)", absChartPath), nil
} else {
return fmt.Sprintf("%v@%v", chart.Name, chart.Version), nil
}
}

func ReplaceFormatVariables(format string, chart string, version string, env string) (string, error) {
Expand Down

0 comments on commit 3b54788

Please sign in to comment.