From 6468b5aa6f2097a6ef4503e5241416f4c68a0fb3 Mon Sep 17 00:00:00 2001 From: Mario Candela Date: Sun, 26 Feb 2023 18:04:05 +0100 Subject: [PATCH] refactor:Added Integration test and tiny refactoring (#23) * Refactoring name convention * Added integration test * Added Makefile * Bump golang.org/x/crypto from 0.0.0-20220826181053-bd7e27e6170d to 0.6.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.0.0-20220826181053-bd7e27e6170d to 0.6.0. - [Release notes](https://github.com/golang/crypto/releases) - [Commits](https://github.com/golang/crypto/commits/v0.6.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... * Upgrade go from 1.16 to 1.20 * Added integration test: HTTP, TCP, SSH * Added Makefile Improve README.md * Fixed unit test CI * Fixed go-version * Added integration test into C.I. actions --------- Signed-off-by: Mario Candela Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 10 +- .github/workflows/docker-image.yml | 5 +- Makefile | 24 ++++ README.md | 12 +- builder/{Builder.go => builder.go} | 23 ++-- builder/{Director.go => director.go} | 0 docker-compose.yml | 2 +- go.mod | 17 ++- go.sum | 33 ++++- .../configurations/beelzebub.yaml | 9 ++ .../configurations/services/http-8080.yaml | 19 +++ .../configurations/services/ssh-2222.yaml | 25 ++++ .../configurations/services/tcp-3306.yaml | 6 + integration_test/integration_test.go | 115 ++++++++++++++++++ ...ionsParser.go => configurations_parser.go} | 0 ..._test.go => configurations_parser_test.go} | 0 plugin/OpenAiGPT.go => plugins/openai-gpt.go | 4 +- .../openai-gpt_test.go | 2 +- ...protocolManager.go => protocol_manager.go} | 0 ...nager_test.go => protocol_manager_test.go} | 0 .../hypertext_transfer_protocol.go} | 2 +- .../secure_shell.go} | 12 +- .../transmission_control_protocol.go} | 2 +- 23 files changed, 282 insertions(+), 40 deletions(-) create mode 100644 Makefile rename builder/{Builder.go => builder.go} (86%) rename builder/{Director.go => director.go} (100%) create mode 100644 integration_test/configurations/beelzebub.yaml create mode 100644 integration_test/configurations/services/http-8080.yaml create mode 100644 integration_test/configurations/services/ssh-2222.yaml create mode 100644 integration_test/configurations/services/tcp-3306.yaml create mode 100644 integration_test/integration_test.go rename parser/{configurationsParser.go => configurations_parser.go} (100%) rename parser/{configurationsParser_test.go => configurations_parser_test.go} (100%) rename plugin/OpenAiGPT.go => plugins/openai-gpt.go (97%) rename plugin/OpenAiGPT_test.go => plugins/openai-gpt_test.go (99%) rename protocols/{protocolManager.go => protocol_manager.go} (100%) rename protocols/{protocolManager_test.go => protocol_manager_test.go} (100%) rename protocols/{hypertextTransferProtocolStrategy.go => strategies/hypertext_transfer_protocol.go} (99%) rename protocols/{secureShellStrategy.go => strategies/secure_shell.go} (90%) rename protocols/{transmissionControlProtocolStrategy.go => strategies/transmission_control_protocol.go} (98%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2238ffb..aac369b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: jobs: - build: + CI: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -16,7 +16,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.16 + go-version: 1.20.0 - name: Dependences run: go mod download @@ -28,9 +28,13 @@ jobs: - name: Build run: go build -v ./... + - name: Integration tests + run: | + INTEGRATION=1 go test ./... -v + - name: Unit tests run: | - go test ./... -coverprofile coverage.tmp.out -covermode count + go test ./... -v -coverprofile coverage.tmp.out -covermode count go tool cover -func coverage.tmp.out - name: Quality Gate - Test coverage shall be above threshold diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index a2a413c..22e0fcf 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -6,11 +6,8 @@ on: - 'v*.*.*' jobs: - - build: - + CD: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - name: Docker login diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..20a623a --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +DOCKER_COMPOSE := $(shell which docker-compose) + +ifeq (${DOCKER_COMPOSE},) +DOCKER_COMPOSE = docker compose +endif + +beelzebub.start: + ${DOCKER_COMPOSE} build; + ${DOCKER_COMPOSE} up -d; + +beelzebub.stop: + ${DOCKER_COMPOSE} down; + +test.unit: + go test ./... + +test.unit.verbose: + go test ./... -v + +test.integration: + INTEGRATION=1 go test ./... + +test.integration.verbose: + INTEGRATION=1 go test ./... -v \ No newline at end of file diff --git a/README.md b/README.md index f35778b..0ebe9f6 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,20 @@ $ go build $ ./beelzebub ``` -Unit Test: +###Unit Test: ```bash -$ go test ./... +$ make test.unit ``` +###Integration test: + +Run integration testing +```bash +$ make test.integration + ``` + + ## Features - OpenAPI ChatBot GPT-3 integration diff --git a/builder/Builder.go b/builder/builder.go similarity index 86% rename from builder/Builder.go rename to builder/builder.go index bf8729e..95e0439 100644 --- a/builder/Builder.go +++ b/builder/builder.go @@ -3,6 +3,7 @@ package builder import ( "beelzebub/parser" "beelzebub/protocols" + "beelzebub/protocols/strategies" "beelzebub/tracer" "errors" "fmt" @@ -68,24 +69,22 @@ func (b *Builder) buildRabbitMQ(rabbitMQURI string) error { } func (b *Builder) Close() error { - if err := b.rabbitMQChannel.Close(); err != nil { - return err + if b.rabbitMQConnection != nil { + if err := b.rabbitMQChannel.Close(); err != nil { + return err + } + if err := b.rabbitMQConnection.Close(); err != nil { + return err + } } - if err := b.rabbitMQConnection.Close(); err != nil { - return err - } - if err := b.logsFile.Close(); err != nil { - return err - } - return nil } func (b *Builder) Run() error { // Init Protocol strategies - secureShellStrategy := &protocols.SecureShellStrategy{} - hypertextTransferProtocolStrategy := &protocols.HypertextTransferProtocolStrategy{} - transmissionControlProtocolStrategy := &protocols.TransmissionControlProtocolStrategy{} + secureShellStrategy := &strategies.SecureShellStrategy{} + hypertextTransferProtocolStrategy := &strategies.HypertextTransferProtocolStrategy{} + transmissionControlProtocolStrategy := &strategies.TransmissionControlProtocolStrategy{} // Init Tracer strategies, and set the trace strategy default HTTP protocolManager := protocols.InitProtocolManager(b.traceStrategy, hypertextTransferProtocolStrategy) diff --git a/builder/Director.go b/builder/director.go similarity index 100% rename from builder/Director.go rename to builder/director.go diff --git a/docker-compose.yml b/docker-compose.yml index e3638a6..27000aa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,4 +15,4 @@ services: environment: RABBITMQ_URI: ${RABBITMQ_URI} volumes: - - "./configurations:/configurations" + - "./configurations:/configurations" \ No newline at end of file diff --git a/go.mod b/go.mod index 7ac3f9e..010ced9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module beelzebub -go 1.16 +go 1.20 require ( github.com/gliderlabs/ssh v0.3.5 @@ -10,6 +10,19 @@ require ( github.com/rabbitmq/amqp091-go v1.7.0 github.com/sirupsen/logrus v1.9.0 github.com/stretchr/testify v1.8.1 - golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d + golang.org/x/crypto v0.6.0 gopkg.in/yaml.v3 v3.0.1 ) + +require ( + github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/kr/fs v0.1.0 // indirect + github.com/melbahja/goph v1.3.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/sftp v1.13.5 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/net v0.6.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect +) diff --git a/go.sum b/go.sum index 552144f..0a5e232 100644 --- a/go.sum +++ b/go.sum @@ -11,13 +11,20 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= -github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= +github.com/melbahja/goph v1.3.1 h1:FxFevAwCCpLkM4WBmnVVxcJBcBz6lKQpsN5biV2hA6w= +github.com/melbahja/goph v1.3.1/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go= +github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= 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/rabbitmq/amqp091-go v1.7.0 h1:V5CF5qPem5OGSnEo8BoSbsDGwejg6VUJsKEdneaoTUo= @@ -33,24 +40,33 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -58,22 +74,29 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM= golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/integration_test/configurations/beelzebub.yaml b/integration_test/configurations/beelzebub.yaml new file mode 100644 index 0000000..5b2fe43 --- /dev/null +++ b/integration_test/configurations/beelzebub.yaml @@ -0,0 +1,9 @@ +core: + logging: + debug: false + debugReportCaller: false + logDisableTimestamp: true + logsPath: ./logs + tracing: + rabbitMQEnabled: false + rabbitMQURI: "" diff --git a/integration_test/configurations/services/http-8080.yaml b/integration_test/configurations/services/http-8080.yaml new file mode 100644 index 0000000..8dcf2d1 --- /dev/null +++ b/integration_test/configurations/services/http-8080.yaml @@ -0,0 +1,19 @@ +apiVersion: "v1" +protocol: "http" +address: ":8080" +description: "Wordpress 6.0" +commands: + - regex: "index.php" + handler: "mocked response" + headers: + - "Content-Type: text/html" + - "Server: Apache/2.4.53 (Debian)" + - "X-Powered-By: PHP/7.4.29" + statusCode: 200 + - regex: "^(/wp-login.php|/wp-admin)$" + handler: "mocked response" + headers: + - "Content-Type: text/html" + - "Server: Apache/2.4.53 (Debian)" + - "X-Powered-By: PHP/7.4.29" + statusCode: 400 \ No newline at end of file diff --git a/integration_test/configurations/services/ssh-2222.yaml b/integration_test/configurations/services/ssh-2222.yaml new file mode 100644 index 0000000..46298c5 --- /dev/null +++ b/integration_test/configurations/services/ssh-2222.yaml @@ -0,0 +1,25 @@ +apiVersion: "v1" +protocol: "ssh" +address: ":2222" +description: "SSH interactive" +commands: + - regex: "^ls$" + handler: "Documents Images Desktop Downloads .m2 .kube .ssh .docker" + - regex: "^pwd$" + handler: "/home/" + - regex: "^uname -m$" + handler: "x86_64" + - regex: "^docker ps$" + handler: "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES" + - regex: "^docker .*$" + handler: "Error response from daemon: dial unix docker.raw.sock: connect: connection refused" + - regex: "^uname$" + handler: "Linux" + - regex: "^ps$" + handler: " PID TTY TIME CMD\n21642 ttys000 0:00.07 /bin/dockerd" + - regex: "^(.+)$" + handler: "command not found" +serverVersion: "OpenSSH" +serverName: "ubuntu" +passwordRegex: "^(root|qwerty|Smoker666|123456|jenkins|minecraft|sinus|alex|postgres|Ly123456)$" +deadlineTimeoutSeconds: 60 \ No newline at end of file diff --git a/integration_test/configurations/services/tcp-3306.yaml b/integration_test/configurations/services/tcp-3306.yaml new file mode 100644 index 0000000..b3e9ec5 --- /dev/null +++ b/integration_test/configurations/services/tcp-3306.yaml @@ -0,0 +1,6 @@ +apiVersion: "v1" +protocol: "tcp" +address: ":3306" +description: "Mysql 8.0.29" +banner: "8.0.29" +deadlineTimeoutSeconds: 10 \ No newline at end of file diff --git a/integration_test/integration_test.go b/integration_test/integration_test.go new file mode 100644 index 0000000..fb1fffe --- /dev/null +++ b/integration_test/integration_test.go @@ -0,0 +1,115 @@ +package integration + +import ( + "beelzebub/builder" + "beelzebub/parser" + "github.com/go-resty/resty/v2" + "github.com/melbahja/goph" + "github.com/stretchr/testify/suite" + "golang.org/x/crypto/ssh" + "net" + "net/http" + "os" + "testing" +) + +type IntegrationTestSuite struct { + suite.Suite + beelzebubBuilder *builder.Builder + httpHoneypotHost string + tcpHoneypotHost string + sshHoneypotHost string +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} + +func (suite *IntegrationTestSuite) SetupSuite() { + suite.T().Helper() + if os.Getenv("INTEGRATION") == "" { + suite.T().Skip("skipping integration tests, set environment variable INTEGRATION") + } + suite.httpHoneypotHost = "http://localhost:8080" + suite.tcpHoneypotHost = "localhost:3306" + suite.sshHoneypotHost = "localhost" + + beelzebubConfigPath := "./configurations/beelzebub.yaml" + servicesConfigDirectory := "./configurations/services/" + + parser := parser.Init(beelzebubConfigPath, servicesConfigDirectory) + + coreConfigurations, err := parser.ReadConfigurationsCore() + suite.Require().NoError(err) + + beelzebubServicesConfiguration, err := parser.ReadConfigurationsServices() + suite.Require().NoError(err) + + suite.beelzebubBuilder = builder.NewBuilder() + + director := builder.NewDirector(suite.beelzebubBuilder) + + suite.beelzebubBuilder, err = director.BuildBeelzebub(coreConfigurations, beelzebubServicesConfiguration) + suite.Require().NoError(err) + + suite.Require().NoError(suite.beelzebubBuilder.Run()) +} + +func (suite *IntegrationTestSuite) TestInvokeHTTPHoneypot() { + response, err := resty.New().R(). + Get(suite.httpHoneypotHost + "/index.php") + + suite.Require().NoError(err) + suite.Equal(http.StatusOK, response.StatusCode()) + suite.Equal("mocked response", string(response.Body())) + + response, err = resty.New().R(). + Get(suite.httpHoneypotHost + "/wp-admin") + + suite.Require().NoError(err) + suite.Equal(http.StatusBadRequest, response.StatusCode()) + suite.Equal("mocked response", string(response.Body())) +} + +func (suite *IntegrationTestSuite) TestInvokeTCPHoneypot() { + tcpAddr, err := net.ResolveTCPAddr("tcp", suite.tcpHoneypotHost) + suite.Require().NoError(err) + + conn, err := net.DialTCP("tcp", nil, tcpAddr) + suite.Require().NoError(err) + defer conn.Close() + + _, err = conn.Write([]byte("hello!")) + suite.Require().NoError(err) + + reply := make([]byte, 1024) + + n, err := conn.Read(reply) + suite.Require().NoError(err) + + suite.Equal("8.0.29\n", string(reply[:n])) +} + +func (suite *IntegrationTestSuite) TestInvokeSSHHoneypot() { + client, err := goph.NewConn( + &goph.Config{ + User: "root", + Addr: suite.sshHoneypotHost, + Port: 2222, + Auth: goph.Password("root"), + Callback: ssh.InsecureIgnoreHostKey(), + }) + suite.Require().NoError(err) + defer client.Close() + + out, err := client.Run("") + suite.Require().NoError(err) + + suite.Equal("root@ubuntu:~$ ", string(out)) +} + +//TODO test rabbitmq + +func (suite *IntegrationTestSuite) TestShutdownBeelzebub() { + suite.Require().NoError(suite.beelzebubBuilder.Close()) +} diff --git a/parser/configurationsParser.go b/parser/configurations_parser.go similarity index 100% rename from parser/configurationsParser.go rename to parser/configurations_parser.go diff --git a/parser/configurationsParser_test.go b/parser/configurations_parser_test.go similarity index 100% rename from parser/configurationsParser_test.go rename to parser/configurations_parser_test.go diff --git a/plugin/OpenAiGPT.go b/plugins/openai-gpt.go similarity index 97% rename from plugin/OpenAiGPT.go rename to plugins/openai-gpt.go index fa8edeb..e6558ca 100644 --- a/plugin/OpenAiGPT.go +++ b/plugins/openai-gpt.go @@ -1,4 +1,4 @@ -package plugin +package plugins import ( "encoding/json" @@ -58,7 +58,7 @@ type gptRequest struct { Stop []string `json:"stop"` } -//Reference: https://www.engraved.blog/building-a-virtual-machine-inside/ +// Reference: https://www.engraved.blog/building-a-virtual-machine-inside/ const promptVirtualizeLinuxTerminal = "I want you to act as a Linux terminal. I will type commands and you will reply with what the terminal should show. I want you to only reply with the terminal output inside one unique code block, and nothing else. Do no write explanations. Do not type commands unless I instruct you to do so.\n\nA:pwd\n\nQ:/home/user\n\n" func buildPrompt(histories []History, command string) string { diff --git a/plugin/OpenAiGPT_test.go b/plugins/openai-gpt_test.go similarity index 99% rename from plugin/OpenAiGPT_test.go rename to plugins/openai-gpt_test.go index 311b8a3..b41b864 100644 --- a/plugin/OpenAiGPT_test.go +++ b/plugins/openai-gpt_test.go @@ -1,4 +1,4 @@ -package plugin +package plugins import ( "github.com/go-resty/resty/v2" diff --git a/protocols/protocolManager.go b/protocols/protocol_manager.go similarity index 100% rename from protocols/protocolManager.go rename to protocols/protocol_manager.go diff --git a/protocols/protocolManager_test.go b/protocols/protocol_manager_test.go similarity index 100% rename from protocols/protocolManager_test.go rename to protocols/protocol_manager_test.go diff --git a/protocols/hypertextTransferProtocolStrategy.go b/protocols/strategies/hypertext_transfer_protocol.go similarity index 99% rename from protocols/hypertextTransferProtocolStrategy.go rename to protocols/strategies/hypertext_transfer_protocol.go index 1d79860..121867f 100644 --- a/protocols/hypertextTransferProtocolStrategy.go +++ b/protocols/strategies/hypertext_transfer_protocol.go @@ -1,4 +1,4 @@ -package protocols +package strategies import ( "beelzebub/parser" diff --git a/protocols/secureShellStrategy.go b/protocols/strategies/secure_shell.go similarity index 90% rename from protocols/secureShellStrategy.go rename to protocols/strategies/secure_shell.go index d5f2ab4..7a41167 100644 --- a/protocols/secureShellStrategy.go +++ b/protocols/strategies/secure_shell.go @@ -1,8 +1,8 @@ -package protocols +package strategies import ( "beelzebub/parser" - "beelzebub/plugin" + "beelzebub/plugins" "beelzebub/tracer" "fmt" "github.com/gliderlabs/ssh" @@ -40,7 +40,7 @@ func (SSHStrategy *SecureShellStrategy) Init(beelzebubServiceConfiguration parse }) term := terminal.NewTerminal(sess, buildPrompt(sess.User(), beelzebubServiceConfiguration.ServerName)) - var histories []plugin.History + var histories []plugins.History for { commandInput, err := term.ReadLine() if err != nil { @@ -68,8 +68,8 @@ func (SSHStrategy *SecureShellStrategy) Init(beelzebubServiceConfiguration parse if matched { commandOutput := command.Handler - if command.Plugin == plugin.ChatGPTPluginName { - openAIGPTVirtualTerminal := plugin.OpenAIGPTVirtualTerminal{Histories: histories, OpenAPIChatGPTSecretKey: beelzebubServiceConfiguration.Plugin.OpenAPIChatGPTSecretKey} + if command.Plugin == plugins.ChatGPTPluginName { + openAIGPTVirtualTerminal := plugins.OpenAIGPTVirtualTerminal{Histories: histories, OpenAPIChatGPTSecretKey: beelzebubServiceConfiguration.Plugin.OpenAPIChatGPTSecretKey} openAIGPTVirtualTerminal.InjectDependency() if commandOutput, err = openAIGPTVirtualTerminal.GetCompletions(commandInput); err != nil { @@ -78,7 +78,7 @@ func (SSHStrategy *SecureShellStrategy) Init(beelzebubServiceConfiguration parse } } - histories = append(histories, plugin.History{Input: commandInput, Output: commandOutput}) + histories = append(histories, plugins.History{Input: commandInput, Output: commandOutput}) term.Write(append([]byte(commandOutput), '\n')) break diff --git a/protocols/transmissionControlProtocolStrategy.go b/protocols/strategies/transmission_control_protocol.go similarity index 98% rename from protocols/transmissionControlProtocolStrategy.go rename to protocols/strategies/transmission_control_protocol.go index 53b0b96..cdc47eb 100644 --- a/protocols/transmissionControlProtocolStrategy.go +++ b/protocols/strategies/transmission_control_protocol.go @@ -1,4 +1,4 @@ -package protocols +package strategies import ( "beelzebub/parser"