Skip to content

Commit

Permalink
microcluster/rest/resources: Compare the joining node's extensions ag…
Browse files Browse the repository at this point in the history
…ainst the leader's

During a cluster join, the joining node communicate its extensions as seen earlier.
When received (by the leader), we make sure that the target extensions (the joining node ones) and the source
extensions (the leader ones) by comparing them. If they the target ones are supported, we add a serialized view
of both the `internal` and `external` part to the `internal_cluster_members` tables.

Signed-off-by: Gabriel Mougard <[email protected]>
  • Loading branch information
gabrielmougard committed Feb 20, 2024
1 parent ea70f30 commit 6b5ca01
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions internal/rest/resources/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/canonical/microcluster/client"
"github.com/canonical/microcluster/cluster"
"github.com/canonical/microcluster/internal/db"
"github.com/canonical/microcluster/internal/rest/access"
internalClient "github.com/canonical/microcluster/internal/rest/client"
internalTypes "github.com/canonical/microcluster/internal/rest/types"
Expand Down Expand Up @@ -129,14 +130,30 @@ func clusterPost(s *state.State, r *http.Request) response.Response {
return response.SyncResponse(true, tokenResponse)
}

// Check if the joining node's extensions are compatible with the leader's.
targetExtensions, err := db.NewExtensionRegistryFromList(req.Extensions)
if err != nil {
return response.SmartError(err)
}

err = s.Extensions.Supports(targetExtensions)
if err != nil {
return response.SmartError(err)
}

// Then add the new member's extensions to the database.
internalExtensions, externalExtensions := targetExtensions.SerializeForDB()

err = s.Database.Transaction(s.Context, func(ctx context.Context, tx *sql.Tx) error {
dbClusterMember := cluster.InternalClusterMember{
Name: req.Name,
Address: req.Address.String(),
Certificate: req.Certificate.String(),
Schema: req.SchemaVersion,
Heartbeat: time.Time{},
Role: cluster.Pending,
Name: req.Name,
Address: req.Address.String(),
Certificate: req.Certificate.String(),
Schema: req.SchemaVersion,
InternalAPIExtensions: internalExtensions,
ExternalAPIExtensions: externalExtensions,
Heartbeat: time.Time{},
Role: cluster.Pending,
}

record, err := cluster.GetInternalTokenRecord(ctx, tx, req.Secret)
Expand Down

0 comments on commit 6b5ca01

Please sign in to comment.