Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): add otelto opentdf services #1858

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6e8a078
feat(core): add otelto opentdf services
sujankota Jan 14, 2025
61adb72
more changes
sujankota Jan 15, 2025
2a93192
more traces
sujankota Jan 16, 2025
34e7bee
add code to push traces
sujankota Jan 23, 2025
daf8b85
cleanup
sujankota Jan 26, 2025
f0ea802
Update the docker compose
sujankota Jan 28, 2025
b284880
Merge branch 'main' into feat/add-otel-to-service
sujankota Jan 28, 2025
bfcdc0e
fix the go.mod file
sujankota Jan 28, 2025
ef5f004
fix lint error
sujankota Jan 28, 2025
538aab5
Fix the go.mod
sujankota Jan 28, 2025
1249aac
Merge branch 'main' into feat/add-otel-to-service
sujankota Jan 28, 2025
96e7ae2
Merge branch 'main' into feat/add-otel-to-service
sujankota Jan 29, 2025
1e70449
fix lint errors
sujankota Jan 29, 2025
e61045b
Fix the unittests
sujankota Jan 29, 2025
1fc4c01
Merge branch 'main' into feat/add-otel-to-service
sujankota Jan 29, 2025
201a996
fix lint issues
sujankota Jan 29, 2025
5c029e5
fix unittests
sujankota Jan 29, 2025
a46a397
Fix the build'
sujankota Jan 29, 2025
bdd13e4
Fix the build
sujankota Jan 29, 2025
bfca207
Fix the build
sujankota Jan 29, 2025
0e6f0e6
Fix the build
sujankota Jan 29, 2025
d028b36
fix build
sujankota Jan 29, 2025
67ea89e
fix build
sujankota Jan 30, 2025
edb1490
fix the build
sujankota Jan 30, 2025
d67db7b
Update go.sum
dmihalcik-virtru Jan 30, 2025
1530e6b
updates to go 1.22.11
dmihalcik-virtru Jan 30, 2025
2595bce
Merge branch 'main' into feat/add-otel-to-service
sujankota Feb 1, 2025
a09f6a6
Address code review comments
sujankota Feb 3, 2025
1abfeb5
fix lint error
sujankota Feb 3, 2025
b444eec
Merge branch 'main' into feat/add-otel-to-service
sujankota Feb 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions opentdf-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ logger:
level: debug
type: text
output: stdout
trace:
enabled: true
folder: "traces"
# DB and Server configurations are defaulted for local development
# db:
# host: localhost
Expand Down
21 changes: 21 additions & 0 deletions service/authorization/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/opentdf/platform/service/pkg/db"
"github.com/opentdf/platform/service/pkg/serviceregistry"
"github.com/opentdf/platform/service/policies"
"go.opentelemetry.io/otel/trace"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
Expand All @@ -42,6 +43,7 @@ type AuthorizationService struct { //nolint:revive // AuthorizationService is a
config Config
logger *logger.Logger
eval rego.PreparedEvalQuery
trace.Tracer
}

type Config struct {
Expand Down Expand Up @@ -137,6 +139,7 @@ func NewRegistration() *serviceregistry.Service[authorizationconnect.Authorizati
}

as.config = *authZCfg
as.Tracer = srp.Tracer

return as, nil
},
Expand All @@ -151,6 +154,12 @@ func (as AuthorizationService) IsReady(ctx context.Context) error {
}

