Skip to content

Commit a47db4b

Browse files
authored
Merge pull request #1 from cruxstack/dev
feat: add initial bot logic
2 parents 1f4d96a + 92c9073 commit a47db4b

File tree

22 files changed

+1291
-11
lines changed

22 files changed

+1291
-11
lines changed

.editorconfig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[*]
2+
indent_style = space
3+
indent_size = 2
4+
end_of_line = lf
5+
insert_final_newline = true
6+
trim_trailing_whitespace = true
7+
charset = utf-8
8+
9+
[{Dockerfile,Dockerfile.*}]
10+
indent_size = 4
11+
tab_width = 4
12+
13+
[{Makefile,makefile,GNUmakefile}]
14+
indent_style = tab
15+
indent_size = 4
16+
17+
[Makefile.*]
18+
indent_style = tab
19+
indent_size = 4
20+
21+
[**/*.{go,mod,sum}]
22+
indent_style = tab
23+
indent_size = unset
24+
25+
[**/*.py]
26+
indent_size = 4

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
APP_DEBUG_ENABLED=true
2+
APP_SLACK_CHANNEL=
3+
APP_SLACK_TOKEN=
4+
APP_AWS_CONSOLE_URL=https://us-east-1.console.aws.amazon.com

.github/.dependabot.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "daily"

.github/workflows/release.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout Code
16+
uses: actions/checkout@v3
17+
- name: Bump Version
18+
id: tag_version
19+
uses: mathieudutour/github-tag-action@v6.1
20+
with:
21+
github_token: ${{ secrets.GITHUB_TOKEN }}
22+
default_bump: minor
23+
custom_release_rules: bug:patch:Fixes,chore:patch:Chores,docs:patch:Documentation,feat:minor:Features,refactor:minor:Refactors,test:patch:Tests,ci:patch:Development,dev:patch:Development
24+
- name: Create Release
25+
uses: ncipollo/release-action@v1.12.0
26+
with:
27+
tag: ${{ steps.tag_version.outputs.new_tag }}
28+
name: ${{ steps.tag_version.outputs.new_tag }}
29+
body: ${{ steps.tag_version.outputs.changelog }}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: semantic-check
2+
on:
3+
pull_request_target:
4+
types:
5+
- opened
6+
- edited
7+
- synchronize
8+
9+
permissions:
10+
contents: read
11+
pull-requests: read
12+
13+
jobs:
14+
main:
15+
name: Semantic Commit Message Check
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout Code
19+
uses: actions/checkout@v3
20+
- uses: amannn/action-semantic-pull-request@v5.2.0
21+
name: Check PR for Semantic Commit Message
22+
env:
23+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24+
with:
25+
requireScope: false
26+
validateSingleCommit: true

.gitignore

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# .gitignore
2+
3+
# terraform files
4+
.terraform.lock.hcl
5+
.terraform.tfstate.lock.info
6+
*.tfvars.*
7+
*.tfstate
8+
*.tfstate.*.backup
9+
*.tfstate.backup
10+
*.tfplan
11+
*.terraform/
12+
*.tfvars
13+
.grunt
14+
backend.tf.json
15+
16+
# node.js / typescript
17+
node_modules
18+
npm-debug.log
19+
yarn-error.log
20+
dist
21+
out
22+
*.tsbuildinfo
23+
24+
# logs
25+
logs
26+
*.log
27+
npm-debug.log*
28+
yarn-debug.log*
29+
yarn-error.log*
30+
31+
# runtime data
32+
pids
33+
*.pid
34+
*.seed
35+
*.pid.lock
36+
37+
# coverage directories
38+
coverage
39+
lib-cov
40+
41+
# docker files
42+
*.tar
43+
dockerfile.*.bak
44+
45+
# general
46+
tmp/
47+
!**/.gitkeep
48+
.DS_Store
49+
.env
50+
.env.local
51+
.env.development.local
52+
.env.test.local
53+
.env.production.local
54+
55+
# ides
56+
.vscode
57+
.idea
58+
*.swp
59+
*.swo
60+
61+
# opa
62+
bundle.tar.gz
63+

README.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# aws-backup-integration-slack-go
22

3-
**UNDER DEVELOPMENT**
4-
53
AWS Lambda function that listens to **AWS Backup** events via **Amazon
64
EventBridge** and publishes clean, threaded messages to Slack.
75

@@ -26,11 +24,11 @@ EventBridge** and publishes clean, threaded messages to Slack.
2624
### Steps
2725

