Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update 4/19/2024 #7

Merged
merged 49 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
4904d16
ci: use the latest ubuntu instead of 18.04
ivan1993spb Jan 17, 2024
a12b024
refactor(internal/types): remove unnecessary consts
ivan1993spb Jan 16, 2024
ab60eb9
fix(internal/bot): linter errors in bot
ivan1993spb Jan 16, 2024
281049f
style(internal/bot): adjust a comment format
ivan1993spb Jan 18, 2024
3381762
ci: enable check for formatting
ivan1993spb Jan 18, 2024
99c89d8
chore: use go 1.21.5 and update dependencies
ivan1993spb Jan 17, 2024
9d04056
refactor: rename server to http
ivan1993spb Jan 17, 2024
b7980a0
refactor: move models out of http
ivan1993spb Jan 17, 2024
db33d44
fix(internal/models): erroneous structure tags
ivan1993spb Jan 19, 2024
18b2ec4
ci: enable staticckeck for go
ivan1993spb Jan 18, 2024
5f651ff
ci: enable code linter for go
ivan1993spb Jan 18, 2024
6dec11b
test: add counterfeiter for mocks
ivan1993spb Jan 18, 2024
4849d70
feat(internal/models): add sorted list of games
ivan1993spb Jan 19, 2024
8e7f6c6
refactor(internal/models): remove error model
ivan1993spb Jan 19, 2024
323745a
refactor: clean up logging subsystem
ivan1993spb Jan 19, 2024
f3648d4
feat(internal/utils): add clock implementation and mock
ivan1993spb Feb 23, 2024
c029144
feat(internal/utils): add concurrency safe rand source
ivan1993spb Feb 23, 2024
913d0c7
test(internal/connect): add tests for connector
ivan1993spb Feb 23, 2024
d0da464
refactor(internal/connect): concurrency safe ctx-aware connection
ivan1993spb Feb 23, 2024
7fa6b00
chore(internal/connect): generate connection mock
ivan1993spb Feb 23, 2024
5622ea5
fix(internal/bot): remove unnecessary stopper
ivan1993spb Feb 23, 2024
5b37ce8
docs(internal/core): add comment for diff helper
ivan1993spb Feb 23, 2024
f054db5
chore(internal/core): rename unit test for diff
ivan1993spb Feb 23, 2024
f4623f2
feat(internal/core): add helpers for diffs
ivan1993spb Feb 23, 2024
b62af16
refactor(internal/core): change interfaces and architecture
ivan1993spb Feb 23, 2024
a7c9baa
test(internal/core): generate mocks
ivan1993spb Mar 11, 2024
96b8ab7
test(internal/core): test core
ivan1993spb Mar 11, 2024
76ef0e0
test(internal/core): test bot operator
ivan1993spb Mar 11, 2024
4023bfe
refactor(internal/config): remove field label consts
ivan1993spb Mar 17, 2024
5889958
feat(internal/http): add middleware to include request id to ctx
ivan1993spb Mar 17, 2024
8f02449
feat(internal/http): add jwt security middleware
ivan1993spb Apr 4, 2024
fe14a1a
refactor(internal/http): get and set state handlers
ivan1993spb Nov 27, 2023
8d26873
refactor: server start
ivan1993spb Apr 5, 2024
33bb08f
test(internal/http/handlers): add tests for get and set state handlers
ivan1993spb Apr 5, 2024
c94f3d2
feat(internal/http/handlers): add logs in welcome handler
ivan1993spb Apr 4, 2024
80dc910
feat(internal/http/handlers): add logs in openapi handler
ivan1993spb Apr 4, 2024
f7d0185
feat(internal/core): add bot config storage
ivan1993spb Mar 9, 2024
cc0c296
chore: add supplement files to .gitignore
ivan1993spb Jan 16, 2024
1881060
feat: add automaxprocs
ivan1993spb Jan 15, 2024
476fd84
feat(scripts): add jwt generation script
ivan1993spb Jan 16, 2024
311ccd8
docs: add step-by-step explanation in readme
ivan1993spb Jan 16, 2024
ce19345
docs(api): rewrite openapi specification
ivan1993spb Jan 16, 2024
cb27586
ci: add openapi spec validator
ivan1993spb Jan 16, 2024
79f9343
build: add /etc/group to the image
ivan1993spb Jan 17, 2024
158c365
chore: add todo comment for ci for go
ivan1993spb Jan 18, 2024
2712851
chore: update year in license
ivan1993spb Jan 16, 2024
c8d8c72
refactor(internal/http/middlewares): logging panics
ivan1993spb Jan 19, 2024
de88964
test(internal/http/middlewares): panicing handler scenario
ivan1993spb Jan 19, 2024
fa47d2d
fix(internal/http): error deadline exceeded yields 503
ivan1993spb Apr 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,38 @@ on: push
jobs:

build:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.19.5
go-version: 1.21.5

- name: Go Mod
run: go mod download

# TODO: Add Go format step.
#- name: Go Format
# run: gofmt -s -w . && git diff --exit-code
- name: Go Format
run: gofmt -s -w . && git diff --exit-code

- name: Go Tidy
run: go mod tidy && git diff --exit-code

# TODO: Add a propper vetting step go vet ./...
- name: Go Vet
run: go vet

# TODO: Add a staticcheck step.
#- uses: dominikh/[email protected]
# with:
# version: "2022.1"
# install-go: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.55.2

# TODO: add go lint
- name: Go staticcheck
uses: dominikh/[email protected]
with:
version: "2023.1"
install-go: false

- name: Go Build
run: go build -v ./...
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/openapi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
on: push
name: Validate OpenAPI specification
jobs:
validate:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: swagger-validator
uses: mbowman100/swagger-validator-action@master
with:
files: api/openapi.yaml
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
/snake-bot
/*.html
*.yaml
*.json
*.base64
*.jwt
*.diff
*.patch
*.log
*.test
*.out
*.svg
!examples/*
11 changes: 7 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

# See Makefile
ARG IMAGE_GOLANG=golang:1.19.5-alpine3.16
ARG IMAGE_ALPINE=alpine:3.16
ARG IMAGE_GOLANG=golang:1.21.5-alpine3.19
ARG IMAGE_ALPINE=alpine:3.19

FROM $IMAGE_ALPINE AS helper

RUN adduser -u 10001 -h /dev/null -H -D -s /sbin/nologin snake

RUN sed -i '/^snake/!d' /etc/passwd
RUN sed -i '/^snake/!d' /etc/passwd /etc/group

FROM $IMAGE_GOLANG AS builder

Expand All @@ -21,12 +21,15 @@ COPY . .
ENV CGO_ENABLED=0

RUN go build \
-ldflags "-s -w -X main.Version=${VERSION} -X main.Build=${BUILD::7}" \
-ldflags "-s -w \
-X github.com/ivan1993spb/snake-bot/internal/app.Version=${VERSION} \
-X github.com/ivan1993spb/snake-bot/internal/app.Build=${BUILD::7}" \
-v -x -o /snake-bot ./cmd/snake-bot

FROM scratch

COPY --from=helper /etc/passwd /etc/passwd
COPY --from=helper /etc/group /etc/group

USER snake

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2021 Ivan Pushkin
Copyright (c) 2024 Ivan Pushkin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ _=$(foreach exec,$(EXECUTABLES), \

IMAGE=ivan1993spb/snake-bot

IMAGE_GOLANG=golang:1.19.5-alpine3.16
IMAGE_ALPINE=alpine:3.16
IMAGE_GOLANG=golang:1.21.5-alpine3.19
IMAGE_ALPINE=alpine:3.19

BINARY_NAME=snake-bot
VERSION=$(shell git describe --tags --abbrev=0 2>/dev/null || echo v0.0.0)
BUILD=$(shell git rev-parse --short HEAD)

LDFLAGS=-ldflags "-s -w -X main.Version=$(VERSION) -X main.Build=$(BUILD)"
MODULE=github.com/ivan1993spb/snake-bot
LDFLAGS=-ldflags "-s -w \
-X $(MODULE)/internal/app.Version=$(VERSION) \
-X $(MODULE)/internal/app.Build=$(BUILD)"

DOCKER_BUILD_ARGS=\
--build-arg VERSION=$(VERSION) \
--build-arg BUILD=$(BUILD) \
Expand Down
62 changes: 53 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,59 @@

# The snake bot
# Snake-Bot

- **MVP**
- clumsy
- copypasta
- no comments
- no tests
- bugs
### Install Snake-Bot

```
curl -X POST -H 'X-Snake-Bot-Token: hOayYn7Jbbq1TwDzJTsKX_eDb8Ww7LFEu0l6egnViGtCBCNbAPHo00b1uVCly9Rd' localhost:8080/config
go install github.com/ivan1993spb/snake-bot@latest
```

https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
### Start Snake-Server

```
docker run --rm -d -p 8080:8080 ivan1993spb/snake-server:latest --enable-web

# Create a game
curl -X POST -d limit=15 -d width=100 -d height=60 -d enable_walls=true localhost:8080/api/games
```

### Start Snake-Bot

```
# Generate a secret for JWT
openssl rand -base64 -out secret.base64 32

snake-bot -snake-server localhost:8080 -jwt-secret secret.base64 -address :9090
```

### Generate JWT

```
python3 scripts/getjwt.py --subject admin --jwt-secret secret.base64 > token.jwt
token=`cat token.jwt`
header="Authorization: Bearer ${token}"
```

### Call the API

```
# Get config
curl -X GET -H "$header" localhost:9090/api/bots
# Add 1 bot in game 1
curl -X POST -H "$header" -d game=1 -d bots=1 localhost:9090/api/bots

cd examples
curl -X POST -H "$header" --data-binary @bots.yaml -H 'Content-Type: text/yaml' localhost:9090/api/bots
curl -X POST -H "$header" --data-binary @bots.json -H 'Content-Type: application/json' localhost:9090/api/bots
```

### Watch the result

[![Demo](demo.gif)](http://localhost:8080)

### How it works

[wiki: Dijkstra's algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)

### License

See [LICENSE](LICENSE).
85 changes: 53 additions & 32 deletions api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ openapi: 3.0.3
info:
title: Snake-Bot API
description: |
Snake-Bot provides control over a swarm of bots running on a
Snake-Bot service controls a swarm of bots running on a
preconfigured instance of Snake-Server.
version: 0.0.0
version: 1.0.0
license:
name: MIT
contact:
name: Ivan Pushkin
url: https://twitter.com/IvanDeveloper
url: https://github.com/ivan1993spb

servers:
- url: /api
Expand All @@ -25,13 +25,13 @@ servers:
paths:
/bots:
post:
summary: Launches a swarm of bots in specified games.
summary: Start bots.
description: |
The method launches a given number of bots in a specified games.
The method starts the given numbers of bots in specified games.
tags:
- Bots
security:
- ApiKeyAuth: []
- bearerAuth: []
requestBody:
required: true
content:
Expand All @@ -46,32 +46,30 @@ paths:
$ref: '#/components/schemas/Games'
responses:
201:
description: Current setup.
description: The bots have been started.
content:
application/json:
text/yaml:
schema:
$ref: '#/components/schemas/Games'
text/yaml:
application/json:
schema:
$ref: '#/components/schemas/Games'
400:
$ref: '#/components/responses/InvalidParameters'
401:
$ref: '#/components/responses/AuthorizationError'
500:
$ref: '#/components/responses/ServerError'
503:
description: Service unavailable, cannot create bots.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
404:
$ref: '#/components/responses/GameNotFound'
$ref: '#/components/responses/ServiceUnavailable'
get:
summary: Returns the working current setup.
summary: Get the numbers of bots.
description: |
Returns the numbers of bots for each game.
tags:
- Bots
security:
- ApiKeyAuth: []
- bearerAuth: []
responses:
200:
description: Current setup.
Expand All @@ -82,52 +80,76 @@ paths:
text/yaml:
schema:
$ref: '#/components/schemas/Games'
400:
$ref: '#/components/responses/InvalidParameters'
401:
$ref: '#/components/responses/AuthorizationError'
500:
$ref: '#/components/responses/ServerError'

components:

securitySchemes:

ApiKeyAuth:
type: apiKey
in: header
name: X-Snake-Bot-Token
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT

responses:
InvalidParameters:
description: Invalid parameters.
content:
text/yaml:
schema:
$ref: '#/components/schemas/Error'
application/json:
schema:
$ref: '#/components/schemas/Error'
ServerError:
description: An internal server error.
description: Internal server error.
content:
text/yaml:
schema:
$ref: '#/components/schemas/Error'
application/json:
schema:
$ref: '#/components/schemas/Error'
GameNotFound:
description: A game has not been found.
AuthorizationError:
description: Authorization error.
content:
text/yaml:
schema:
$ref: '#/components/schemas/Error'
application/json:
schema:
$ref: '#/components/schemas/Error'
ServiceUnavailable:
description: Service is unavailable.
content:
text/yaml:
schema:
$ref: '#/components/schemas/Error'
application/json:
schema:
$ref: '#/components/schemas/Error'


schemas:

Game:
type: object
description: |
The object contains a game identifier and a number of bots to launch.
The object contains a game ID and a number of bots.
required:
- game
- bots
properties:
game:
description: A game identifier.
description: Game ID
type: integer
format: int32
bots:
description: A bots number.
description: Number of bots
type: integer
format: int32

Expand All @@ -138,16 +160,15 @@ components:
- games
properties:
games:
description: A list of game identifiers and numbers of bots.
description: A list of game IDs and numbers of bots.
type: array
items:
$ref: '#/components/schemas/Game'

Error:
type: object
description: |
The object contains an error code and short description of what went
wrong.
The object contains an error code and short description.
required:
- code
- text
Expand Down
Loading
Loading