diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..d2145dd --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: OldTyT diff --git a/.github/workflows/golang.yml b/.github/workflows/golang.yml new file mode 100644 index 0000000..89af686 --- /dev/null +++ b/.github/workflows/golang.yml @@ -0,0 +1,31 @@ +name: Test golang build and lint +on: + push: + pull_request: + workflow_dispatch: + + +jobs: + golangci: + name: Lint check + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.18.x + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: latest + build: + name: Test build + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: install Go + uses: actions/setup-go@v3 + with: + go-version: 1.18.x + - run: go build . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..eff7124 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release binary +on: + release: + types: [created] + +env: + BINARY_NAME: alerta_notify + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: 1.18.x + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: latest + release-linux-amd64: + name: release linux/amd64 + runs-on: ubuntu-latest + strategy: + matrix: + goos: [linux, windows, darwin] + goarch: ["386", amd64, arm64] + exclude: + - goarch: "386" + goos: darwin + steps: + - uses: actions/checkout@v3 + - uses: wangyoucao577/go-release-action@v1.32 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + goos: ${{ matrix.goos }} + goarch: ${{ matrix.goarch }} + binary_name: "${{ env.BINARY_NAME }}" + extra_files: LICENSE.md README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6cf39c9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +dev.config.json + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + diff --git a/config.json b/config.json new file mode 100644 index 0000000..09af2c9 --- /dev/null +++ b/config.json @@ -0,0 +1,6 @@ +{ + "alerta_username": "alerta_username", + "alerta_password": "alerta_password", + "alerta_url": "https://alerta.io", + "time_sleep": 30 +} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5922c14 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module github.com/OldTyT/alerta_notify + +go 1.18 + +require ( + github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb // indirect + github.com/martinlindhe/notify v0.0.0-20181008203735-20632c9a275a // indirect + github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect + gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..83c357a --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb h1:6S+TKObz6+Io2c8IOkcbK4Sz7nj6RpEVU7TkvmsZZcw= +github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb/go.mod h1:wf3nKtOnQqCp7kp9xB7hHnNlZ6m3NoiOxjrB9hFRq4Y= +github.com/martinlindhe/notify v0.0.0-20181008203735-20632c9a275a h1:nQcAxLK581HrmqF0TVy2GC3iFjB8X+aWGtxQ/t2uyGE= +github.com/martinlindhe/notify v0.0.0-20181008203735-20632c9a275a/go.mod h1:zL1p4SieQ27ZZ4V4KdVYdEcSkVl1OwNoi8xI1r5hJkc= +github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ= +github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= +gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 h1:MZF6J7CV6s/h0HBkfqebrYfKCVEo5iN+wzE4QhV3Evo= +gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2/go.mod h1:s1Sn2yZos05Qfs7NKt867Xe18emOmtsO3eAKbDaon0o= diff --git a/internal/vars/vars.go b/internal/vars/vars.go new file mode 100644 index 0000000..6004e5d --- /dev/null +++ b/internal/vars/vars.go @@ -0,0 +1,17 @@ +package vars + +type NotifierCFG struct { + AlertaUsername string `json:"alerta_username"` + AlertaPassword string `json:"alerta_password"` + AlertaURL string `json:"alerta_url"` + TimeSleep int `json:"time_sleep"` +} + +type OtherCFG struct { + AlertaToken string +} + +var ( + Notifier NotifierCFG + Other OtherCFG +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..4932d6a --- /dev/null +++ b/main.go @@ -0,0 +1,113 @@ +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/OldTyT/alerta_notify/internal/vars" + "github.com/martinlindhe/notify" +) + +func main() { + ConfFile := flag.String("conf", "config.json", "Path to conf file.") + flag.Parse() + file, err := os.Open(*ConfFile) + if err != nil { + fmt.Println(err) + fmt.Println("Error open conf file -", *ConfFile) + os.Exit(1) + } + defer file.Close() + decoder := json.NewDecoder(file) + err = decoder.Decode(&vars.Notifier) + if err != nil { + fmt.Println("error:", err) + os.Exit(1) + } + LoginAlerta() + UpdateAlerts() +} + +func LoginAlerta() { + type AlertaAuth struct { + UserName string `json:"username"` + Password string `json:"password"` + } + type AlertaToken struct { + Token string `json:"token"` + } + var ( + AlertaAuthData AlertaAuth + TokenLocal AlertaToken + ) + AlertaAuthData.Password = vars.Notifier.AlertaPassword + AlertaAuthData.UserName = vars.Notifier.AlertaUsername + JsonData, err := json.Marshal(AlertaAuthData) + if err != nil { + fmt.Println(err) + } + URL := vars.Notifier.AlertaURL + "/auth/login" + resp, err := http.Post(URL, "application/json", bytes.NewBuffer(JsonData)) + if err != nil { + fmt.Println("Error auth in alerta.") + fmt.Println(err) + os.Exit(1) + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + fmt.Println("Response status != 200, exiting") + notify.Alert("Alerta Notify", "Alerta Notify", "Response status != 200, exiting", "path/to/icon.png") + os.Exit(1) + } + body, err := ioutil.ReadAll(resp.Body) + if err := json.Unmarshal(body, &TokenLocal); err != nil { + fmt.Println("Can't unmarshal JSON") + fmt.Println(err) + os.Exit(1) + } + vars.Other.AlertaToken = TokenLocal.Token + notify.Notify("Alerta Notify", "Alerta Notify", "Success auth in Alerta", "path/to/icon.png") +} + +func UpdateAlerts() { + type AlertaAlertList struct { + Total int `json:"total"` + } + var AlertsSummary AlertaAlertList + URL := vars.Notifier.AlertaURL + "/alerts?sort-by=lastReceiveTime&status=open" + for true { + client := &http.Client{} + req, err := http.NewRequest("GET", URL, nil) + if err != nil { + notify.Notify("Alerta Notify", "Alerta Notify", "Failure to get alerts.", "path/to/icon.png") + } + req.Header.Set("Authorization", "Bearer "+vars.Other.AlertaToken) + resp, err := client.Do(req) + if err != nil { + notify.Notify("Alerta Notify", "Alerta Notify", "Failure to get alerts.", "path/to/icon.png") + } + if resp.StatusCode != 200 { + fmt.Println("Response status != 200") + notify.Alert("Alerta Notify", "Alerta Notify", "Response status != 200", "path/to/icon.png") + } else { + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err = json.Unmarshal(body, &AlertsSummary); err != nil { + fmt.Println("Can't unmarshal JSON") + fmt.Println(err) + os.Exit(1) + } + if AlertsSummary.Total != 0 { + notify.Alert("Alerta Notify", "Alerta Notify", "Find active alerts!", "path/to/icon.png") + } + } + time.Sleep(time.Duration(vars.Notifier.TimeSleep) * time.Second) + } + +}