diff --git a/common/tag/tag_map.go b/common/tag/tag_map.go index 4985ea4..b7a8839 100644 --- a/common/tag/tag_map.go +++ b/common/tag/tag_map.go @@ -21,3 +21,12 @@ func GetSelectedValuesStringArray(selectedValues []SelectedOption) []string { return result } + +const ( + ImpactActionID = "impact_action_id" + IssueTypesActionID = "issue_types_action_id" +) + +const ( + ImpactLabel = "Impact" +) diff --git a/common/util/env/environment_constant.go b/common/util/env/environment_constant.go index d8c505a..18fd036 100644 --- a/common/util/env/environment_constant.go +++ b/common/util/env/environment_constant.go @@ -1,5 +1,7 @@ package env +import "github.com/spf13/viper" + const ( DefaultZendutyTimeout = "DEFAULT_ZENDUTY_TIMEOUT" ZendutyBaseUrl = "ZENDUTY_BASE_URL" @@ -14,3 +16,7 @@ const ( APP_NAME = "APP_NAME" QA_APP_NAME = "qa-houston" ) + +func IsQAApp() bool { + return viper.GetString(APP_NAME) == QA_APP_NAME +} diff --git a/common/util/slack/slack_helpers.go b/common/util/slack/slack_helpers.go index fd9472b..7f403b3 100644 --- a/common/util/slack/slack_helpers.go +++ b/common/util/slack/slack_helpers.go @@ -91,39 +91,43 @@ func buildTagsBlock(tagValues []tagUtil.TagMapValue) []*slack.SectionBlock { var tagsBlocks []*slack.SectionBlock for _, tagValue := range tagValues { if tagValue.SingleSelectedOption.Value != "" { - tagsBlocks = append( - tagsBlocks, - slack.NewSectionBlock( - &slack.TextBlockObject{ - Type: MarkDownElementType, - Text: fmt.Sprintf( - "*%s* : %s", tagValue.Label, tagValue.SingleSelectedOption.Value), - }, - nil, - nil, - ), - ) + tagsBlocks = append(tagsBlocks, buildTextBlockSection( + fmt.Sprintf("*%s* : %s", tagValue.Label, tagValue.SingleSelectedOption.Value), + )) } if len(tagValue.MultiSelectedOptions) > 0 { - tagsBlocks = append( - tagsBlocks, - slack.NewSectionBlock( - &slack.TextBlockObject{ - Type: MarkDownElementType, - Text: fmt.Sprintf( - "*%s* : %s", - tagValue.Label, - strings.Join(tagUtil.GetSelectedValuesStringArray(tagValue.MultiSelectedOptions), ", "), - ), - }, - nil, - nil), - ) + tagsBlocks = append(tagsBlocks, buildTextBlockSection( + fmt.Sprintf( + "*%s* : %s", + tagValue.Label, + strings.Join(tagUtil.GetSelectedValuesStringArray(tagValue.MultiSelectedOptions), ", "), + ), + )) + } + if tagValue.Value != "" { + tagsBlocks = append(tagsBlocks, buildTextBlockSection( + fmt.Sprintf( + "*%s* : %s", + tagValue.Label, + tagValue.Value, + ), + )) } } return tagsBlocks } +func buildTextBlockSection(text string) *slack.SectionBlock { + return slack.NewSectionBlock( + &slack.TextBlockObject{ + Type: MarkDownElementType, + Text: text, + }, + nil, + nil, + ) +} + func buildRCASummaryBlock(rcaValue string) *slack.SectionBlock { field := slack.TextBlockObject{ Type: MarkDownElementType, Text: fmt.Sprintf("*%s* : %s", RCASummaryLabel, rcaValue), Verbatim: false, diff --git a/internal/processor/action/start_incident_modal_submission_action.go b/internal/processor/action/start_incident_modal_submission_action.go index 4180127..5cb73ce 100644 --- a/internal/processor/action/start_incident_modal_submission_action.go +++ b/internal/processor/action/start_incident_modal_submission_action.go @@ -7,6 +7,7 @@ import ( "gorm.io/gorm" "houston/appcontext" "houston/common/metrics" + "houston/common/util/env" stringUtil "houston/common/util/string" "houston/internal" "houston/logger" @@ -100,13 +101,17 @@ func buildCreateIncidentRequestV3(callback slack.InteractionCallback) (*request. reportingTeamId, err := stringUtil.StringToUint(requestMap["reportingTeamId"]) responderTeamId, err := stringUtil.StringToUint(requestMap["responderTeamId"]) - severityId, err := stringUtil.StringToUint(requestMap["severityId"]) - if err != nil { - return nil, err + if env.IsQAApp() { + createIncidentRequest.SeverityID = incident.Sev3Id + } else { + severityId, err := stringUtil.StringToUint(requestMap["severityId"]) + if err != nil { + return nil, err + } + createIncidentRequest.SeverityID = severityId } createIncidentRequest.Title = requestMap["title"] createIncidentRequest.Description = requestMap["description"] - createIncidentRequest.SeverityID = severityId createIncidentRequest.ReportingTeamID = reportingTeamId createIncidentRequest.ResponderTeamID = responderTeamId createIncidentRequest.ProductIds = privateMetadata.ProductIds diff --git a/internal/processor/action/view/create_incident_modal.go b/internal/processor/action/view/create_incident_modal.go index 385a2a4..b3ee8a7 100644 --- a/internal/processor/action/view/create_incident_modal.go +++ b/internal/processor/action/view/create_incident_modal.go @@ -3,6 +3,7 @@ package view import ( "fmt" "houston/common/util" + "houston/common/util/env" "houston/internal" "houston/model/severity" "houston/model/team" @@ -30,10 +31,13 @@ func GenerateModalRequest( closeText := slack.NewTextBlockObject(slack.PlainTextType, "Close", false, false) submitText := slack.NewTextBlockObject(slack.PlainTextType, "Send", false, false) + blockSet := make([]slack.Block, 0) + headerText := slack.NewTextBlockObject( "mrkdwn", fmt.Sprintf("Start incident for *%s*", productNames), false, false, ) headerSection := slack.NewSectionBlock(headerText, nil, nil) + blockSet = append(blockSet, headerSection) reportingTeamsOptions := createOptionBlockObjectsForTeamsV2(reportingTeams) reportingTeamText := slack.NewTextBlockObject(slack.PlainTextType, "Reporting Team", false, false) @@ -45,6 +49,7 @@ func GenerateModalRequest( reportingTeamOption.InitialOption = defaultReportingTeamOption } reportingTeamBlock := slack.NewInputBlock("reporting_team", reportingTeamText, nil, reportingTeamOption) + blockSet = append(blockSet, reportingTeamBlock) responderTeamsOptions := createOptionBlockObjectsForTeamsV2(responderTeams) responderTeamText := slack.NewTextBlockObject(slack.PlainTextType, "Responder Team", false, false) @@ -56,18 +61,23 @@ func GenerateModalRequest( responderTeamOption.InitialOption = defaultResponderOption } responderTeamBlock := slack.NewInputBlock("incident_type", responderTeamText, nil, responderTeamOption) + blockSet = append(blockSet, responderTeamBlock) - severityOptions := createOptionBlockObjectsForSeverity(severities) - severityText := slack.NewTextBlockObject(slack.PlainTextType, "Severity", false, false) - severityTextPlaceholder := slack.NewTextBlockObject(slack.PlainTextType, "The severity for the incident to create", false, false) - severityOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, severityTextPlaceholder, "severityId", severityOptions...) - severityBlock := slack.NewInputBlock("incident_severity", severityText, nil, severityOption) + if !env.IsQAApp() { + severityOptions := createOptionBlockObjectsForSeverity(severities) + severityText := slack.NewTextBlockObject(slack.PlainTextType, "Severity", false, false) + severityTextPlaceholder := slack.NewTextBlockObject(slack.PlainTextType, "The severity for the incident to create", false, false) + severityOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, severityTextPlaceholder, "severityId", severityOptions...) + severityBlock := slack.NewInputBlock("incident_severity", severityText, nil, severityOption) + blockSet = append(blockSet, severityBlock) + } incidentTitleText := slack.NewTextBlockObject(slack.PlainTextType, "Incident title", false, false) incidentTitlePlaceholder := slack.NewTextBlockObject(slack.PlainTextType, "Write something", false, false) incidentTitleElement := slack.NewPlainTextInputBlockElement(incidentTitlePlaceholder, "title") incidentTitleElement.MaxLength = IncidentTitleLength incidentTitle := slack.NewInputBlock("Incident title", incidentTitleText, nil, incidentTitleElement) + blockSet = append(blockSet, incidentTitle) incidentDescriptionText := slack.NewTextBlockObject(slack.PlainTextType, "Incident description", false, false) incidentDescriptionPlaceholder := slack.NewTextBlockObject(slack.PlainTextType, "Write something", false, false) @@ -75,16 +85,10 @@ func GenerateModalRequest( incidentDescriptionElement.Multiline = true incidentDescription := slack.NewInputBlock("Incident description", incidentDescriptionText, nil, incidentDescriptionElement) incidentDescription.Optional = false + blockSet = append(blockSet, incidentDescription) blocks := slack.Blocks{ - BlockSet: []slack.Block{ - headerSection, - reportingTeamBlock, - responderTeamBlock, - severityBlock, - incidentTitle, - incidentDescription, - }, + BlockSet: blockSet, } return slack.ModalViewRequest{ diff --git a/service/incident/impl/incident_update_status.go b/service/incident/impl/incident_update_status.go index 8d5d636..dda5026 100644 --- a/service/incident/impl/incident_update_status.go +++ b/service/incident/impl/incident_update_status.go @@ -617,6 +617,10 @@ func (i *IncidentServiceV2) getTagsAsMap(request service.ResolveIncidentRequest) } } + if !util.IsBlank(request.Impact) { + tagMap[tagUtil.ImpactActionID] = tagUtil.TagMapValue{Label: tagUtil.ImpactLabel, Value: request.Impact} + } + return tagMap, nil } @@ -761,7 +765,8 @@ func (i *IncidentServiceV2) checkAllActiveTagsAreSet(incidentEntity *incident.In ), ) } - if incidentTag.TagValueIds == nil || len(incidentTag.TagValueIds) < 1 { + if (incidentTag.TagValueIds == nil || len(incidentTag.TagValueIds) < 1) && + (incidentTag.FreeTextValue == nil || util.IsBlank(*incidentTag.FreeTextValue)) { logger.Error(fmt.Sprintf(" %s for incidentId: %v is not set", activeTag.Label, incidentEntity.ID)) notSetTagLabels = append(notSetTagLabels, activeTag.Label) } diff --git a/service/request/resolve_incident_request.go b/service/request/resolve_incident_request.go index 49fd13d..84854ae 100644 --- a/service/request/resolve_incident_request.go +++ b/service/request/resolve_incident_request.go @@ -2,8 +2,8 @@ package service import ( "github.com/slack-go/slack" - "github.com/spf13/viper" "go.uber.org/zap" + "houston/common/tag" "houston/common/util/env" slackUtil "houston/common/util/slack" stringUtil "houston/common/util/string" @@ -19,6 +19,7 @@ type ResolveIncidentRequest struct { RcaSummary string `json:"rca_summary"` JiraLinks []string `json:"jira_links"` IssueTypes []uint `json:"issue_types"` + Impact string `json:"impact"` } func ConvertSlackActionToResolveIncidentRequest( @@ -29,31 +30,32 @@ func ConvertSlackActionToResolveIncidentRequest( resolveIncidentRequest.IncidentID = incidentId - businessAffected, err := slackUtil.GetMultiValueArrayFromSlackOptionBlock(actions["business_affected_action_id"].SelectedOptions) - if err != nil { - logger.Error("Error while getting business affected", zap.Error(err)) - } - resolveIncidentRequest.BusinessAffected = businessAffected + if !env.IsQAApp() { + businessAffected, err := slackUtil.GetMultiValueArrayFromSlackOptionBlock(actions["business_affected_action_id"].SelectedOptions) + if err != nil { + logger.Error("Error while getting business affected", zap.Error(err)) + } + resolveIncidentRequest.BusinessAffected = businessAffected - contributingFactor := actions["contributing_factors_action_id"].SelectedOption.Value - contributingFactorID, err := strconv.Atoi(contributingFactor) - if err != nil { - return nil, err - } - resolveIncidentRequest.ContributingFactors = uint(contributingFactorID) + contributingFactor := actions["contributing_factors_action_id"].SelectedOption.Value + contributingFactorID, err := strconv.Atoi(contributingFactor) + if err != nil { + return nil, err + } + resolveIncidentRequest.ContributingFactors = uint(contributingFactorID) - additionalTags, err := slackUtil.GetMultiValueArrayFromSlackOptionBlock(actions["additional_tags_action_id"].SelectedOptions) - if err != nil { - logger.Error("Error while getting additional tags", zap.Error(err)) - } - resolveIncidentRequest.AdditionalTags = additionalTags - - if viper.GetString(env.APP_NAME) == env.QA_APP_NAME { - issueTypes, err := slackUtil.GetMultiValueArrayFromSlackOptionBlock(actions["issue_types_action_id"].SelectedOptions) + additionalTags, err := slackUtil.GetMultiValueArrayFromSlackOptionBlock(actions["additional_tags_action_id"].SelectedOptions) + if err != nil { + logger.Error("Error while getting additional tags", zap.Error(err)) + } + resolveIncidentRequest.AdditionalTags = additionalTags + } else { + issueTypes, err := slackUtil.GetMultiValueArrayFromSlackOptionBlock(actions[tag.IssueTypesActionID].SelectedOptions) if err != nil { logger.Error("Error while getting issue types", zap.Error(err)) } resolveIncidentRequest.IssueTypes = issueTypes + resolveIncidentRequest.Impact = actions[tag.ImpactActionID].Value } resolveIncidentRequest.RcaSummary = actions["set_rca_summary"].Value