Skip to content

Commit

Permalink
feat(cli): Create Slack Channel Alerts 🚨 (#165)
Browse files Browse the repository at this point in the history
Users now can create Slack Channel Alert Integrations via the CLI:
```
$ lacework integration create
? Choose an integration type to create:  Slack Channel Alert
â–¸ Name:  #tech-ally-notify
â–¸ Slack URL:  https://hooks.slack.com/services/1234/ABC/abc123
â–¸ Alert Severity Level:  Critical
The integration was created.
```

Signed-off-by: Salim Afiune Maya <[email protected]>
  • Loading branch information
afiune committed Jul 17, 2020
1 parent fb81416 commit 0d1f8c7
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 6 deletions.
36 changes: 32 additions & 4 deletions api/integrations_slack_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,35 @@ func NewSlackChannelIntegration(name string, data SlackChannelData) SlackChanInt
}
}

type SlackAlertLevel int

const (
CriticalSlackAlertLevel SlackAlertLevel = 1
HighSlackAlertLevel SlackAlertLevel = 2
MediumSlackAlertLevel SlackAlertLevel = 3
LowSlackAlertLevel SlackAlertLevel = 4
AllSlackAlertLevel SlackAlertLevel = 5
)

// SlackAlertLevels is the list of available slack alert levels
var SlackAlertLevels = map[SlackAlertLevel]string{
CriticalSlackAlertLevel: "Critical",
HighSlackAlertLevel: "High",
MediumSlackAlertLevel: "Medium",
LowSlackAlertLevel: "Low",
AllSlackAlertLevel: "All",
}

// String returns the string representation of a slack alert level
func (i SlackAlertLevel) String() string {
return SlackAlertLevels[i]
}

// Int returns the int representation of a slack alert level
func (i SlackAlertLevel) Int() int {
return int(i)
}

// CreateSlackChannel creates a slack channel alert integration on the Lacework Server
func (svc *IntegrationsService) CreateSlackChannel(integration SlackChanIntegration) (
response SlackChanIntResponse,
Expand Down Expand Up @@ -95,8 +124,7 @@ type SlackChanIntegration struct {
}

type SlackChannelData struct {
IssueGrouping string `json:"ISSUE_GROUPING,omitempty"`
SlackUrl string `json:"SLACK_URL"`
// TODO: @afiune to convert to an actual ENUM
MinAlertSeverity int `json:"MIN_ALERT_SEVERITY"`
IssueGrouping string `json:"ISSUE_GROUPING,omitempty"`
SlackUrl string `json:"SLACK_URL"`
MinAlertSeverity SlackAlertLevel `json:"MIN_ALERT_SEVERITY"`
}
4 changes: 2 additions & 2 deletions api/integrations_slack_channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func TestIntegrationsCreateSlackChannel(t *testing.T) {
assert.Equal(t, "integration_name", resData.Name)
assert.True(t, resData.State.Ok)
assert.Equal(t, "https://hooks.slack.com/services/ABCD/12345/abcd1234", resData.Data.SlackUrl)
assert.Equal(t, 3, resData.Data.MinAlertSeverity)
assert.Equal(t, api.SlackAlertLevel(3), resData.Data.MinAlertSeverity)
}
}

Expand Down Expand Up @@ -120,7 +120,7 @@ func TestIntegrationsGetSlackChannel(t *testing.T) {
assert.Equal(t, "integration_name", resData.Name)
assert.True(t, resData.State.Ok)
assert.Equal(t, "https://hooks.slack.com/services/ABCD/12345/abcd1234", resData.Data.SlackUrl)
assert.Equal(t, 3, resData.Data.MinAlertSeverity)
assert.Equal(t, api.SlackAlertLevel(3), resData.Data.MinAlertSeverity)
}
}

Expand Down
3 changes: 3 additions & 0 deletions cli/cmd/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ func promptCreateIntegration() error {
prompt = &survey.Select{
Message: "Choose an integration type to create: ",
Options: []string{
"Slack Channel Alert",
"Docker Hub",
"AWS Config",
"AWS CloudTrail",
Expand All @@ -203,6 +204,8 @@ func promptCreateIntegration() error {
}

switch integration {
case "Slack Channel Alert":
return createSlackChannelIntegration()
case "Docker Hub":
return createDockerHubIntegration()
case "AWS Config":
Expand Down
96 changes: 96 additions & 0 deletions cli/cmd/integration_slack_channel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// Author:: Salim Afiune Maya (<[email protected]>)
// Copyright:: Copyright 2020, Lacework Inc.
// License:: Apache License, Version 2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package cmd

import (
"github.com/AlecAivazis/survey/v2"

"github.com/lacework/go-sdk/api"
)

func createSlackChannelIntegration() error {
questions := []*survey.Question{
{
Name: "name",
Prompt: &survey.Input{Message: "Name: "},
Validate: survey.Required,
},
{
Name: "url",
Prompt: &survey.Input{Message: "Slack URL: "},
Validate: survey.Required,
},
{
Name: "alert_severity_level",
Prompt: &survey.Select{
Message: "Alert Severity Level: ",
Options: []string{
"Critical",
"High and above",
"Medium and above",
"Low and above",
"All",
},
},
Validate: survey.Required,
},
}

answers := struct {
Name string
Url string
AlertSeverity string `survey:"alert_severity_level"`
}{}

err := survey.Ask(questions, &answers,
survey.WithIcons(promptIconsFunc),
)
if err != nil {
return err
}

slack := api.NewSlackChannelIntegration(answers.Name,
api.SlackChannelData{
SlackUrl: answers.Url,
MinAlertSeverity: alertSeverityToEnum(answers.AlertSeverity),
},
)

cli.StartProgress(" Creating integration...")
_, err = cli.LwApi.Integrations.CreateSlackChannel(slack)
cli.StopProgress()
return err
}

func alertSeverityToEnum(level string) api.SlackAlertLevel {
switch level {
case "Critical":
return api.CriticalSlackAlertLevel
case "High and above":
return api.HighSlackAlertLevel
case "Medium and above":
return api.MediumSlackAlertLevel
case "Low and above":
return api.LowSlackAlertLevel
case "All":
return api.AllSlackAlertLevel
default:
return api.MediumSlackAlertLevel
}
}

0 comments on commit 0d1f8c7

Please sign in to comment.