2826
```bash
29-
git clone https://github.com/cruxstack/aws-backup-integration-slack.git
30-
cd aws-backup-integration-slack
27+
git clone https://github.com/cruxstack/aws-backup-integration-slack-go.git
28+
cd aws-backup-integration-slack-go
3129

3230
# build static Linux binary for lambda
33-
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o bootstrap
31+
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -C cmd/lambda -o ../../bootstrap
3432

3533
# package
3634
zip deployment.zip bootstrap
@@ -56,11 +54,18 @@ zip deployment.zip bootstrap
5654
* Upload `deployment.zip`
5755
* Set environment variables above
5856
3. **EventBridge rule**
59-
```json
60-
{
61-
"source": ["aws.backup"],
62-
"detail-type": ["Backup Job State Change"]
63-
}
57+
```json
58+
{
59+
"source": ["aws.backup"],
60+
"detail-type": [
61+
"Backup Job State Change",
62+
"Backup Plan State Change",
63+
"Backup Vault State Change",
64+
"Copy Job State Change",
65+
"Region Setting State Change",
66+
"Restore Job State Change"
67+
]
68+
}
6469
```
6570
Target: the Lambda function.
6671
4. **Slack App**
@@ -75,7 +80,7 @@ zip deployment.zip bootstrap
7580

7681
```bash
7782
cp .env.example .env # edit the values
78-
go run .
83+
go run -C cmd/sample .
7984
```
8085

8186
The sample runner replays `fixtures/samples.json` and posts to Slack exactly as

assets/slack/manifest.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"display_information": {
3+
"name": "AWS Backup",
4+
"description": "AWS Backup Bot",
5+
"background_color": "#00802f"
6+
},
7+
"features": {
8+
"bot_user": {
9+
"display_name": "AWS Backup",
10+
"always_online": false
11+
}
12+
},
13+
"oauth_config": {
14+
"scopes": {
15+
"bot": [
16+
"channels:join",
17+
"channels:read",
18+
"chat:write.public",
19+
"chat:write"
20+
]
21+
}
22+
},
23+
"settings": {
24+
"org_deploy_enabled": false,
25+
"socket_mode_enabled": false,
26+
"token_rotation_enabled": false
27+
}
28+
}

cmd/lambda/main.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"log"
7+
"sync"
8+
9+
awsevents "github.com/aws/aws-lambda-go/events"
10+
"github.com/aws/aws-lambda-go/lambda"
11+
"github.com/cruxstack/aws-backup-slack-integration-go/internal/app"
12+
)
13+
14+
/*
15+
Lambda wrapper helpers
16+
*/
17+
18+
var (
19+
once sync.Once
20+
a *app.App
21+
initErr error
22+
)
23+
24+
// LambdaHandler satisfies aws-lambda-go.
25+
func LambdaHandler(_ context.Context, evt awsevents.CloudWatchEvent) error {
26+
once.Do(func() {
27+
cfg, err := app.NewConfig()
28+
if err != nil {
29+
initErr = err
30+
return
31+
}
32+
a = app.New(cfg)
33+
})
34+
35+
if initErr != nil {
36+
// returning (not panic) preserves clean CW metrics
37+
return initErr
38+
}
39+
40+
if a.Config.DebugEnabled {
41+
j, _ := json.Marshal(evt)
42+
log.Print(string(j))
43+
}
44+
45+
return a.Process(evt)
46+
}
47+
48+
func main() {
49+
lambda.Start(LambdaHandler)
50+
}

cmd/sample/main.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"log"
6+
"os"
7+
"path/filepath"
8+
9+
awsevents "github.com/aws/aws-lambda-go/events"
10+
"github.com/joho/godotenv"
11+
12+
"github.com/cruxstack/aws-backup-slack-integration-go/internal/app"
13+
)
14+
15+
func main() {
16+
envpath := filepath.Join("..", "..", ".env")
17+
log.Print(envpath)
18+
if _, err := os.Stat(envpath); err == nil {
19+
_ = godotenv.Load(envpath)
20+
}
21+
22+
cfg, err := app.NewConfig()
23+
if err != nil {
24+
log.Fatal(err)
25+
}
26+
a := app.New(cfg)
27+
28+
path := filepath.Join("..", "..", "fixtures", "samples.json")
29+
raw, err := os.ReadFile(path)
30+
if err != nil {
31+
log.Fatal(err)
32+
}
33+
34+
var evts []awsevents.CloudWatchEvent
35+
if err := json.Unmarshal(raw, &evts); err != nil {
36+
log.Fatal(err)
37+
}
38+
39+
for _, e := range evts {
40+
if err := a.Process(e); err != nil {
41+
log.Fatalf("process id=%s: %v", e.ID, err)
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)