TP-0000 | Initialize houston repo (#1)
* TP-0000 | intialize houston repo * TP-0000 | intialize houston repo
This commit is contained in:
committed by
GitHub Enterprise
parent
db0f4f09f8
commit
b974cb6bf3
44
cmd/app/handler/severity_handler.go
Normal file
44
cmd/app/handler/severity_handler.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"houston/model/request"
|
||||
"houston/pkg/postgres/query"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type severityHandler struct {
|
||||
gin *gin.Engine
|
||||
logger *zap.Logger
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewSeverityHandler(gin *gin.Engine, logger *zap.Logger, db *gorm.DB) *severityHandler {
|
||||
return &severityHandler{
|
||||
gin: gin,
|
||||
logger: logger,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (sh *severityHandler) AddSeverity(c *gin.Context) {
|
||||
var addSeverityRequest request.AddSeverityRequest
|
||||
if err := c.ShouldBindJSON(&addSeverityRequest); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
sh.logger.Info("add severity request received", zap.String("severity_name", addSeverityRequest.Name))
|
||||
|
||||
err := query.AddSeverity(sh.db, sh.logger, addSeverityRequest)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, nil)
|
||||
|
||||
}
|
||||
95
cmd/app/handler/slack_handler.go
Normal file
95
cmd/app/handler/slack_handler.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"houston/pkg/slack/houston"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/slackevents"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type slackHandler struct {
|
||||
logger *zap.Logger
|
||||
socketModeClient *socketmode.Client
|
||||
slackClient *slack.Client
|
||||
db *gorm.DB
|
||||
houstonCommandHandler *houston.HoustonCommandHandler
|
||||
}
|
||||
|
||||
func NewSlackHandler(logger *zap.Logger, socketModeClient *socketmode.Client,
|
||||
db *gorm.DB,
|
||||
slackClient *slack.Client) *slackHandler {
|
||||
return &slackHandler{
|
||||
logger: logger,
|
||||
socketModeClient: socketModeClient,
|
||||
db: db,
|
||||
slackClient: slackClient,
|
||||
houstonCommandHandler: houston.NewHoustonCommandHandler(socketModeClient, logger, db),
|
||||
}
|
||||
}
|
||||
|
||||
func (sh *slackHandler) HoustonConnect() {
|
||||
go func() {
|
||||
for evt := range sh.socketModeClient.Events {
|
||||
switch evt.Type {
|
||||
case socketmode.EventTypeConnecting:
|
||||
sh.logger.Info("houston connecting to slack with socket mode ...")
|
||||
case socketmode.EventTypeConnectionError:
|
||||
sh.logger.Error("Blazelss connection failed. retrying later ...")
|
||||
case socketmode.EventTypeConnected:
|
||||
sh.logger.Info("houston connected to slack with socket mode.")
|
||||
case socketmode.EventTypeEventsAPI:
|
||||
ev, _ := evt.Data.(slackevents.EventsAPIEvent)
|
||||
sh.logger.Info("event api", zap.Any("ev", ev))
|
||||
switch ev.Type {
|
||||
case slackevents.CallbackEvent:
|
||||
iev := ev.InnerEvent
|
||||
switch ev := iev.Data.(type) {
|
||||
case *slackevents.AppMentionEvent:
|
||||
case *slackevents.MemberJoinedChannelEvent:
|
||||
sh.houstonCommandHandler.ProcessMemberJoinEvent(ev, evt.Request)
|
||||
}
|
||||
case slackevents.URLVerification:
|
||||
case string(slackevents.MemberJoinedChannel):
|
||||
}
|
||||
case socketmode.EventTypeInteractive:
|
||||
callback, _ := evt.Data.(slack.InteractionCallback)
|
||||
|
||||
switch callback.Type {
|
||||
case slack.InteractionTypeBlockActions:
|
||||
sh.logger.Info("received interaction type block action",
|
||||
zap.String("action_id", callback.ActionID), zap.String("block_id", callback.BlockID))
|
||||
sh.houstonCommandHandler.ProcessButtonHandler(callback, evt.Request)
|
||||
case slack.InteractionTypeShortcut:
|
||||
case slack.InteractionTypeViewSubmission:
|
||||
sh.logger.Info("received interaction type view submission",
|
||||
zap.String("action_id", callback.ActionID), zap.String("block_id", callback.BlockID))
|
||||
|
||||
sh.logger.Info("payload data", zap.Any("callback", callback), zap.Any("request", evt.Request))
|
||||
sh.houstonCommandHandler.ProcessModalCallbackEvent(callback, evt.Request)
|
||||
case slack.InteractionTypeDialogSubmission:
|
||||
default:
|
||||
|
||||
}
|
||||
// command.ProcessStartIncidentCommand(client, evt.Request, callback.TriggerID)
|
||||
case socketmode.EventTypeSlashCommand:
|
||||
cmd, _ := evt.Data.(slack.SlashCommand)
|
||||
|
||||
sh.logger.Info("houston processing slash command",
|
||||
zap.String("command", cmd.Text), zap.String("channel_name", cmd.ChannelName), zap.String("user_name", cmd.UserName))
|
||||
|
||||
sh.houstonCommandHandler.ProcessSlashCommand(evt)
|
||||
|
||||
// command.ProcessMainCommand(client, evt.Request)
|
||||
|
||||
// client.Ack(*evt.Request, payload)
|
||||
default:
|
||||
sh.logger.Error("houston unexpected event type received", zap.Any("event_type", evt.Type))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
go sh.socketModeClient.Run()
|
||||
}
|
||||
42
cmd/app/handler/team_handler.go
Normal file
42
cmd/app/handler/team_handler.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"houston/model/request"
|
||||
"houston/pkg/postgres/query"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type teamHandler struct {
|
||||
gin *gin.Engine
|
||||
logger *zap.Logger
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewTeamHandler(gin *gin.Engine, logger *zap.Logger, db *gorm.DB) *teamHandler {
|
||||
return &teamHandler{
|
||||
gin: gin,
|
||||
logger: logger,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (th *teamHandler) AddTeam(c *gin.Context) {
|
||||
var addTeamRequest request.AddTeamRequest
|
||||
if err := c.ShouldBindJSON(&addTeamRequest); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
th.logger.Info("add team request received", zap.String("team_name", addTeamRequest.Name))
|
||||
err := query.AddTeam(th.db, addTeamRequest)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, nil)
|
||||
}
|
||||
54
cmd/app/server.go
Normal file
54
cmd/app/server.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/cmd/app/handler"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
gin *gin.Engine
|
||||
logger *zap.Logger
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewServer(gin *gin.Engine, logger *zap.Logger, db *gorm.DB) *Server {
|
||||
return &Server{
|
||||
gin: gin,
|
||||
logger: logger,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Handler() {
|
||||
s.teamHandler()
|
||||
s.severityHandler()
|
||||
|
||||
//this should always be at the end since it opens websocket to connect to slack
|
||||
s.houstonHandler()
|
||||
}
|
||||
|
||||
func (s *Server) houstonHandler() {
|
||||
houstonClient := NewHoustonClient(s.logger)
|
||||
houstonHandler := handler.NewSlackHandler(s.logger, houstonClient.socketmodeClient, s.db, houstonClient.slackClient)
|
||||
houstonHandler.HoustonConnect()
|
||||
}
|
||||
|
||||
func (s *Server) teamHandler() {
|
||||
teamHandler := handler.NewTeamHandler(s.gin, s.logger, s.db)
|
||||
s.gin.POST("/team/add", teamHandler.AddTeam)
|
||||
}
|
||||
|
||||
func (s *Server) severityHandler() {
|
||||
severityHandler := handler.NewSeverityHandler(s.gin, s.logger, s.db)
|
||||
s.gin.POST("/severity/add", severityHandler.AddSeverity)
|
||||
}
|
||||
|
||||
func (s *Server) Start() {
|
||||
s.logger.Info("starting houston server", zap.String("port", viper.GetString("port")))
|
||||
s.gin.Run(fmt.Sprintf(":%v", "8080"))
|
||||
}
|
||||
63
cmd/app/slack.go
Normal file
63
cmd/app/slack.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type HoustonSlack struct {
|
||||
socketmodeClient *socketmode.Client
|
||||
slackClient *slack.Client
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewHoustonClient(logger *zap.Logger) *HoustonSlack {
|
||||
socketmodeClient, slackClient := slackConnect(logger)
|
||||
|
||||
return &HoustonSlack{
|
||||
socketmodeClient: socketmodeClient,
|
||||
slackClient: slackClient,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func slackConnect(logger *zap.Logger) (*socketmode.Client, *slack.Client) {
|
||||
appToken := os.Getenv("HOUSTON_SLACK_APP_TOKEN")
|
||||
if appToken == "" {
|
||||
logger.Error("HOUSTON_SLACK_APP_TOKEN must be set.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(appToken, "xapp-") {
|
||||
logger.Error("HOUSTON_SLACK_APP_TOKEN must have the prefix \"xapp-\".")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
botToken := os.Getenv("HOUSTON_SLACK_BOT_TOKEN")
|
||||
if botToken == "" {
|
||||
logger.Error("HOUSTON_SLACK_BOT_TOKEN must be set.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(botToken, "xoxb-") {
|
||||
logger.Error("HOUSTON_SLACK_BOT_TOKEN must have the prefix \"xoxb-\".")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
api := slack.New(
|
||||
botToken,
|
||||
slack.OptionDebug(false),
|
||||
slack.OptionAppLevelToken(appToken),
|
||||
)
|
||||
|
||||
client := socketmode.New(
|
||||
api,
|
||||
socketmode.OptionDebug(false),
|
||||
)
|
||||
|
||||
return client, api
|
||||
}
|
||||
46
cmd/main.go
Normal file
46
cmd/main.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"houston/cmd/app"
|
||||
"houston/config"
|
||||
"houston/pkg/postgres"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
ginzap "github.com/gin-contrib/zap"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/spf13/cobra"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logger, _ := zap.NewProduction()
|
||||
config.LoadHoustonConfig(logger)
|
||||
godotenv.Load()
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "houston",
|
||||
Short: "houston is replacement for blameless and incident management slack bot at Navi",
|
||||
Long: "houston is replacement for blameless and incident management slack bot at Navi",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
r := gin.New()
|
||||
|
||||
r.Use(ginzap.Ginzap(logger, time.RFC3339, true))
|
||||
|
||||
r.Use(ginzap.RecoveryWithZap(logger, true))
|
||||
db := postgres.PQConnection(logger)
|
||||
sv := app.NewServer(r, logger, db)
|
||||
|
||||
sv.Handler()
|
||||
sv.Start()
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
if err := command.Execute(); err != nil {
|
||||
logger.Error("alfred core command execution failed", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
13
config/application-blazeless.properties
Normal file
13
config/application-blazeless.properties
Normal file
@@ -0,0 +1,13 @@
|
||||
BLAZELESS_SLACK_APP_TOKEN=xapp-1-A0444DP8XU5-4136817231606-8e441610b1696fd4f5fa81e9507a3d6f625504ac07588c63543972ff3b147321
|
||||
BLAZELESS_SLACK_BOT_TOKEN=
|
||||
BOOTSTRAP_SERVERS=localhost:9092
|
||||
GROUP_ID=blaze-group
|
||||
AUTO_OFFSET_RESET=newest
|
||||
ENABLE=true
|
||||
ACKS=0
|
||||
SECURITY_PROTOCOL=
|
||||
SASL_MECHANISMS=
|
||||
SASL_USERNAME=
|
||||
SASL_PASSWORD=
|
||||
ENVIRONMENT=local
|
||||
SHOW_INCIDENTS_LIMIT=10
|
||||
12
config/application-houston.properties
Normal file
12
config/application-houston.properties
Normal file
@@ -0,0 +1,12 @@
|
||||
HOUSTON_SLACK_APP_TOKEN=xapp-1-A0444DP8XU5-4136817231606-8e441610b1696fd4f5fa81e9507a3d6f625504ac07588c63543972ff3b147321
|
||||
HOUSTON_SLACK_BOT_TOKEN=j22
|
||||
BOOTSTRAP_SERVERS=localhost:9092
|
||||
GROUP_ID=blaze-group
|
||||
AUTO_OFFSET_RESET=newest
|
||||
ENABLE=true
|
||||
ACKS=0
|
||||
SECURITY_PROTOCOL=
|
||||
SASL_MECHANISMS=
|
||||
SASL_USERNAME=
|
||||
SASL_PASSWORD=
|
||||
ENVIRONMENT=local
|
||||
24
config/config.go
Normal file
24
config/config.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
||||
func LoadHoustonConfig(logger *zap.Logger) {
|
||||
viper.AutomaticEnv()
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
viper.SetConfigName("blazeless-config")
|
||||
viper.SetConfigType("properties")
|
||||
viper.SetConfigFile("./config/application-blazeless.properties")
|
||||
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
logger.Error("Error while loading blazeless configuration", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
16
entity/alerts.go
Normal file
16
entity/alerts.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type AlertsEntity struct {
|
||||
gorm.Model
|
||||
Name string
|
||||
Team string
|
||||
Service string
|
||||
Status bool
|
||||
Version int
|
||||
}
|
||||
|
||||
func (AlertsEntity) TableName() string {
|
||||
return "alerts"
|
||||
}
|
||||
16
entity/audit.go
Normal file
16
entity/audit.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type IncidentAuditEntity struct {
|
||||
gorm.Model
|
||||
IncidentId uint
|
||||
Event string
|
||||
UserName string
|
||||
UserId string
|
||||
Version int
|
||||
}
|
||||
|
||||
func (IncidentAuditEntity) TableName() string {
|
||||
return "incident_audit"
|
||||
}
|
||||
13
entity/contributing_factor.go
Normal file
13
entity/contributing_factor.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type ContributingFactorEntity struct {
|
||||
gorm.Model
|
||||
Label string
|
||||
Version int
|
||||
}
|
||||
|
||||
func (ContributingFactorEntity) TableName() string {
|
||||
return "contributing_factor"
|
||||
}
|
||||
13
entity/customer_tags.go
Normal file
13
entity/customer_tags.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type CustomerTagsEntity struct {
|
||||
gorm.Model
|
||||
Label string
|
||||
Version int
|
||||
}
|
||||
|
||||
func (CustomerTagsEntity) TableName() string {
|
||||
return "customer_tags"
|
||||
}
|
||||
54
entity/incident.go
Normal file
54
entity/incident.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type IncidentStatus string
|
||||
|
||||
const (
|
||||
Investigating IncidentStatus = "INVESTIGATING"
|
||||
Identified = "IDENTIFIED"
|
||||
Monitoring = "MONITORING"
|
||||
Resolved = "RESOLVED"
|
||||
Duplicated = "DUPLICATED"
|
||||
)
|
||||
|
||||
type IncidentEntity struct {
|
||||
gorm.Model
|
||||
Title string
|
||||
Description string
|
||||
Status IncidentStatus
|
||||
SeverityId int
|
||||
IncidentName string
|
||||
SlackChannel string
|
||||
DetectionTime time.Time
|
||||
CustomerImpactStartTime time.Time
|
||||
CustomerImpactEndTime time.Time
|
||||
TeamsId int
|
||||
JiraId string
|
||||
ConfluenceId string
|
||||
SeverityTat time.Time
|
||||
RemindMeAt time.Time
|
||||
EnableReminder bool
|
||||
CreatedBy string
|
||||
UpdatedBy string
|
||||
Version int
|
||||
}
|
||||
|
||||
func (IncidentEntity) TableName() string {
|
||||
return "incidents"
|
||||
}
|
||||
|
||||
type IncidentStatusEntity struct {
|
||||
gorm.Model
|
||||
Name string
|
||||
Description string
|
||||
Version int
|
||||
}
|
||||
|
||||
func (IncidentStatusEntity) TableName() string {
|
||||
return "incident_status"
|
||||
}
|
||||
24
entity/incident_roles.go
Normal file
24
entity/incident_roles.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type IncidentRole string
|
||||
|
||||
const (
|
||||
RETROSPECTIVE IncidentRole = "RETROSPECTIVE"
|
||||
RESPONDER IncidentRole = "RESPONDER"
|
||||
SERVICE_OWNER IncidentRole = "SERVICE_OWNER"
|
||||
)
|
||||
|
||||
type IncidentRoles struct {
|
||||
gorm.Model
|
||||
IncidentId int
|
||||
Role IncidentRole
|
||||
AssignedToUserSlackId string
|
||||
AssignedByUserSlackId string
|
||||
Version int
|
||||
}
|
||||
|
||||
func (IncidentRoles) TableName() string {
|
||||
return "incident_roles"
|
||||
}
|
||||
12
entity/incident_severity_team_join.go
Normal file
12
entity/incident_severity_team_join.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package entity
|
||||
|
||||
type IncidentSeverityTeamJoinEntity struct {
|
||||
IncidentId int
|
||||
Title string
|
||||
Status IncidentStatus
|
||||
SeverityId int
|
||||
SeverityName string
|
||||
SlackChannel string
|
||||
TeamsId int
|
||||
TeamsName string
|
||||
}
|
||||
14
entity/incident_tags_contributing_factor_mapping.go
Normal file
14
entity/incident_tags_contributing_factor_mapping.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type IncidentTagsContributingFactorMapping struct {
|
||||
gorm.Model
|
||||
IncidentId int
|
||||
ContributingFactorId int
|
||||
Version int
|
||||
}
|
||||
|
||||
func (IncidentTagsContributingFactorMapping) TableName() string {
|
||||
return "incidents_tags_contributing_factor_mapping"
|
||||
}
|
||||
14
entity/incidents_tags_customer_mapping.go
Normal file
14
entity/incidents_tags_customer_mapping.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type IncidentTagsCustomerMapping struct {
|
||||
gorm.Model
|
||||
IncidentId int
|
||||
CustomerTagsId int
|
||||
Version int
|
||||
}
|
||||
|
||||
func (IncidentTagsCustomerMapping) TableName() string {
|
||||
return "incidents_tags_customer_mapping"
|
||||
}
|
||||
14
entity/incidents_tags_data_platform_mapping.go
Normal file
14
entity/incidents_tags_data_platform_mapping.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type IncidentsTagsDataPlatformMapping struct {
|
||||
gorm.Model
|
||||
IncidentId int
|
||||
DataPlatformTag string
|
||||
Version int
|
||||
}
|
||||
|
||||
func (IncidentsTagsDataPlatformMapping) TableName() string {
|
||||
return "incidents_tags_data_platform_mapping"
|
||||
}
|
||||
14
entity/incidents_tags_mapping.go
Normal file
14
entity/incidents_tags_mapping.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type IncidentsTagsMapping struct {
|
||||
gorm.Model
|
||||
IncidentId int
|
||||
TagId int
|
||||
Version int
|
||||
}
|
||||
|
||||
func (IncidentsTagsMapping) TableName() string {
|
||||
return "incidents_tags_mapping"
|
||||
}
|
||||
21
entity/messages.go
Normal file
21
entity/messages.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type MessageEntity struct {
|
||||
gorm.Model
|
||||
SlackChannel string `gorm:"column:slack_channel"`
|
||||
IncidentName string `gorm:"column:incident_name"`
|
||||
MessageTimeStamp string `gorm:"column:message_timestamp"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
Version int
|
||||
}
|
||||
|
||||
func (MessageEntity) TableName() string {
|
||||
return "message"
|
||||
}
|
||||
15
entity/severity.go
Normal file
15
entity/severity.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type SeverityEntity struct {
|
||||
gorm.Model
|
||||
Name string `gorm:"column:name"`
|
||||
Description string `gorm:"column:description"`
|
||||
Version int
|
||||
Sla int
|
||||
}
|
||||
|
||||
func (SeverityEntity) TableName() string {
|
||||
return "severity"
|
||||
}
|
||||
13
entity/tags.go
Normal file
13
entity/tags.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type TagsEntity struct {
|
||||
gorm.Model
|
||||
Label string `gorm:"column:label"`
|
||||
Version int
|
||||
}
|
||||
|
||||
func (TagsEntity) TableName() string {
|
||||
return "tags"
|
||||
}
|
||||
14
entity/team_tags_mapping.go
Normal file
14
entity/team_tags_mapping.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package entity
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type TeamTagsMapping struct {
|
||||
gorm.Model
|
||||
TeamsId int
|
||||
TagId int
|
||||
Version int
|
||||
}
|
||||
|
||||
func (TeamTagsMapping) TableName() string {
|
||||
return "teams_tags_mapping"
|
||||
}
|
||||
20
entity/teams.go
Normal file
20
entity/teams.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type TeamEntity struct {
|
||||
gorm.Model
|
||||
Name string `gorm:"column:name"`
|
||||
OncallHandle string `gorm:"column:oncall_handle"`
|
||||
SecondaryOncallHandle string `gorm:"column:secondary_oncall_handle"`
|
||||
ManagerHandle string `gorm:"column:manager_handle"`
|
||||
SecondaryManagerHandle string `gorm:"column:secondary_manager_handle"`
|
||||
Active bool `gorm:"column:active"`
|
||||
Version int `gorm:"column:version"`
|
||||
}
|
||||
|
||||
func (TeamEntity) TableName() string {
|
||||
return "teams"
|
||||
}
|
||||
26
entity/teams_severity_users_mapping.go
Normal file
26
entity/teams_severity_users_mapping.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type EntityType string
|
||||
|
||||
const (
|
||||
TEAM EntityType = "TEAM"
|
||||
SEVERITY EntityType = "SEVERITY"
|
||||
)
|
||||
|
||||
type TeamsSeverityUsersMapping struct {
|
||||
gorm.Model
|
||||
EntityType EntityType
|
||||
EntityId int
|
||||
UsersId int
|
||||
DefaultAddInIncidents bool
|
||||
teamRole string
|
||||
Version int
|
||||
}
|
||||
|
||||
func (TeamsSeverityUsersMapping) TableName() string {
|
||||
return "teams_severity_user_mapping"
|
||||
}
|
||||
11
entity/users.go
Normal file
11
entity/users.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package entity
|
||||
|
||||
type UsersEntity struct {
|
||||
Name string
|
||||
SlackUserId string
|
||||
Active bool
|
||||
}
|
||||
|
||||
func (UsersEntity) TableName() string {
|
||||
return "users"
|
||||
}
|
||||
92
go.mod
Normal file
92
go.mod
Normal file
@@ -0,0 +1,92 @@
|
||||
module houston
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/Shopify/sarama v1.38.1
|
||||
github.com/gin-contrib/zap v0.1.0
|
||||
github.com/gin-gonic/gin v1.9.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/slack-go/slack v0.12.1
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/viper v1.15.0
|
||||
go.uber.org/zap v1.24.0
|
||||
google.golang.org/api v0.107.0
|
||||
gorm.io/driver/postgres v1.4.8
|
||||
gorm.io/gorm v1.24.5
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.14.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/bytedance/sonic v1.8.2 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/eapache/go-resiliency v1.3.0 // indirect
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6 // indirect
|
||||
github.com/eapache/queue v1.1.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.2 // indirect
|
||||
github.com/goccy/go-json v0.10.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.3.0 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.16.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/spf13/afero v1.9.4 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.10 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/otel v1.13.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.13.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/arch v0.2.0 // indirect
|
||||
golang.org/x/crypto v0.6.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect
|
||||
google.golang.org/grpc v1.52.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
709
go.sum
Normal file
709
go.sum
Normal file
@@ -0,0 +1,709 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0=
|
||||
cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Shopify/sarama v1.38.1 h1:lqqPUPQZ7zPqYlWpTh+LQ9bhYNu2xJL6k1SJN4WVe2A=
|
||||
github.com/Shopify/sarama v1.38.1/go.mod h1:iwv9a67Ha8VNa+TifujYoWGxWnu2kNVAQdSdZ4X2o5g=
|
||||
github.com/Shopify/toxiproxy/v2 v2.5.0 h1:i4LPT+qrSlKNtQf5QliVjdP08GyAH8+BUIc9gT0eahc=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.8.2 h1:Eq1oE3xWIBE3tj2ZtJFK1rDAx7+uA4bRytozVhXMHKY=
|
||||
github.com/bytedance/sonic v1.8.2/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eapache/go-resiliency v1.3.0 h1:RRL0nge+cWGlxXbUzJ7yMcq6w2XBEr19dCN6HECGaT0=
|
||||
github.com/eapache/go-resiliency v1.3.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6 h1:8yY/I9ndfrgrXUbOGObLHKBR4Fl3nZXwM2c7OYTT8hM=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20230111030713-bf00bc1b83b6/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
|
||||
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-contrib/zap v0.1.0 h1:RMSFFJo34XZogV62OgOzvrlaMNmXrNxmJ3bFmMwl6Cc=
|
||||
github.com/gin-contrib/zap v0.1.0/go.mod h1:hvnZaPs478H1PGvRP8w89ZZbyJUiyip4ddiI/53WG3o=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
|
||||
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
|
||||
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
||||
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
|
||||
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.3.0 h1:/NQi8KHMpKWHInxXesC8yD4DhkXPrVhmnwYkjp9AmBA=
|
||||
github.com/jackc/pgx/v5 v5.3.0/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
|
||||
github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
|
||||
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4=
|
||||
github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
|
||||
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/slack-go/slack v0.12.1 h1:X97b9g2hnITDtNsNe5GkGx6O2/Sz/uC20ejRZN6QxOw=
|
||||
github.com/slack-go/slack v0.12.1/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
|
||||
github.com/spf13/afero v1.9.4 h1:Sd43wM1IWz/s1aVXdOBkjJvuP8UdyqioeE4AmM0QsBs=
|
||||
github.com/spf13/afero v1.9.4/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
|
||||
github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/ugorji/go/codec v1.2.10 h1:eimT6Lsr+2lzmSZxPhLFoOWFmQqwk0fllJJ5hEbTXtQ=
|
||||
github.com/ugorji/go/codec v1.2.10/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ=
|
||||
go.opentelemetry.io/otel v1.13.0 h1:1ZAKnNQKwBBxFtww/GwxNUyTf0AxkZzrukO8MeXqe4Y=
|
||||
go.opentelemetry.io/otel v1.13.0/go.mod h1:FH3RtdZCzRkJYFTCsAKDy9l/XYjMdNv6QrkFFB8DvVg=
|
||||
go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM=
|
||||
go.opentelemetry.io/otel/trace v1.13.0 h1:CBgRZ6ntv+Amuj1jDsMhZtlAPT6gbyIRdaIzFhfBSdY=
|
||||
go.opentelemetry.io/otel/trace v1.13.0/go.mod h1:muCvmmO9KKpvuXSf3KKAXXB2ygNYHQ+ZfI5X08d3tds=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.2.0 h1:W1sUEHXiJTfjaFJ5SLo0N6lZn+0eO5gWD1MFeTGqQEY=
|
||||
golang.org/x/arch v0.2.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk=
|
||||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.107.0 h1:I2SlFjD8ZWabaIFOfeEDg3pf0BHJDh6iYQ1ic3Yu/UU=
|
||||
google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY=
|
||||
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
|
||||
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/postgres v1.4.8 h1:NDWizaclb7Q2aupT0jkwK8jx1HVCNzt+PQ8v/VnxviA=
|
||||
gorm.io/driver/postgres v1.4.8/go.mod h1:O9MruWGNLUBUWVYfWuBClpf3HeGjOoybY0SNmCs3wsw=
|
||||
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.5 h1:g6OPREKqqlWq4kh/3MCQbZKImeB9e6Xgc4zD+JgNZGE=
|
||||
gorm.io/gorm v1.24.5/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
BIN
golang-1.png
Normal file
BIN
golang-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 138 KiB |
BIN
model/.DS_Store
vendored
Normal file
BIN
model/.DS_Store
vendored
Normal file
Binary file not shown.
29
model/create_incident.go
Normal file
29
model/create_incident.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CreateIncident struct {
|
||||
IncidentType string `json:"incident_type,omitempty"`
|
||||
Pagerduty string `json:"pagerduty,omitempty"`
|
||||
IncidentTitle string `json:"incident_title,omitempty"`
|
||||
IncidentDescription string `json:"incident_description,omitempty"`
|
||||
RequestOriginatedSlackChannel string
|
||||
IncidentSeverity string `json:"incident_severity,omitempty"`
|
||||
Status entity.IncidentStatus
|
||||
IncidentName string
|
||||
SlackChannel string
|
||||
DetectionTime time.Time
|
||||
CustomerImpactStartTime time.Time
|
||||
CustomerImpactEndTime time.Time
|
||||
TeamsId int
|
||||
JiraId string
|
||||
ConfluenceId string
|
||||
RemindMeAt time.Time
|
||||
EnableReminder bool
|
||||
CreatedBy string
|
||||
UpdatedBy string
|
||||
Version int
|
||||
}
|
||||
7
model/request/create_message.go
Normal file
7
model/request/create_message.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package request
|
||||
|
||||
type CreateMessage struct {
|
||||
SlackChannel string `gorm:"column:slack_channel"`
|
||||
IncidentName string `gorm:"column:incident_name"`
|
||||
MessageTimeStamp string `gorm:"column:message_timestamp"`
|
||||
}
|
||||
10
model/request/incident_role.go
Normal file
10
model/request/incident_role.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package request
|
||||
|
||||
import "houston/entity"
|
||||
|
||||
type AddIncidentRoleRequest struct {
|
||||
UserId string `json:"users_select,omitempty"`
|
||||
Role entity.IncidentRole `json:"role_type,omitempty"`
|
||||
IncidentId int
|
||||
CreatedById string
|
||||
}
|
||||
6
model/request/incident_status.go
Normal file
6
model/request/incident_status.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package request
|
||||
|
||||
type AddIncidentStatusRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
17
model/request/severity.go
Normal file
17
model/request/severity.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package request
|
||||
|
||||
type AddSeverityRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
type AddSeverityUserMappingRequest struct {
|
||||
SeverityId uint16 `json:"severity_id,omitempty"`
|
||||
Users []AddSeverityUserData `json:"users,omitempty"`
|
||||
}
|
||||
|
||||
type AddSeverityUserData struct {
|
||||
SlackUserId string `json:"slack_user_id,omitempty"`
|
||||
Primary bool `json:"primary,omitempty"`
|
||||
Secondary bool `json:"secondary,omitempty"`
|
||||
}
|
||||
6
model/request/team.go
Normal file
6
model/request/team.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package request
|
||||
|
||||
type AddTeamRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
OncallHandle string `json:"oncall_handle,omitempty"`
|
||||
}
|
||||
BIN
pkg/.DS_Store
vendored
Normal file
BIN
pkg/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
pkg/kafka/.DS_Store
vendored
Normal file
BIN
pkg/kafka/.DS_Store
vendored
Normal file
Binary file not shown.
80
pkg/kafka/config.go
Normal file
80
pkg/kafka/config.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package kafka
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Shopify/sarama"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func SaramaSyncProducer() (sarama.AsyncProducer, error) {
|
||||
return sarama.NewAsyncProducer(strings.Split(viper.GetString("kafka.brokers"), ","), kafkaProducerConfig())
|
||||
}
|
||||
|
||||
func SaramaKafkaConsumer(groupID string) (sarama.ConsumerGroup, error) {
|
||||
consumerGroup, err := sarama.NewConsumerGroup(strings.Split(viper.GetString("kafka.brokers"), ","), groupID, kafkaConsumerConfig(groupID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return consumerGroup, nil
|
||||
}
|
||||
|
||||
func kafkaProducerConfig() *sarama.Config {
|
||||
config := kafkaConfig()
|
||||
|
||||
config.Producer.Retry.Max = 3
|
||||
config.Producer.RequiredAcks = sarama.WaitForLocal
|
||||
config.Producer.Compression = sarama.CompressionSnappy
|
||||
config.Producer.Return.Successes = true
|
||||
config.Producer.Flush.Bytes = 100
|
||||
config.Producer.Flush.Frequency = 100
|
||||
config.Producer.Flush.Messages = 100
|
||||
config.Producer.Flush.MaxMessages = 100
|
||||
|
||||
config.Metadata.RefreshFrequency = 1 * time.Minute
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func kafkaConsumerConfig(groupId string) *sarama.Config {
|
||||
config := kafkaConfig()
|
||||
|
||||
config.Version = sarama.V3_3_1_0
|
||||
config.Consumer.Offsets.Initial = sarama.OffsetNewest
|
||||
config.Consumer.Return.Errors = true
|
||||
config.ClientID = groupId
|
||||
config.Consumer.Group.Rebalance.Strategy = sarama.BalanceStrategyRoundRobin
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func kafkaConfig() *sarama.Config {
|
||||
config := sarama.NewConfig()
|
||||
env := viper.GetString("env")
|
||||
|
||||
if env == "local" {
|
||||
return config
|
||||
}
|
||||
|
||||
if env == "prod" {
|
||||
config.Net.SASL.Mechanism = sarama.SASLTypePlaintext
|
||||
} else {
|
||||
config.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA512
|
||||
config.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient {
|
||||
return &XDGSCRAMClient{HashGeneratorFcn: SHA512}
|
||||
}
|
||||
}
|
||||
|
||||
config.Net.SASL.User = viper.GetString("kafka.username")
|
||||
config.Net.SASL.Password = viper.GetString("kafka.password")
|
||||
config.Net.SASL.Enable = viper.GetBool("kafka.sasl.enabled")
|
||||
config.Net.TLS.Enable = viper.GetBool("kafka.tls.enabled")
|
||||
config.Net.TLS.Config = &tls.Config{
|
||||
InsecureSkipVerify: viper.GetBool("kafka.tls.insecureSkipVerify"),
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
63
pkg/kafka/produce/produce.go
Normal file
63
pkg/kafka/produce/produce.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package kafka
|
||||
|
||||
import (
|
||||
"blaze/pkg/kafka"
|
||||
"os"
|
||||
|
||||
"github.com/Shopify/sarama"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type KProducer struct {
|
||||
sarama.AsyncProducer
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewKProducer(logger *zap.Logger) *KProducer {
|
||||
producer, err := kafka.SaramaSyncProducer()
|
||||
if err != nil {
|
||||
logger.Error("sarama kafka producer failed", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
kProducer := &KProducer{
|
||||
AsyncProducer: producer,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
kProducer.Errors()
|
||||
kProducer.Successes()
|
||||
|
||||
return kProducer
|
||||
}
|
||||
|
||||
// Errors keep the track of failed messages.
|
||||
func (kp *KProducer) Errors() {
|
||||
go func() {
|
||||
for err := range kp.AsyncProducer.Errors() {
|
||||
keyBytes, errEncode := err.Msg.Key.Encode()
|
||||
if errEncode != nil {
|
||||
kp.logger.Error("key encoding failed for failed message", zap.String("topic", err.Msg.Topic))
|
||||
}
|
||||
|
||||
// metrics.KafkaEventIngestionEventFailureCounter.WithLabelValues(err.Msg.Topic).Inc()
|
||||
kp.logger.Error("failed to emit event to kafka", zap.String("topic", err.Msg.Topic),
|
||||
zap.String("key", string(keyBytes)), zap.Any("value", string(keyBytes)), zap.String("error", err.Error()))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Successes is to check if message successfully delivered to kafka
|
||||
func (kp *KProducer) Successes() {
|
||||
go func() {
|
||||
for msg := range kp.AsyncProducer.Successes() {
|
||||
keyBytes, errEncode := msg.Key.Encode()
|
||||
if errEncode != nil {
|
||||
kp.logger.Error("key encoding failed for failed message", zap.String("topic", msg.Topic))
|
||||
}
|
||||
|
||||
// metrics.KafkaEventIngestionEventSuccessCounter.WithLabelValues(msg.Topic).Inc()
|
||||
kp.logger.Info("successfully ingested event to kafka", zap.String("topic", msg.Topic), zap.String("key", string(keyBytes)))
|
||||
}
|
||||
}()
|
||||
}
|
||||
21
pkg/postgres/config.go
Normal file
21
pkg/postgres/config.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func PQConnection(logger *zap.Logger) *gorm.DB {
|
||||
dsn := ""
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
logger.Error("database connection failed", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logger.Info("database connection successful")
|
||||
return db
|
||||
}
|
||||
71
pkg/postgres/query/contributing_factor.go
Normal file
71
pkg/postgres/query/contributing_factor.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func FindContributingFactorsByIncidentId(db *gorm.DB, incidentId int) (*entity.ContributingFactorEntity, error) {
|
||||
|
||||
var cf entity.ContributingFactorEntity
|
||||
result := db.Where("incidents_tags_contributing_factor_mapping.incident_id = ? AND contributing_factor.deleted_at is NULL AND incidents_tags_contributing_factor_mapping.deleted_at is NULL", incidentId).Joins("JOIN incidents_tags_contributing_factor_mapping on incidents_tags_contributing_factor_mapping.contributing_factor_id = contributing_factor.id").Find(&cf)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return &cf, nil
|
||||
}
|
||||
|
||||
func FetchAllContributingFactors(db *gorm.DB) ([]entity.ContributingFactorEntity, error) {
|
||||
var cf []entity.ContributingFactorEntity
|
||||
result := db.Find(&cf).Where("deleted_at is NULL")
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return cf, nil
|
||||
}
|
||||
|
||||
func UpsertContributingFactorIdToIncidentId(db *gorm.DB, cfId int, incidentId int) error {
|
||||
|
||||
incidentTagsContributingFactorMapping := &entity.IncidentTagsContributingFactorMapping{
|
||||
ContributingFactorId: cfId,
|
||||
IncidentId: incidentId,
|
||||
}
|
||||
var cf entity.IncidentTagsContributingFactorMapping
|
||||
result := db.Find(&cf).Where("incident_id = ? and contributing_factor_id = ? and deleted_at is NULL", incidentId, cfId)
|
||||
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 1 {
|
||||
cf.ContributingFactorId = cfId
|
||||
cf.UpdatedAt = time.Now()
|
||||
result := db.Save(cf)
|
||||
if result != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
} else if result.RowsAffected == 0 {
|
||||
addResult := db.Create(incidentTagsContributingFactorMapping)
|
||||
if addResult != nil {
|
||||
return addResult.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return gorm.ErrInvalidData
|
||||
|
||||
}
|
||||
|
||||
func SetContributingFactorDeletedAt(db *gorm.DB, incidentId int) error {
|
||||
var cf entity.IncidentTagsContributingFactorMapping
|
||||
result := db.Model(&cf).Where(" incident_id = ?", incidentId).Update("deleted_at", time.Now())
|
||||
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
63
pkg/postgres/query/customer_tags.go
Normal file
63
pkg/postgres/query/customer_tags.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func FindCustomerTagsByIncidentId(logger *zap.Logger, db *gorm.DB, incidentId int) ([]entity.CustomerTagsEntity, error) {
|
||||
|
||||
var customerTags []entity.CustomerTagsEntity
|
||||
result := db.Where("incidents_tags_customer_mapping.incident_id = ? AND customer_tags.deleted_at is NULL AND incidents_tags_customer_mapping.deleted_at is NULL", incidentId).Joins("JOIN incidents_tags_customer_mapping on incidents_tags_customer_mapping.customer_tags_id = customer_tags.id").Find(&customerTags)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return customerTags, nil
|
||||
}
|
||||
|
||||
func FetchAllCustomerTags(db *gorm.DB) ([]entity.CustomerTagsEntity, error) {
|
||||
var customerTags []entity.CustomerTagsEntity
|
||||
result := db.Find(&customerTags).Where("deleted_at is NULL")
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return customerTags, nil
|
||||
}
|
||||
|
||||
func FindCustomerTagIdMappingWithIncidentByIncidentId(db *gorm.DB, incidentId int) ([]entity.IncidentTagsCustomerMapping, error) {
|
||||
var incidentTagsCustomerMapping []entity.IncidentTagsCustomerMapping
|
||||
result := db.Find(&incidentTagsCustomerMapping).Where("incident_id = ? AND deleted_at is NULL")
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return incidentTagsCustomerMapping, nil
|
||||
}
|
||||
|
||||
func SetIncidentCustomerTagDeletedAt(db *gorm.DB, customerTagId int, incidentId int) error {
|
||||
var incidentTagsCustomerMapping entity.IncidentTagsCustomerMapping
|
||||
result := db.Model(&incidentTagsCustomerMapping).Where("customer_tags_id = ? AND incident_id = ?", customerTagId, incidentId).Update("deleted_at", time.Now())
|
||||
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func AddCustomerIdMappingToIncidentId(db *gorm.DB, customerTagId int, incidentId int) error {
|
||||
var incidentTagsCustomerMapping = &entity.IncidentTagsCustomerMapping{
|
||||
IncidentId: incidentId,
|
||||
CustomerTagsId: customerTagId,
|
||||
}
|
||||
|
||||
result := db.Create(incidentTagsCustomerMapping)
|
||||
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
104
pkg/postgres/query/incident.go
Normal file
104
pkg/postgres/query/incident.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"houston/model"
|
||||
"strconv"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func CreateIncident(db *gorm.DB, request *model.CreateIncident) (*entity.IncidentEntity, error) {
|
||||
severityId, err := strconv.Atoi(request.IncidentSeverity)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetch channel conversationInfo failed. err: %v", err)
|
||||
}
|
||||
incidentEntity := &entity.IncidentEntity{
|
||||
Title: request.IncidentTitle,
|
||||
Description: request.IncidentDescription,
|
||||
Status: request.Status,
|
||||
SeverityId: severityId,
|
||||
IncidentName: request.IncidentName,
|
||||
SlackChannel: request.SlackChannel,
|
||||
DetectionTime: request.DetectionTime,
|
||||
CustomerImpactStartTime: request.CustomerImpactStartTime,
|
||||
CustomerImpactEndTime: request.CustomerImpactEndTime,
|
||||
TeamsId: request.TeamsId,
|
||||
JiraId: request.JiraId,
|
||||
ConfluenceId: request.ConfluenceId,
|
||||
RemindMeAt: request.RemindMeAt,
|
||||
EnableReminder: request.EnableReminder,
|
||||
CreatedBy: request.CreatedBy,
|
||||
UpdatedBy: request.UpdatedBy,
|
||||
Version: request.Version,
|
||||
}
|
||||
|
||||
result := db.Create(incidentEntity)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
return incidentEntity, nil
|
||||
}
|
||||
|
||||
func UpdateIncident(db *gorm.DB, incidentEntity *entity.IncidentEntity) error {
|
||||
result := db.Updates(incidentEntity)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func FindIncidentById(db *gorm.DB, incidentId string) (*entity.IncidentEntity, error) {
|
||||
var incidentEntity entity.IncidentEntity
|
||||
|
||||
result := db.Find(&incidentEntity, "id = ?", incidentId)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
return &incidentEntity, nil
|
||||
}
|
||||
|
||||
func FindNotResolvedLatestIncidents(db *gorm.DB, limit int) ([]entity.IncidentSeverityTeamJoinEntity, error) {
|
||||
var incidentSeverityTeamJoinEntity []entity.IncidentSeverityTeamJoinEntity
|
||||
|
||||
result := db.Limit(limit).Where("status <> ? AND incidents.deleted_at IS NULL", entity.Resolved).Order("incidents.created_at desc").Joins("JOIN severity ON severity.id = incidents.severity_id").Joins("JOIN teams ON teams.id = incidents.teams_id").Select("incidents.title,incidents.status,incidents.slack_channel,severity.id as severity_id,severity.name as severity_name,teams.id as teams_id,teams.name as teams_name").Find(&entity.IncidentEntity{}).Scan(&incidentSeverityTeamJoinEntity)
|
||||
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
return incidentSeverityTeamJoinEntity, nil
|
||||
}
|
||||
|
||||
func FindIncidentByChannelId(db *gorm.DB, channelId string) (*entity.IncidentEntity, error) {
|
||||
var incidentEntity entity.IncidentEntity
|
||||
|
||||
result := db.Find(&incidentEntity, "slack_channel = ?", channelId)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &incidentEntity, nil
|
||||
}
|
||||
|
||||
func FindIncidentSeverityTeamJoin(db *gorm.DB, slackChannelId string) (*entity.IncidentSeverityTeamJoinEntity, error) {
|
||||
var incidentSeverityTeamJoinEntity entity.IncidentSeverityTeamJoinEntity
|
||||
|
||||
result := db.Where("incidents.slack_channel = ? and incidents.deleted_at IS NULL", slackChannelId).Joins("JOIN severity ON severity.id = incidents.severity_id").Joins("JOIN teams ON teams.id = incidents.teams_id").Select("incidents.id as incident_id,incidents.title,incidents.status,incidents.slack_channel,severity.id as severity_id,severity.name as severity_name,teams.id as teams_id,teams.name as teams_name").Find(&entity.IncidentEntity{}).Scan(&incidentSeverityTeamJoinEntity)
|
||||
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &incidentSeverityTeamJoinEntity, nil
|
||||
}
|
||||
42
pkg/postgres/query/incident_role.go
Normal file
42
pkg/postgres/query/incident_role.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"houston/model/request"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func UpsertIncidentRole(db *gorm.DB, addIncidnentRoleRequest *request.AddIncidentRoleRequest) error {
|
||||
incidentRolesEntity := &entity.IncidentRoles{
|
||||
IncidentId: addIncidnentRoleRequest.IncidentId,
|
||||
Role: addIncidnentRoleRequest.Role,
|
||||
AssignedToUserSlackId: addIncidnentRoleRequest.UserId,
|
||||
AssignedByUserSlackId: addIncidnentRoleRequest.CreatedById,
|
||||
}
|
||||
var incidentRoles entity.IncidentRoles
|
||||
|
||||
result := db.Find(&incidentRoles, "incident_id = ? AND role = ?", addIncidnentRoleRequest.IncidentId, addIncidnentRoleRequest.Role)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 1 {
|
||||
incidentRolesEntity.ID = incidentRoles.ID
|
||||
incidentRolesEntity.CreatedAt = incidentRoles.CreatedAt
|
||||
incidentRolesEntity.UpdatedAt = time.Now()
|
||||
addResult := db.Save(incidentRolesEntity)
|
||||
if addResult != nil {
|
||||
return addResult.Error
|
||||
}
|
||||
return nil
|
||||
|
||||
} else if result.RowsAffected == 0 {
|
||||
addResult := db.Create(incidentRolesEntity)
|
||||
if addResult != nil {
|
||||
return addResult.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return gorm.ErrInvalidData
|
||||
}
|
||||
45
pkg/postgres/query/incident_status.go
Normal file
45
pkg/postgres/query/incident_status.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"houston/model/request"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func CreateIncidentStatus(db *gorm.DB, request *request.AddIncidentStatusRequest) error {
|
||||
incidentStatusEntity := &entity.IncidentStatusEntity{
|
||||
Name: request.Name,
|
||||
Description: request.Description,
|
||||
}
|
||||
|
||||
result := db.Create(incidentStatusEntity)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindIncidentStatusById(db *gorm.DB, incidentStatusId int) (*entity.IncidentStatusEntity, error) {
|
||||
var incidentStatusEntity entity.IncidentStatusEntity
|
||||
|
||||
result := db.Find(&incidentStatusEntity, "id = ?", incidentStatusId)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &incidentStatusEntity, nil
|
||||
}
|
||||
|
||||
func FetchAllIncidentStatus(db *gorm.DB) ([]entity.IncidentStatusEntity, error) {
|
||||
var incidentStatusEntity []entity.IncidentStatusEntity
|
||||
result := db.Find(&incidentStatusEntity)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return incidentStatusEntity, nil
|
||||
}
|
||||
52
pkg/postgres/query/incidents_tags_data_platform_mapping.go
Normal file
52
pkg/postgres/query/incidents_tags_data_platform_mapping.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func FindDataPlataformTagsByIncidentId(incidenttId int, db *gorm.DB, logger *zap.Logger) (*entity.IncidentsTagsDataPlatformMapping, error) {
|
||||
|
||||
var cf entity.IncidentsTagsDataPlatformMapping
|
||||
result := db.Where("incidents_tags_data_platform_mapping.incident_id = ? AND incidents_tags_data_platform_mapping.deleted_at is NULL", incidenttId).Find(&cf)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return &cf, nil
|
||||
}
|
||||
|
||||
func UpsertDataPlatformTagToIncidentId(db *gorm.DB, dataPlatform string, incidentId int) error {
|
||||
dpEntity := &entity.IncidentsTagsDataPlatformMapping{
|
||||
DataPlatformTag: dataPlatform,
|
||||
IncidentId: incidentId,
|
||||
}
|
||||
var dp entity.IncidentsTagsDataPlatformMapping
|
||||
result := db.Where("incident_id = ? and deleted_at is NULL", incidentId).Find(&dp)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 1 {
|
||||
dp.DataPlatformTag = dataPlatform
|
||||
dp.UpdatedAt = time.Now()
|
||||
addResult := db.Save(dp)
|
||||
if addResult != nil {
|
||||
return addResult.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
} else if result.RowsAffected == 0 {
|
||||
addResult := db.Create(dpEntity)
|
||||
if addResult != nil {
|
||||
return addResult.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return gorm.ErrInvalidData
|
||||
|
||||
}
|
||||
38
pkg/postgres/query/messages.go
Normal file
38
pkg/postgres/query/messages.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"houston/model/request"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func CreateMessage(db *gorm.DB, request *request.CreateMessage) (error) {
|
||||
messageEntity := &entity.MessageEntity {
|
||||
SlackChannel: request.SlackChannel,
|
||||
MessageTimeStamp: request.MessageTimeStamp,
|
||||
IncidentName: request.IncidentName,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
Version: 0,
|
||||
}
|
||||
|
||||
result := db.Create(&messageEntity)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindMessageByIncidentName(db *gorm.DB, incidentName string) ([]entity.MessageEntity, error) {
|
||||
var messages []entity.MessageEntity
|
||||
|
||||
result := db.Find(&messages, "incident_name = ?", incidentName)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
return messages, nil
|
||||
}
|
||||
72
pkg/postgres/query/severity.go
Normal file
72
pkg/postgres/query/severity.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"houston/model/request"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func FindSeverity(db *gorm.DB, logger *zap.Logger) ([]entity.SeverityEntity, error) {
|
||||
var severityEntity []entity.SeverityEntity
|
||||
result := db.Find(&severityEntity)
|
||||
if result.Error != nil {
|
||||
logger.Error("fetching severity query failed", zap.Error(result.Error))
|
||||
return nil, result.Error
|
||||
}
|
||||
return severityEntity, nil
|
||||
}
|
||||
|
||||
func FindIncidentSeverityEntity(db *gorm.DB, logger *zap.Logger) ([]entity.SeverityEntity, error) {
|
||||
var severityEntity []entity.SeverityEntity
|
||||
|
||||
result := db.Find(&severityEntity).Where("deleted_at is NULL")
|
||||
if result.Error != nil {
|
||||
logger.Error("fetching severity query failed", zap.Error(result.Error))
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
return severityEntity, nil
|
||||
}
|
||||
|
||||
func FindIncidentSeverityEntityById(db *gorm.DB, logger *zap.Logger, id int) (*entity.SeverityEntity, error) {
|
||||
var severityEntity entity.SeverityEntity
|
||||
|
||||
result := db.Find(&severityEntity, "id = ?", id)
|
||||
if result.Error != nil {
|
||||
logger.Error("fetching severity query failed", zap.Error(result.Error))
|
||||
return nil, result.Error
|
||||
} else if result.RowsAffected == 0 {
|
||||
logger.Error("SeverityEntity not found", zap.Error(result.Error))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &severityEntity, nil
|
||||
}
|
||||
|
||||
func AddSeverity(db *gorm.DB, logger *zap.Logger, addSeverityRequest request.AddSeverityRequest) error {
|
||||
severityEntity := &entity.SeverityEntity{
|
||||
Name: addSeverityRequest.Name,
|
||||
Description: addSeverityRequest.Description,
|
||||
}
|
||||
|
||||
result := db.Create(severityEntity)
|
||||
if result.Error != nil {
|
||||
logger.Error("failed to add severity in the database", zap.Error(result.Error))
|
||||
return result.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindSeverityById(db *gorm.DB, severityId int) (*entity.SeverityEntity, error) {
|
||||
var severityEntity entity.SeverityEntity
|
||||
|
||||
result := db.Find(&severityEntity, "id = ?", severityId)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
return &severityEntity, nil
|
||||
}
|
||||
133
pkg/postgres/query/tags.go
Normal file
133
pkg/postgres/query/tags.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func FindTagsByTeamsId(db *gorm.DB, teamsId int) ([]entity.TagsEntity, error) {
|
||||
var tags []entity.TagsEntity
|
||||
|
||||
result := db.Where("teams_tags_mapping.teams_id = ? AND teams_tags_mapping.deleted_at IS NULL", teamsId).Joins("JOIN teams_tags_mapping ON tags.id = teams_tags_mapping.tag_id").Find(&tags)
|
||||
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
func FindTagsByIncidentId(db *gorm.DB, incidentId int) ([]entity.TagsEntity, error) {
|
||||
var tags []entity.TagsEntity
|
||||
|
||||
result := db.Where("incidents_tags_mapping.incident_id = ? AND incidents_tags_mapping.deleted_at IS NULL", incidentId).Joins("JOIN incidents_tags_mapping ON incidents_tags_mapping.tag_id = tags.id").Find(&tags)
|
||||
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
func AddTagsIdMappingToTeamsId(db *gorm.DB, tagsId int, teamsId int) error {
|
||||
teamsTagsMapping := &entity.TeamTagsMapping{
|
||||
TeamsId: teamsId,
|
||||
TagId: tagsId,
|
||||
}
|
||||
result := db.Create(teamsTagsMapping)
|
||||
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func FindTagRecordByTeamsIdAndTagsId(db *gorm.DB, tagsId int, teamsId int) (*entity.TagsEntity, error) {
|
||||
var tagsMapping entity.TagsEntity
|
||||
|
||||
result := db.Find(tagsMapping).Where("tagsId = ? AND teamsId = ? AND deleted_at IS NULL", tagsId, teamsId).Joins("JOIN teams_tags_mapping ON tags.id = teams_tags_mapping.tags_id")
|
||||
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return &tagsMapping, nil
|
||||
|
||||
}
|
||||
|
||||
func FindTagRecordByIncidentSlackChannelIddAndTagsId(db *gorm.DB, tagsId int, incidentSlackChannelId string) (*entity.IncidentsTagsMapping, error) {
|
||||
var incidentsTagsMapping entity.IncidentsTagsMapping
|
||||
|
||||
result := db.Find(incidentsTagsMapping).Where("incident_id = ? AND tags_id = ? AND deleted_at IS NULL", incidentSlackChannelId, tagsId)
|
||||
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return &incidentsTagsMapping, nil
|
||||
|
||||
}
|
||||
|
||||
func FindTagRecordListByIncidentId(db *gorm.DB, incidenId int) ([]entity.IncidentsTagsMapping, error) {
|
||||
var incidentsTagsMapping []entity.IncidentsTagsMapping
|
||||
|
||||
result := db.Find(&incidentsTagsMapping).Where("incident_id = ? AND deleted_at IS NULL", incidenId)
|
||||
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
return incidentsTagsMapping, nil
|
||||
|
||||
}
|
||||
|
||||
func AddTagsIdMappingToIncidentId(db *gorm.DB, tagId, incidenId int) error {
|
||||
var incidentsTagsMapping = &entity.IncidentsTagsMapping{
|
||||
IncidentId: incidenId,
|
||||
TagId: tagId,
|
||||
}
|
||||
|
||||
result := db.Create(incidentsTagsMapping)
|
||||
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func SetTagsDeletedAt(db *gorm.DB, tagId int, resultId int) error {
|
||||
|
||||
var incidentTags entity.IncidentsTagsMapping
|
||||
result := db.Model(&incidentTags).Where("tag_id = ? AND incident_id = ?", tagId, resultId).Update("deleted_at", time.Now())
|
||||
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func FindTagsById(db *gorm.DB, tagId int) (*entity.TagsEntity, error) {
|
||||
var tagsEntity entity.TagsEntity
|
||||
|
||||
result := db.Find(tagsEntity).Where("id = ? AND deleted_at IS NULL", tagId)
|
||||
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return &tagsEntity, nil
|
||||
|
||||
}
|
||||
70
pkg/postgres/query/teams.go
Normal file
70
pkg/postgres/query/teams.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"houston/model/request"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func FindTeam(db *gorm.DB) ([]string, error) {
|
||||
teams := make([]string, 0)
|
||||
var teamEntity []entity.TeamEntity
|
||||
result := db.Find(&teamEntity, "active = ?", true)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
for _, team := range teamEntity {
|
||||
teams = append(teams, team.Name)
|
||||
}
|
||||
|
||||
return teams, nil
|
||||
}
|
||||
|
||||
func FindTeamList(db *gorm.DB) ([]entity.TeamEntity, error) {
|
||||
var teamEntity []entity.TeamEntity
|
||||
result := db.Find(&teamEntity, "active = ?", true)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
return teamEntity, nil
|
||||
}
|
||||
|
||||
func FindTeamByName(db *gorm.DB, name string) (*entity.TeamEntity, error) {
|
||||
var teamEntity entity.TeamEntity
|
||||
result := db.Find(&teamEntity, "name = ?", name)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
return &teamEntity, nil
|
||||
}
|
||||
|
||||
func AddTeam(db *gorm.DB, addTeamRequest request.AddTeamRequest) error {
|
||||
teamEntity := &entity.TeamEntity{
|
||||
Name: addTeamRequest.Name,
|
||||
OncallHandle: addTeamRequest.OncallHandle,
|
||||
}
|
||||
|
||||
result := db.Create(teamEntity)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindTeamById(db *gorm.DB, teamId int) (*entity.TeamEntity, error) {
|
||||
var teamEntity entity.TeamEntity
|
||||
|
||||
result := db.Find(&teamEntity, "id = ?", teamId)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
} else if result.RowsAffected == 0 {
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
|
||||
return &teamEntity, nil
|
||||
}
|
||||
35
pkg/postgres/query/users.go
Normal file
35
pkg/postgres/query/users.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func FindDefaultUserIdToBeAddedBySeverity(db *gorm.DB, severityId int) ([]string, error) {
|
||||
userIds := make([]string, 0)
|
||||
var user []entity.UsersEntity
|
||||
result := db.Where("users.active = true And teams_severity_user_mapping.deleted_at is NULL AND teams_severity_user_mapping.default_add_in_incidents = ? AND teams_severity_user_mapping.entity_type = ? AND teams_severity_user_mapping.entity_id = ?", true, entity.SEVERITY, severityId).Joins("JOIN teams_severity_user_mapping on teams_severity_user_mapping.users_id = users.id").Find(&user)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
for _, users := range user {
|
||||
userIds = append(userIds, users.SlackUserId)
|
||||
}
|
||||
|
||||
return userIds, nil
|
||||
}
|
||||
|
||||
func FindDefaultUserIdToBeAddedByTeam(db *gorm.DB, teamId int) ([]string, error) {
|
||||
userIds := make([]string, 0)
|
||||
var user []entity.UsersEntity
|
||||
result := db.Where("users.active = true And teams_severity_user_mapping.deleted_at is NULL AND teams_severity_user_mapping.default_add_in_incidents = ? AND teams_severity_user_mapping.entity_type = ? AND teams_severity_user_mapping.entity_id = ?", true, entity.TEAM, teamId).Joins("JOIN teams_severity_user_mapping on teams_severity_user_mapping.users_id = users.id").Find(&user)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
for _, users := range user {
|
||||
userIds = append(userIds, users.SlackUserId)
|
||||
}
|
||||
|
||||
return userIds, nil
|
||||
}
|
||||
BIN
pkg/slack/.DS_Store
vendored
Normal file
BIN
pkg/slack/.DS_Store
vendored
Normal file
Binary file not shown.
49
pkg/slack/common/channel.go
Normal file
49
pkg/slack/common/channel.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func FindParticipants(client *socketmode.Client, logger *zap.Logger, channelId string) ([]string, error) {
|
||||
request := &slack.GetUsersInConversationParameters{
|
||||
ChannelID: channelId,
|
||||
Limit: 1000,
|
||||
}
|
||||
channelInfo, _, err := client.GetUsersInConversation(request)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetch channel conversationInfo failed. err: %v", err)
|
||||
}
|
||||
|
||||
return channelInfo, nil
|
||||
}
|
||||
|
||||
func CreateChannel(client *socketmode.Client, logger *zap.Logger, channelName string) (string, error) {
|
||||
request := slack.CreateConversationParams{
|
||||
ChannelName: channelName,
|
||||
IsPrivate: false,
|
||||
}
|
||||
|
||||
channel, err := client.CreateConversation(request)
|
||||
if err != nil {
|
||||
logger.Error("create slack channel failed", zap.String("channel_name", channelName), zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
logger.Info("created slack channel successfully", zap.String("channel_name", channelName), zap.String("channel_id", channel.ID))
|
||||
return channel.ID, nil
|
||||
}
|
||||
|
||||
func InviteUsersToConversation(client *socketmode.Client, logger *zap.Logger, channelId string, userId ...string) {
|
||||
_, err := client.InviteUsersToConversation(channelId, userId...)
|
||||
if err != nil {
|
||||
logger.Error("invite users to conversation failed",
|
||||
zap.String("channel_id", channelId), zap.Any("user_ids", userId), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("successfully invite users to conversation", zap.String("channel_id", channelId), zap.Any("user_ids", userId))
|
||||
}
|
||||
1
pkg/slack/config.go
Normal file
1
pkg/slack/config.go
Normal file
@@ -0,0 +1 @@
|
||||
package slack
|
||||
38
pkg/slack/houston/blazeless_main_command.go
Normal file
38
pkg/slack/houston/blazeless_main_command.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"houston/pkg/postgres/query"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func HoustonMainCommand(db *gorm.DB, client *socketmode.Client, logger *zap.Logger, evt *socketmode.Event) {
|
||||
cmd, ok := evt.Data.(slack.SlashCommand)
|
||||
logger.Info("processing houston command", zap.Any("payload", cmd))
|
||||
if !ok {
|
||||
logger.Error("event data to slash command conversion failed", zap.Any("data", evt))
|
||||
return
|
||||
}
|
||||
|
||||
//TODO - DOES NOT THROW ERROR IF SAME SLACK ID IS PRESENT MULTIPLE TIMES
|
||||
result, err := query.FindIncidentByChannelId(db, cmd.ChannelID)
|
||||
if err != nil {
|
||||
logger.Error("FindIncidentBySlackChannelId errors",
|
||||
zap.String("channel_id", cmd.ChannelID), zap.String("channel", cmd.ChannelName),
|
||||
zap.String("user_id", cmd.UserID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
if result != nil {
|
||||
logger.Info("Result", zap.String("result", result.IncidentName))
|
||||
payload := houston.OptionsBlock()
|
||||
client.Ack(*evt.Request, payload)
|
||||
}
|
||||
|
||||
payload := houston.ButtonDesign()
|
||||
client.Ack(*evt.Request, payload)
|
||||
}
|
||||
599
pkg/slack/houston/command/020003558014
Normal file
599
pkg/slack/houston/command/020003558014
Normal file
@@ -0,0 +1,599 @@
|
||||
020003558014
|
||||
020003900893
|
||||
020003333489
|
||||
027620996
|
||||
020003445139
|
||||
021702862
|
||||
027409590
|
||||
020004267232
|
||||
025883146
|
||||
020000040077
|
||||
027259677
|
||||
020003732743
|
||||
020003341765
|
||||
020004269102
|
||||
020003447657
|
||||
020003300976
|
||||
020003524585
|
||||
020003454356
|
||||
020004506061
|
||||
021583078
|
||||
020003576779
|
||||
022465360
|
||||
020003341738
|
||||
026592869
|
||||
020004408853
|
||||
020003680059
|
||||
020003521018
|
||||
020004464121
|
||||
020004295982
|
||||
020004699471
|
||||
020003492076
|
||||
020004421882
|
||||
020003620905
|
||||
021844073
|
||||
020003905104
|
||||
020004835161
|
||||
021830531
|
||||
020003530514
|
||||
020003331307
|
||||
020003424364
|
||||
020004395272
|
||||
025911471
|
||||
020003830373
|
||||
020003509994
|
||||
020004066362
|
||||
020004205112
|
||||
020162216
|
||||
020004010831
|
||||
026504309
|
||||
020003765224
|
||||
020003565794
|
||||
024415636
|
||||
024086936
|
||||
020003423080
|
||||
020003841894
|
||||
021628510
|
||||
020003422987
|
||||
026117018
|
||||
020004575492
|
||||
020004259951
|
||||
020003718823
|
||||
027599428
|
||||
020003181757
|
||||
028267509
|
||||
029988750
|
||||
020003502316
|
||||
020004649161
|
||||
022524458
|
||||
022408293
|
||||
020004653651
|
||||
020003318189
|
||||
020004017401
|
||||
020003446105
|
||||
020003734153
|
||||
020003404739
|
||||
022535780
|
||||
020003020055
|
||||
020003305629
|
||||
020003641184
|
||||
020003309586
|
||||
021866406
|
||||
025109686
|
||||
020663707
|
||||
028204765
|
||||
020003519985
|
||||
020003719493
|
||||
020003509334
|
||||
020003984191
|
||||
020004263641
|
||||
020003654445
|
||||
020006116642
|
||||
020007731381
|
||||
020005767123
|
||||
020004848105
|
||||
020005929313
|
||||
020006498112
|
||||
020004477507
|
||||
020005393927
|
||||
020004781476
|
||||
020006272862
|
||||
|
||||
|
||||
020005322935
|
||||
020005236375
|
||||
020005303595
|
||||
020005488425
|
||||
020004654559
|
||||
020006051913
|
||||
020005488175
|
||||
020004608600
|
||||
020005492575
|
||||
020005312368
|
||||
020005304248
|
||||
020005315735
|
||||
020007508881
|
||||
020004823974
|
||||
020006194523
|
||||
020005246918
|
||||
020006404662
|
||||
020007650991
|
||||
020005356386
|
||||
020005786724
|
||||
020005968223
|
||||
020005821414
|
||||
020006612462
|
||||
020007973331
|
||||
020008056531
|
||||
020007582001
|
||||
020004823859
|
||||
020006077182
|
||||
020008088441
|
||||
020007926721
|
||||
020003841686
|
||||
020005397835
|
||||
020006364113
|
||||
020004593200
|
||||
020005882723
|
||||
020005439094
|
||||
020008022001
|
||||
020006649852
|
||||
020007854771
|
||||
020005859074
|
||||
020005151627
|
||||
020005354737
|
||||
020007799021
|
||||
020004753940
|
||||
020005431224
|
||||
020005414436
|
||||
020005428978
|
||||
020006698082
|
||||
020005613886
|
||||
020005283297
|
||||
020007780281
|
||||
|
||||
|
||||
|
||||
020007091041
|
||||
020006582162
|
||||
020008101671
|
||||
020006309823
|
||||
020008344001
|
||||
020008364981
|
||||
020005674135
|
||||
020005019339
|
||||
020006693612
|
||||
020005633437
|
||||
020004730030
|
||||
020005927584
|
||||
020005447816
|
||||
020005660997
|
||||
020006171863
|
||||
020005667075
|
||||
020005314367
|
||||
020006163912
|
||||
020004791270
|
||||
020008274491
|
||||
020007904631
|
||||
020004441634
|
||||
020004442564
|
||||
020003977800
|
||||
020005083822
|
||||
020003883850
|
||||
020003901247
|
||||
020003800026
|
||||
020005794061
|
||||
020005262551
|
||||
020004367433
|
||||
020004474784
|
||||
020005925561
|
||||
020006074041
|
||||
020004749644
|
||||
020004862063
|
||||
020004767843
|
||||
020004060670
|
||||
020004066814
|
||||
025221920
|
||||
020003707965
|
||||
020003605755
|
||||
020005994721
|
||||
020005172043
|
||||
020004949973
|
||||
020004225623
|
||||
020004185030
|
||||
020003851584
|
||||
020004266845
|
||||
020004048067
|
||||
|
||||
|
||||
|
||||
020004523853
|
||||
020004529807
|
||||
020003750367
|
||||
020004016159
|
||||
020004291054
|
||||
020004687113
|
||||
020004518973
|
||||
020006395481
|
||||
020004622625
|
||||
020004051316
|
||||
020003562855
|
||||
020004031785
|
||||
020004391227
|
||||
020005664332
|
||||
020004105055
|
||||
020004280939
|
||||
020004105319
|
||||
020004351819
|
||||
020004845424
|
||||
020004359819
|
||||
020006265381
|
||||
020005322412
|
||||
020004719983
|
||||
020005631321
|
||||
020003895569
|
||||
020003912236
|
||||
020006657611
|
||||
020004048521
|
||||
020003843318
|
||||
020004308010
|
||||
020003956458
|
||||
020004516044
|
||||
020004028898
|
||||
020006388711
|
||||
020005244533
|
||||
020004855953
|
||||
020004317519
|
||||
020005589062
|
||||
020004403309
|
||||
020005639722
|
||||
020006468191
|
||||
020004475026
|
||||
020006503751
|
||||
020004094780
|
||||
020005344703
|
||||
020004962484
|
||||
020004085627
|
||||
020003857609
|
||||
020006681381
|
||||
020004603504
|
||||
020006700661
|
||||
020003756527
|
||||
020004029457
|
||||
020004579728
|
||||
020005137302
|
||||
020004580898
|
||||
020004640226
|
||||
020005324463
|
||||
020004611985
|
||||
020004589018
|
||||
020004701175
|
||||
020005067154
|
||||
020006844231
|
||||
020004378755
|
||||
020004705107
|
||||
020004728556
|
||||
020005225482
|
||||
020004324990
|
||||
020005703772
|
||||
020003958907
|
||||
020005829962
|
||||
020004812545
|
||||
020005599603
|
||||
020004553915
|
||||
020005909552
|
||||
020004592108
|
||||
020004373517
|
||||
020004236989
|
||||
020004740387
|
||||
020004953424
|
||||
020005419151
|
||||
020006204921
|
||||
020004432370
|
||||
020005246083
|
||||
020004809305
|
||||
020004921568
|
||||
020006414051
|
||||
020004699517
|
||||
020004686966
|
||||
020004507368
|
||||
020004845566
|
||||
020006843091
|
||||
020005607562
|
||||
020005928102
|
||||
020005490352
|
||||
020004696605
|
||||
020004865257
|
||||
020005575043
|
||||
020004987926
|
||||
020003414947
|
||||
028026488
|
||||
020003597024
|
||||
020004738471
|
||||
020003564164
|
||||
020004553411
|
||||
020003461578
|
||||
022691120
|
||||
020003182638
|
||||
020004777461
|
||||
020004064332
|
||||
020744216
|
||||
027498632
|
||||
020003506595
|
||||
023032271
|
||||
020005744212
|
||||
020004885505
|
||||
020005900452
|
||||
020004693747
|
||||
020005074815
|
||||
020005468072
|
||||
020003764580
|
||||
020004965517
|
||||
020007176641
|
||||
020005283484
|
||||
020005713413
|
||||
020005236293
|
||||
020005720442
|
||||
020004330539
|
||||
020005531753
|
||||
020007034831
|
||||
020007305511
|
||||
020005861982
|
||||
020005775983
|
||||
020003788957
|
||||
020005975172
|
||||
020004663899
|
||||
020005386144
|
||||
020006609581
|
||||
020004133039
|
||||
020005035375
|
||||
020004884588
|
||||
020005099556
|
||||
020007390911
|
||||
020005760873
|
||||
020005021048
|
||||
020006199092
|
||||
020005190004
|
||||
020004722715
|
||||
020005527164
|
||||
020007537971
|
||||
020004980066
|
||||
020004704249
|
||||
020005892283
|
||||
020004732207
|
||||
020006232942
|
||||
020004918868
|
||||
020005192896
|
||||
020007667311
|
||||
020004989398
|
||||
020007634441
|
||||
020005155257
|
||||
020006957991
|
||||
020007106211
|
||||
020005268715
|
||||
020007660811
|
||||
020004970205
|
||||
020004627675
|
||||
020004703536
|
||||
020007729571
|
||||
020007634671
|
||||
020005573314
|
||||
020004676109
|
||||
020004638768
|
||||
020005226084
|
||||
020005117416
|
||||
020005688292
|
||||
020005659304
|
||||
020004749349
|
||||
020006235552
|
||||
020004527110
|
||||
020007661711
|
||||
020005982203
|
||||
020005295306
|
||||
020007188841
|
||||
020007780811
|
||||
020004480188
|
||||
020007569521
|
||||
020006321722
|
||||
020004855608
|
||||
020005397565
|
||||
020005542684
|
||||
020007799701
|
||||
020005576724
|
||||
020005320687
|
||||
020006260652
|
||||
020005651084
|
||||
021699853
|
||||
020003211467
|
||||
020004212672
|
||||
020003311478
|
||||
023115669
|
||||
022053955
|
||||
020004028623
|
||||
020003854803
|
||||
022269713
|
||||
020004367491
|
||||
020003489234
|
||||
020003968141
|
||||
020004088703
|
||||
020004781631
|
||||
020003590698
|
||||
020003608224
|
||||
021764301
|
||||
024569436
|
||||
028897136
|
||||
020003347254
|
||||
027004176
|
||||
020003804756
|
||||
020003269885
|
||||
020004230903
|
||||
020909972
|
||||
020003690530
|
||||
020003226696
|
||||
020004083264
|
||||
020003742206
|
||||
025347015
|
||||
020004291153
|
||||
020004498423
|
||||
020003794844
|
||||
020003834190
|
||||
020003756936
|
||||
020003511559
|
||||
020003877095
|
||||
020003487918
|
||||
020004685822
|
||||
020003885889
|
||||
020003859649
|
||||
020003564235
|
||||
020004316152
|
||||
020003844290
|
||||
020003810679
|
||||
020004611121
|
||||
020004261744
|
||||
020003281276
|
||||
020003797567
|
||||
020004515253
|
||||
020004924352
|
||||
020003741998
|
||||
020004576931
|
||||
020003953776
|
||||
020004879391
|
||||
020003606930
|
||||
020003836000
|
||||
020003820747
|
||||
020004514243
|
||||
020004065301
|
||||
020004002255
|
||||
020003701809
|
||||
020003967615
|
||||
020004673341
|
||||
023079283
|
||||
020004371223
|
||||
020003834269
|
||||
020003998142
|
||||
020005491341
|
||||
020004762351
|
||||
020005058981
|
||||
020004007182
|
||||
020004365432
|
||||
020004243373
|
||||
020004081526
|
||||
020004109482
|
||||
020003898056
|
||||
020005321451
|
||||
020004066579
|
||||
020004152485
|
||||
020004386274
|
||||
020003626450
|
||||
020004306653
|
||||
020003746067
|
||||
020004007525
|
||||
020004174104
|
||||
020004034759
|
||||
020004118316
|
||||
020005108101
|
||||
020003575255
|
||||
020005378251
|
||||
020004803142
|
||||
020004605093
|
||||
020003578367
|
||||
020004499083
|
||||
020003684524
|
||||
020003956310
|
||||
020004024798
|
||||
020004911582
|
||||
020004676942
|
||||
020005315441
|
||||
020005450321
|
||||
020004520313
|
||||
020005014731
|
||||
020003667279
|
||||
020005111272
|
||||
020005045472
|
||||
020003872436
|
||||
020004030080
|
||||
020005636231
|
||||
020003800375
|
||||
020004406494
|
||||
020004175355
|
||||
020004066941
|
||||
020005318352
|
||||
020005022482
|
||||
020003932950
|
||||
020003842090
|
||||
020003950158
|
||||
020004532024
|
||||
023848787
|
||||
020004698222
|
||||
020003320654
|
||||
020004430581
|
||||
020003317020
|
||||
020003697824
|
||||
020003997801
|
||||
025731975
|
||||
020003413630
|
||||
020003374006
|
||||
020003980663
|
||||
027051673
|
||||
027208549
|
||||
029903465
|
||||
027792784
|
||||
020003311545
|
||||
020003356864
|
||||
022120906
|
||||
023757053
|
||||
020004074581
|
||||
020003527228
|
||||
020003297107
|
||||
020002220051
|
||||
020003526434
|
||||
020003740864
|
||||
020003438775
|
||||
020003958341
|
||||
025944636
|
||||
027254319
|
||||
028068077
|
||||
026641741
|
||||
020004125482
|
||||
020003629339
|
||||
020004398392
|
||||
022283492
|
||||
020003444186
|
||||
022260920
|
||||
020003506690
|
||||
021615995
|
||||
020003505914
|
||||
023691708
|
||||
020004385372
|
||||
020004292781
|
||||
020003413417
|
||||
026580479
|
||||
020004034222
|
||||
028432029
|
||||
020003384586
|
||||
020003438709
|
||||
020004034062
|
||||
020003506854
|
||||
020003373047
|
||||
022850287
|
||||
020003844314
|
||||
020004087263
|
||||
020004657911
|
||||
020003376667
|
||||
020004576882
|
||||
020003421694
|
||||
020003333266
|
||||
024739738
|
||||
020003609754
|
||||
022630719
|
||||
020003403645
|
||||
020003483055
|
||||
020004141901
|
||||
023640399
|
||||
020004177831
|
||||
020003979512
|
||||
024127386
|
||||
024093227
|
||||
027507965
|
||||
020004251691
|
||||
020003269657
|
||||
@@ -0,0 +1 @@
|
||||
["020007091041","020006582162","020008101671","020006309823","020008344001","020008364981","020005674135","020005019339","020006693612","020005633437","020004730030","020005927584","020005447816","020005660997","020006171863","020005667075","020005314367","020006163912","020004791270","020008274491","020007904631","020004441634","020004442564","020003977800","020005083822","020003883850","020003901247","020003800026","020005794061","020005262551","020004367433","020004474784","020005925561","020006074041","020004749644","020004862063","020004767843","020004060670","020004066814","025221920","020003707965","020003605755","020005994721","020005172043","020004949973","020004225623","020004185030","020003851584","020004266845","020004048067"]
|
||||
94
pkg/slack/houston/command/incident_assign.go
Normal file
94
pkg/slack/houston/command/incident_assign.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"houston/model/request"
|
||||
"houston/pkg/postgres/query"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidentAssignProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentAssignProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidentAssignProcessor {
|
||||
return &incidentAssignProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (iap *incidentAssignProcessor) IncidentAssignProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
|
||||
modalRequest := houston.GenerateModalForIncidentAssign(callback.Channel)
|
||||
_, err := iap.client.OpenView(callback.TriggerID, modalRequest)
|
||||
if err != nil {
|
||||
iap.logger.Error("houston slack openview command failed.",
|
||||
zap.String("trigger_id", callback.TriggerID), zap.String("channel_id", callback.Channel.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
iap.client.Ack(*request, payload)
|
||||
|
||||
}
|
||||
|
||||
func (iap *incidentAssignProcessor) IncidentAssignModalCommandProcessing(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
incidentEntity, err := query.FindIncidentByChannelId(iap.db, callback.View.PrivateMetadata)
|
||||
if err != nil {
|
||||
iap.logger.Error("FindIncidentByChannelId error",
|
||||
zap.String("incident_slack_channel_id", callback.View.PrivateMetadata),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
} else if incidentEntity == nil {
|
||||
iap.logger.Error("IncidentEntity not found ",
|
||||
zap.String("incident_slack_channel_id", callback.View.PrivateMetadata), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
assignIncidentRoleRequest := buildAssignIncidentRoleRequest(callback.View.State.Values)
|
||||
assignIncidentRoleRequest.CreatedById = callback.User.ID
|
||||
assignIncidentRoleRequest.IncidentId = int(incidentEntity.ID)
|
||||
iap.logger.Info("request", zap.Any("request", assignIncidentRoleRequest))
|
||||
err = query.UpsertIncidentRole(iap.db, assignIncidentRoleRequest)
|
||||
if err != nil {
|
||||
iap.logger.Error("UpsertIncidentRole failed", zap.Error(err))
|
||||
return
|
||||
}
|
||||
msgOption := slack.MsgOptionText(fmt.Sprintf("<@%s> is assigned to %s by <@%s>", assignIncidentRoleRequest.UserId, assignIncidentRoleRequest.Role, assignIncidentRoleRequest.CreatedById), false)
|
||||
_, _, errMessage := iap.client.PostMessage(callback.View.PrivateMetadata, msgOption)
|
||||
if errMessage != nil {
|
||||
iap.logger.Error("post response failed for IncidentAssignModalCommandProcessing", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
|
||||
var payload interface{}
|
||||
iap.client.Ack(*request, payload)
|
||||
|
||||
}
|
||||
|
||||
func buildAssignIncidentRoleRequest(blockActions map[string]map[string]slack.BlockAction) *request.AddIncidentRoleRequest {
|
||||
var addIncidentRoleRequest request.AddIncidentRoleRequest
|
||||
var requestMap = make(map[string]string, 0)
|
||||
for _, actions := range blockActions {
|
||||
for actionID, action := range actions {
|
||||
if action.Type == "users_select" {
|
||||
requestMap[actionID] = action.SelectedUser
|
||||
}
|
||||
if action.Type == "static_select" {
|
||||
requestMap[actionID] = action.SelectedOption.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
desRequestMap, _ := json.Marshal(requestMap)
|
||||
json.Unmarshal(desRequestMap, &addIncidentRoleRequest)
|
||||
return &addIncidentRoleRequest
|
||||
}
|
||||
62
pkg/slack/houston/command/incident_resolve.go
Normal file
62
pkg/slack/houston/command/incident_resolve.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"houston/pkg/postgres/query"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidentResolveProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentResolveProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidentResolveProcessor {
|
||||
return &incidentResolveProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (irp *incidentResolveProcessor) IncidentResolveProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
channelId := callback.Channel.ID
|
||||
incidentEntity, err := query.FindIncidentByChannelId(irp.db, channelId)
|
||||
if err != nil {
|
||||
irp.logger.Error("incident not found",
|
||||
zap.String("channel", channelId),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
}
|
||||
|
||||
incidentEntity.Status = entity.Resolved
|
||||
|
||||
err = query.UpdateIncident(irp.db, incidentEntity)
|
||||
if err != nil {
|
||||
irp.logger.Error("failed to update incident to resolve state",
|
||||
zap.String("channel", channelId),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
}
|
||||
|
||||
irp.logger.Info("successfully resolved the incident",
|
||||
zap.String("channel", channelId),
|
||||
zap.String("user_id", callback.User.ID))
|
||||
|
||||
msgOption := slack.MsgOptionText(fmt.Sprintf("<@%s> > set status to %s", callback.User.ID, incidentEntity.Status), false)
|
||||
|
||||
_, _, errMessage := irp.client.PostMessage(callback.Channel.ID, msgOption)
|
||||
if errMessage != nil {
|
||||
irp.logger.Error("post response failed for ResolveIncident", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
|
||||
irp.client.ArchiveConversation(channelId)
|
||||
|
||||
var payload interface{}
|
||||
irp.client.Ack(*request, payload)
|
||||
}
|
||||
108
pkg/slack/houston/command/incident_show_tags.go
Normal file
108
pkg/slack/houston/command/incident_show_tags.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/pkg/postgres/query"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidenShowTagsProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentShowTagsProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidenShowTagsProcessor {
|
||||
return &incidenShowTagsProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (isp *incidenShowTagsProcessor) IncidentShowTagsRequestProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
result, err := query.FindIncidentSeverityTeamJoin(isp.db, callback.Channel.ID)
|
||||
if err != nil {
|
||||
isp.logger.Error("IncidentShowTagsRequestProcess error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
} else if result == nil {
|
||||
isp.logger.Error("IncidentSeverityTeamJoin Not found",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
savedContributingFactor, err := query.FindContributingFactorsByIncidentId(isp.db, result.IncidentId)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindContributingFactorsByIncidentId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
cfString := "No tags"
|
||||
if savedContributingFactor != nil {
|
||||
cfString = savedContributingFactor.Label
|
||||
}
|
||||
|
||||
savedCustomerTags, err := query.FindCustomerTagsByIncidentId(isp.logger, isp.db, result.IncidentId)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindCustomerTagsByIncidentId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
var customerTagString string
|
||||
if len(savedCustomerTags) == 0 {
|
||||
customerTagString = "No tags"
|
||||
} else {
|
||||
for _, o := range savedCustomerTags {
|
||||
customerTagString = customerTagString + " " + o.Label
|
||||
}
|
||||
}
|
||||
|
||||
savedTags, err := query.FindTagsByIncidentId(isp.db, result.IncidentId)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindTagsByIncidentId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
var tagString string
|
||||
if len(savedTags) == 0 {
|
||||
tagString = "No tags"
|
||||
} else {
|
||||
for _, o := range savedTags {
|
||||
tagString = tagString + " " + o.Label
|
||||
}
|
||||
}
|
||||
|
||||
savedDp, err := query.FindDataPlataformTagsByIncidentId(result.IncidentId, isp.db, isp.logger)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindDataPlataformTagsByIncidentId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var dpString string = "No tags"
|
||||
if savedDp != nil && (len(savedDp.DataPlatformTag)) != 0 {
|
||||
dpString = savedDp.DataPlatformTag
|
||||
}
|
||||
|
||||
msgOption := slack.MsgOptionText(fmt.Sprintf("\n\nCONTRIBUTING-FACTORS: \n %s \n\n CUSTOMER: \n %s \n\n CUSTOMER:%s \n %s \n\n DATA-PLATFORM: \n %s", cfString, customerTagString, result.TeamsName, tagString, dpString), true)
|
||||
_, errMessage := isp.client.PostEphemeral(callback.Channel.ID, callback.User.ID, msgOption)
|
||||
if errMessage != nil {
|
||||
isp.logger.Error("PostEphemeralmresponse failed for IncidentShowTagsRequestProcess", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
isp.client.Ack(*request, payload)
|
||||
|
||||
}
|
||||
100
pkg/slack/houston/command/incident_update_description.go
Normal file
100
pkg/slack/houston/command/incident_update_description.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/pkg/postgres/query"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidentUpdateDescriptionProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentUpdateDescriptionProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidentUpdateDescriptionProcessor {
|
||||
return &incidentUpdateDescriptionProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (idp *incidentUpdateDescriptionProcessor) IncidentUpdateDescriptionRequestProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
result, err := query.FindIncidentByChannelId(idp.db, callback.Channel.ID)
|
||||
if err != nil {
|
||||
idp.logger.Error("FindIncidentByChannelId error ",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
} else if result == nil {
|
||||
idp.logger.Error("IncidentEntity not found ",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
modalRequest := houston.BuildIncidentUpdateDescriptionModal(idp.db, callback.Channel, result.Description)
|
||||
|
||||
_, err = idp.client.OpenView(callback.TriggerID, modalRequest)
|
||||
if err != nil {
|
||||
idp.logger.Error("houston slack openview command for IncidentUpdateDescriptionRequestProcess failed.",
|
||||
zap.String("trigger_id", callback.TriggerID), zap.String("channel_id", callback.Channel.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
idp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func (itp *incidentUpdateDescriptionProcessor) IncidentUpdateDescription(callback slack.InteractionCallback, request *socketmode.Request, channel slack.Channel, user slack.User) {
|
||||
incidentEntity, err := query.FindIncidentByChannelId(itp.db, callback.View.PrivateMetadata)
|
||||
if err != nil {
|
||||
itp.logger.Error("FindIncidentByChannelId error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
} else if incidentEntity == nil {
|
||||
itp.logger.Error("IncidentEntity not found ",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
incidentDescription := buildUpdateIncidentDescriptionRequest(callback.View.State.Values)
|
||||
|
||||
incidentEntity.Description = incidentDescription
|
||||
incidentEntity.UpdatedBy = user.ID
|
||||
err = query.UpdateIncident(itp.db, incidentEntity)
|
||||
if err != nil {
|
||||
itp.logger.Error("IncidentUpdateDescription error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
msgOption := slack.MsgOptionText(fmt.Sprintf("<@%s> > set description to %s", user.ID, incidentEntity.Description), false)
|
||||
_, _, errMessage := itp.client.PostMessage(callback.View.PrivateMetadata, msgOption)
|
||||
if errMessage != nil {
|
||||
itp.logger.Error("post response failed for IncidentUpdateDescription", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
|
||||
var payload interface{}
|
||||
itp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func buildUpdateIncidentDescriptionRequest(blockActions map[string]map[string]slack.BlockAction) string {
|
||||
var requestMap = make(map[string]string, 0)
|
||||
for _, actions := range blockActions {
|
||||
for actionID, action := range actions {
|
||||
if action.Type == "plain_text_input" {
|
||||
requestMap[actionID] = action.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return requestMap["incident_description"]
|
||||
}
|
||||
125
pkg/slack/houston/command/incident_update_severity.go
Normal file
125
pkg/slack/houston/command/incident_update_severity.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/pkg/postgres/query"
|
||||
"houston/pkg/slack/common"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidentUpdateSevertityProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentUpdateSeverityProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidentUpdateSevertityProcessor {
|
||||
return &incidentUpdateSevertityProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (isp *incidentUpdateSevertityProcessor) IncidentUpdateSeverityRequestProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
incidentSeverity, err := query.FindIncidentSeverityEntity(isp.db, isp.logger)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindSeverityEntity error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
modalRequest := houston.BuildIncidentUpdateSeverityModal(callback.Channel, incidentSeverity)
|
||||
|
||||
_, err = isp.client.OpenView(callback.TriggerID, modalRequest)
|
||||
if err != nil {
|
||||
isp.logger.Error("houston slack openview command failed.",
|
||||
zap.String("trigger_id", callback.TriggerID), zap.String("channel_id", callback.Channel.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
isp.client.Ack(*request, payload)
|
||||
|
||||
}
|
||||
|
||||
func (isp *incidentUpdateSevertityProcessor) IncidentUpdateSeverity(callback slack.InteractionCallback, request *socketmode.Request, channel slack.Channel, user slack.User) {
|
||||
incidentEntity, err := query.FindIncidentByChannelId(isp.db, callback.View.PrivateMetadata)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindIncidentByChannelId error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
} else if incidentEntity == nil {
|
||||
isp.logger.Error("IncidentEntity not found ",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
incidentSeverityId := buildUpdateIncidentSeverityRequest(isp.logger, callback.View.State.Values)
|
||||
result, err := query.FindIncidentSeverityEntityById(isp.db, isp.logger, incidentSeverityId)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindIncidentSeverityEntityById error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
} else if result == nil {
|
||||
isp.logger.Error("SeverityEntity not found",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
incidentEntity.SeverityId = int(result.ID)
|
||||
incidentEntity.UpdatedBy = user.ID
|
||||
incidentEntity.SeverityTat = time.Now().AddDate(0, 0, result.Sla)
|
||||
err = query.UpdateIncident(isp.db, incidentEntity)
|
||||
if err != nil {
|
||||
isp.logger.Error("UpdateIncident error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
}
|
||||
userIdList, err := query.FindDefaultUserIdToBeAddedBySeverity(isp.db, int(result.ID))
|
||||
if err != nil {
|
||||
isp.logger.Error("FindDefaultUserIdToBeAddedBySeverity error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
for _, o := range userIdList {
|
||||
common.InviteUsersToConversation(isp.client, isp.logger, callback.View.PrivateMetadata, o)
|
||||
}
|
||||
msgOption := slack.MsgOptionText(fmt.Sprintf("<@%s> > set severity to %s", user.ID, result.Name), false)
|
||||
_, _, errMessage := isp.client.PostMessage(callback.View.PrivateMetadata, msgOption)
|
||||
if errMessage != nil {
|
||||
isp.logger.Error("post response failed for IncidentUpdateSeverity", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
isp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
//TODO - ADD USER ACCORDING TO SEVERITY
|
||||
|
||||
func buildUpdateIncidentSeverityRequest(logger *zap.Logger, blockActions map[string]map[string]slack.BlockAction) int {
|
||||
var requestMap = make(map[string]string, 0)
|
||||
for _, actions := range blockActions {
|
||||
for actionID, action := range actions {
|
||||
if action.Type == "static_select" {
|
||||
requestMap[actionID] = action.SelectedOption.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectedValue := requestMap["incident_severity_modal_request"]
|
||||
selectedValueInInt, err := strconv.Atoi(selectedValue)
|
||||
if err != nil {
|
||||
logger.Error("String conversion to int faileed in buildUpdateIncidentTypeRequest for "+selectedValue, zap.Error(err))
|
||||
}
|
||||
return selectedValueInInt
|
||||
}
|
||||
111
pkg/slack/houston/command/incident_update_status.go
Normal file
111
pkg/slack/houston/command/incident_update_status.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"houston/pkg/postgres/query"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
"strconv"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidentUpdateStatusProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentUpdateStatusProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidentUpdateStatusProcessor {
|
||||
return &incidentUpdateStatusProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (isp *incidentUpdateStatusProcessor) IncidentUpdateStatusRequestProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
modalRequest := houston.BuildIncidentUpdateStatusModal(isp.db, callback.Channel)
|
||||
|
||||
_, err := isp.client.OpenView(callback.TriggerID, modalRequest)
|
||||
if err != nil {
|
||||
isp.logger.Error("houston slack openview command failed.",
|
||||
zap.String("trigger_id", callback.TriggerID), zap.String("channel_id", callback.Channel.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
isp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func (isp *incidentUpdateStatusProcessor) IncidentUpdateStatus(callback slack.InteractionCallback, request *socketmode.Request, channel slack.Channel, user slack.User) {
|
||||
incidentEntity, err := query.FindIncidentByChannelId(isp.db, callback.View.PrivateMetadata)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindIncidentBySlackChannelId error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
} else if incidentEntity == nil {
|
||||
isp.logger.Error("IncidentEntity Object Not Found",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
incidentStatusId := buildUpdateIncidentStatusRequest(isp.logger, callback.View.State.Values)
|
||||
result, err := query.FindIncidentStatusById(isp.db, incidentStatusId)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindIncidentStatusById error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
} else if result == nil {
|
||||
isp.logger.Error("IncidentStatusEntity Object not found",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
incidentEntity.Status = entity.IncidentStatus(result.Name)
|
||||
incidentEntity.UpdatedBy = user.ID
|
||||
err = query.UpdateIncident(isp.db, incidentEntity)
|
||||
if err != nil {
|
||||
isp.logger.Error("UpdateIncident error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
}
|
||||
msgOption := slack.MsgOptionText(fmt.Sprintf("<@%s> > set status to %s", user.ID, incidentEntity.Status), false)
|
||||
_, _, errMessage := isp.client.PostMessage(callback.View.PrivateMetadata, msgOption)
|
||||
if errMessage != nil {
|
||||
isp.logger.Error("post response failed for IncidentUpdateStatus", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
|
||||
if incidentEntity.Status == "RESOLVED" {
|
||||
isp.client.ArchiveConversation(callback.View.PrivateMetadata)
|
||||
}
|
||||
|
||||
var payload interface{}
|
||||
isp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
//TODO - FOR RESOLVED SCENARIO
|
||||
|
||||
func buildUpdateIncidentStatusRequest(logger *zap.Logger, blockActions map[string]map[string]slack.BlockAction) int {
|
||||
var requestMap = make(map[string]string, 0)
|
||||
for _, actions := range blockActions {
|
||||
for actionID, action := range actions {
|
||||
if action.Type == "static_select" {
|
||||
requestMap[actionID] = action.SelectedOption.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectedValue := requestMap["incident_status_modal_request"]
|
||||
selectedValueInInt, err := strconv.Atoi(selectedValue)
|
||||
if err != nil {
|
||||
logger.Error("String conversion to int faileed in buildUpdateIncidentTypeRequest for "+selectedValue, zap.Error(err))
|
||||
}
|
||||
return selectedValueInInt
|
||||
}
|
||||
315
pkg/slack/houston/command/incident_update_tags.go
Normal file
315
pkg/slack/houston/command/incident_update_tags.go
Normal file
@@ -0,0 +1,315 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"houston/pkg/postgres/query"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
"strconv"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidentUpdateTagsProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentUpdateTagsProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidentUpdateTagsProcessor {
|
||||
return &incidentUpdateTagsProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (idp *incidentUpdateTagsProcessor) IncidentUpdateTagsRequestProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
result, err := query.FindIncidentSeverityTeamJoin(idp.db, callback.Channel.ID)
|
||||
if err != nil {
|
||||
idp.logger.Error("FindIncidentSeverityTeamJoin error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
} else if result == nil {
|
||||
idp.logger.Error("IncidentSeverityTeamJoin Not found",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
tags, err := query.FindTagsByTeamsId(idp.db, result.TeamsId)
|
||||
if err != nil {
|
||||
idp.logger.Error("FindTagsByTeamsId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
incidentTags, err := query.FindTagsByIncidentId(idp.db, result.IncidentId)
|
||||
if err != nil {
|
||||
idp.logger.Error("FindTagsByIncidentId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
cf, savedCf, err := findContributingFactors(result.IncidentId, idp.db, idp.logger)
|
||||
if err != nil {
|
||||
idp.logger.Error("findContrxibutingFactors error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
customerTags, savedCustomrTags, err := findCustomerTags(result.IncidentId, idp.db, idp.logger)
|
||||
if err != nil {
|
||||
idp.logger.Error("findCustomerTags error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
savedDataPlatformTags, err := query.FindDataPlataformTagsByIncidentId(result.IncidentId, idp.db, idp.logger)
|
||||
if err != nil {
|
||||
idp.logger.Error("findDataPlataformTagsByIncidentInt error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
modalRequest := houston.BuildIncidentUpdateTagModal(callback.Channel, tags, result.TeamsName, incidentTags, savedCf, cf, savedCustomrTags, customerTags, savedDataPlatformTags)
|
||||
|
||||
_, err = idp.client.OpenView(callback.TriggerID, modalRequest)
|
||||
if err != nil {
|
||||
idp.logger.Error("houston slack openview command for IncidentUpdateTagsRequestProcess failed.",
|
||||
zap.String("trigger_id", callback.TriggerID), zap.String("channel_id", callback.Channel.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
idp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func (itp *incidentUpdateTagsProcessor) IncidentUpdateTags(callback slack.InteractionCallback, request *socketmode.Request, channel slack.Channel, user slack.User) {
|
||||
result, err := query.FindIncidentSeverityTeamJoin(itp.db, callback.View.PrivateMetadata)
|
||||
if err != nil {
|
||||
itp.logger.Error("FindIncidentSeverityTeamJoin error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
} else if result == nil {
|
||||
itp.logger.Error("IncidentSeverityTeamJoin Not found",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
cfId, customerTagIdRequests, incidentTagIdRequests, dataPlatformString := buildUpdateIncidentTagsRequest(itp.logger, callback.View.State.Values)
|
||||
|
||||
//Update Contributing factors
|
||||
if cfId == 0 {
|
||||
err = query.SetContributingFactorDeletedAt(itp.db, result.IncidentId)
|
||||
if err != nil {
|
||||
itp.logger.Error("SetContributingFactorDeletedAt err",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
} else {
|
||||
err = query.UpsertContributingFactorIdToIncidentId(itp.db, cfId, result.IncidentId)
|
||||
if err != nil {
|
||||
itp.logger.Error("UpsertContributingFactorIdToIncidentId err",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Update Customer Tag Id mapping
|
||||
customerTagIdExist, err := query.FindCustomerTagIdMappingWithIncidentByIncidentId(itp.db, result.IncidentId)
|
||||
var customerTagIdList []int
|
||||
|
||||
for _, o := range customerTagIdExist {
|
||||
customerTagIdList = append(customerTagIdList, o.CustomerTagsId)
|
||||
}
|
||||
|
||||
UpdateCustomerTagId(result, callback, itp.db, itp.logger, customerTagIdList, customerTagIdRequests)
|
||||
|
||||
// Team tag Id Mapping
|
||||
tagsExist, err := query.FindTagRecordListByIncidentId(itp.db, result.IncidentId)
|
||||
var tagIdList []int
|
||||
for _, o := range tagsExist {
|
||||
tagIdList = append(tagIdList, o.TagId)
|
||||
}
|
||||
|
||||
UpdateTeamTagId(result, callback, itp.db, itp.logger, tagIdList, incidentTagIdRequests)
|
||||
|
||||
// Update Data Platform tags
|
||||
err = query.UpsertDataPlatformTagToIncidentId(itp.db, dataPlatformString, result.IncidentId)
|
||||
if err != nil {
|
||||
itp.logger.Error("UpsertDataPlatformTagToIncidentId err",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
itp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func buildUpdateIncidentTagsRequest(logger *zap.Logger, blockActions map[string]map[string]slack.BlockAction) (int, []int, []int, string) {
|
||||
var requestMap = make(map[string][]slack.OptionBlockObject)
|
||||
var requestMapString = make(map[string]string, 0)
|
||||
for _, actions := range blockActions {
|
||||
for actionID, action := range actions {
|
||||
if action.Type == "multi_static_select" {
|
||||
requestMap[actionID] = action.SelectedOptions
|
||||
} else if action.Type == "static_select" {
|
||||
requestMapString[actionID] = action.SelectedOption.Value
|
||||
} else if action.Type == "plain_text_input" {
|
||||
requestMapString[actionID] = action.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
var customerTags []int
|
||||
var tagsList []int
|
||||
|
||||
for _, o := range requestMap["incident_customer_tags_modal_request"] {
|
||||
selectedValueInInt, err := strconv.Atoi(o.Value)
|
||||
if err != nil {
|
||||
logger.Error("String to int conversion failed in buildUpdateIncidentTagseRequest for " + o.Value)
|
||||
} else {
|
||||
customerTags = append(customerTags, selectedValueInInt)
|
||||
}
|
||||
}
|
||||
|
||||
for _, o := range requestMap["incident_tags_modal_request"] {
|
||||
selectedValueInInt, err := strconv.Atoi(o.Value)
|
||||
if err != nil {
|
||||
logger.Error("String to int conversion failed in buildUpdateIncidentTagseRequest for " + o.Value)
|
||||
} else {
|
||||
tagsList = append(tagsList, selectedValueInInt)
|
||||
}
|
||||
}
|
||||
|
||||
var cfId int
|
||||
var err1 error
|
||||
if len(requestMapString["incident_cf_modal_request"]) != 0 {
|
||||
cfId, err1 = strconv.Atoi(requestMapString["incident_cf_modal_request"])
|
||||
if err1 != nil {
|
||||
logger.Error("String to int conversion in CF failed in buildUpdateIncidentTagseRequest for " + requestMapString["incident_cf_modal_request"])
|
||||
}
|
||||
}
|
||||
|
||||
return cfId, customerTags, tagsList, requestMapString["incident_data_platform_tag_modal_request"]
|
||||
}
|
||||
|
||||
func diffLists(list1 []int, list2 []int) ([]int, []int) {
|
||||
set1 := make(map[int]bool)
|
||||
set2 := make(map[int]bool)
|
||||
result1 := []int{}
|
||||
result2 := []int{}
|
||||
|
||||
for _, num := range list1 {
|
||||
set1[num] = true
|
||||
}
|
||||
|
||||
for _, num := range list2 {
|
||||
set2[num] = true
|
||||
}
|
||||
|
||||
for num, _ := range set1 {
|
||||
if _, ok := set2[num]; !ok {
|
||||
result1 = append(result1, num)
|
||||
}
|
||||
}
|
||||
|
||||
for num, _ := range set2 {
|
||||
if _, ok := set1[num]; !ok {
|
||||
result2 = append(result2, num)
|
||||
}
|
||||
}
|
||||
|
||||
return result1, result2
|
||||
}
|
||||
|
||||
func findContributingFactors(incidentId int, db *gorm.DB, logger *zap.Logger) ([]entity.ContributingFactorEntity, *entity.ContributingFactorEntity, error) {
|
||||
cf, err := query.FetchAllContributingFactors(db)
|
||||
if err != nil {
|
||||
logger.Error("FetchAllContributingFactors error")
|
||||
return nil, nil, err
|
||||
}
|
||||
savedCf, err := query.FindContributingFactorsByIncidentId(db, incidentId)
|
||||
if err != nil {
|
||||
logger.Error("FindContributingFactorsByIncidentId error")
|
||||
return nil, nil, err
|
||||
}
|
||||
return cf, savedCf, nil
|
||||
|
||||
}
|
||||
|
||||
func findCustomerTags(incidentId int, db *gorm.DB, logger *zap.Logger) ([]entity.CustomerTagsEntity, []entity.CustomerTagsEntity, error) {
|
||||
customerTags, err := query.FetchAllCustomerTags(db)
|
||||
if err != nil {
|
||||
logger.Error("FetchAllCustomerTags error")
|
||||
return nil, nil, err
|
||||
}
|
||||
savedCustomerTags, err := query.FindCustomerTagsByIncidentId(logger, db, incidentId)
|
||||
if err != nil {
|
||||
logger.Error("FindCustomerTagsByIncidentId error")
|
||||
return nil, nil, err
|
||||
}
|
||||
return customerTags, savedCustomerTags, nil
|
||||
|
||||
}
|
||||
|
||||
func UpdateCustomerTagId(result *entity.IncidentSeverityTeamJoinEntity, callback slack.InteractionCallback, db *gorm.DB, logger *zap.Logger, customerTagIdList []int, customerTagIdRequests []int) {
|
||||
|
||||
listCustomerTag1, listCustomerTag2 := diffLists(customerTagIdList, customerTagIdRequests)
|
||||
|
||||
for _, o := range listCustomerTag1 {
|
||||
err := query.SetIncidentCustomerTagDeletedAt(db, o, result.IncidentId)
|
||||
if err != nil {
|
||||
logger.Error("SetIncidentCustomerTagDeletedAt error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, index := range listCustomerTag2 {
|
||||
err := query.AddCustomerIdMappingToIncidentId(db, index, result.IncidentId)
|
||||
if err != nil {
|
||||
logger.Error("AddCustomerIMappingToIncidentId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func UpdateTeamTagId(result *entity.IncidentSeverityTeamJoinEntity, callback slack.InteractionCallback, db *gorm.DB, logger *zap.Logger, tagIdList []int, tagIdRequests []int) {
|
||||
|
||||
list1, list2 := diffLists(tagIdList, tagIdRequests)
|
||||
|
||||
for _, o := range list1 {
|
||||
err := query.SetTagsDeletedAt(db, o, result.IncidentId)
|
||||
if err != nil {
|
||||
logger.Error("SetDeletedAt error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, index := range list2 {
|
||||
err := query.AddTagsIdMappingToIncidentId(db, index, result.IncidentId)
|
||||
if err != nil {
|
||||
logger.Error("AddTagsIdMappingToIncidentId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
111
pkg/slack/houston/command/incident_update_title.go
Normal file
111
pkg/slack/houston/command/incident_update_title.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/pkg/postgres/query"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidentUpdateTitleProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentUpdateTitleProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidentUpdateTitleProcessor {
|
||||
return &incidentUpdateTitleProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (itp *incidentUpdateTitleProcessor) IncidentUpdateTitleRequestProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
result, err := query.FindIncidentByChannelId(itp.db, callback.Channel.ID)
|
||||
if err != nil {
|
||||
itp.logger.Error("FindIncidentByChannelId error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
} else if result == nil {
|
||||
itp.logger.Error("IncidentEntity not found ",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
modalRequest := houston.BuildIncidentUpdateTitleModal(itp.db, callback.Channel, result.Title)
|
||||
|
||||
_, err = itp.client.OpenView(callback.TriggerID, modalRequest)
|
||||
if err != nil {
|
||||
itp.logger.Error("houston slack openview command for IncidentUpdateTitleRequestProcess failed.",
|
||||
zap.String("trigger_id", callback.TriggerID), zap.String("channel_id", callback.Channel.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
itp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func (itp *incidentUpdateTitleProcessor) IncidentUpdateTitle(callback slack.InteractionCallback, request *socketmode.Request, channel slack.Channel, user slack.User) {
|
||||
incidentEntity, err := query.FindIncidentByChannelId(itp.db, callback.View.PrivateMetadata)
|
||||
if err != nil {
|
||||
itp.logger.Error("FindIncidentByChannelId error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
} else if incidentEntity == nil {
|
||||
itp.logger.Error("IncidentEntity not found ",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
incidentTitle := buildUpdateIncidentTitleRequest(callback.View.State.Values)
|
||||
|
||||
incidentEntity.Title = incidentTitle
|
||||
incidentEntity.UpdatedBy = user.ID
|
||||
err = query.UpdateIncident(itp.db, incidentEntity)
|
||||
if err != nil {
|
||||
itp.logger.Error("IncidentUpdateTitle error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
msgOption := slack.MsgOptionText(fmt.Sprintf("<@%s> > set title to %s", user.ID, incidentEntity.Title), false)
|
||||
_, _, errMessage := itp.client.PostMessage(callback.View.PrivateMetadata, msgOption)
|
||||
if errMessage != nil {
|
||||
itp.logger.Error("post response failed for IncidentUpdateTitle", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
|
||||
result, err := query.FindIncidentSeverityTeamJoin(itp.db, incidentEntity.SlackChannel)
|
||||
if err != nil {
|
||||
itp.logger.Error("query failed for FindIncidentSeverityTeamJoin", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
msgOption = slack.MsgOptionText(fmt.Sprintf("set the channel topic: %s : %s %s | %s", result.TeamsName, result.SeverityName, incidentEntity.IncidentName, incidentEntity.Title), false)
|
||||
_, _, errMessage = itp.client.PostMessage(callback.View.PrivateMetadata, msgOption)
|
||||
if errMessage != nil {
|
||||
itp.logger.Error("post response failed for IncidentUpdateTitle", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
itp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func buildUpdateIncidentTitleRequest(blockActions map[string]map[string]slack.BlockAction) string {
|
||||
var requestMap = make(map[string]string, 0)
|
||||
for _, actions := range blockActions {
|
||||
for actionID, action := range actions {
|
||||
if action.Type == "plain_text_input" {
|
||||
requestMap[actionID] = action.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return requestMap["incident_title"]
|
||||
}
|
||||
123
pkg/slack/houston/command/incident_update_type.go
Normal file
123
pkg/slack/houston/command/incident_update_type.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/pkg/postgres/query"
|
||||
"houston/pkg/slack/common"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
"strconv"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type incidentUpdateTypeProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewIncidentUpdateTypeProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *incidentUpdateTypeProcessor {
|
||||
return &incidentUpdateTypeProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (itp *incidentUpdateTypeProcessor) IncidentUpdateTypeRequestProcess(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
teams, err := query.FindTeamList(itp.db)
|
||||
if err != nil {
|
||||
itp.logger.Error("FindTeamList error",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
modalRequest := houston.BuildIncidentUpdateTypeModal(callback.Channel, teams)
|
||||
|
||||
_, err = itp.client.OpenView(callback.TriggerID, modalRequest)
|
||||
if err != nil {
|
||||
itp.logger.Error("houston slack openview command failed.",
|
||||
zap.String("trigger_id", callback.TriggerID), zap.String("channel_id", callback.Channel.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
itp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func (isp *incidentUpdateTypeProcessor) IncidentUpdateType(callback slack.InteractionCallback, request *socketmode.Request, channel slack.Channel, user slack.User) {
|
||||
incidentEntity, err := query.FindIncidentByChannelId(isp.db, callback.View.PrivateMetadata)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindIncidentByChannelId error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
} else if incidentEntity == nil {
|
||||
isp.logger.Error("IncidentEntity not found ",
|
||||
zap.String("incident_slack_channel_id", callback.Channel.ID), zap.String("channel", callback.Channel.Name),
|
||||
zap.String("user_id", callback.User.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
incidentTypeId := buildUpdateIncidentTypeRequest(isp.logger, callback.View.State.Values)
|
||||
result, err := query.FindTeamById(isp.db, incidentTypeId)
|
||||
if err != nil {
|
||||
isp.logger.Error("FindTeamEntityById error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
} else if result == nil {
|
||||
isp.logger.Error("Team Not Found",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
incidentEntity.TeamsId = int(result.ID)
|
||||
incidentEntity.UpdatedBy = user.ID
|
||||
err = query.UpdateIncident(isp.db, incidentEntity)
|
||||
if err != nil {
|
||||
isp.logger.Error("UpdateIncident error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
}
|
||||
|
||||
userIdList, err := query.FindDefaultUserIdToBeAddedByTeam(isp.db, int(result.ID))
|
||||
if err != nil {
|
||||
isp.logger.Error("FindDefaultUserIdToBeAddedByTeam error",
|
||||
zap.String("incident_slack_channel_id", channel.ID), zap.String("channel", channel.Name),
|
||||
zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
for _, o := range userIdList {
|
||||
common.InviteUsersToConversation(isp.client, isp.logger, callback.View.PrivateMetadata, o)
|
||||
}
|
||||
msgOption := slack.MsgOptionText(fmt.Sprintf("<@%s> > set Team to %s", user.ID, result.Name), false)
|
||||
_, _, errMessage := isp.client.PostMessage(callback.View.PrivateMetadata, msgOption)
|
||||
if errMessage != nil {
|
||||
isp.logger.Error("post response failed for IncidentUpdateType", zap.Error(errMessage))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
isp.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func buildUpdateIncidentTypeRequest(logger *zap.Logger, blockActions map[string]map[string]slack.BlockAction) int {
|
||||
var requestMap = make(map[string]string, 0)
|
||||
for _, actions := range blockActions {
|
||||
for actionID, action := range actions {
|
||||
if action.Type == "static_select" {
|
||||
requestMap[actionID] = action.SelectedOption.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectedValue := requestMap["incident_type_modal_request"]
|
||||
selectedValueInInt, err := strconv.Atoi(selectedValue)
|
||||
if err != nil {
|
||||
logger.Error("String conversion to int faileed in buildUpdateIncidentTypeRequest for "+selectedValue, zap.Error(err))
|
||||
}
|
||||
return selectedValueInInt
|
||||
}
|
||||
55
pkg/slack/houston/command/member_join_event.go
Normal file
55
pkg/slack/houston/command/member_join_event.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"houston/pkg/postgres/query"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/slackevents"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type memberJoinProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewMemberJoinProcessor(socketmodeClient *socketmode.Client, db *gorm.DB, logger *zap.Logger) *memberJoinProcessor {
|
||||
return &memberJoinProcessor{
|
||||
client: socketmodeClient,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *memberJoinProcessor) MemberJoinProcessCommand(memberJoinedChannelEvent *slackevents.MemberJoinedChannelEvent) {
|
||||
mp.logger.Info("processing member join event", zap.String("channel", memberJoinedChannelEvent.Channel))
|
||||
|
||||
incidentEntity, err := query.FindIncidentByChannelId(mp.db, memberJoinedChannelEvent.Channel)
|
||||
if err != nil {
|
||||
mp.logger.Error("error in searching incident", zap.String("channel", memberJoinedChannelEvent.Channel),
|
||||
zap.String("user_id", memberJoinedChannelEvent.User), zap.Error(err))
|
||||
return
|
||||
} else if err == nil && incidentEntity == nil {
|
||||
mp.logger.Info("incident not found", zap.String("channel", memberJoinedChannelEvent.Channel),
|
||||
zap.String("user_id", memberJoinedChannelEvent.User), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
blocks, err := houston.IncidentSummarySection(incidentEntity, mp.db)
|
||||
if err != nil {
|
||||
mp.logger.Error("error in creating incident summary section inside incident",
|
||||
zap.String("channel", memberJoinedChannelEvent.Channel),
|
||||
zap.String("user_id", memberJoinedChannelEvent.User), zap.Error(err))
|
||||
return
|
||||
}
|
||||
mp.logger.Info("member join block", zap.Any("blocks", blocks))
|
||||
msgOption := slack.MsgOptionBlocks(blocks...)
|
||||
_, err = mp.client.PostEphemeral(memberJoinedChannelEvent.Channel, memberJoinedChannelEvent.User, msgOption)
|
||||
if err != nil {
|
||||
mp.logger.Error("post response failed", zap.Error(err))
|
||||
}
|
||||
}
|
||||
49
pkg/slack/houston/command/show_incidents.go
Normal file
49
pkg/slack/houston/command/show_incidents.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"houston/pkg/postgres/query"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ShowIncidentsButtonProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func ShowIncidentsProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *ShowIncidentsButtonProcessor {
|
||||
return &ShowIncidentsButtonProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (sip *ShowIncidentsButtonProcessor) ProcessShowIncidentsButtonCommand(channel slack.Channel, user slack.User, triggerId string, request *socketmode.Request) {
|
||||
|
||||
limit := viper.GetInt("SHOW_INCIDENTS_LIMT")
|
||||
s, err := query.FindNotResolvedLatestIncidents(sip.db, limit)
|
||||
|
||||
if err != nil {
|
||||
sip.logger.Error("FindNotResolvedLatestIncidents query failed.",
|
||||
zap.String("trigger_id", triggerId), zap.String("channel_id", channel.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
blocks := houston.GenerateModalForShowIncidentsButtonSection(s)
|
||||
msgOption := slack.MsgOptionBlocks(blocks...)
|
||||
_, err = sip.client.Client.PostEphemeral(channel.ID, user.ID, msgOption)
|
||||
if err != nil {
|
||||
sip.logger.Error("houston slack PostEphemeral command failed for ProcessShowIncidentsButtonCommand.",
|
||||
zap.String("trigger_id", triggerId), zap.String("channel_id", channel.ID), zap.String("user_id", user.ID), zap.Error(err))
|
||||
return
|
||||
}
|
||||
var payload interface{}
|
||||
sip.client.Ack(*request, payload)
|
||||
|
||||
}
|
||||
36
pkg/slack/houston/command/start_incident.go
Normal file
36
pkg/slack/houston/command/start_incident.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type startIncidentButtonProcessor struct {
|
||||
client *socketmode.Client
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewStartIncidentProcessor(client *socketmode.Client, db *gorm.DB, logger *zap.Logger) *startIncidentButtonProcessor {
|
||||
return &startIncidentButtonProcessor{
|
||||
client: client,
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (sip *startIncidentButtonProcessor) ProcessStartIncidentButtonCommand(channelId, triggerId string) {
|
||||
modal := houston.GenerateModalRequest(sip.db, sip.logger, channelId)
|
||||
_, err := sip.client.OpenView(triggerId, modal)
|
||||
if err != nil {
|
||||
sip.logger.Error("houston slack openview command failed.",
|
||||
zap.String("trigger_id", triggerId), zap.String("channel_id", channelId), zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
sip.logger.Info("houston successfully send modal to slack", zap.String("trigger_id", triggerId))
|
||||
// client.Ack(*request, payload)
|
||||
}
|
||||
203
pkg/slack/houston/command/start_incident_modal_submission.go
Normal file
203
pkg/slack/houston/command/start_incident_modal_submission.go
Normal file
@@ -0,0 +1,203 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"houston/model"
|
||||
"houston/model/request"
|
||||
"houston/pkg/postgres/query"
|
||||
"houston/pkg/slack/common"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/api/calendar/v3"
|
||||
"google.golang.org/api/option"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type createIncidentProcessor struct {
|
||||
client *socketmode.Client
|
||||
logger *zap.Logger
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewCreateIncidentProcessor(client *socketmode.Client, logger *zap.Logger, db *gorm.DB) *createIncidentProcessor {
|
||||
return &createIncidentProcessor{
|
||||
client: client,
|
||||
logger: logger,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (cip *createIncidentProcessor) CreateIncidentModalCommandProcessing(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
// Build create incident request
|
||||
createIncidentRequest := buildCreateIncidentRequest(callback.View.State.Values)
|
||||
createIncidentRequest.RequestOriginatedSlackChannel = callback.View.PrivateMetadata
|
||||
cip.logger.Info("incident request created", zap.Any("request", createIncidentRequest))
|
||||
|
||||
// Create a new Slack channel for the incident
|
||||
channelName := fmt.Sprintf("incident-%s", time.Now().Format("150405"))
|
||||
channelID, err := common.CreateChannel(cip.client, cip.logger, channelName)
|
||||
if err != nil {
|
||||
cip.logger.Error("Unable to create channel", zap.Error(err))
|
||||
}
|
||||
createIncidentRequest.Status = entity.Investigating
|
||||
createIncidentRequest.IncidentName = channelName
|
||||
createIncidentRequest.SlackChannel = channelID
|
||||
|
||||
// Set default values for some fields
|
||||
createIncidentRequest.DetectionTime = time.Now()
|
||||
createIncidentRequest.CustomerImpactStartTime = time.Now()
|
||||
createIncidentRequest.CustomerImpactEndTime = time.Now()
|
||||
createIncidentRequest.TeamsId = 1
|
||||
createIncidentRequest.JiraId = ""
|
||||
createIncidentRequest.ConfluenceId = ""
|
||||
createIncidentRequest.RemindMeAt = time.Now()
|
||||
createIncidentRequest.EnableReminder = false
|
||||
createIncidentRequest.CreatedBy = callback.User.ID
|
||||
createIncidentRequest.UpdatedBy = callback.User.ID
|
||||
createIncidentRequest.Version = 0
|
||||
|
||||
// Save the incident to the database
|
||||
incidentEntity, err := query.CreateIncident(cip.db, createIncidentRequest)
|
||||
if err != nil {
|
||||
cip.logger.Error("Error while creating incident", zap.Error(err))
|
||||
}
|
||||
|
||||
// Post incident summary to Blaze Group channel and incident channel
|
||||
err = postIncidentSummary(cip.client, callback.View.PrivateMetadata, channelID, incidentEntity, cip.db)
|
||||
if err != nil {
|
||||
cip.logger.Error("error while posting incident summary", zap.Error(err))
|
||||
}
|
||||
err = addDefaultUsersToIncident(cip, channelID, incidentEntity.SeverityId, incidentEntity.TeamsId)
|
||||
if err != nil {
|
||||
cip.logger.Error("error while adding default users to incident", zap.Error(err))
|
||||
}
|
||||
//gmeet := createGmeetLink(cip.logger, channelName)
|
||||
//if len(gmeet) != 0 {
|
||||
// msgOption := slack.MsgOptionText(fmt.Sprintf("gmeet Link :", gmeet), false)
|
||||
// cip.client.PostMessage(channelID, msgOption)
|
||||
//}
|
||||
|
||||
// Acknowledge the interaction callback
|
||||
var payload interface{}
|
||||
cip.client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func addDefaultUsersToIncident(cip *createIncidentProcessor, channelId string, severityId, teamId int) (error) {
|
||||
userIdList, err := query.FindDefaultUserIdToBeAddedBySeverity(cip.db, severityId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, o := range userIdList {
|
||||
common.InviteUsersToConversation(cip.client, cip.logger, channelId, o)
|
||||
}
|
||||
userIdList, err = query.FindDefaultUserIdToBeAddedByTeam(cip.db, teamId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, o := range userIdList {
|
||||
common.InviteUsersToConversation(cip.client, cip.logger, channelId, o)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func postIncidentSummary(
|
||||
client *socketmode.Client,
|
||||
blazeGroupChannelID, incidentChannelID string,
|
||||
incidentEntity *entity.IncidentEntity,
|
||||
db *gorm.DB) error {
|
||||
// Post incident summary to Blaze Group channel and incident channel
|
||||
blocks, err := houston.IncidentSummarySection(incidentEntity, db)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in creating incident summary err: %v", err)
|
||||
}
|
||||
msgOptions := []slack.MsgOption{slack.MsgOptionBlocks(blocks...)}
|
||||
_, timestamp, err := client.PostMessage(blazeGroupChannelID, msgOptions...)
|
||||
if (err == nil) {
|
||||
query.CreateMessage(db, &request.CreateMessage{
|
||||
SlackChannel: blazeGroupChannelID,
|
||||
MessageTimeStamp: timestamp,
|
||||
IncidentName: incidentEntity.IncidentName,
|
||||
})
|
||||
} else {
|
||||
return fmt.Errorf("error in saving message %v", err)
|
||||
}
|
||||
_, timestamp, err = client.PostMessage(incidentChannelID, msgOptions...)
|
||||
if (err == nil) {
|
||||
query.CreateMessage(db, &request.CreateMessage{
|
||||
SlackChannel: incidentChannelID,
|
||||
MessageTimeStamp: timestamp,
|
||||
IncidentName: incidentEntity.IncidentName,
|
||||
})
|
||||
} else {
|
||||
return fmt.Errorf("error in saving message %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildCreateIncidentRequest(blockActions map[string]map[string]slack.BlockAction) *model.CreateIncident {
|
||||
var createIncidentRequest model.CreateIncident
|
||||
var requestMap = make(map[string]string, 0)
|
||||
for _, actions := range blockActions {
|
||||
for actionID, action := range actions {
|
||||
if action.Type == "plain_text_input" {
|
||||
requestMap[actionID] = action.Value
|
||||
}
|
||||
if action.Type == "static_select" {
|
||||
requestMap[actionID] = action.SelectedOption.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
desRequestMap, _ := json.Marshal(requestMap)
|
||||
json.Unmarshal(desRequestMap, &createIncidentRequest)
|
||||
return &createIncidentRequest
|
||||
}
|
||||
|
||||
func createGmeetLink(logger *zap.Logger, channelName string) string {
|
||||
calclient, err := calendar.NewService(context.Background(), option.WithCredentialsFile(""))
|
||||
if err != nil {
|
||||
logger.Error("Unable to read client secret file: ", zap.Error(err))
|
||||
return ""
|
||||
}
|
||||
t0 := time.Now().Format(time.RFC3339)
|
||||
t1 := time.Now().Add(1 * time.Hour).Format(time.RFC3339)
|
||||
event := &calendar.Event{
|
||||
Summary: channelName,
|
||||
Description: "Incident",
|
||||
Start: &calendar.EventDateTime{
|
||||
DateTime: t0,
|
||||
},
|
||||
End: &calendar.EventDateTime{
|
||||
DateTime: t1,
|
||||
},
|
||||
ConferenceData: &calendar.ConferenceData{
|
||||
CreateRequest: &calendar.CreateConferenceRequest{
|
||||
RequestId: uuid.NewString(),
|
||||
ConferenceSolutionKey: &calendar.ConferenceSolutionKey{
|
||||
Type: "hangoutsMeet",
|
||||
},
|
||||
Status: &calendar.ConferenceRequestStatus{
|
||||
StatusCode: "success",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
calendarID := "primary" //use "primary"
|
||||
event, err = calclient.Events.Insert(calendarID, event).ConferenceDataVersion(1).Do()
|
||||
if err != nil {
|
||||
logger.Error("Unable to create event. %v\n", zap.Error(err))
|
||||
return ""
|
||||
}
|
||||
|
||||
calclient.Events.Delete(calendarID, event.Id).Do()
|
||||
return event.HangoutLink
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"houston/pkg/postgres/query"
|
||||
"strconv"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func BuildIncidentUpdateStatusModal(db *gorm.DB, channel slack.Channel) slack.ModalViewRequest {
|
||||
titleText := slack.NewTextBlockObject("plain_text", "Set Status of Incident", false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
submitText := slack.NewTextBlockObject("plain_text", "Submit", false, false)
|
||||
|
||||
headerText := slack.NewTextBlockObject("mrkdwn", "Status", false, false)
|
||||
headerSection := slack.NewSectionBlock(headerText, nil, nil)
|
||||
|
||||
incidentStatus, _ := query.FetchAllIncidentStatus(db)
|
||||
|
||||
incidentStatusBlockOption := createIncidentStatusBlock(incidentStatus)
|
||||
|
||||
incidentStatusText := slack.NewTextBlockObject(slack.PlainTextType, "Incident Status", false, false)
|
||||
incidentStatusOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, nil, "incident_status_modal_request", incidentStatusBlockOption...)
|
||||
incidentStatusBlock := slack.NewInputBlock("incident_status_modal_request_input", incidentStatusText, nil, incidentStatusOption)
|
||||
|
||||
blocks := slack.Blocks{
|
||||
BlockSet: []slack.Block{
|
||||
headerSection,
|
||||
incidentStatusBlock,
|
||||
},
|
||||
}
|
||||
|
||||
return slack.ModalViewRequest{
|
||||
Type: slack.ViewType("modal"),
|
||||
Title: titleText,
|
||||
Close: closeText,
|
||||
Submit: submitText,
|
||||
Blocks: blocks,
|
||||
PrivateMetadata: channel.ID,
|
||||
CallbackID: "setIncidentStatus",
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createIncidentStatusBlock(options []entity.IncidentStatusEntity) []*slack.OptionBlockObject {
|
||||
optionBlockObjects := make([]*slack.OptionBlockObject, 0, len(options))
|
||||
for _, o := range options {
|
||||
txt := fmt.Sprintf("%s - %s", o.Name, o.Description)
|
||||
optionText := slack.NewTextBlockObject(slack.PlainTextType, txt, false, false)
|
||||
optionBlockObjects = append(optionBlockObjects, slack.NewOptionBlockObject(strconv.FormatUint(uint64(o.ID), 10), optionText, nil))
|
||||
}
|
||||
return optionBlockObjects
|
||||
}
|
||||
92
pkg/slack/houston/design/blazeless_modal.go
Normal file
92
pkg/slack/houston/design/blazeless_modal.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
"houston/pkg/postgres/query"
|
||||
"strconv"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func GenerateModalRequest(db *gorm.DB, logger *zap.Logger, channel string) slack.ModalViewRequest {
|
||||
// Create a ModalViewRequest with a header and two inputs
|
||||
titleText := slack.NewTextBlockObject("plain_text", "Houston", false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
submitText := slack.NewTextBlockObject("plain_text", "Send", false, false)
|
||||
|
||||
headerText := slack.NewTextBlockObject("mrkdwn", "Start Incident", false, false)
|
||||
headerSection := slack.NewSectionBlock(headerText, nil, nil)
|
||||
|
||||
teams, _ := query.FindTeam(db)
|
||||
incidentTypeOptions := createOptionBlockObjectsForTeams(teams)
|
||||
incidentTypeText := slack.NewTextBlockObject(slack.PlainTextType, "Incident Type", false, false)
|
||||
incidentTypePlaceholder := slack.NewTextBlockObject("plain_text", "The incident type for the incident to create", false, false)
|
||||
incidentTypeOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, incidentTypePlaceholder, "incident_type", incidentTypeOptions...)
|
||||
incidentTypeBlock := slack.NewInputBlock("incident_type", incidentTypeText, nil, incidentTypeOption)
|
||||
|
||||
severities, _ := query.FindSeverity(db, logger)
|
||||
severityOptions := createOptionBlockObjectsForSeverity(severities)
|
||||
severityText := slack.NewTextBlockObject(slack.PlainTextType, "Severity", false, false)
|
||||
severityTextPlaceholder := slack.NewTextBlockObject("plain_text", "The severity for the incident to create", false, false)
|
||||
severityOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, severityTextPlaceholder, "incident_severity", severityOptions...)
|
||||
severityBlock := slack.NewInputBlock("incident_severity", severityText, nil, severityOption)
|
||||
|
||||
pagerDutyImpactedServiceText := slack.NewTextBlockObject("plain_text", "Pagerduty", false, false)
|
||||
pagerDutyImpactedServicePlaceholder := slack.NewTextBlockObject("plain_text", "Select pagerduty impacted services", false, false)
|
||||
pagerDutyImpactedServiceElement := slack.NewPlainTextInputBlockElement(pagerDutyImpactedServicePlaceholder, "pagerduty_impacted")
|
||||
pagerDutyImpactedService := slack.NewInputBlock("Pagerduty impacted service", pagerDutyImpactedServiceText, nil, pagerDutyImpactedServiceElement)
|
||||
pagerDutyImpactedService.Optional = true
|
||||
|
||||
incidentTitleText := slack.NewTextBlockObject("plain_text", "Incident Title", false, false)
|
||||
incidentTitlePlaceholder := slack.NewTextBlockObject("plain_text", "Write something", false, false)
|
||||
incidentTitleElement := slack.NewPlainTextInputBlockElement(incidentTitlePlaceholder, "incident_title")
|
||||
incidentTitle := slack.NewInputBlock("Incident title", incidentTitleText, nil, incidentTitleElement)
|
||||
|
||||
incidentDescriptionText := slack.NewTextBlockObject("plain_text", "Incident description", false, false)
|
||||
incidentDescriptionPlaceholder := slack.NewTextBlockObject("plain_text", "Write something", false, false)
|
||||
incidentDescriptionElement := slack.NewPlainTextInputBlockElement(incidentDescriptionPlaceholder, "incident_description")
|
||||
incidentDescriptionElement.Multiline = true
|
||||
incidentDescription := slack.NewInputBlock("Incident description", incidentDescriptionText, nil, incidentDescriptionElement)
|
||||
incidentDescription.Optional = true
|
||||
|
||||
blocks := slack.Blocks{
|
||||
BlockSet: []slack.Block{
|
||||
headerSection,
|
||||
incidentTypeBlock,
|
||||
severityBlock,
|
||||
pagerDutyImpactedService,
|
||||
incidentTitle,
|
||||
incidentDescription,
|
||||
},
|
||||
}
|
||||
|
||||
return slack.ModalViewRequest{
|
||||
Type: slack.ViewType("modal"),
|
||||
Title: titleText,
|
||||
Close: closeText,
|
||||
Submit: submitText,
|
||||
Blocks: blocks,
|
||||
PrivateMetadata: channel,
|
||||
CallbackID: "start_incident_button",
|
||||
}
|
||||
}
|
||||
|
||||
func createOptionBlockObjectsForSeverity(options []entity.SeverityEntity) []*slack.OptionBlockObject {
|
||||
optionBlockObjects := make([]*slack.OptionBlockObject, 0, len(options))
|
||||
for _, o := range options {
|
||||
optionText := slack.NewTextBlockObject(slack.PlainTextType, o.Name, false, false)
|
||||
optionBlockObjects = append(optionBlockObjects, slack.NewOptionBlockObject(strconv.Itoa(int(o.ID)), optionText, nil))
|
||||
}
|
||||
return optionBlockObjects
|
||||
}
|
||||
|
||||
func createOptionBlockObjectsForTeams(options []string) []*slack.OptionBlockObject {
|
||||
optionBlockObjects := make([]*slack.OptionBlockObject, 0, len(options))
|
||||
for _, o := range options {
|
||||
optionText := slack.NewTextBlockObject(slack.PlainTextType, o, false, false)
|
||||
optionBlockObjects = append(optionBlockObjects, slack.NewOptionBlockObject(o, optionText, nil))
|
||||
}
|
||||
return optionBlockObjects
|
||||
}
|
||||
285
pkg/slack/houston/design/blazeless_section.go
Normal file
285
pkg/slack/houston/design/blazeless_section.go
Normal file
@@ -0,0 +1,285 @@
|
||||
package houston
|
||||
|
||||
import "github.com/slack-go/slack"
|
||||
|
||||
func ButtonDesign() map[string]interface{} {
|
||||
payload := map[string]interface{}{
|
||||
"blocks": []slack.Block{
|
||||
slack.NewActionBlock("start_incident_button",
|
||||
slack.NewButtonBlockElement(
|
||||
"start_incident_button",
|
||||
"start_incident_button_value",
|
||||
&slack.TextBlockObject{
|
||||
Type: slack.PlainTextType,
|
||||
Text: "Start Incident",
|
||||
},
|
||||
),
|
||||
slack.NewButtonBlockElement(
|
||||
"show_incidents_button",
|
||||
"show_incidents_button_value",
|
||||
&slack.TextBlockObject{
|
||||
Type: slack.PlainTextType,
|
||||
Text: "Show Incidents",
|
||||
},
|
||||
),
|
||||
slack.NewButtonBlockElement(
|
||||
"show_on_call_button",
|
||||
"show_on_call_button_value",
|
||||
&slack.TextBlockObject{
|
||||
Type: slack.PlainTextType,
|
||||
Text: "Show On-Call",
|
||||
},
|
||||
),
|
||||
slack.NewButtonBlockElement(
|
||||
"help_commands_button",
|
||||
"help_commands_button_value",
|
||||
&slack.TextBlockObject{
|
||||
Type: slack.PlainTextType,
|
||||
Text: "Help-Commands",
|
||||
},
|
||||
)),
|
||||
},
|
||||
}
|
||||
|
||||
return payload
|
||||
|
||||
// client.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func OptionsBlock() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"blocks": []slack.Block{
|
||||
incidentSectionBlock(),
|
||||
taskSectionBlock(),
|
||||
tagsSectionBlock(),
|
||||
onCallSectionBlock(),
|
||||
botHelpSectionBlock(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func incidentSectionBlock() *slack.SectionBlock {
|
||||
textBlock := &slack.TextBlockObject{
|
||||
Type: "mrkdwn",
|
||||
Text: "Incident",
|
||||
}
|
||||
|
||||
optionBlockObjects := []*slack.OptionBlockObject{
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Assign Incident Role",
|
||||
},
|
||||
Value: "assignIncidentRole",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Resolve Incident",
|
||||
},
|
||||
Value: "resolveIncident",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Set Incident Status",
|
||||
},
|
||||
Value: "setIncidentStatus",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Set Incident Type",
|
||||
},
|
||||
Value: "setIncidentType",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Set Incident Severity",
|
||||
},
|
||||
Value: "setIncidentSeverity",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Set Incident Title",
|
||||
},
|
||||
Value: "setIncidentTitle",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Set Incident Description",
|
||||
},
|
||||
Value: "setIncidentDescription",
|
||||
},
|
||||
}
|
||||
|
||||
accessoryOption := &slack.Accessory{
|
||||
SelectElement: &slack.SelectBlockElement{
|
||||
Type: "static_select",
|
||||
ActionID: "incident",
|
||||
Options: optionBlockObjects,
|
||||
Placeholder: slack.NewTextBlockObject("plain_text", "Select Command", false, false),
|
||||
},
|
||||
}
|
||||
return slack.NewSectionBlock(textBlock, nil, accessoryOption, slack.SectionBlockOptionBlockID("incident"))
|
||||
}
|
||||
|
||||
func taskSectionBlock() *slack.SectionBlock {
|
||||
textBlock := &slack.TextBlockObject{
|
||||
Type: "mrkdwn",
|
||||
Text: "Task",
|
||||
}
|
||||
|
||||
optionBlockObjects := []*slack.OptionBlockObject{
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Add Task",
|
||||
},
|
||||
Value: "addTask",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Assign Task",
|
||||
},
|
||||
Value: "assignTask",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "View Your Tasks",
|
||||
},
|
||||
Value: "viewYourTasks",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "View All Tasks",
|
||||
},
|
||||
Value: "viewAllTasks",
|
||||
},
|
||||
}
|
||||
|
||||
accessoryOption := &slack.Accessory{
|
||||
SelectElement: &slack.SelectBlockElement{
|
||||
Type: "static_select",
|
||||
ActionID: "task",
|
||||
Options: optionBlockObjects,
|
||||
Placeholder: slack.NewTextBlockObject("plain_text", "Select Command", false, false),
|
||||
},
|
||||
}
|
||||
return slack.NewSectionBlock(textBlock, nil, accessoryOption, slack.SectionBlockOptionBlockID("task"))
|
||||
}
|
||||
|
||||
func tagsSectionBlock() *slack.SectionBlock {
|
||||
textBlock := &slack.TextBlockObject{
|
||||
Type: "mrkdwn",
|
||||
Text: "Tags",
|
||||
}
|
||||
|
||||
optionBlockObjects := []*slack.OptionBlockObject{
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Add Tag(s)",
|
||||
},
|
||||
Value: "addTags",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Show Tags",
|
||||
},
|
||||
Value: "showTags",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Remove Tag",
|
||||
},
|
||||
Value: "removeTag",
|
||||
},
|
||||
}
|
||||
|
||||
accessoryOption := &slack.Accessory{
|
||||
SelectElement: &slack.SelectBlockElement{
|
||||
Type: "static_select",
|
||||
ActionID: "tags",
|
||||
Options: optionBlockObjects,
|
||||
Placeholder: slack.NewTextBlockObject("plain_text", "Select Command", false, false),
|
||||
},
|
||||
}
|
||||
return slack.NewSectionBlock(textBlock, nil, accessoryOption, slack.SectionBlockOptionBlockID("tags"))
|
||||
}
|
||||
|
||||
func onCallSectionBlock() *slack.SectionBlock {
|
||||
textBlock := &slack.TextBlockObject{
|
||||
Type: "mrkdwn",
|
||||
Text: "On-Call",
|
||||
}
|
||||
|
||||
optionBlockObjects := []*slack.OptionBlockObject{
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Show On-Call",
|
||||
},
|
||||
Value: "showOncall",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Show Escalation Policy",
|
||||
},
|
||||
Value: "showEscalationPolicy",
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Trigger Alert",
|
||||
},
|
||||
Value: "triggerAlert",
|
||||
},
|
||||
}
|
||||
|
||||
accessoryOption := &slack.Accessory{
|
||||
SelectElement: &slack.SelectBlockElement{
|
||||
Type: "static_select",
|
||||
ActionID: "on-call",
|
||||
Options: optionBlockObjects,
|
||||
Placeholder: slack.NewTextBlockObject("plain_text", "Select Command", false, false),
|
||||
},
|
||||
}
|
||||
return slack.NewSectionBlock(textBlock, nil, accessoryOption, slack.SectionBlockOptionBlockID("on-call"))
|
||||
}
|
||||
|
||||
func botHelpSectionBlock() *slack.SectionBlock {
|
||||
textBlock := &slack.TextBlockObject{
|
||||
Type: "mrkdwn",
|
||||
Text: "Bot Help",
|
||||
}
|
||||
|
||||
optionBlockObjects := []*slack.OptionBlockObject{
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: "Help - Commands",
|
||||
},
|
||||
Value: "helpCommands",
|
||||
},
|
||||
}
|
||||
|
||||
accessoryOption := &slack.Accessory{
|
||||
SelectElement: &slack.SelectBlockElement{
|
||||
Type: "static_select",
|
||||
ActionID: "bot-helps",
|
||||
Options: optionBlockObjects,
|
||||
Placeholder: slack.NewTextBlockObject("plain_text", "Select Command", false, false),
|
||||
},
|
||||
}
|
||||
return slack.NewSectionBlock(textBlock, nil, accessoryOption, slack.SectionBlockOptionBlockID("bot-helps"))
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
func GenerateModalForShowIncidentsButtonSection(incident []entity.IncidentSeverityTeamJoinEntity) []slack.Block {
|
||||
contextBlock := slack.NewContextBlock("", slack.NewTextBlockObject("mrkdwn", ":eye: Only visible to you", false, false))
|
||||
|
||||
sectionBlocks := []*slack.SectionBlock{}
|
||||
for i := 0; i < len(incident); i++ {
|
||||
fields := []*slack.TextBlockObject{
|
||||
slack.NewTextBlockObject("mrkdwn", "\n`"+incident[i].SeverityName+"` `"+incident[i].TeamsName+" Incident` \n "+incident[i].Title+"\n <#"+incident[i].SlackChannel+">", false, false),
|
||||
}
|
||||
sectionBlocks = append(sectionBlocks, slack.NewSectionBlock(nil, fields, nil))
|
||||
}
|
||||
|
||||
blocks := []slack.Block{
|
||||
contextBlock,
|
||||
}
|
||||
for i := 0; i < len(sectionBlocks); i++ {
|
||||
blocks = append(blocks, sectionBlocks[i])
|
||||
}
|
||||
|
||||
return blocks
|
||||
|
||||
}
|
||||
79
pkg/slack/houston/design/blazeless_summary_section.go
Normal file
79
pkg/slack/houston/design/blazeless_summary_section.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"houston/pkg/postgres/query"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func SummarySection(incidentEntity *entity.IncidentEntity) []slack.Block {
|
||||
return []slack.Block{
|
||||
buildSummaryHeader(incidentEntity.Title),
|
||||
buildTypeAndChannelSectionBlock(incidentEntity, "", ""),
|
||||
buildSeverityAndTicketSectionBlock(incidentEntity),
|
||||
buildStatusAndMeetingSectionBlock(incidentEntity),
|
||||
}
|
||||
}
|
||||
|
||||
func IncidentSummarySection(incidentEntity *entity.IncidentEntity, db *gorm.DB) ([]slack.Block, error) {
|
||||
teamEntity, err := query.FindTeamById(db, incidentEntity.TeamsId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in searching team with id: %d, err: %v", incidentEntity.TeamsId, err)
|
||||
}
|
||||
|
||||
severityEntity, err := query.FindSeverityById(db, incidentEntity.SeverityId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in searching severity with id: %d, err: %v", incidentEntity.SeverityId, err)
|
||||
}
|
||||
return []slack.Block{
|
||||
buildTypeAndChannelSectionBlock(incidentEntity, teamEntity.Name, severityEntity.Name),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func buildSummaryHeader(incidentTitle string) *slack.SectionBlock {
|
||||
headerText := slack.NewTextBlockObject("plain_text", incidentTitle, true, true)
|
||||
headerSection := slack.NewSectionBlock(headerText, nil, nil)
|
||||
|
||||
return headerSection
|
||||
}
|
||||
|
||||
func buildTypeAndChannelSectionBlock(incidentEntity *entity.IncidentEntity, teamName, severityName string) *slack.SectionBlock {
|
||||
fields := []*slack.TextBlockObject{
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*<@%s>* \n*%s* - *%s*\n", incidentEntity.CreatedBy, incidentEntity.IncidentName, incidentEntity.Title), false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", "\n", false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", incidentEntity.Description, false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", "\n", false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Type*\n%s", teamName), false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Channel*\n<#%s>", incidentEntity.SlackChannel), false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Severity*\n%s", severityName), false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Ticket*\n%s", "Integration Disabled"), false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Status*\n%s", incidentEntity.Status), false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Meeting*\n%s", "Integration Disabled"), false, false),
|
||||
}
|
||||
block := slack.NewSectionBlock(nil, fields, nil)
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
func buildSeverityAndTicketSectionBlock(incidentEntity *entity.IncidentEntity) *slack.SectionBlock {
|
||||
fields := []*slack.TextBlockObject{
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Severity*\n%d", incidentEntity.SeverityId), false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Ticket*\n%s", "integration disabled"), false, false),
|
||||
}
|
||||
block := slack.NewSectionBlock(nil, fields, nil)
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
func buildStatusAndMeetingSectionBlock(incidentEntity *entity.IncidentEntity) *slack.SectionBlock {
|
||||
fields := []*slack.TextBlockObject{
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Status*\n%s", incidentEntity.Status), false, false),
|
||||
slack.NewTextBlockObject("mrkdwn", fmt.Sprintf("*Meeting*\n%s", "integration disabled"), false, false),
|
||||
}
|
||||
block := slack.NewSectionBlock(nil, fields, nil)
|
||||
|
||||
return block
|
||||
}
|
||||
67
pkg/slack/houston/design/incident_assign.go
Normal file
67
pkg/slack/houston/design/incident_assign.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"houston/entity"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
func GenerateModalForIncidentAssign(channel slack.Channel) slack.ModalViewRequest {
|
||||
|
||||
titleText := slack.NewTextBlockObject("plain_text", "Houston", false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
submitText := slack.NewTextBlockObject("plain_text", "Submit", false, false)
|
||||
headerText := slack.NewTextBlockObject("mrkdwn", ":information_source: Incident roles are customizable by your organization. While a user can be assigned multiple roles, a role cannot be assigned to multiple users.", false, false)
|
||||
headerSection := slack.NewSectionBlock(headerText, nil, nil)
|
||||
|
||||
optionBlockObjects := []*slack.OptionBlockObject{
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: string(entity.RESPONDER),
|
||||
},
|
||||
Value: string(entity.RESPONDER),
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: string(entity.SERVICE_OWNER),
|
||||
},
|
||||
Value: string(entity.SERVICE_OWNER),
|
||||
},
|
||||
{
|
||||
Text: &slack.TextBlockObject{
|
||||
Type: "plain_text",
|
||||
Text: string(entity.RETROSPECTIVE),
|
||||
},
|
||||
Value: string(entity.RETROSPECTIVE),
|
||||
},
|
||||
}
|
||||
|
||||
rolePlaceholder := slack.NewTextBlockObject("plain_text", "Select a role", false, false)
|
||||
roleTypeOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, rolePlaceholder, "role_type", optionBlockObjects...)
|
||||
roleTypeText := slack.NewTextBlockObject(slack.PlainTextType, "Roles", false, false)
|
||||
roleBlock := slack.NewInputBlock("role_type", roleTypeText, nil, roleTypeOption)
|
||||
|
||||
userPlaceholder := slack.NewTextBlockObject("plain_text", "Select people", false, false)
|
||||
userTypeOption := slack.NewOptionsSelectBlockElement(slack.OptTypeUser, userPlaceholder, "users_select")
|
||||
userTypeText := slack.NewTextBlockObject(slack.PlainTextType, "Users", false, false)
|
||||
userBlock := slack.NewInputBlock("user_type", userTypeText, nil, userTypeOption)
|
||||
blocks := slack.Blocks{
|
||||
BlockSet: []slack.Block{
|
||||
headerSection,
|
||||
roleBlock,
|
||||
userBlock,
|
||||
},
|
||||
}
|
||||
return slack.ModalViewRequest{
|
||||
Type: slack.ViewType("modal"),
|
||||
Title: titleText,
|
||||
Close: closeText,
|
||||
Submit: submitText,
|
||||
Blocks: blocks,
|
||||
PrivateMetadata: channel.ID,
|
||||
CallbackID: "assignIncidentRole",
|
||||
}
|
||||
|
||||
}
|
||||
42
pkg/slack/houston/design/incident_description.go
Normal file
42
pkg/slack/houston/design/incident_description.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"github.com/slack-go/slack"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func BuildIncidentUpdateDescriptionModal(db *gorm.DB, channel slack.Channel, description string) slack.ModalViewRequest {
|
||||
titleText := slack.NewTextBlockObject("plain_text", "Set Description", false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
submitText := slack.NewTextBlockObject("plain_text", "Submit", false, false)
|
||||
|
||||
headerText := slack.NewTextBlockObject("mrkdwn", "Description", false, false)
|
||||
headerSection := slack.NewSectionBlock(headerText, nil, nil)
|
||||
|
||||
incidentDescriptionText := slack.NewTextBlockObject("plain_text", "Incident description", false, false)
|
||||
incidentDescriptionPlaceholder := slack.NewTextBlockObject("plain_text", "Write something", false, false)
|
||||
incidentDescriptionElement := slack.NewPlainTextInputBlockElement(incidentDescriptionPlaceholder, "incident_description")
|
||||
incidentDescriptionElement.Multiline = true
|
||||
incidentDescriptionElement.InitialValue = description
|
||||
incidentDescriptionElement.MaxLength = 3000
|
||||
incidentDescription := slack.NewInputBlock("Incident description", incidentDescriptionText, nil, incidentDescriptionElement)
|
||||
incidentDescription.Optional = true
|
||||
|
||||
blocks := slack.Blocks{
|
||||
BlockSet: []slack.Block{
|
||||
headerSection,
|
||||
incidentDescription,
|
||||
},
|
||||
}
|
||||
|
||||
return slack.ModalViewRequest{
|
||||
Type: slack.ViewType("modal"),
|
||||
Title: titleText,
|
||||
Close: closeText,
|
||||
Submit: submitText,
|
||||
Blocks: blocks,
|
||||
PrivateMetadata: channel.ID,
|
||||
CallbackID: "setIncidentDescription",
|
||||
}
|
||||
|
||||
}
|
||||
52
pkg/slack/houston/design/incident_severity.go
Normal file
52
pkg/slack/houston/design/incident_severity.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"strconv"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
func BuildIncidentUpdateSeverityModal(channel slack.Channel, incidentSeverity []entity.SeverityEntity) slack.ModalViewRequest {
|
||||
titleText := slack.NewTextBlockObject("plain_text", "Set Severity of Incident", false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
submitText := slack.NewTextBlockObject("plain_text", "Submit", false, false)
|
||||
|
||||
headerText := slack.NewTextBlockObject("mrkdwn", "Severity", false, false)
|
||||
headerSection := slack.NewSectionBlock(headerText, nil, nil)
|
||||
|
||||
incidentStatusBlockOption := createIncidentSeverityBlock(incidentSeverity)
|
||||
|
||||
incidentSeverityText := slack.NewTextBlockObject(slack.PlainTextType, "Incident Severity", false, false)
|
||||
incidentSeverityOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, nil, "incident_severity_modal_request", incidentStatusBlockOption...)
|
||||
incidentSeverityBlock := slack.NewInputBlock("incident_severity_modal_request_input", incidentSeverityText, nil, incidentSeverityOption)
|
||||
|
||||
blocks := slack.Blocks{
|
||||
BlockSet: []slack.Block{
|
||||
headerSection,
|
||||
incidentSeverityBlock,
|
||||
},
|
||||
}
|
||||
|
||||
return slack.ModalViewRequest{
|
||||
Type: slack.ViewType("modal"),
|
||||
Title: titleText,
|
||||
Close: closeText,
|
||||
Submit: submitText,
|
||||
Blocks: blocks,
|
||||
PrivateMetadata: channel.ID,
|
||||
CallbackID: "setIncidentSeverity",
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createIncidentSeverityBlock(options []entity.SeverityEntity) []*slack.OptionBlockObject {
|
||||
optionBlockObjects := make([]*slack.OptionBlockObject, 0, len(options))
|
||||
for _, o := range options {
|
||||
txt := fmt.Sprintf("%s (%s)", o.Name, o.Description)
|
||||
optionText := slack.NewTextBlockObject(slack.PlainTextType, txt, false, false)
|
||||
optionBlockObjects = append(optionBlockObjects, slack.NewOptionBlockObject(strconv.FormatUint(uint64(o.ID), 10), optionText, nil))
|
||||
}
|
||||
return optionBlockObjects
|
||||
}
|
||||
40
pkg/slack/houston/design/incident_title.go
Normal file
40
pkg/slack/houston/design/incident_title.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"github.com/slack-go/slack"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func BuildIncidentUpdateTitleModal(db *gorm.DB, channel slack.Channel, title string) slack.ModalViewRequest {
|
||||
titleText := slack.NewTextBlockObject("plain_text", "Set Title of Incident", false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
submitText := slack.NewTextBlockObject("plain_text", "Submit", false, false)
|
||||
|
||||
headerText := slack.NewTextBlockObject("mrkdwn", "Title", false, false)
|
||||
headerSection := slack.NewSectionBlock(headerText, nil, nil)
|
||||
|
||||
incidentTitleText := slack.NewTextBlockObject("plain_text", "Incident Title", false, false)
|
||||
incidentTitlePlaceholder := slack.NewTextBlockObject("plain_text", "Write something", false, false)
|
||||
incidentTitleElement := slack.NewPlainTextInputBlockElement(incidentTitlePlaceholder, "incident_title")
|
||||
incidentTitleElement.InitialValue = title
|
||||
incidentBelowText := slack.NewTextBlockObject("plain_text", "The title to set for the incident.", false, false)
|
||||
incidentTitle := slack.NewInputBlock("Incident title", incidentTitleText, incidentBelowText, incidentTitleElement)
|
||||
|
||||
blocks := slack.Blocks{
|
||||
BlockSet: []slack.Block{
|
||||
headerSection,
|
||||
incidentTitle,
|
||||
},
|
||||
}
|
||||
|
||||
return slack.ModalViewRequest{
|
||||
Type: slack.ViewType("modal"),
|
||||
Title: titleText,
|
||||
Close: closeText,
|
||||
Submit: submitText,
|
||||
Blocks: blocks,
|
||||
PrivateMetadata: channel.ID,
|
||||
CallbackID: "setIncidentTitle",
|
||||
}
|
||||
|
||||
}
|
||||
105
pkg/slack/houston/design/incident_update_tags.go
Normal file
105
pkg/slack/houston/design/incident_update_tags.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
func BuildIncidentUpdateTagModal(channel slack.Channel, tags []entity.TagsEntity, teamName string, savedTags []entity.TagsEntity,
|
||||
savedContributingFactor *entity.ContributingFactorEntity, contributingFactors []entity.ContributingFactorEntity,
|
||||
savedCustomerTags []entity.CustomerTagsEntity, customerTags []entity.CustomerTagsEntity, savedDataPlatformTags *entity.IncidentsTagsDataPlatformMapping) slack.ModalViewRequest {
|
||||
|
||||
titleText := slack.NewTextBlockObject("plain_text", "Edit Tags", false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
submitText := slack.NewTextBlockObject("plain_text", "Submit", false, false)
|
||||
|
||||
contributingFactorBlockOption := createContributingFactorBlocks(contributingFactors)
|
||||
contributingFactorText := slack.NewTextBlockObject(slack.PlainTextType, "CONTRIBUTING-FACTORS", false, false)
|
||||
contributingFactorPlaceholder := slack.NewTextBlockObject(slack.PlainTextType, fmt.Sprint("SELECT CONTRIBUTING-FACTORS tags"), false, false)
|
||||
contributingFactorOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, contributingFactorPlaceholder, "incident_cf_modal_request", contributingFactorBlockOption...)
|
||||
if savedContributingFactor != nil {
|
||||
contributingFactorOption.InitialOption = slack.NewOptionBlockObject(strconv.FormatUint(uint64(savedContributingFactor.ID), 10), slack.NewTextBlockObject(slack.PlainTextType, savedContributingFactor.Label, false, false), nil)
|
||||
}
|
||||
contributingFactorHint := slack.NewTextBlockObject(slack.PlainTextType, "CONTRIBUTING-FACTORS is configured to have one single tag, please select appropriate single tag from the dropdown", false, false)
|
||||
contributingFactorBlock := slack.NewInputBlock("incident_cf_modal_request_input", contributingFactorText, contributingFactorHint, contributingFactorOption)
|
||||
contributingFactorBlock.Optional = true
|
||||
|
||||
customerBlockOption := createCustomerBlocks(customerTags)
|
||||
customerText := slack.NewTextBlockObject(slack.PlainTextType, "CUSTOMER", false, false)
|
||||
customerPlaceholder := slack.NewTextBlockObject(slack.PlainTextType, fmt.Sprint("SELECT CUSTOMER tags"), false, false)
|
||||
customerOption := slack.NewOptionsMultiSelectBlockElement(slack.MultiOptTypeStatic, customerPlaceholder, "incident_customer_tags_modal_request", customerBlockOption...)
|
||||
customerOption.InitialOptions = createCustomerBlocks(savedCustomerTags)
|
||||
customerBlock := slack.NewInputBlock("incident_customer_tags_modal_request_input", customerText, nil, customerOption)
|
||||
customerBlock.Optional = true
|
||||
|
||||
incidentStatusBlockOption := createIncidentTagsBlock(tags)
|
||||
incidentTagText := slack.NewTextBlockObject(slack.PlainTextType, fmt.Sprint("CUSTOMER: "+strings.ToUpper(teamName)), false, false)
|
||||
incidentTagPlaceholder := slack.NewTextBlockObject(slack.PlainTextType, fmt.Sprint("SELECT CUSTOMER: "+strings.ToUpper(teamName)+" tags"), false, false)
|
||||
incidentTypeOption := slack.NewOptionsMultiSelectBlockElement(slack.MultiOptTypeStatic, incidentTagPlaceholder, "incident_tags_modal_request", incidentStatusBlockOption...)
|
||||
incidentTypeOption.InitialOptions = createIncidentTagsBlock(savedTags)
|
||||
incidentTypeBlock := slack.NewInputBlock("incident_tags_modal_request_input", incidentTagText, nil, incidentTypeOption)
|
||||
incidentTypeBlock.Optional = true
|
||||
|
||||
dataPlatformText := slack.NewTextBlockObject("plain_text", "DATA PLATFORM", false, false)
|
||||
dataPlatformPlaceholder := slack.NewTextBlockObject("plain_text", "Comma seperated list of tags", false, false)
|
||||
dataPlatformElement := slack.NewPlainTextInputBlockElement(dataPlatformPlaceholder, "incident_data_platform_tag_modal_request")
|
||||
if savedDataPlatformTags != nil {
|
||||
dataPlatformElement.InitialValue = savedDataPlatformTags.DataPlatformTag
|
||||
}
|
||||
dataPlatformTitle := slack.NewInputBlock("DATA_PLATFORM", dataPlatformText, nil, dataPlatformElement)
|
||||
dataPlatformTitle.Optional = true
|
||||
|
||||
blocks := slack.Blocks{
|
||||
BlockSet: []slack.Block{
|
||||
contributingFactorBlock,
|
||||
customerBlock,
|
||||
incidentTypeBlock,
|
||||
dataPlatformTitle,
|
||||
},
|
||||
}
|
||||
|
||||
return slack.ModalViewRequest{
|
||||
Type: slack.ViewType("modal"),
|
||||
Title: titleText,
|
||||
Close: closeText,
|
||||
Submit: submitText,
|
||||
Blocks: blocks,
|
||||
PrivateMetadata: channel.ID,
|
||||
CallbackID: "updateTag",
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createIncidentTagsBlock(options []entity.TagsEntity) []*slack.OptionBlockObject {
|
||||
optionBlockObjects := make([]*slack.OptionBlockObject, 0, len(options))
|
||||
for _, o := range options {
|
||||
txt := fmt.Sprintf(o.Label)
|
||||
optionText := slack.NewTextBlockObject(slack.PlainTextType, txt, false, false)
|
||||
optionBlockObjects = append(optionBlockObjects, slack.NewOptionBlockObject(strconv.FormatUint(uint64(o.ID), 10), optionText, nil))
|
||||
}
|
||||
return optionBlockObjects
|
||||
}
|
||||
|
||||
func createContributingFactorBlocks(options []entity.ContributingFactorEntity) []*slack.OptionBlockObject {
|
||||
optionBlockObjects := make([]*slack.OptionBlockObject, 0, len(options))
|
||||
for _, o := range options {
|
||||
txt := fmt.Sprintf(o.Label)
|
||||
optionText := slack.NewTextBlockObject(slack.PlainTextType, txt, false, false)
|
||||
optionBlockObjects = append(optionBlockObjects, slack.NewOptionBlockObject(strconv.FormatUint(uint64(o.ID), 10), optionText, nil))
|
||||
}
|
||||
return optionBlockObjects
|
||||
}
|
||||
|
||||
func createCustomerBlocks(options []entity.CustomerTagsEntity) []*slack.OptionBlockObject {
|
||||
optionBlockObjects := make([]*slack.OptionBlockObject, 0, len(options))
|
||||
for _, o := range options {
|
||||
txt := fmt.Sprintf("%s", o.Label)
|
||||
optionText := slack.NewTextBlockObject(slack.PlainTextType, txt, false, false)
|
||||
optionBlockObjects = append(optionBlockObjects, slack.NewOptionBlockObject(strconv.FormatUint(uint64(o.ID), 10), optionText, nil))
|
||||
}
|
||||
return optionBlockObjects
|
||||
}
|
||||
52
pkg/slack/houston/design/incident_update_type.go
Normal file
52
pkg/slack/houston/design/incident_update_type.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"houston/entity"
|
||||
"strconv"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
)
|
||||
|
||||
func BuildIncidentUpdateTypeModal(channel slack.Channel, teams []entity.TeamEntity) slack.ModalViewRequest {
|
||||
titleText := slack.NewTextBlockObject("plain_text", "Set Type of Incident", false, false)
|
||||
closeText := slack.NewTextBlockObject("plain_text", "Close", false, false)
|
||||
submitText := slack.NewTextBlockObject("plain_text", "Submit", false, false)
|
||||
|
||||
headerText := slack.NewTextBlockObject("mrkdwn", "Type", false, false)
|
||||
headerSection := slack.NewSectionBlock(headerText, nil, nil)
|
||||
|
||||
incidentStatusBlockOption := createIncidentTypeBlock(teams)
|
||||
|
||||
incidentTypeText := slack.NewTextBlockObject(slack.PlainTextType, "Incident Type", false, false)
|
||||
incidentTypeOption := slack.NewOptionsSelectBlockElement(slack.OptTypeStatic, nil, "incident_type_modal_request", incidentStatusBlockOption...)
|
||||
incidentTypeBlock := slack.NewInputBlock("incident_type_modal_request_input", incidentTypeText, nil, incidentTypeOption)
|
||||
|
||||
blocks := slack.Blocks{
|
||||
BlockSet: []slack.Block{
|
||||
headerSection,
|
||||
incidentTypeBlock,
|
||||
},
|
||||
}
|
||||
|
||||
return slack.ModalViewRequest{
|
||||
Type: slack.ViewType("modal"),
|
||||
Title: titleText,
|
||||
Close: closeText,
|
||||
Submit: submitText,
|
||||
Blocks: blocks,
|
||||
PrivateMetadata: channel.ID,
|
||||
CallbackID: "setIncidentType",
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createIncidentTypeBlock(options []entity.TeamEntity) []*slack.OptionBlockObject {
|
||||
optionBlockObjects := make([]*slack.OptionBlockObject, 0, len(options))
|
||||
for _, o := range options {
|
||||
txt := fmt.Sprintf("%s", o.Name)
|
||||
optionText := slack.NewTextBlockObject(slack.PlainTextType, txt, false, false)
|
||||
optionBlockObjects = append(optionBlockObjects, slack.NewOptionBlockObject(strconv.FormatUint(uint64(o.ID), 10), optionText, nil))
|
||||
}
|
||||
return optionBlockObjects
|
||||
}
|
||||
181
pkg/slack/houston/slash_command_processor.go
Normal file
181
pkg/slack/houston/slash_command_processor.go
Normal file
@@ -0,0 +1,181 @@
|
||||
package houston
|
||||
|
||||
import (
|
||||
"houston/pkg/postgres/query"
|
||||
"houston/pkg/slack/houston/command"
|
||||
houston "houston/pkg/slack/houston/design"
|
||||
|
||||
"github.com/slack-go/slack"
|
||||
"github.com/slack-go/slack/slackevents"
|
||||
"github.com/slack-go/slack/socketmode"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type HoustonCommandHandler struct {
|
||||
logger *zap.Logger
|
||||
socketmodeClient *socketmode.Client
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewHoustonCommandHandler(socketmodeClient *socketmode.Client, logger *zap.Logger, db *gorm.DB) *HoustonCommandHandler {
|
||||
return &HoustonCommandHandler{
|
||||
socketmodeClient: socketmodeClient,
|
||||
logger: logger,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (bch *HoustonCommandHandler) ProcessSlashCommand(evt socketmode.Event) {
|
||||
HoustonMainCommand(bch.db, bch.socketmodeClient, bch.logger, &evt)
|
||||
|
||||
}
|
||||
|
||||
func (bch *HoustonCommandHandler) ProcessCallbackEvent(callback slack.InteractionCallback) {
|
||||
bch.logger.Info("process callback event", zap.Any("callback", callback))
|
||||
}
|
||||
|
||||
func (bch *HoustonCommandHandler) ProcessModalCallbackEvent(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
var callbackId = callback.View.CallbackID
|
||||
switch callbackId {
|
||||
case "start_incident_button":
|
||||
cip := command.NewCreateIncidentProcessor(bch.socketmodeClient, bch.logger, bch.db)
|
||||
cip.CreateIncidentModalCommandProcessing(callback, request)
|
||||
case "assignIncidentRole":
|
||||
iap := command.NewIncidentAssignProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
iap.IncidentAssignModalCommandProcessing(callback, request)
|
||||
case "setIncidentStatus":
|
||||
isp := command.NewIncidentUpdateStatusProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
isp.IncidentUpdateStatus(callback, request, callback.Channel, callback.User)
|
||||
case "setIncidentTitle":
|
||||
itp := command.NewIncidentUpdateTitleProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentUpdateTitle(callback, request, callback.Channel, callback.User)
|
||||
case "setIncidentDescription":
|
||||
idp := command.NewIncidentUpdateDescriptionProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
idp.IncidentUpdateDescription(callback, request, callback.Channel, callback.User)
|
||||
case "setIncidentSeverity":
|
||||
isp := command.NewIncidentUpdateSeverityProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
isp.IncidentUpdateSeverity(callback, request, callback.Channel, callback.User)
|
||||
case "setIncidentType":
|
||||
itp := command.NewIncidentUpdateTypeProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentUpdateType(callback, request, callback.Channel, callback.User)
|
||||
case "updateTag":
|
||||
itp := command.NewIncidentUpdateTagsProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentUpdateTags(callback, request, callback.Channel, callback.User)
|
||||
}
|
||||
incidentEntity, _ := query.FindIncidentByChannelId(bch.db, callback.View.PrivateMetadata)
|
||||
if incidentEntity != nil {
|
||||
messages, _ := query.FindMessageByIncidentName(bch.db, incidentEntity.IncidentName)
|
||||
blocks, _ := houston.IncidentSummarySection(incidentEntity, bch.db)
|
||||
msgOptions := []slack.MsgOption{slack.MsgOptionBlocks(blocks...)}
|
||||
for _, message := range messages {
|
||||
bch.socketmodeClient.UpdateMessage(message.SlackChannel, message.MessageTimeStamp, msgOptions...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (bch *HoustonCommandHandler) ProcessButtonHandler(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
actionId := callback.ActionCallback.BlockActions[0].ActionID
|
||||
bch.logger.Info("process button callback event", zap.Any("action_id", actionId),
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
|
||||
switch actionId {
|
||||
case "start_incident_button":
|
||||
bch.logger.Info("start incident button command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
sip := command.NewStartIncidentProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
sip.ProcessStartIncidentButtonCommand(callback.Channel.ID, callback.TriggerID)
|
||||
case "show_incidents_button":
|
||||
bch.logger.Info("show incidents button command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
sip := command.ShowIncidentsProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
sip.ProcessShowIncidentsButtonCommand(callback.Channel, callback.User, callback.TriggerID, request)
|
||||
case "incident":
|
||||
bch.processIncidentCommands(callback, request)
|
||||
case "tags":
|
||||
bch.processTagsCommands(callback, request)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (bch *HoustonCommandHandler) ProcessMemberJoinEvent(memberJoinedChannelEvent *slackevents.MemberJoinedChannelEvent, request *socketmode.Request) {
|
||||
memberJoinProcessor := command.NewMemberJoinProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
memberJoinProcessor.MemberJoinProcessCommand(memberJoinedChannelEvent)
|
||||
var payload interface{}
|
||||
bch.socketmodeClient.Ack(*request, payload)
|
||||
}
|
||||
|
||||
func (bch *HoustonCommandHandler) processIncidentCommands(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
action := callback.ActionCallback.BlockActions[0].SelectedOption.Value
|
||||
switch action {
|
||||
case "assignIncidentRole":
|
||||
bch.logger.Info("incident assign button command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
iap := command.NewIncidentAssignProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
iap.IncidentAssignProcess(callback, request)
|
||||
case "resolveIncident":
|
||||
bch.logger.Info("incident update button command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
irp := command.NewIncidentResolveProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
irp.IncidentResolveProcess(callback, request)
|
||||
case "setIncidentStatus":
|
||||
bch.logger.Info("incident update status command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
isp := command.NewIncidentUpdateStatusProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
isp.IncidentUpdateStatusRequestProcess(callback, request)
|
||||
case "setIncidentType":
|
||||
bch.logger.Info("incident update type command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
itp := command.NewIncidentUpdateTypeProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentUpdateTypeRequestProcess(callback, request)
|
||||
case "setIncidentSeverity":
|
||||
bch.logger.Info("incident update severity command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
itp := command.NewIncidentUpdateSeverityProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentUpdateSeverityRequestProcess(callback, request)
|
||||
case "setIncidentTitle":
|
||||
bch.logger.Info("incident update title command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
itp := command.NewIncidentUpdateTitleProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentUpdateTitleRequestProcess(callback, request)
|
||||
case "setIncidentDescription":
|
||||
bch.logger.Info("incident update description command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
idp := command.NewIncidentUpdateDescriptionProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
idp.IncidentUpdateDescriptionRequestProcess(callback, request)
|
||||
}
|
||||
}
|
||||
|
||||
func (bch *HoustonCommandHandler) processTagsCommands(callback slack.InteractionCallback, request *socketmode.Request) {
|
||||
action := callback.ActionCallback.BlockActions[0].SelectedOption.Value
|
||||
switch action {
|
||||
case "addTags":
|
||||
bch.logger.Info("Add Tags command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
itp := command.NewIncidentUpdateTagsProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentUpdateTagsRequestProcess(callback, request)
|
||||
case "showTags":
|
||||
bch.logger.Info("Show Tags command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
itp := command.NewIncidentShowTagsProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentShowTagsRequestProcess(callback, request)
|
||||
case "removeTag":
|
||||
bch.logger.Info("Remove Tags command received",
|
||||
zap.String("channel", callback.Channel.Name), zap.String("user_id", callback.User.ID),
|
||||
zap.String("user_name", callback.User.Name))
|
||||
itp := command.NewIncidentUpdateTagsProcessor(bch.socketmodeClient, bch.db, bch.logger)
|
||||
itp.IncidentUpdateTagsRequestProcess(callback, request)
|
||||
}
|
||||
}
|
||||
231
schema.sql
Normal file
231
schema.sql
Normal file
@@ -0,0 +1,231 @@
|
||||
CREATE TABLE tenant (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name text,
|
||||
key text,
|
||||
url text,
|
||||
vertical text,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE grafana (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name text,
|
||||
url text,
|
||||
tenant_id bigint,
|
||||
status boolean DEFAULT false,
|
||||
alert_id bigint,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE alerts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name text,
|
||||
team_name text,
|
||||
service_name text,
|
||||
status boolean DEFAULT false,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE incidents (
|
||||
id SERIAL PRIMARY KEY,
|
||||
title text,
|
||||
description text,
|
||||
status varchar(50),
|
||||
severity_id bigint,
|
||||
incident_name text,
|
||||
slack_channel varchar(100),
|
||||
detection_time timestamp without time zone,
|
||||
customer_impact_start_time timestamp without time zone,
|
||||
customer_impact_end_time timestamp without time zone,
|
||||
teams_id bigint,
|
||||
jira_id varchar(100),
|
||||
confluence_id varchar(100),
|
||||
created_by varchar(100),
|
||||
updated_by varchar(100),
|
||||
severity_tat timestamp without time zone,
|
||||
remind_me_at timestamp without time zone,
|
||||
enable_reminder boolean DEFAULT false,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone,
|
||||
version bigint default 0
|
||||
);
|
||||
|
||||
CREATE TABLE teams (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name varchar(50),
|
||||
oncall_handle varchar(100),
|
||||
secondary_oncall_handle varchar(100),
|
||||
manager_handle varchar(100),
|
||||
secondary_manager_handle varchar(100),
|
||||
active boolean DEFAULT false,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE teams_severity_user_mapping (
|
||||
id SERIAL PRIMARY KEY,
|
||||
entity_type varchar(100),
|
||||
entity_id bigint,
|
||||
users_id bigint,
|
||||
version bigint default 0,
|
||||
default_add_in_incidents boolean DEFAULT false,
|
||||
team_role varchar(100),
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name varchar(50),
|
||||
slack_user_id varchar(100),
|
||||
active boolean DEFAULT true
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE severity (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name varchar(50),
|
||||
description text,
|
||||
version bigint default 0,
|
||||
sla int,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE teams_tags_mapping (
|
||||
id SERIAL PRIMARY KEY,
|
||||
teams_id bigint,
|
||||
tag_id bigint,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE incidents_tags_mapping (
|
||||
id SERIAL PRIMARY KEY,
|
||||
incident_id bigint,
|
||||
tag_id bigint,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE incidents_tags_contributing_factor_mapping (
|
||||
id SERIAL PRIMARY KEY,
|
||||
incident_id bigint,
|
||||
contributing_factor_id bigint,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE contributing_factor (
|
||||
id SERIAL PRIMARY KEY,
|
||||
label varchar(100),
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE incidents_tags_customer_mapping (
|
||||
id SERIAL PRIMARY KEY,
|
||||
incident_id bigint,
|
||||
customer_tags_id bigint,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE customer_tags (
|
||||
id SERIAL PRIMARY KEY,
|
||||
label varchar(100),
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE incidents_tags_data_platform_mapping (
|
||||
id SERIAL PRIMARY KEY,
|
||||
incident_id bigint,
|
||||
data_platform_tag text,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE tags (
|
||||
id SERIAL PRIMARY KEY,
|
||||
label text,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE incident_status (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name varchar(50),
|
||||
description text,
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE incident_roles (
|
||||
id SERIAL PRIMARY KEY,
|
||||
incident_id bigint,
|
||||
role varchar(100),
|
||||
assigned_to_user_slack_id varchar(100),
|
||||
assigned_by_user_slack_id varchar(100),
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE messages (
|
||||
id SERIAL PRIMARY KEY,
|
||||
slack_channel varchar(100),
|
||||
incident_name text,
|
||||
message_timestamp varchar(100),
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE audit (
|
||||
id SERIAL PRIMARY KEY,
|
||||
incident_id bigint,
|
||||
event text,
|
||||
user_name varchar(100),
|
||||
user_id varchar(100),
|
||||
version bigint default 0,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
deleted_at timestamp without time zone
|
||||
);
|
||||
Reference in New Issue
Block a user