Skip to content
This repository has been archived by the owner on Jul 19, 2022. It is now read-only.

Commit

Permalink
Update repository #1
Browse files Browse the repository at this point in the history
  • Loading branch information
betorvs committed May 25, 2021
1 parent 1b6f876 commit 4018059
Show file tree
Hide file tree
Showing 40 changed files with 1,067 additions and 331 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Test Coveralls

on: [push]

jobs:
test:
name: coverage
runs-on: ubuntu-latest
steps:
- name: Install Go
if: success()
uses: actions/setup-go@v2
with:
go-version: 1.16.x
- name: Checkout code
uses: actions/checkout@v2
- name: Calc coverage
run: TESTRUN=true go test -v ./... -covermode=count -coverprofile=coverage.out
- name: gcov2lcov-action
uses: jandelgado/gcov2lcov-action@v1.0.8
- name: Coveralls
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: coverage.lcov
13 changes: 13 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Go Lint

on: [push]

jobs:
test:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Run golangci-lint
uses: actions-contrib/golangci-lint@v1
19 changes: 19 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Publish to Registry
on:
release:
types: [published]
push:
branches:
- main
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: betorvs/sensubot
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
tag_semver: true
18 changes: 18 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Go Test

on: [push]

jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Go 1.16
uses: actions/setup-go@v1
with:
go-version: 1.16
id: go
- name: Test
run: TESTRUN=true go test -v ./...
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.vscode*
sensubot
sensubot
ca.pem
coverage.out
31 changes: 0 additions & 31 deletions .travis.yml

This file was deleted.

8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.0.0] - 2021-06-01
### Changed
- golang version to 1.16
- golangspell-core templates
- github actions
- change from nlopes/slack to slack-go/slack
- change tests to assert lib

## [0.0.1] - 2020-02-03
### Added
- Slack Endpoint sensu_bot_url/sensubot/v1/slack
Expand Down
26 changes: 17 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
FROM golang:1.13.6-alpine3.11 AS golang
FROM golang:1.16.0-alpine3.12 AS golang

ARG LOC=/builds/go/src/github.com/betorvs/sensubot/
RUN apk add --no-cache git
RUN mkdir -p /builds/go/src/github.com/betorvs/sensubot/
ENV GOPATH /builds/go
COPY . /builds/go/src/github.com/betorvs/sensubot/
RUN mkdir -p $LOC
ENV GOPATH /go
COPY . $LOC
ENV CGO_ENABLED 0
RUN cd /builds/go/src/github.com/betorvs/sensubot/ && go build
RUN cd $LOC && TESTRUN=true go test ./... && go build

FROM alpine:3.11
FROM alpine:3.12
ARG LOC=/builds/go/src/github.com/betorvs/sensubot
WORKDIR /
VOLUME /tmp
RUN apk add --no-cache ca-certificates
COPY --from=golang /builds/go/src/github.com/betorvs/sensubot/sensubot /
RUN update-ca-certificates
RUN mkdir -p /app
RUN addgroup -g 1000 -S app && \
adduser -u 1000 -G app -S -D -h /app app && \
chmod 755 /app
COPY --from=golang $LOC/sensubot /app

EXPOSE 9090
RUN chmod +x /sensubot
CMD ["/sensubot"]
RUN chmod +x /app/sensubot
WORKDIR /app
USER app
CMD ["/app/sensubot"]
40 changes: 33 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
SensuBot
========

