From 4f8f5e831dfcb3488006c6e72f93a14155cbf4de Mon Sep 17 00:00:00 2001 From: Benjamin Boehm Date: Wed, 23 Oct 2024 18:14:53 +0200 Subject: [PATCH] Initial commit --- .github/workflows/go.yml | 28 ++++++++++++ .github/workflows/release.yml | 21 +++++++++ .gitignore | 1 + Makefile | 10 +++++ README.md | 48 ++++++++++++++++++++ go.mod | 13 ++++++ go.sum | 27 ++++++++++++ main.go | 83 +++++++++++++++++++++++++++++++++++ 8 files changed, 231 insertions(+) create mode 100644 .github/workflows/go.yml create mode 100644 .github/workflows/release.yml create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..c097e5d --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,28 @@ +# This workflow will build a golang project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go + +name: Go + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.23' + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v ./... diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..36ad79f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,21 @@ +name: release + +on: + release: + types: [created] + +permissions: + contents: write + packages: write + +jobs: + release-linux-amd64: + name: release linux/amd64 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: wangyoucao577/go-release-action@v1 + with: + github_token: ${{ secrets.ACTIONS_KEY }} + goos: linux + goarch: amd64 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d74e21 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..51e5d4d --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +.PHONY: lint vet + +build: + go build -o check_ecs_snapshots main.go +lint: + go fmt $(go list ./... | grep -v /vendor/) +vet: + go vet $(go list ./... | grep -v /vendor/) +test: + go test -v -cover ./... diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb5e4d5 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# Description +Check for Elastic Cloud Server (ECS) snapshot age on Open Telekom Cloud (OTC) + +# Environment + +* Option 1: clouds.yaml + * create config file (~/.config/openstack/clouds.yaml or /etc/openstack/clouds.yaml) + ```yaml + --- + clouds: + myCloud: + auth: + username: '' + password: '' + project_name: 'eu-de' + user_domain_name: '' + auth_url: 'https://iam.eu-de.otc.t-systems.com/v3' + interface: 'public' + identity_api_version: 3 # !Important + ``` + * set env which cloud credentials should be used + ```bash + export OS_CLOUD=myCloud + ``` + +* Option 2: Environment Variables + ```bash + export OS_PROJECT_NANME=eu-de + export OS_AUTH_URL="https://iam.eu-de.otc.t-systems.com:443/v3" + export OS_USER_DOMAIN_NAME="" + export OS_USERNAME="" + export OS_PASSWORD="" + ``` + +# Run +```bash +go run cmd/main.go +``` + +# Build +```bash +make build +``` + +# Dependencies + +* OTC Cloud SDK: https://github.com/opentelekomcloud/gophertelekomcloud/ +* Netways monitoring plugins library: https://github.com/NETWAYS/go-check diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3e9714a --- /dev/null +++ b/go.mod @@ -0,0 +1,13 @@ +module github.com/BenjaminBoehm/check-ecs-snapshots + +go 1.23.2 + +require ( + github.com/NETWAYS/go-check v0.6.2 + github.com/opentelekomcloud/gophertelekomcloud v0.9.3 +) + +require ( + github.com/spf13/pflag v1.0.5 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e1b4410 --- /dev/null +++ b/go.sum @@ -0,0 +1,27 @@ +github.com/NETWAYS/go-check v0.6.2 h1:H/9Q/+rVzLbSUV/6QS9eDhyMUml7sf67TF4nSuHBwJo= +github.com/NETWAYS/go-check v0.6.2/go.mod h1:qx8m3s2Xul9wqfUjrCSArEFkOdtwxIyUmBYYrCkqA/8= +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/opentelekomcloud/gophertelekomcloud v0.9.3 h1:zdttgRAWc4uHgJ3PX5hP8ulhT1VYBh2JeRsItNPp8dg= +github.com/opentelekomcloud/gophertelekomcloud v0.9.3/go.mod h1:M1F6OfSRZRzAmAFKQqSLClX952at5hx5rHe4UTEykgg= +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/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +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/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +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.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..f63ee04 --- /dev/null +++ b/main.go @@ -0,0 +1,83 @@ +package main + +import ( + "fmt" + "log" + "time" + + check "github.com/NETWAYS/go-check" + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/openstack" + "github.com/opentelekomcloud/gophertelekomcloud/openstack/cbr/v3/backups" +) + +func main() { + config := check.NewConfig() + config.Name = "check-ecs-snapshots" + config.Readme = `Check for Elastic Cloud Server (ECS) snapshot age on Open Telekom Cloud (OTC)` + config.Version = "1.0.0" + + critical := config.FlagSet.IntP("critical", "c", 60, "critical threshold for age of snapshot in days") + warning := config.FlagSet.IntP("warning", "w", 30, "warning threshold for age of snapshot in days") + + config.ParseArguments() + + env := openstack.NewEnv("OS_", true) + cloud, err := env.Cloud() + + if err != nil { + panic(err) + } + + providerClient, err := openstack.AuthenticatedClientFromCloud(cloud) + + if err != nil { + log.Fatalf("Can't authenticate: %s", err) + } + + cbr, err := openstack.NewCBRService(providerClient, golangsdk.EndpointOpts{}) + + if err != nil { + log.Fatalf("Problem with cbr Service: %s", err) + } + + snaps, err := backups.List(cbr, backups.ListOpts{}) + + if err != nil { + log.Fatal(err) + } + currentTime := time.Now() + layout := "2006-01-02T15:04:05.999999" + + criticalCount := 0 + warningCount := 0 + okCount := 0 + + for _, s := range snaps { + createdAtParsed, err := time.Parse(layout, s.CreatedAt) + if err != nil { + fmt.Println("Could not parse time:", err, createdAtParsed, currentTime) + } + + duration := currentTime.Sub(createdAtParsed) + daysDiff := int(duration.Hours() / 24) + + if *critical <= daysDiff { + criticalCount += 1 + + } else if *warning <= daysDiff { + warningCount += 1 + } else { + okCount += 1 + } + } + + if criticalCount > 0 { + check.Exitf(check.Critical, "%d Snapshots older than %d days\n", criticalCount, *critical) + } else if warningCount > 0 { + check.Exitf(check.Warning, "%d Snapshots older than %d days\n", warningCount, *warning) + } else { + check.Exitf(check.OK, "No snapshots (%d) older than %d days\n", okCount, *warning) + } + +}