func (as *AuthorizationService) GetDecisionsByToken(ctx context.Context, req *connect.Request[authorization.GetDecisionsByTokenRequest]) (*connect.Response[authorization.GetDecisionsByTokenResponse], error) {
if as.Tracer != nil {
var span trace.Span
ctx, span = as.Tracer.Start(ctx, "GetDecisionsByToken")
defer span.End()
}

decisionsRequests := []*authorization.DecisionRequest{}
// for each token decision request
for _, tdr := range req.Msg.GetDecisionRequests() {
Expand Down Expand Up @@ -184,6 +193,12 @@ func (as *AuthorizationService) GetDecisionsByToken(ctx context.Context, req *co
func (as *AuthorizationService) GetDecisions(ctx context.Context, req *connect.Request[authorization.GetDecisionsRequest]) (*connect.Response[authorization.GetDecisionsResponse], error) {
as.logger.DebugContext(ctx, "getting decisions")

if as.Tracer != nil {
var span trace.Span
ctx, span = as.Tracer.Start(ctx, "GetDecisions")
defer span.End()
}
Copy link
Member

Choose a reason for hiding this comment

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

I am thinking we might want to create some type of metrics / tracing package that we could use to abstract away a lot of these if as.Tracer != nil checks

Copy link
Member

Choose a reason for hiding this comment

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

we already have a tracing package so we can probably add it there.


// Temporary canned echo response with permit decision for all requested decision/entity/ra combos
rsp := &authorization.GetDecisionsResponse{
DecisionResponses: make([]*authorization.DecisionResponse, 0),
Expand Down Expand Up @@ -494,6 +509,12 @@ func makeScopeMap(scope *authorization.ResourceAttribute) map[string]bool {
func (as *AuthorizationService) GetEntitlements(ctx context.Context, req *connect.Request[authorization.GetEntitlementsRequest]) (*connect.Response[authorization.GetEntitlementsResponse], error) {
as.logger.DebugContext(ctx, "getting entitlements")

if as.Tracer != nil {
var span trace.Span
ctx, span = as.Tracer.Start(ctx, "GetEntitlements")
defer span.End()
}

var nextOffset int32
attrsList := make([]*policy.Attribute, 0)
subjectMappingsList := make([]*policy.SubjectMapping, 0)
Expand Down
2 changes: 1 addition & 1 deletion service/cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func migrateDBClient(cmd *cobra.Command, opts ...db.OptsFunc) (*db.Client, error
if err != nil {
panic(fmt.Errorf("could not load config: %w", err))
}
return db.New(context.Background(), conf.DB, conf.Logger, opts...)
return db.New(context.Background(), conf.DB, conf.Logger, nil, opts...)
}

func init() {
Expand Down
2 changes: 1 addition & 1 deletion service/cmd/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func policyDBClient(conf *config.Config) (policydb.PolicyDBClient, error) {
if !strings.HasSuffix(conf.DB.Schema, "_policy") {
conf.DB.Schema += "_policy"
}
dbClient, err := db.New(context.Background(), conf.DB, conf.Logger, db.WithMigrations(policy.Migrations))
dbClient, err := db.New(context.Background(), conf.DB, conf.Logger, nil, db.WithMigrations(policy.Migrations))
if err != nil {
//nolint:wrapcheck // we want to return the error as is. the start command will wrap it
return policydb.PolicyDBClient{}, err
Expand Down
2 changes: 1 addition & 1 deletion service/cmd/provisionFixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ You can clear/recycle your database with 'docker compose down' and 'docker compo
panic(fmt.Errorf("could not load config: %w", err))
}

dbClient, err := db.New(context.Background(), cfg.DB, cfg.Logger)
dbClient, err := db.New(context.Background(), cfg.DB, cfg.Logger, nil)
if err != nil {
panic(fmt.Errorf("issue creating database client: %w", err))
}
Expand Down
8 changes: 8 additions & 0 deletions service/entityresolution/claims/claims_entity_resolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
auth "github.com/opentdf/platform/service/authorization"
"github.com/opentdf/platform/service/logger"
"github.com/opentdf/platform/service/pkg/serviceregistry"
"go.opentelemetry.io/otel/trace"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/structpb"
Expand All @@ -20,6 +21,7 @@ import (
type ClaimsEntityResolutionService struct {
entityresolution.UnimplementedEntityResolutionServiceServer
logger *logger.Logger
trace.Tracer
}

func RegisterClaimsERS(_ serviceregistry.ServiceConfig, logger *logger.Logger) (ClaimsEntityResolutionService, serviceregistry.HandlerServer) {
Expand All @@ -33,6 +35,12 @@ func (s ClaimsEntityResolutionService) ResolveEntities(ctx context.Context, req
}

func (s ClaimsEntityResolutionService) CreateEntityChainFromJwt(ctx context.Context, req *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) {
if s.Tracer != nil {
var span trace.Span
ctx, span = s.Tracer.Start(ctx, "CreateEntityChainFromJwt")
defer span.End()
}

resp, err := CreateEntityChainFromJwt(ctx, req.Msg, s.logger)
return connect.NewResponse(&resp), err
}
Expand Down
7 changes: 6 additions & 1 deletion service/entityresolution/entityresolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
claims "github.com/opentdf/platform/service/entityresolution/claims"
keycloak "github.com/opentdf/platform/service/entityresolution/keycloak"
"github.com/opentdf/platform/service/pkg/serviceregistry"
"go.opentelemetry.io/otel/trace"
)

type ERSConfig struct {
Expand All @@ -20,6 +21,7 @@ const (

type EntityResolution struct {
entityresolutionconnect.EntityResolutionServiceHandler
trace.Tracer
}

func NewRegistration() *serviceregistry.Service[entityresolutionconnect.EntityResolutionServiceHandler] {
Expand All @@ -37,12 +39,15 @@ func NewRegistration() *serviceregistry.Service[entityresolutionconnect.EntityRe
}
if inputConfig.Mode == ClaimsMode {
claimsSVC, claimsHandler := claims.RegisterClaimsERS(srp.Config, srp.Logger)
claimsSVC.Tracer = srp.Tracer
return EntityResolution{EntityResolutionServiceHandler: claimsSVC}, claimsHandler
}

// Default to keycloak ERS
kcSVC, kcHandler := keycloak.RegisterKeycloakERS(srp.Config, srp.Logger)
return EntityResolution{EntityResolutionServiceHandler: kcSVC}, kcHandler
kcSVC.Tracer = srp.Tracer

return EntityResolution{EntityResolutionServiceHandler: kcSVC, Tracer: srp.Tracer}, kcHandler
},
},
}
Expand Down
16 changes: 16 additions & 0 deletions service/entityresolution/keycloak/keycloak_entity_resolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
auth "github.com/opentdf/platform/service/authorization"
"github.com/opentdf/platform/service/logger"
"github.com/opentdf/platform/service/pkg/serviceregistry"
"go.opentelemetry.io/otel/trace"
"google.golang.org/grpc/codes"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/structpb"
Expand All @@ -39,6 +40,7 @@ type KeycloakEntityResolutionService struct {
entityresolution.UnimplementedEntityResolutionServiceServer
idpConfig KeycloakConfig
logger *logger.Logger
trace.Tracer
}

type KeycloakConfig struct {
Expand All @@ -62,11 +64,25 @@ func RegisterKeycloakERS(config serviceregistry.ServiceConfig, logger *logger.Lo
}

func (s KeycloakEntityResolutionService) ResolveEntities(ctx context.Context, req *connect.Request[entityresolution.ResolveEntitiesRequest]) (*connect.Response[entityresolution.ResolveEntitiesResponse], error) {
if s.Tracer != nil {
var span trace.Span
ctx, span = s.Tracer.Start(ctx, "ResolveEntities")
defer span.End()
}

resp, err := EntityResolution(ctx, req.Msg, s.idpConfig, s.logger)
return connect.NewResponse(&resp), err
}

// - On rewrap - call keyclocks get client with the username

func (s KeycloakEntityResolutionService) CreateEntityChainFromJwt(ctx context.Context, req *connect.Request[entityresolution.CreateEntityChainFromJwtRequest]) (*connect.Response[entityresolution.CreateEntityChainFromJwtResponse], error) {
if s.Tracer != nil {
var span trace.Span
ctx, span = s.Tracer.Start(ctx, "CreateEntityChainFromJwt")
defer span.End()
}

resp, err := CreateEntityChainFromJwt(ctx, req.Msg, s.idpConfig, s.logger)
return connect.NewResponse(&resp), err
}
Expand Down
12 changes: 10 additions & 2 deletions service/internal/fixtures/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import (

"github.com/opentdf/platform/service/internal/config"
"github.com/opentdf/platform/service/logger"

"github.com/opentdf/platform/service/pkg/db"
policydb "github.com/opentdf/platform/service/policy/db"
"github.com/opentdf/platform/service/tracing"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
)

var (
Expand All @@ -31,7 +33,13 @@ func NewDBInterface(cfg config.Config) DBInterface {
config := cfg.DB
config.Schema = cfg.DB.Schema
logCfg := cfg.Logger
c, err := db.New(context.Background(), config, logCfg)

var tracer trace.Tracer
if cfg.Trace.Enabled {
tracer = otel.Tracer(tracing.ServiceName)
}

c, err := db.New(context.Background(), config, logCfg, &tracer)
if err != nil {
slog.Error("issue creating database client", slog.String("error", err.Error()))
panic(err)
Expand Down
9 changes: 7 additions & 2 deletions service/pkg/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
"github.com/jackc/pgx/v5/stdlib"
"github.com/opentdf/platform/service/logger"
"go.opentelemetry.io/otel/trace"
)

type Table struct {
Expand Down Expand Up @@ -112,14 +113,14 @@ type Client struct {
ranMigrations bool
// This is the stdlib connection that is used for transactions
SQLDB *sql.DB
trace.Tracer
}

/*
Connections and pools seems to be pulled in from env vars
We should be able to tell the platform how to run
*/

func New(ctx context.Context, config Config, logCfg logger.Config, o ...OptsFunc) (*Client, error) {
func New(ctx context.Context, config Config, logCfg logger.Config, tracer *trace.Tracer, o ...OptsFunc) (*Client, error) {
for _, f := range o {
config = f(config)
}
Expand All @@ -128,6 +129,10 @@ func New(ctx context.Context, config Config, logCfg logger.Config, o ...OptsFunc
config: config,
}

if tracer != nil {
c.Tracer = *tracer
}

l, err := logger.NewLogger(logger.Config{
Output: logCfg.Output,
Type: logCfg.Type,
Expand Down
6 changes: 3 additions & 3 deletions service/pkg/server/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func startServices(ctx context.Context, cfg config.Config, otdf *server.OpenTDFS
if svc.IsDBRequired() && svcDBClient == nil {
logger.Debug("creating database client", slog.String("namespace", ns))
var err error
svcDBClient, err = newServiceDBClient(ctx, cfg.Logger, cfg.DB, ns, svc.DBMigrations())
svcDBClient, err = newServiceDBClient(ctx, cfg.Logger, cfg.DB, tracer, ns, svc.DBMigrations())
if err != nil {
return err
}
Expand Down Expand Up @@ -241,10 +241,10 @@ func extractServiceLoggerConfig(cfg serviceregistry.ServiceConfig) (string, erro
// newServiceDBClient creates a new database client for the specified namespace.
// It initializes the client with the provided context, logger configuration, database configuration,
// namespace, and migrations. It returns the created client and any error encountered during creation.
func newServiceDBClient(ctx context.Context, logCfg logging.Config, dbCfg db.Config, ns string, migrations *embed.FS) (*db.Client, error) {
func newServiceDBClient(ctx context.Context, logCfg logging.Config, dbCfg db.Config, trace trace.Tracer, ns string, migrations *embed.FS) (*db.Client, error) {
var err error

client, err := db.New(ctx, dbCfg, logCfg,
client, err := db.New(ctx, dbCfg, logCfg, &trace,
db.WithService(ns),
db.WithMigrations(migrations),
)
Expand Down
21 changes: 21 additions & 0 deletions service/policy/attributes/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import (
"github.com/opentdf/platform/service/pkg/serviceregistry"
policyconfig "github.com/opentdf/platform/service/policy/config"
policydb "github.com/opentdf/platform/service/policy/db"
"go.opentelemetry.io/otel/trace"
)

type AttributesService struct { //nolint:revive // AttributesService is a valid name for this struct
dbClient policydb.PolicyDBClient
logger *logger.Logger
config *policyconfig.Config
trace.Tracer
}

func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *serviceregistry.Service[attributesconnect.AttributesServiceHandler] {
Expand All @@ -37,6 +39,7 @@ func NewRegistration(ns string, dbRegister serviceregistry.DBRegister) *servicer
dbClient: policydb.NewClient(srp.DBClient, srp.Logger, int32(cfg.ListRequestLimitMax), int32(cfg.ListRequestLimitDefault)),
logger: srp.Logger,
config: cfg,
Tracer: srp.Tracer,
}, nil
},
},
Expand Down Expand Up @@ -80,6 +83,12 @@ func (s AttributesService) CreateAttribute(ctx context.Context,
func (s *AttributesService) ListAttributes(ctx context.Context,
req *connect.Request[attributes.ListAttributesRequest],
) (*connect.Response[attributes.ListAttributesResponse], error) {
if s.Tracer != nil {
var span trace.Span
ctx, span = s.Tracer.Start(ctx, "ListAttributes")
defer span.End()
}

state := req.Msg.GetState().String()
s.logger.Debug("listing attribute definitions", slog.String("state", state))

Expand All @@ -94,6 +103,12 @@ func (s *AttributesService) ListAttributes(ctx context.Context,
func (s *AttributesService) GetAttribute(ctx context.Context,
req *connect.Request[attributes.GetAttributeRequest],
) (*connect.Response[attributes.GetAttributeResponse], error) {
if s.Tracer != nil {
var span trace.Span
ctx, span = s.Tracer.Start(ctx, "GetAttribute")
defer span.End()
}

rsp := &attributes.GetAttributeResponse{}

item, err := s.dbClient.GetAttribute(ctx, req.Msg.GetId())
Expand All @@ -108,6 +123,12 @@ func (s *AttributesService) GetAttribute(ctx context.Context,
func (s *AttributesService) GetAttributeValuesByFqns(ctx context.Context,
req *connect.Request[attributes.GetAttributeValuesByFqnsRequest],
) (*connect.Response[attributes.GetAttributeValuesByFqnsResponse], error) {
if s.Tracer != nil {
var span trace.Span
ctx, span = s.Tracer.Start(ctx, "GetAttributeValuesByFqns")
defer span.End()
}

rsp := &attributes.GetAttributeValuesByFqnsResponse{}

fqnsToAttributes, err := s.dbClient.GetAttributesByValueFqns(ctx, req.Msg)
Expand Down
7 changes: 7 additions & 0 deletions service/policy/db/attribute_fqn.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/opentdf/platform/protocol/go/policy/attributes"
"github.com/opentdf/platform/protocol/go/policy/namespaces"
"github.com/opentdf/platform/service/pkg/db"
"go.opentelemetry.io/otel/trace"
)

// AttrFqnReindex will reindex all namespace, attribute, and attribute_value FQNs
Expand Down Expand Up @@ -74,6 +75,12 @@ func (c *PolicyDBClient) AttrFqnReindex(ctx context.Context) (res struct { //nol
func (c *PolicyDBClient) GetAttributesByValueFqns(ctx context.Context, r *attributes.GetAttributeValuesByFqnsRequest) (map[string]*attributes.GetAttributeValuesByFqnsResponse_AttributeAndValue, error) {
fqns := r.GetFqns()

if c.Tracer != nil {
var span trace.Span
ctx, span = c.Tracer.Start(ctx, "DB:GetAttributesByValueFqns")
defer span.End()
}

list := make(map[string]*attributes.GetAttributeValuesByFqnsResponse_AttributeAndValue, len(fqns))

for i, fqn := range fqns {
Expand Down
Loading