Travis-CI: [![Build Status](https://travis-ci.org/betorvs/sensubot.svg?branch=master)](https://travis-ci.org/betorvs/sensubot)
![Go Test](https://github.com/betorvs/sensubot/workflows/Go%20Test/badge.svg)

SensuBot can receive messages from Slack and/or Telegram. It can answer simple commands like get, execute and silence.

It can list almost all resources available in Sensu: assets, checks, entities, events, namespaces, mutators, filters, handlers, hooks and health.

# Build

```sh
go build
```

# Environment Variables

* **SENSUBOT_PORT**: default "9090";
Expand Down Expand Up @@ -125,3 +119,35 @@ or directly messages:
```
get all checks
```

# Build

```sh
go build
```

## Test and coverage

Run the tests

```sh
TESTRUN=true go test ./... -coverprofile=coverage.out

go tool cover -html=coverage.out
```

Install [golangci-lint](https://github.com/golangci/golangci-lint#install) and run lint:

```sh
golangci-lint run
```


# references

## Golang Spell
The project was initialized using [Golang Spell](https://github.com/golangspell/golangspell).

## Architectural Model
The Architectural Model adopted to structure the application is based on The Clean Architecture.
Further details can be found here: [The Clean Architecture](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html) and in the Clean Architecture Book.
50 changes: 39 additions & 11 deletions appcontext/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package appcontext

import "sync"

//List of consts containing the names of the available componentes in the Application Context - appcontext.Current
//List of consts containing the names of the available components in the Application Context - appcontext.Current (Add your component names here as constants)
const (
Logger = "Logger"
SensuRepository = "SensuRepository"
SlackRepository = "SlackRepository"
TelegramRepository = "TelegramRepository"
Expand All @@ -12,42 +13,69 @@ const (
//Component is the Base interface for all Components
type Component interface{}

//ComponentInitializerFunction specifies a function for lazily initializing a component
type ComponentInitializerFunction func() Component

//ComponentInfo holds the function to lazy initialize the component and the instance created following the singleton pattern
type ComponentInfo struct {
Initializer ComponentInitializerFunction
Instance Component
}

//Get s the instance. If it is not created, creates and stores it to the next calls
func (componentInfo *ComponentInfo) Get() Component {

if componentInfo.Instance == nil {
componentInfo.Instance = componentInfo.Initializer()
}

return componentInfo.Instance
}

//ApplicationContext is the type defining a map of Components
type ApplicationContext struct {
components map[string]Component
componentMu sync.Mutex
components map[string]*ComponentInfo
componentMutex sync.Mutex
}

//Current keeps all components available, initialized in the application startup
var Current ApplicationContext

//Add a component By Name
func (applicationContext *ApplicationContext) Add(componentName string, component Component) {
applicationContext.componentMu.Lock()
defer applicationContext.componentMu.Unlock()
applicationContext.components[componentName] = component
func (applicationContext *ApplicationContext) Add(componentName string, componentInitializerFunction ComponentInitializerFunction) {
applicationContext.componentMutex.Lock()
defer applicationContext.componentMutex.Unlock()

applicationContext.components[componentName] = &ComponentInfo{Initializer: componentInitializerFunction}
}

//Get a component By Name
func (applicationContext *ApplicationContext) Get(componentName string) Component {
applicationContext.componentMu.Lock()
defer applicationContext.componentMu.Unlock()
return applicationContext.components[componentName]
if applicationContext.components[componentName] == nil {
return nil
}
return applicationContext.components[componentName].Get()
}

//Delete a component By Name
func (applicationContext *ApplicationContext) Delete(componentName string) {
applicationContext.componentMutex.Lock()
defer applicationContext.componentMutex.Unlock()

delete(applicationContext.components, componentName)
}

//Count returns the count of components registered
func (applicationContext *ApplicationContext) Count() int {
applicationContext.componentMutex.Lock()
defer applicationContext.componentMutex.Unlock()

return len(applicationContext.components)
}

//CreateApplicationContext creates a new ApplicationContext instance
func CreateApplicationContext() ApplicationContext {
return ApplicationContext{components: make(map[string]Component)}
return ApplicationContext{components: make(map[string]*ComponentInfo)}
}

func init() {
Expand Down
32 changes: 17 additions & 15 deletions appcontext/appcontext_test.go → appcontext/context_test.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,48 @@
package appcontext

import "testing"
import (
"testing"
)

func TestContext_Add(t *testing.T) {
type fields struct {
components map[string]Component
components map[string]ComponentInfo
}
type args struct {
componentName string
component Component
component ComponentInfo
}
components := make(map[string]Component)
components := make(map[string]ComponentInfo)
tests := []struct {
name string
fields fields
args args
}{
{
name: "Add complete repository",
name: "Add Component and Delete",
fields: fields{components: components},
args: args{
componentName: SensuRepository,
component: ApplicationContext{},
componentName: Logger,
component: ComponentInfo{Initializer: func() Component { return ApplicationContext{} }},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
context := CreateApplicationContext()
context.Add(tt.args.componentName, tt.args.component)
context.Add(tt.args.componentName, tt.args.component.Initializer)
if context.Count() == 0 {
t.Error("Component not added")
}
SensuRepository :=
context.Get(SensuRepository)
if SensuRepository == nil {
Config :=
context.Get(Logger)
if Config == nil {
t.Error("Component not found")
}
context.Delete("SensuRepository")
SensuRepository =
context.Get("SensuRepository")
if SensuRepository != nil {
context.Delete("Config")
Config =
context.Get("Config")
if Config != nil {
t.Error("Component not deleted")
}
})
Expand Down
Loading

0 comments on commit 4018059

Please sign in to comment.