mirror of
https://github.com/absmach/magistrala.git
synced 2026-08-07 07:14:46 +00:00
168e8b90cb
Property Based Tests / api-test (push) Has been cancelled
Continuous Delivery / lint-and-build (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled
CI Pipeline / Lint Proto (push) Has been cancelled
CI Pipeline / Detect Changes (push) Has been cancelled
Continuous Delivery / Build and Push Docker Images (push) Has been cancelled
CI Pipeline / lint-and-build (push) Has been cancelled
CI Pipeline / Test ${{ matrix.module }} (push) Has been cancelled
CI Pipeline / Upload Coverage (push) Has been cancelled
Signed-off-by: dusan <borovcanindusan1@gmail.com>
147 lines
4.1 KiB
Go
147 lines
4.1 KiB
Go
// Copyright (c) Abstract Machines
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Package main contains the one-shot Magistrala Atom bootstrap command.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/absmach/magistrala/pkg/atom"
|
|
)
|
|
|
|
const (
|
|
defaultRetries = 30
|
|
defaultRetryInterval = 2 * time.Second
|
|
defaultTimeout = 30 * time.Second
|
|
)
|
|
|
|
func main() {
|
|
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
|
|
|
|
cfg := atom.LoadConfig()
|
|
if cfg.URL == "" {
|
|
log.Fatal("ATOM_URL is required")
|
|
}
|
|
|
|
client := atom.NewClient(cfg)
|
|
if len(os.Args) > 1 {
|
|
switch os.Args[1] {
|
|
case "bootstrap-actions":
|
|
runBootstrapActions(client)
|
|
return
|
|
case "provision-tokens":
|
|
runProvisionTokens(client, os.Args[2:])
|
|
return
|
|
default:
|
|
log.Fatalf("unknown command %q", os.Args[1])
|
|
}
|
|
}
|
|
runBootstrapActions(client)
|
|
}
|
|
|
|
func runBootstrapActions(client *atom.Client) {
|
|
retries := envInt("MG_ATOM_BOOTSTRAP_RETRIES", defaultRetries)
|
|
retryInterval := envDuration("MG_ATOM_BOOTSTRAP_RETRY_INTERVAL", defaultRetryInterval)
|
|
timeout := envDuration("MG_ATOM_BOOTSTRAP_TIMEOUT", defaultTimeout)
|
|
|
|
var lastErr error
|
|
for attempt := 1; attempt <= retries; attempt++ {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
err := atom.BootstrapMagistralaActions(ctx, client)
|
|
cancel()
|
|
if err == nil {
|
|
log.Printf("Magistrala Atom action bootstrap completed")
|
|
return
|
|
}
|
|
lastErr = err
|
|
if attempt < retries {
|
|
log.Printf("Magistrala Atom action bootstrap attempt %d/%d failed: %v; retrying in %s", attempt, retries, err, retryInterval)
|
|
time.Sleep(retryInterval)
|
|
}
|
|
}
|
|
|
|
log.Fatalf("Magistrala Atom action bootstrap failed after %d attempts: %v", retries, lastErr)
|
|
}
|
|
|
|
func runProvisionTokens(client *atom.Client, args []string) {
|
|
fs := flag.NewFlagSet("provision-tokens", flag.ExitOnError)
|
|
output := fs.String("output", envString("MG_ATOM_TOKENS_OUTPUT", "docker/.env.tokens"), "path to write generated token env file")
|
|
rotate := fs.String("rotate", "", "rotate one token by name/env var, or all")
|
|
entityID := fs.String("entity-id", envString("ATOM_SERVICE_ENTITY_ID", atom.DefaultServiceEntityID), "Atom service entity ID to receive access tokens")
|
|
if err := fs.Parse(args); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
retries := envInt("MG_ATOM_BOOTSTRAP_RETRIES", defaultRetries)
|
|
retryInterval := envDuration("MG_ATOM_BOOTSTRAP_RETRY_INTERVAL", defaultRetryInterval)
|
|
timeout := envDuration("MG_ATOM_BOOTSTRAP_TIMEOUT", defaultTimeout)
|
|
|
|
var lastErr error
|
|
for attempt := 1; attempt <= retries; attempt++ {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
result, err := atom.ProvisionServiceTokens(ctx, client, atom.TokenProvisionOptions{
|
|
OutputPath: *output,
|
|
ServiceEntityID: *entityID,
|
|
Rotate: *rotate,
|
|
})
|
|
cancel()
|
|
if err == nil {
|
|
log.Printf("Magistrala Atom token provisioning completed: output=%s preserved=%d created=%d rotated=%d",
|
|
result.OutputPath, len(result.Preserved), len(result.Created), len(result.Rotated))
|
|
return
|
|
}
|
|
lastErr = err
|
|
if attempt < retries {
|
|
log.Printf("Magistrala Atom token provisioning attempt %d/%d failed: %v; retrying in %s", attempt, retries, err, retryInterval)
|
|
time.Sleep(retryInterval)
|
|
}
|
|
}
|
|
|
|
log.Fatalf("Magistrala Atom token provisioning failed after %d attempts: %v", retries, lastErr)
|
|
}
|
|
|
|
func envInt(key string, fallback int) int {
|
|
raw := strings.TrimSpace(os.Getenv(key))
|
|
if raw == "" {
|
|
return fallback
|
|
}
|
|
value, err := strconv.Atoi(raw)
|
|
if err != nil || value <= 0 {
|
|
return fallback
|
|
}
|
|
return value
|
|
}
|
|
|
|
func envDuration(key string, fallback time.Duration) time.Duration {
|
|
raw := strings.TrimSpace(os.Getenv(key))
|
|
if raw == "" {
|
|
return fallback
|
|
}
|
|
value, err := time.ParseDuration(raw)
|
|
if err == nil && value > 0 {
|
|
return value
|
|
}
|
|
seconds, err := strconv.Atoi(raw)
|
|
if err == nil && seconds > 0 {
|
|
return time.Duration(seconds) * time.Second
|
|
}
|
|
fmt.Fprintf(os.Stderr, "invalid %s=%q, using %s\n", key, raw, fallback)
|
|
return fallback
|
|
}
|
|
|
|
func envString(key, fallback string) string {
|
|
value := strings.TrimSpace(os.Getenv(key))
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
return value
|
|
}
|