test: enable mosquitto password auth; add mqttping endpoint; use credentials in subscriber; publish defaults
This commit is contained in:
+18
-2
@@ -13,10 +13,11 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"git.piskot.si/SeminarM2/lambdaiot-core/internal/config"
|
"git.piskot.si/SeminarM2/lambdaiot-core/internal/config"
|
||||||
mqttclient "git.piskot.si/SeminarM2/lambdaiot-core/internal/mqtt"
|
|
||||||
"git.piskot.si/SeminarM2/lambdaiot-core/internal/handler"
|
"git.piskot.si/SeminarM2/lambdaiot-core/internal/handler"
|
||||||
"git.piskot.si/SeminarM2/lambdaiot-core/internal/middleware"
|
"git.piskot.si/SeminarM2/lambdaiot-core/internal/middleware"
|
||||||
|
mqttclient "git.piskot.si/SeminarM2/lambdaiot-core/internal/mqtt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// load configuration (look for ./config.toml by default)
|
// load configuration (look for ./config.toml by default)
|
||||||
cfg, err := config.Load("")
|
cfg, err := config.Load("")
|
||||||
@@ -41,6 +42,7 @@ func main() {
|
|||||||
log.Printf("warning: mqtt connect failed: %v", err)
|
log.Printf("warning: mqtt connect failed: %v", err)
|
||||||
} else {
|
} else {
|
||||||
mq = mqc
|
mq = mqc
|
||||||
|
mqttclient.SetDefault(mqc)
|
||||||
// publish a startup message (non-blocking)
|
// publish a startup message (non-blocking)
|
||||||
go func() {
|
go func() {
|
||||||
msg := fmt.Sprintf("lambdaiot-core started on %s", addr)
|
msg := fmt.Sprintf("lambdaiot-core started on %s", addr)
|
||||||
@@ -51,7 +53,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mqttping endpoint will be added after router initialization
|
||||||
|
|
||||||
// Gin setup
|
// Gin setup
|
||||||
r := gin.New()
|
r := gin.New()
|
||||||
@@ -63,6 +65,20 @@ func main() {
|
|||||||
r.GET("/hello", handler.Hello)
|
r.GET("/hello", handler.Hello)
|
||||||
r.POST("/login", handler.Login)
|
r.POST("/login", handler.Login)
|
||||||
|
|
||||||
|
// mqttping endpoint: publish current timestamp to MQTT topic
|
||||||
|
r.POST("/mqttping", func(c *gin.Context) {
|
||||||
|
ts := time.Now().Format(time.RFC3339)
|
||||||
|
if mq == nil {
|
||||||
|
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "mqtt not connected"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := mq.Publish(cfg.MQTT.Topic, []byte(ts)); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, gin.H{"timestamp": ts})
|
||||||
|
})
|
||||||
|
|
||||||
// Protected routes
|
// Protected routes
|
||||||
auth := r.Group("/")
|
auth := r.Group("/")
|
||||||
auth.Use(middleware.AuthMiddleware(cfg.Server.JWTSecret))
|
auth.Use(middleware.AuthMiddleware(cfg.Server.JWTSecret))
|
||||||
|
|||||||
+17
-1
@@ -4,14 +4,30 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
paho "github.com/eclipse/paho.mqtt.golang"
|
|
||||||
"git.piskot.si/SeminarM2/lambdaiot-core/internal/config"
|
"git.piskot.si/SeminarM2/lambdaiot-core/internal/config"
|
||||||
|
paho "github.com/eclipse/paho.mqtt.golang"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
client paho.Client
|
client paho.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default is a package-level client used by helpers
|
||||||
|
var Default *Client
|
||||||
|
|
||||||
|
// SetDefault sets the package default client
|
||||||
|
func SetDefault(c *Client) {
|
||||||
|
Default = c
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublishDefault publishes using the default client
|
||||||
|
func PublishDefault(topic string, payload []byte) error {
|
||||||
|
if Default == nil {
|
||||||
|
return fmt.Errorf("no default mqtt client")
|
||||||
|
}
|
||||||
|
return Default.Publish(topic, payload)
|
||||||
|
}
|
||||||
|
|
||||||
func Connect(cfg config.MQTTConfig) (*Client, error) {
|
func Connect(cfg config.MQTTConfig) (*Client, error) {
|
||||||
opts := paho.NewClientOptions()
|
opts := paho.NewClientOptions()
|
||||||
opts.AddBroker(cfg.Broker)
|
opts.AddBroker(cfg.Broker)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ services:
|
|||||||
- MQTT_BROKER=tcp://mosquitto:1883
|
- MQTT_BROKER=tcp://mosquitto:1883
|
||||||
- MQTT_CLIENT_ID=lambdaiot-server
|
- MQTT_CLIENT_ID=lambdaiot-server
|
||||||
- MQTT_TOPIC=lambdaiot
|
- MQTT_TOPIC=lambdaiot
|
||||||
|
- MQTT_USERNAME=testuser
|
||||||
|
- MQTT_PASSWORD=testpass
|
||||||
depends_on:
|
depends_on:
|
||||||
- mosquitto
|
- mosquitto
|
||||||
# server image now waits for MQTT broker itself via entrypoint
|
# server image now waits for MQTT broker itself via entrypoint
|
||||||
@@ -27,6 +29,8 @@ services:
|
|||||||
- mosquitto_data:/mosquitto/data
|
- mosquitto_data:/mosquitto/data
|
||||||
- mosquitto_log:/mosquitto/log
|
- mosquitto_log:/mosquitto/log
|
||||||
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
|
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
|
||||||
|
# ensure a password file exists and start mosquitto with our config
|
||||||
|
command: sh -c "mosquitto_passwd -b /mosquitto/config/passwordfile testuser testpass >/dev/null 2>&1 || true; /usr/sbin/mosquitto -c /mosquitto/config/mosquitto.conf"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "sh", "-c", "nc -z localhost 1883 || exit 1"]
|
test: ["CMD", "sh", "-c", "nc -z localhost 1883 || exit 1"]
|
||||||
interval: 2s
|
interval: 2s
|
||||||
@@ -41,6 +45,8 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- MQTT_BROKER=mosquitto:1883
|
- MQTT_BROKER=mosquitto:1883
|
||||||
- MQTT_TOPIC=lambdaiot
|
- MQTT_TOPIC=lambdaiot
|
||||||
|
- MQTT_USERNAME=testuser
|
||||||
|
- MQTT_PASSWORD=testpass
|
||||||
command: sh -c "pip install paho-mqtt && python subscribe.py"
|
command: sh -c "pip install paho-mqtt && python subscribe.py"
|
||||||
depends_on:
|
depends_on:
|
||||||
- mosquitto
|
- mosquitto
|
||||||
|
|||||||
+4
-1
@@ -1,6 +1,9 @@
|
|||||||
# Allow external connections on port 1883
|
# Allow external connections on port 1883
|
||||||
|
# listen on all interfaces
|
||||||
listener 1883 0.0.0.0
|
listener 1883 0.0.0.0
|
||||||
allow_anonymous true
|
# do not allow anonymous in this test stack; require password_file
|
||||||
|
allow_anonymous false
|
||||||
|
password_file /mosquitto/config/passwordfile
|
||||||
# Increase persistence location so container can map volume if needed
|
# Increase persistence location so container can map volume if needed
|
||||||
persistence true
|
persistence true
|
||||||
persistence_location /mosquitto/data/
|
persistence_location /mosquitto/data/
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import paho.mqtt.client as mqtt
|
|||||||
|
|
||||||
broker = os.getenv('MQTT_BROKER', 'localhost:1883')
|
broker = os.getenv('MQTT_BROKER', 'localhost:1883')
|
||||||
topic = os.getenv('MQTT_TOPIC', 'lambdaiot')
|
topic = os.getenv('MQTT_TOPIC', 'lambdaiot')
|
||||||
|
username = os.getenv('MQTT_USERNAME')
|
||||||
|
password = os.getenv('MQTT_PASSWORD')
|
||||||
|
|
||||||
if broker.startswith('tcp://'):
|
if broker.startswith('tcp://'):
|
||||||
broker = broker[len('tcp://'):]
|
broker = broker[len('tcp://'):]
|
||||||
@@ -28,6 +30,8 @@ def on_message(client, userdata, msg):
|
|||||||
client = mqtt.Client()
|
client = mqtt.Client()
|
||||||
client.on_connect = on_connect
|
client.on_connect = on_connect
|
||||||
client.on_message = on_message
|
client.on_message = on_message
|
||||||
|
if username:
|
||||||
|
client.username_pw_set(username, password)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.connect(host, port, 60)
|
client.connect(host, port, 60)
|
||||||
|
|||||||
Reference in New Issue
Block a user