diff --git a/.gitignore b/.gitignore index 18f2c63..31fe69a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ # common editors config files .vscode + +# docker compose env file, might be used to store secrets -> must not be comitted +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6b2a4c7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,35 @@ +FROM golang:1.22.2-alpine AS builder +RUN apk add --no-cache make + +# swagger docs generation will fail if cgo is used +ENV CGO_ENABLED=0 + +WORKDIR /src/ + +# preinstall dependencies for better build caching +COPY go.mod . +COPY go.sum . +RUN go mod download + +COPY Makefile . + +# preinstall code generation tools for better build caching +RUN make install-code-generation-tools + +# copy api related source files and generate api docs +COPY pkg/web pkg/web +COPY pkg/models pkg/models +RUN make api-docs + +# copy rest of the source files and build +COPY cmd cmd +COPY pkg pkg +RUN make test +RUN make build + +FROM busybox +# service files +COPY --from=builder /src/api /api +COPY --from=builder /src/bin/notification-service /bin/ + +ENTRYPOINT ["./bin/notification-service"] diff --git a/Makefile b/Makefile index 17b196a..01e80b9 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ all: api-docs build test -.PHONY: install-code-generation-tools api-docs generate-code build test +.PHONY: install-code-generation-tools api-docs generate-code build test start-services SWAG = github.com/swaggo/swag/cmd/swag@v1.16.2 @@ -16,3 +16,9 @@ build: test: # run unit tests go test ./... -cover + +start-services: ## start service and dependencies with docker + docker compose -f docker-compose.yml -f docker-compose.service.yml up --build --abort-on-container-exit + +cleanup-services: # delete service, dependencies and all persistent data + docker compose -f docker-compose.yml -f docker-compose.service.yml down -v diff --git a/README.md b/README.md index 79b34c6..66fdc48 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,75 @@ # OpenSight Notification Service -The Notification Service allows to display all notifications in a central place in the frontend. +The Notification Service allows to display all notifications in a central place in the frontend. All OpenSight backend services can use it to send notifications to the user. ## Table of Contents +- [Usage](#usage) - [Requirements](#requirements) -- [Development](#development) +- [Configuration](#configuration) +- [Running](#running) + - [Running non-containerized service](#running-non-containerized-service) +- [Build and test](#build-and-test) - [Maintainer](#maintainer) - [License](#license) +## Usage + +The Notification Service is intended to be deployed along the others openSight services on the appliance. The service provides a REST API. See the [OpenApi definition](../api/notification-service/notificationService_swagger.yaml) for details. You can view them e.g. in the [Swagger Editor](https://editor.swagger.io/). + +Backend services can send notifications via the `Create Notification` endpoint. Those notifications can then be retrieved via `List Notifications` to provide them to the user. + ## Requirements +To run the service and its dependencies on you local machine you need a working installation of [docker](https://docs.docker.com/engine/install/) and `make`. + +For running the Notification Service outside of docker the latest version of [go](https://go.dev/doc/install) must be installed. + +## Configuration + +The service is configured via environment variables. Refer to the [Config](pkg/config/config.go) for the available options and their defaults. + +## Running + +> The following instructions are targeted at openSight developers. As end user the services should be run in orchestration with the other openSight services, which is not in the scope of this readme. + +Before starting the services you need to set the environment variable `DB_PASSWORD` for the database password. This password is set (only) on the first start of the database, so make sure to use the same password on consecutive runs. All other configuration parameters are already set in the docker compose files. + +Then you can start the notification service and the required dependent service [Postgres](https://www.postgresql.org/) with + +```sh +# make sure the `DB_PASSWORD` environment variable is set +make start-services +``` + +The port of the notification service is forwarded, so you can access its API directly from the host machine at the base url http://localhost:8085/api/notification-service. A convenient way to interact with the service are the Swagger docs served by the running service at URL http://localhost:8085/docs/notification-service/notification-service/index.html. + +### Running non-containerized service + +If you are actively developing it might be more convenient to run the notification service directly on the host machine. + +First start the containerized database with + +```sh +docker compose up -d +``` + +Then load the configuration parameters into environment variables and start the notification service: + +```sh +# make sure the `DB_PASSWORD` environment variable is set beforehand +source set_env_vars_local_setup.sh && go run ./cmd/notification-service +``` +From here everything is identical to the docker compose setup. +If there are errors regarding the database, verify that it is running with `docker ps` (should show a running container for postgres). -## Development +## Build and test +> Refer to [Makefile](./Makefile) to get an overview of all commands +To build run `make build`. To run the unit tests run `make test`. The rest API docs can be generated with `make api-docs`. ## Maintainer diff --git a/cmd/notification-service/main.go b/cmd/notification-service/main.go index c04087c..8c84450 100644 --- a/cmd/notification-service/main.go +++ b/cmd/notification-service/main.go @@ -1,8 +1,96 @@ -// SPDX-FileCopyrightText: 2024 Greenbone AG -// -// SPDX-License-Identifier: AGPL-3.0-or-later - package main +import ( + "context" + "fmt" + "net/http" + "os" + "os/signal" + + "github.com/greenbone/opensight-notification-service/pkg/config" + "github.com/greenbone/opensight-notification-service/pkg/logging" + "github.com/greenbone/opensight-notification-service/pkg/repository" + "github.com/greenbone/opensight-notification-service/pkg/repository/notificationrepository" + "github.com/greenbone/opensight-notification-service/pkg/services/healthservice" + "github.com/greenbone/opensight-notification-service/pkg/services/notificationservice" + "github.com/greenbone/opensight-notification-service/pkg/web" + "github.com/greenbone/opensight-notification-service/pkg/web/healthcontroller" + "github.com/greenbone/opensight-notification-service/pkg/web/notificationcontroller" + + "github.com/rs/zerolog/log" +) + func main() { + config, err := config.ReadConfig() + if err != nil { + log.Fatal().Err(err).Msg("failed to read config") + } + + err = logging.SetupLogger(config.LogLevel) + if err != nil { + log.Fatal().Err(err).Msg("failed to set up logger") + } + + check(run(config)) +} + +func run(config config.Config) error { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ctx, stop := signal.NotifyContext(ctx, os.Interrupt) + defer stop() + + pgClient, err := repository.NewClient(config.Database) + if err != nil { + return err + } + notificationRepository, err := notificationrepository.NewNotificationRepository(pgClient) + if err != nil { + return err + } + + notificationService := notificationservice.NewNotificationService(notificationRepository) + healthService := healthservice.NewHealthService(pgClient) + + gin := web.NewWebEngine() + rootRouter := gin.Group("/") + notificationServiceRouter := gin.Group("/api/notification-service") + docsRouter := gin.Group("/docs/notification-service") + + // rest api docs + web.RegisterSwaggerDocsRoute(docsRouter) + healthcontroller.RegisterSwaggerDocsRoute(docsRouter) + + //instantiate controllers + notificationcontroller.NewNotificationController(notificationServiceRouter, notificationService) + healthcontroller.NewHealthController(rootRouter, healthService) // for health probes (not a data source) + + srv := &http.Server{ + Addr: fmt.Sprintf(":%d", config.Http.Port), + Handler: gin, + ReadTimeout: config.Http.ReadTimeout, + WriteTimeout: config.Http.WriteTimeout, + IdleTimeout: config.Http.IdleTimeout, + } + + go func() { + if err := srv.ListenAndServe(); err != http.ErrServerClosed { + check(err) + } + }() + + <-ctx.Done() + log.Info().Msg("Received signal. Shutting down") + err = srv.Shutdown(ctx) + if err != nil { + return fmt.Errorf("failed to shut down error: %w", err) + } + + return nil +} + +func check(err error) { + if err != nil { + log.Fatal().Err(err).Msg("critical error") + } } diff --git a/docker-compose.service.yml b/docker-compose.service.yml new file mode 100644 index 0000000..3c43d23 --- /dev/null +++ b/docker-compose.service.yml @@ -0,0 +1,22 @@ +# only to be used in combination with `docker-compose.yml` + +# version: '3' # uncomment for compatibility with old docker compose versions + +services: + notification-service: + build: . # replace this line with `image: ghcr.io/greenbone/notification-service:` if you want to use an already built image instead of building one from the active working directory + environment: + DB_HOST: postgres + DB_PORT: 5432 + DB_USERNAME: postgres + DB_PASSWORD: $DB_PASSWORD + DB_NAME: notification_service + DB_SSL_MODE: disable + LOG_LEVEL: debug + ports: + - 8085:8085 + networks: + - notification-service-net + depends_on: + postgres: + condition: service_healthy diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..dace8ff --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,26 @@ +# version: '3' # uncomment for compatibility with old docker compose versions + +services: + postgres: + image: postgres:16 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: $DB_PASSWORD + POSTGRES_DB: notification_service + volumes: + - postgres-data:/var/lib/postgresql/data + ports: + - 5432:5432 + networks: + - notification-service-net + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 1s + timeout: 5s + retries: 10 + +volumes: + postgres-data: + +networks: + notification-service-net: diff --git a/go.mod b/go.mod index 9328ba6..0d88f7b 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/greenbone/opensight-notification-service go 1.22.2 require ( + github.com/gin-contrib/logger v1.1.1 github.com/gin-gonic/gin v1.9.1 github.com/golang-migrate/migrate/v4 v4.17.1 github.com/greenbone/opensight-golang-libraries v1.3.1 @@ -17,8 +18,9 @@ require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/bytedance/sonic v1.11.3 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect + github.com/chenzhuoyu/iasm v0.9.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect @@ -38,7 +40,7 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -48,7 +50,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -59,10 +61,10 @@ require ( github.com/spf13/viper v1.18.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/arch v0.3.0 // indirect + golang.org/x/arch v0.7.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect golang.org/x/net v0.22.0 // indirect diff --git a/go.sum b/go.sum index ec78ddc..615580b 100644 --- a/go.sum +++ b/go.sum @@ -13,11 +13,16 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= +github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA= +github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= +github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= +github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -44,6 +49,8 @@ github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uq github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= +github.com/gin-contrib/logger v1.1.1 h1:78Qzfpx3JvpnNX/6bErifIcnFqwbVKl2gS5WGExFPOs= +github.com/gin-contrib/logger v1.1.1/go.mod h1:Cmqqcc6Yce4+r776VET1AcU4ydAR6sMKuDtBKLje20Y= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= @@ -112,8 +119,9 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -150,14 +158,13 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= -github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= +github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -185,6 +192,7 @@ github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMV 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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -204,8 +212,8 @@ github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg= github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= @@ -220,8 +228,8 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= @@ -247,7 +255,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20220704084225-05e143d24a9e/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -275,8 +282,9 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -290,4 +298,5 @@ gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go new file mode 100644 index 0000000..0d677a5 --- /dev/null +++ b/pkg/logging/logging.go @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2024 Greenbone AG +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +package logging + +import ( + "fmt" + + "github.com/rs/zerolog" +) + +const AllowedLogLevels string = "disabled|trace|debug|info|warn|error|fatal|panic" + +func SetupLogger(logLevel string) error { + level, err := zerolog.ParseLevel(logLevel) + if err != nil { + return fmt.Errorf("failed parsing log level: %w; only allowed levels are: %s", err, AllowedLogLevels) + } + + zerolog.SetGlobalLevel(level) + return nil +} diff --git a/pkg/services/notificationservice/notificationService.go b/pkg/services/notificationservice/notificationService.go new file mode 100644 index 0000000..eb4cd36 --- /dev/null +++ b/pkg/services/notificationservice/notificationService.go @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2024 Greenbone AG +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +package notificationservice + +import ( + "context" + + "github.com/greenbone/opensight-golang-libraries/pkg/query" + "github.com/greenbone/opensight-notification-service/pkg/models" + "github.com/greenbone/opensight-notification-service/pkg/port" +) + +type NotificationService struct { + store port.NotificationRepository +} + +func NewNotificationService(store port.NotificationRepository) *NotificationService { + return &NotificationService{store: store} +} + +func (s *NotificationService) ListNotifications(ctx context.Context, resultSelector query.ResultSelector) (notifications []models.Notification, totalResult uint64, err error) { + return +} + +func (s *NotificationService) CreateNotification(ctx context.Context, notificationIn models.Notification) (notification models.Notification, err error) { + return +} diff --git a/pkg/web/web.go b/pkg/web/web.go new file mode 100644 index 0000000..f0090ac --- /dev/null +++ b/pkg/web/web.go @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2023 Greenbone AG +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +package web + +import ( + "github.com/gin-contrib/logger" + "github.com/gin-gonic/gin" +) + +func NewWebEngine() *gin.Engine { + ginWebEngine := gin.New() + ginWebEngine.Use(logger.SetLogger(), gin.Recovery()) + return ginWebEngine +} diff --git a/set_env_vars_local_setup.sh b/set_env_vars_local_setup.sh index 8ae28af..5772d03 100644 --- a/set_env_vars_local_setup.sh +++ b/set_env_vars_local_setup.sh @@ -1,7 +1,14 @@ +# only intended to be used for the local setup + # volues for which we don't have a default export DB_USERNAME=postgres -export DB_PASSWORD=password +export DB_NAME=notification_service export DB_SSL_MODE=disable +if [[ -z "$DB_PASSWORD" ]]; then # this is a secret, set this env var by other means + echo "warning: database password not set, but is required" > /dev/stderr; return 1 +else + export DB_PASSWORD +fi # log level for convenience export LOG_LEVEL=debug