Skip to content

Conversation

@doanac
Copy link
Member

@doanac doanac commented Oct 20, 2025

This set of changes does some minor cleanups and then exposes the bare minimum of an API for other Golang modules to use.

The current internal module is quite large, so I did something similar to how we gradually cleaned up the Fioup API and am just wrapping what we need. We can eventually clean this up more if we ever choose to.

Signed-off-by: Andy Doan <andy@foundries.io>
Signed-off-by: Andy Doan <andy@foundries.io>
Signed-off-by: Andy Doan <andy@foundries.io>
This allows a caller of the API to understand what config paths are
being used.

Signed-off-by: Andy Doan <andy@foundries.io>
Signed-off-by: Andy Doan <andy@foundries.io>
@doanac doanac requested review from detsch and mike-sul October 20, 2025 18:19
@doanac
Copy link
Member Author

doanac commented Oct 20, 2025

I was able to get something going pretty quick in fioup with:

diff --git a/cmd/fioup/daemon.go b/cmd/fioup/daemon.go
index 44f8023..a6fa880 100644
--- a/cmd/fioup/daemon.go
+++ b/cmd/fioup/daemon.go
@@ -6,9 +6,11 @@ package main
 import (
 	"errors"
 	"log/slog"
+	"os"
 	"strconv"
 	"time"
 
+	fioconfig "github.com/foundriesio/fioconfig/app"
 	"github.com/foundriesio/fioup/internal/events"
 	"github.com/foundriesio/fioup/pkg/api"
 	"github.com/foundriesio/fioup/pkg/client"
@@ -19,6 +21,12 @@ import (
 type (
 	daemonOptions struct {
 		runOnce bool
+
+		// FioConfig related options
+		runFioConfig    bool
+		secretsDir      string
+		unsafeHandlers  bool
+		configExtracted bool
 	}
 )
 
@@ -35,7 +43,11 @@ func init() {
 		Args: cobra.NoArgs,
 	}
 	cmd.Flags().BoolVar(&opts.runOnce, "run-once", false, "Run a single update check and exit.")
+	cmd.Flags().BoolVar(&opts.runFioConfig, "fioconfig", true, "Include FioConfig daemon logic.")
+	cmd.Flags().StringVar(&opts.secretsDir, "secrets-dir", "/run/secrets", "Directory to hold FioConfig secrets when enabled.")
+	cmd.Flags().BoolVar(&opts.unsafeHandlers, "unsafe-handlers", false, "Enable unsafe FioConfig handlers.")
 	_ = cmd.Flags().MarkHidden("run-once")
+	_ = cmd.Flags().MarkHidden("unsafe-handlers")
 	rootCmd.AddCommand(cmd)
 }
 
@@ -54,6 +66,17 @@ func doDaemon(cmd *cobra.Command, opts *daemonOptions) {
 		slog.Error("Failed to create gateway client", "error", err)
 		return
 	}
+
+	var configApp *fioconfig.App
+
+	if opts.runFioConfig {
+		configApp, err = fioconfig.NewAppWithConfig(config.TomlConfig(), opts.secretsDir, opts.unsafeHandlers)
+		if err != nil {
+			slog.Error("Failed to create FioConfig handle", "error", err)
+			return
+		}
+	}
+
 	if eventSender, err = events.NewEventSender(config, gwClient); err != nil {
 		slog.Error("Failed to create event sender", "error", err)
 		return
@@ -62,6 +85,10 @@ func doDaemon(cmd *cobra.Command, opts *daemonOptions) {
 	defer eventSender.Stop()
 
 	for {
+		if opts.runFioConfig {
+			configCheck(opts, configApp)
+		}
+
 		err := api.Update(cmd.Context(), config, -1,
 			api.WithGatewayClient(gwClient),
 			api.WithEventSender(eventSender),
@@ -81,3 +108,27 @@ func doDaemon(cmd *cobra.Command, opts *daemonOptions) {
 		}
 	}
 }
+
+func configCheck(opts *daemonOptions, app *fioconfig.App) {
+	if _, err := os.Stat(opts.secretsDir); os.IsNotExist(err) {
+		slog.Debug("Creating FioConfig secrets directory", "dir", opts.secretsDir)
+		if err := os.MkdirAll(opts.secretsDir, 0o700); err != nil {
+			slog.Error("Failed to create secrets directory", "dir", opts.secretsDir, "error", err)
+			return
+		}
+	}
+	if !opts.configExtracted {
+		slog.Debug("Running FioConfig secret extraction")
+		if err := app.Extract(); err != nil {
+			slog.Error("FioConfig secret extraction failed", "error", err)
+		} else {
+			slog.Debug("FioConfig extraction completed successfully")
+			opts.configExtracted = true
+		}
+	}
+	if err := app.CheckIn(); err != nil {
+		if err != fioconfig.NotModifiedError {
+			slog.Error("FioConfig check-in failed", "error", err)
+		}
+	}
+}

Copy link
Member

@detsch detsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

This exposes the minimum surface area of Fioconfig while avoiding some
of the more complex things like certificate rotation which aren't
supported in Fioup or the community edition of FoundriesFactory.

Signed-off-by: Andy Doan <andy@foundries.io>
Copy link
Contributor

@mike-sul mike-sul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@doanac doanac merged commit ae762fe into foundriesio:main Oct 21, 2025
2 checks passed
@doanac doanac deleted the external-api branch October 21, 2025 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants