Skip to content

Commit

Permalink
microcluster/example: Add API extension manipulation examples
Browse files Browse the repository at this point in the history
* Show how we can add API extensions at daemon startup (`example/api/extensions.go`)
* Show how we can manipulate API extensions within hooks.

Signed-off-by: Gabriel Mougard <[email protected]>
  • Loading branch information
gabrielmougard committed Mar 5, 2024
1 parent 2a56296 commit 85c6b85
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
12 changes: 12 additions & 0 deletions example/api/extensions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package api

// These are the extensions that are present when the daemon starts.
var extensions = []string{
"custom_extension_a_0",
"custom_extension_a_1",
}

// Extensions returns the list of MicroOVN extensions.
func Extensions() []string {
return extensions
}
39 changes: 38 additions & 1 deletion example/cmd/microd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/canonical/microcluster/example/api"
"github.com/canonical/microcluster/example/database"
"github.com/canonical/microcluster/example/version"
"github.com/canonical/microcluster/internal/extensions"
"github.com/canonical/microcluster/microcluster"
"github.com/canonical/microcluster/state"
)
Expand Down Expand Up @@ -75,6 +76,42 @@ func (c *cmdDaemon) Run(cmd *cobra.Command, args []string) error {
logCtx[k] = v
}

// You can check your app extensions using the *state.State object.
hasMissingExt := s.Extensions.HasExtension("missing_extension")
if !hasMissingExt {
logger.Warn("The 'missing_extension' is not registered")
}

// You can also check the internal extensions. (starting with "internal:" prefix)
// These are read-only and defined at the MicroCluster level and cannot be added at runtime
hasInternalExt := s.Extensions.HasExtension("internal:runtime_extension_v1")
if !hasInternalExt {
logger.Warn("Every system should have the 'internal:runtime_extension_v1' extension")
}

// You can also register new extensions at runtime.
err := s.Extensions.Register([]string{"new_extension_at_runtime_1", "new_extension_at_runtime_2"})
if err != nil {
return err
}

// This shows the number of extensions that are registered (internal and external).
numberOfExtensions := s.Extensions.Version()
logger.Infof("The number of extensions is %d", numberOfExtensions)

// You can also create a new registry of extensions from a list of extensions.
// This is useful to communicate a system's extensions to other systems, for comparison purposes for example.
newExt, err := extensions.NewExtensionRegistryFromList([]string{"internal:runtime_extension_v1", "new_extension_at_runtime_1", "new_extension_at_runtime_2", "custom_extension_a_0", "custom_extension_a_1"})
if err != nil {
return err
}

// You can compare the extensions of two systems.
err = s.Extensions.IsSameVersion(newExt)
if err != nil {
return err
}

logger.Info("This is a hook that runs after the daemon is initialized and bootstrapped")
logger.Info("Here are the extra configuration keys that were passed into the init --bootstrap command", logCtx)

Expand Down Expand Up @@ -155,7 +192,7 @@ func (c *cmdDaemon) Run(cmd *cobra.Command, args []string) error {
},
}

return m.Start(api.Endpoints, database.SchemaExtensions, []string{}, exampleHooks)
return m.Start(api.Endpoints, database.SchemaExtensions, api.Extensions(), exampleHooks)
}

func init() {
Expand Down

0 comments on commit 85c6b85

Please sign in to comment.