Mainflux.mainflux/bootstrap
b1ackd0t 43a263d7da
NOISSUE - Introduce NATS Jetstream as Default ES (#1907)
* Refactor message broker implementation

This commit refactors the Nats message broker implementation to include pubsub options. These changes include:

- Adding `Option` func that takes in the URL and prefix
- Implement `WithStream` option which can create a different stream for nats stream
- Implement `WithExchange` option which can create a different exchaange for rabbitmq channel
- Implement `WithPrefix` option which allows to you change the publisher prefix

These changes improve the organization and readability of the codebase.

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Use redis URL to configure username, password and db

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Make event store configurable on dev deployment

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Fix adds options to messaging `PubSub` interface

Adding options to PubSub interface allows the use of messaging
package to do es.

The changes in this commit ensure that the code handles errors
properly and provides more informative error messages when
encountering unexpected types.

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add NATS event publisher implementation

This commit adds the implementation of the NATS event publisher.

The NATS event publisher is responsible for publishing events
to a NATS messaging system. It uses the `messaging`
package to interact with the messaging system.

The implementation includes the following features:

- Publishing events to NATS using the `Publish` method.
- Marshaling events to JSON before publishing.
- Setting the message subject and headers based on the event.
- Handling errors during publishing.

This implementation is built with the `!rabbitmq` build tag,
which means it will only be compiled if the `rabbitmq` build tag
is not present.

The NATS event publisher is part of the Mainflux events package
and provides support for the Mainflux NATS events source service functionality.

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add RabbitMQ event publisher implementation

This commit adds the implementation of the RabbitMQ event publisher.

The RabbitMQ event publisher is responsible for publishing events
to a RabbitMQ messaging system. It uses the `messaging`
package to interact with the messaging system.

The implementation includes the following features:

- Publishing events to RabbitMQ using the `Publish` method.
- Marshaling events to JSON before publishing.
- Setting the message subject and headers based on the event.
- Handling errors during publishing.

This implementation is built with the `rabbitmq` build tag,
which means it will only be compiled if the `rabbitmq` build tag
is present.

The RabbitMQ event publisher is part of the Mainflux events package
and provides support for the Mainflux RabbitMQ events source service functionality.

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add configurable implementation for events store

This commit adds a new file `brokers_*.go` which contains the implementation for the different event store. The file includes functions for creating a new publisher and subscriber using different es store.

This commit also includes an `init` function that logs a message indicating that the binary was built using the respective package as the events store.

The purpose of this commit is to add support for alternative events store.

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Fix build flags

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Refactor Makefile and Semaphore configuration

The Makefile has been refactored to include the `MF_ES_STORE_TYPE` tag in the `go build` command. Additionally, the Semaphore configuration has been updated to include a new task for compiling with Redis as the broker type.

This commit addresses the need to compile the codebase with Redis as the event store type and includes the necessary changes in the Makefile and Semaphore configuration.

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Reduced due to memory on testing

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Fix tests for es

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Fix grammar

Co-authored-by: Sammy Kerata Oina <44265300+SammyOina@users.noreply.github.com>
Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Fix linting

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* feat(docker): update environment variables for message broker

The commit updates the environment variable `MF_ES_STORE_TYPE` in the `docker/.env` file. The variable is changed from `${MF_MQTT_BROKER_TYPE}` to `${MF_MESSAGE_BROKER_TYPE}` to accurately reflect the type of message broker being used. This change ensures that the correct message broker is configured for the Event Store.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* feat: Update docker environment variables

- Removed the unused MF_ES_URL variable in the .env file
- Updated the MF_ES_STORE_TYPE and MF_ES_STORE_URL variables in the .env file to match the MF_MESSAGE_BROKER_TYPE and MF_NATS_URL variables respectively

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Fix after rebase

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add godocs for option parameters for brokers

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* pass by value exchange and prefix names

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Rename option functions

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* move variables to constants

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* fix: option example comment

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

---------

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: rodneyosodo <blackd0t@protonmail.com>
Co-authored-by: Sammy Kerata Oina <44265300+SammyOina@users.noreply.github.com>
2023-10-24 17:22:53 +02:00
..
api NOISSUE - Uncomment Code (#1926) 2023-10-18 16:45:08 +02:00
events NOISSUE - Introduce NATS Jetstream as Default ES (#1907) 2023-10-24 17:22:53 +02:00
mocks NOISSUE - Switch to Google Zanzibar Access control approach (#1919) 2023-10-15 22:02:13 +02:00
postgres NOISSUE - Change import name aliases (#1868) 2023-08-11 11:30:25 +02:00
tracing NOISSUE - Return certs on bootstrap view response (#1855) 2023-07-31 14:17:14 +02:00
README.md NOISSUE - Sync Env Veriables With Docker Deployment (#1841) 2023-07-31 14:38:35 +02:00
configs.go NOISSUE - Return certs on bootstrap view response (#1855) 2023-07-31 14:17:14 +02:00
doc.go MF-788 - Remove date and minimize copyright comments (#876) 2019-10-07 16:14:47 +02:00
reader.go NOISSUE - Return certs on bootstrap view response (#1855) 2023-07-31 14:17:14 +02:00
reader_test.go NOISSUE - Uncomment Code (#1926) 2023-10-18 16:45:08 +02:00
service.go NOISSUE - Switch to Google Zanzibar Access control approach (#1919) 2023-10-15 22:02:13 +02:00
service_test.go NOISSUE - Uncomment Code (#1926) 2023-10-18 16:45:08 +02:00
state.go MF-1506 - Group-based Access Control (#1716) 2023-06-14 12:40:37 +02:00

README.md

BOOTSTRAP SERVICE

New devices need to be configured properly and connected to the Mainflux. Bootstrap service is used in order to accomplish that. This service provides the following features:

  1. Creating new Mainflux Things
  2. Providing basic configuration for the newly created Things
  3. Enabling/disabling Things

Pre-provisioning a new Thing is as simple as sending Configuration data to the Bootstrap service. Once the Thing is online, it sends a request for initial config to Bootstrap service. Bootstrap service provides an API for enabling and disabling Things. Only enabled Things can exchange messages over Mainflux. Bootstrapping does not implicitly enable Things, it has to be done manually.

In order to bootstrap successfully, the Thing needs to send bootstrapping request to the specific URL, as well as a secret key. This key and URL are pre-provisioned during the manufacturing process. If the Thing is provisioned on the Bootstrap service side, the corresponding configuration will be sent as a response. Otherwise, the Thing will be saved so that it can be provisioned later.

Thing Configuration Entity

Thing Configuration consists of two logical parts: the custom configuration that can be interpreted by the Thing itself and Mainflux-related configuration. Mainflux config contains:

  1. corresponding Mainflux Thing ID
  2. corresponding Mainflux Thing key
  3. list of the Mainflux channels the Thing is connected to

Note: list of channels contains IDs of the Mainflux channels. These channels are pre-provisioned on the Mainflux side and, unlike corresponding Mainflux Thing, Bootstrap service is not able to create Mainflux Channels.

Enabling and disabling Thing (adding Thing to/from whitelist) is as simple as connecting corresponding Mainflux Thing to the given list of Channels. Configuration keeps state of the Thing:

State What it means
Inactive Thing is created, but isn't enabled
Active Thing is able to communicate using Mainflux

Switching between states Active and Inactive enables and disables Thing, respectively.

Thing configuration also contains the so-called external ID and external key. An external ID is a unique identifier of corresponding Thing. For example, a device MAC address is a good choice for external ID. External key is a secret key that is used for authentication during the bootstrapping procedure.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

Variable Description Default
MF_BOOTSTRAP_LOG_LEVEL Log level for Bootstrap (debug, info, warn, error) info
MF_BOOTSTRAP_DB_HOST Database host address localhost
MF_BOOTSTRAP_DB_PORT Database host port 5432
MF_BOOTSTRAP_DB_USER Database user mainflux
MF_BOOTSTRAP_DB_PASS Database password mainflux
MF_BOOTSTRAP_DB_NAME Name of the database used by the service bootstrap
MF_BOOTSTRAP_DB_SSL_MODE Database connection SSL mode (disable, require, verify-ca, verify-full) disable
MF_BOOTSTRAP_DB_SSL_CERT Path to the PEM encoded certificate file
MF_BOOTSTRAP_DB_SSL_KEY Path to the PEM encoded key file
MF_BOOTSTRAP_DB_SSL_ROOT_CERT Path to the PEM encoded root certificate file
MF_BOOTSTRAP_ENCRYPT_KEY Secret key for secure bootstrapping encryption v7aT0HGxJxt2gULzr3RHwf4WIf6DusPphG5Ftm2bNCWD8mTpyr
MF_BOOTSTRAP_HTTP_HOST Bootstrap service HTTP host
MF_BOOTSTRAP_HTTP_PORT Bootstrap service HTTP port 9013
MF_BOOTSTRAP_HTTP_SERVER_CERT Path to server certificate in pem format
MF_BOOTSTRAP_HTTP_SERVER_KEY Path to server key in pem format
MF_BOOTSTRAP_EVENT_CONSUMER Bootstrap service event source consumer name bootstrap
MF_BOOTSTRAP_ES_URL Bootstrap service event source URL localhost:6379
MF_BOOTSTRAP_ES_PASS Bootstrap service event source password
MF_BOOTSTRAP_ES_DB Bootstrap service event source database 0
MF_AUTH_GRPC_URL Users service gRPC URL localhost:7001
MF_AUTH_GRPC_TIMEOUT Users service gRPC request timeout in seconds 1s
MF_AUTH_GRPC_CLIENT_TLS Enable TLS for gRPC client false
MF_AUTH_GRPC_CA_CERTS CA certificates for gRPC client
MF_THINGS_URL Base url for Mainflux Things http://localhost:9000
MF_JAEGER_URL Jaeger server URL http://jaeger:14268/api/traces
MF_SEND_TELEMETRY Send telemetry to mainflux call home server true
MF_BOOTSTRAP_INSTANCE_ID Bootstrap service instance ID

Deployment

The service itself is distributed as Docker container. Check the boostrap service section in docker-compose to see how service is deployed.

To start the service outside of the container, execute the following shell script:

# download the latest version of the service
git clone https://github.com/mainflux/mainflux

cd mainflux

# compile the service
make bootstrap

# copy binary to bin
make install

# set the environment variables and run the service
MF_BOOTSTRAP_LOG_LEVEL=[Bootstrap log level] \
MF_BOOTSTRAP_ENCRYPT_KEY=[Hex-encoded encryption key used for secure bootstrap] \
MF_BOOTSTRAP_EVENT_CONSUMER=[Bootstrap service event source consumer name] \
MF_BOOTSTRAP_ES_URL=[Bootstrap service event source URL] \
MF_BOOTSTRAP_ES_PASS=[Bootstrap service event source password] \
MF_BOOTSTRAP_ES_DB=[Bootstrap service event source database] \
MF_BOOTSTRAP_HTTP_HOST=[Bootstrap service HTTP host] \
MF_BOOTSTRAP_HTTP_PORT=[Bootstrap service HTTP port] \
MF_BOOTSTRAP_HTTP_SERVER_CERT=[Path to HTTP server certificate in pem format] \
MF_BOOTSTRAP_HTTP_SERVER_KEY=[Path to HTTP server key in pem format] \
MF_BOOTSTRAP_DB_HOST=[Database host address] \
MF_BOOTSTRAP_DB_PORT=[Database host port] \
MF_BOOTSTRAP_DB_USER=[Database user] \
MF_BOOTSTRAP_DB_PASS=[Database password] \
MF_BOOTSTRAP_DB_NAME=[Name of the database used by the service] \
MF_BOOTSTRAP_DB_SSL_MODE=[SSL mode to connect to the database with] \
MF_BOOTSTRAP_DB_SSL_CERT=[Path to the PEM encoded certificate file] \
MF_BOOTSTRAP_DB_SSL_KEY=[Path to the PEM encoded key file] \
MF_BOOTSTRAP_DB_SSL_ROOT_CERT=[Path to the PEM encoded root certificate file] \
MF_AUTH_GRPC_URL=[Users service gRPC URL] \
MF_AUTH_GRPC_TIMEOUT=[Users service gRPC request timeout in seconds] \
MF_AUTH_GRPC_CLIENT_TLS=[Boolean value to enable/disable client TLS] \
MF_AUTH_GRPC_CA_CERT=[Path to trusted CAs in PEM format] \
MF_THINGS_URL=[Base url for Mainflux Things] \
MF_JAEGER_URL=[Jaeger server URL] \
MF_SEND_TELEMETRY=[Send telemetry to mainflux call home server] \
MF_BOOTSTRAP_INSTANCE_ID=[Bootstrap instance ID] \
$GOBIN/mainflux-bootstrap

Setting MF_BOOTSTRAP_CA_CERTS expects a file in PEM format of trusted CAs. This will enable TLS against the Users gRPC endpoint trusting only those CAs that are provided.

Usage

For more information about service capabilities and its usage, please check out the API documentation.