Files
magistrala/bootstrap/sdk_resolver.go
T
Steve Munene 7f03134d8e
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
NOISSUE - Update bootstrap and provision service (#3476)
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: JeffMboya <jangina.mboya@gmail.com>
Co-authored-by: JeffMboya <jangina.mboya@gmail.com>
2026-05-08 10:35:00 +02:00

116 lines
3.1 KiB
Go

// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package bootstrap
import (
"context"
"fmt"
"time"
"github.com/absmach/magistrala/pkg/errors"
svcerr "github.com/absmach/magistrala/pkg/errors/service"
mgsdk "github.com/absmach/magistrala/pkg/sdk"
)
var _ BindingResolver = (*sdkResolver)(nil)
type sdkResolver struct {
sdk mgsdk.SDK
}
// NewSDKResolver returns a BindingResolver that validates resources against
// the Magistrala clients and channels services using the SDK. This resolver
// is called only at binding time; the render path must never call it.
func NewSDKResolver(sdk mgsdk.SDK) BindingResolver {
return &sdkResolver{sdk: sdk}
}
func (r *sdkResolver) Resolve(ctx context.Context, req ResolveRequest) ([]BindingSnapshot, error) {
var snapshots []BindingSnapshot
for _, br := range req.Requested {
snap, err := r.resolveOne(ctx, req.Enrollment.DomainID, req.Token, br)
if err != nil {
return nil, err
}
snapshots = append(snapshots, snap)
}
return snapshots, nil
}
func (r *sdkResolver) resolveOne(ctx context.Context, domainID, token string, br BindingRequest) (BindingSnapshot, error) {
switch br.Type {
case "client":
return r.resolveClient(ctx, domainID, token, br)
case "channel":
return r.resolveChannel(ctx, domainID, token, br)
default:
return BindingSnapshot{}, fmt.Errorf("unsupported binding type %q", br.Type)
}
}
func (r *sdkResolver) resolveClient(ctx context.Context, domainID, token string, br BindingRequest) (BindingSnapshot, error) {
client, sdkErr := r.sdk.Client(ctx, br.ResourceID, domainID, token)
if sdkErr != nil {
return BindingSnapshot{}, errors.Wrap(svcerr.ErrNotFound,
fmt.Errorf("client %q not found: %s", br.ResourceID, sdkErr))
}
snapshot := map[string]any{
"id": client.ID,
"name": client.Name,
}
if client.Credentials.Identity != "" {
snapshot["identity"] = client.Credentials.Identity
}
if client.DomainID != "" {
snapshot["domain_id"] = client.DomainID
}
secret := map[string]any{}
if client.Credentials.Secret != "" {
secret["secret"] = client.Credentials.Secret
}
return BindingSnapshot{
Slot: br.Slot,
Type: br.Type,
ResourceID: br.ResourceID,
Snapshot: snapshot,
SecretSnapshot: secret,
UpdatedAt: time.Now().UTC(),
}, nil
}
func (r *sdkResolver) resolveChannel(ctx context.Context, domainID, token string, br BindingRequest) (BindingSnapshot, error) {
channel, sdkErr := r.sdk.Channel(ctx, br.ResourceID, domainID, token)
if sdkErr != nil {
return BindingSnapshot{}, errors.Wrap(svcerr.ErrNotFound,
fmt.Errorf("channel %q not found: %s", br.ResourceID, sdkErr))
}
snapshot := map[string]any{
"id": channel.ID,
"name": channel.Name,
}
if channel.Route != "" {
snapshot["topic"] = channel.Route
}
if channel.DomainID != "" {
snapshot["domain_id"] = channel.DomainID
}
if channel.Metadata != nil {
snapshot["metadata"] = channel.Metadata
}
return BindingSnapshot{
Slot: br.Slot,
Type: br.Type,
ResourceID: br.ResourceID,
Snapshot: snapshot,
UpdatedAt: time.Now().UTC(),
}, nil
}