Skip to content

Commit

Permalink
Add BusinessTelemetry to authenticated RPC calls (#2117)
Browse files Browse the repository at this point in the history
* Update TelemetryStore fields, i.e. repos, profile, ruletype, etc.

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add Telemetry for ArtifactService

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add login_sha to TelemetryStore

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add Telemetry for OAuthService

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add Telemetry for ProfileService

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add Telemetry for RepositoryService

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add Telemetry for ProfileService - RuleTypes

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add Telemetry for UserService

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Fix linting errors and tests

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Add PR to TelemetryStore.Record func

Signed-off-by: Radoslav Dimitrov <[email protected]>

* Update the not present unit test for telemetry store

Signed-off-by: Radoslav Dimitrov <[email protected]>

---------

Signed-off-by: Radoslav Dimitrov <[email protected]>
  • Loading branch information
rdimitrov authored Jan 19, 2024
1 parent 0553ec3 commit 4416c7f
Show file tree
Hide file tree
Showing 12 changed files with 314 additions and 87 deletions.
17 changes: 17 additions & 0 deletions internal/controlplane/handlers_artifacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

"github.com/stacklok/minder/internal/db"
"github.com/stacklok/minder/internal/engine"
"github.com/stacklok/minder/internal/logger"
"github.com/stacklok/minder/internal/util"
pb "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1"
)
Expand Down Expand Up @@ -60,6 +61,10 @@ func (s *Server) ListArtifacts(ctx context.Context, in *pb.ListArtifactsRequest)
return nil, fmt.Errorf("failed to list artifacts: %w", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = provider.Name
logger.BusinessRecord(ctx).Project = projectID

return &pb.ListArtifactsResponse{Results: results}, nil
}

Expand Down Expand Up @@ -120,6 +125,12 @@ func (s *Server) GetArtifactByName(ctx context.Context, in *pb.GetArtifactByName
return nil, status.Errorf(codes.Unknown, "failed to get artifact versions: %s", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = artifact.Provider
logger.BusinessRecord(ctx).Project = artifact.ProjectID
logger.BusinessRecord(ctx).Artifact = artifact.ID
logger.BusinessRecord(ctx).Repository = artifact.RepositoryID

return &pb.GetArtifactByNameResponse{Artifact: &pb.Artifact{
ArtifactPk: artifact.ID.String(),
Owner: artifact.RepoOwner,
Expand Down Expand Up @@ -174,6 +185,12 @@ func (s *Server) GetArtifactById(ctx context.Context, in *pb.GetArtifactByIdRequ
return nil, status.Errorf(codes.Unknown, "failed to get artifact versions: %s", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = artifact.Provider
logger.BusinessRecord(ctx).Project = artifact.ProjectID
logger.BusinessRecord(ctx).Artifact = artifact.ID
logger.BusinessRecord(ctx).Repository = artifact.RepositoryID

return &pb.GetArtifactByIdResponse{Artifact: &pb.Artifact{
ArtifactPk: artifact.ID.String(),
Owner: artifact.RepoOwner,
Expand Down
7 changes: 7 additions & 0 deletions internal/controlplane/handlers_authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package controlplane

import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"

"github.com/google/uuid"
Expand All @@ -28,6 +30,7 @@ import (
"github.com/stacklok/minder/internal/auth"
"github.com/stacklok/minder/internal/db"
"github.com/stacklok/minder/internal/engine"
"github.com/stacklok/minder/internal/logger"
"github.com/stacklok/minder/internal/util"
minder "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1"
)
Expand All @@ -51,6 +54,10 @@ func lookupUserPermissions(ctx context.Context, store db.Store) auth.UserPermiss

subject := auth.GetUserSubjectFromContext(ctx)

// Attach the login sha for telemetry usage (hash of the user subject from the JWT)
loginSHA := sha256.Sum256([]byte(subject))
logger.BusinessRecord(ctx).LoginHash = hex.EncodeToString(loginSHA[:])

// read all information for user claims
userInfo, err := store.GetUserBySubject(ctx, subject)
if err != nil {
Expand Down
30 changes: 23 additions & 7 deletions internal/controlplane/handlers_oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
mcrypto "github.com/stacklok/minder/internal/crypto"
"github.com/stacklok/minder/internal/db"
"github.com/stacklok/minder/internal/engine"
"github.com/stacklok/minder/internal/logger"
"github.com/stacklok/minder/internal/util"
pb "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1"
)
Expand Down Expand Up @@ -108,13 +109,14 @@ func (s *Server) GetAuthorizationURL(ctx context.Context,
return nil, status.Errorf(codes.Unknown, "error inserting session state: %s", err)
}

// Return the authorization URL and state
url := oauthConfig.AuthCodeURL(state, oauth2.AccessTypeOffline)
// Telemetry logging
logger.BusinessRecord(ctx).Provider = provider.Name
logger.BusinessRecord(ctx).Project = projectID

response := &pb.GetAuthorizationURLResponse{
Url: url,
}
return response, nil
// Return the authorization URL and state
return &pb.GetAuthorizationURLResponse{
Url: oauthConfig.AuthCodeURL(state, oauth2.AccessTypeOffline),
}, nil
}

// ExchangeCodeForTokenCLI exchanges an OAuth2 code for a token
Expand Down Expand Up @@ -211,6 +213,10 @@ func (s *Server) ExchangeCodeForTokenCLI(ctx context.Context,
return nil, status.Errorf(codes.Unknown, "error inserting access token: %s", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = provider.Name
logger.BusinessRecord(ctx).Project = stateData.ProjectID

return &httpbody.HttpBody{
ContentType: "text/html",
Data: auth.OAuthSuccessHtml,
Expand Down Expand Up @@ -283,7 +289,7 @@ func (s *Server) StoreProviderToken(ctx context.Context,
}
encodedToken := base64.StdEncoding.EncodeToString(encryptedToken)

// additionally add owner
// additionally, add an owner
var owner sql.NullString
if in.Owner == nil {
owner = sql.NullString{Valid: false}
Expand All @@ -299,6 +305,11 @@ func (s *Server) StoreProviderToken(ctx context.Context,
} else if err != nil {
return nil, status.Errorf(codes.Internal, "error storing access token: %v", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = provider.Name
logger.BusinessRecord(ctx).Project = projectID

return &pb.StoreProviderTokenResponse{}, nil
}

Expand Down Expand Up @@ -327,5 +338,10 @@ func (s *Server) VerifyProviderTokenFrom(ctx context.Context,
}
return nil, status.Errorf(codes.Internal, "error getting access token: %v", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = provider.Name
logger.BusinessRecord(ctx).Project = projectID

return &pb.VerifyProviderTokenFromResponse{Status: "OK"}, nil
}
36 changes: 35 additions & 1 deletion internal/controlplane/handlers_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/stacklok/minder/internal/db"
"github.com/stacklok/minder/internal/engine"
"github.com/stacklok/minder/internal/engine/entities"
"github.com/stacklok/minder/internal/logger"
"github.com/stacklok/minder/internal/reconcilers"
"github.com/stacklok/minder/internal/util"
minderv1 "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1"
Expand Down Expand Up @@ -168,6 +169,11 @@ func (s *Server) CreateProfile(ctx context.Context,
log.Printf("error publishing reconciler event: %v", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = profile.Provider
logger.BusinessRecord(ctx).Project = profile.ProjectID
logger.BusinessRecord(ctx).Profile = logger.Profile{Name: profile.Name, ID: profile.ID}

return resp, nil
}

Expand Down Expand Up @@ -240,7 +246,7 @@ func (s *Server) DeleteProfile(ctx context.Context,
return nil, util.UserVisibleError(codes.InvalidArgument, "invalid profile ID")
}

_, err = s.store.GetProfileByID(ctx, parsedProfileID)
profile, err := s.store.GetProfileByID(ctx, parsedProfileID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, status.Error(codes.NotFound, "profile not found")
Expand All @@ -253,6 +259,11 @@ func (s *Server) DeleteProfile(ctx context.Context,
return nil, status.Errorf(codes.Internal, "failed to delete profile: %s", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = profile.Provider
logger.BusinessRecord(ctx).Project = profile.ProjectID
logger.BusinessRecord(ctx).Profile = logger.Profile{Name: profile.Name, ID: profile.ID}

return &minderv1.DeleteProfileResponse{}, nil
}

Expand Down Expand Up @@ -282,6 +293,10 @@ func (s *Server) ListProfiles(ctx context.Context,
resp.Profiles = append(resp.Profiles, profile)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = entityCtx.Provider.Name
logger.BusinessRecord(ctx).Project = entityCtx.Project.ID

return &resp, nil
}

Expand Down Expand Up @@ -315,6 +330,11 @@ func (s *Server) GetProfileById(ctx context.Context,
return nil, status.Errorf(codes.Internal, "failed to get profile: %s", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = entityCtx.Provider.Name
logger.BusinessRecord(ctx).Project = entityCtx.Project.ID
logger.BusinessRecord(ctx).Profile = logger.Profile{Name: prof.Name, ID: parsedProfileID}

return &minderv1.GetProfileByIdResponse{
Profile: prof,
}, nil
Expand Down Expand Up @@ -498,6 +518,11 @@ func (s *Server) GetProfileStatusByName(ctx context.Context,
// TODO: Add other entities once we have database entries for them
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = entityCtx.Provider.Name
logger.BusinessRecord(ctx).Project = entityCtx.Project.ID
logger.BusinessRecord(ctx).Profile = logger.Profile{Name: dbstat.Name, ID: dbstat.ID}

return &minderv1.GetProfileStatusByNameResponse{
ProfileStatus: &minderv1.ProfileStatus{
ProfileId: dbstat.ID.String(),
Expand Down Expand Up @@ -546,6 +571,10 @@ func (s *Server) GetProfileStatusByProject(ctx context.Context,
})
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = entityCtx.Provider.Name
logger.BusinessRecord(ctx).Project = entityCtx.Project.ID

return res, nil
}

Expand Down Expand Up @@ -685,6 +714,11 @@ func (s *Server) UpdateProfile(ctx context.Context,
log.Printf("error publishing reconciler event: %v", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = profile.Provider
logger.BusinessRecord(ctx).Project = profile.ProjectID
logger.BusinessRecord(ctx).Profile = logger.Profile{Name: profile.Name, ID: profile.ID}

return resp, nil
}

Expand Down
40 changes: 38 additions & 2 deletions internal/controlplane/handlers_repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (

"github.com/stacklok/minder/internal/db"
"github.com/stacklok/minder/internal/engine"
"github.com/stacklok/minder/internal/logger"
"github.com/stacklok/minder/internal/providers"
github "github.com/stacklok/minder/internal/providers/github"
"github.com/stacklok/minder/internal/reconcilers"
Expand All @@ -41,7 +42,7 @@ const maxFetchLimit = 100
// RegisterRepository adds repositories to the database and registers a webhook
// Once a user had enrolled in a project (they have a valid token), they can register
// repositories to be monitored by the minder by provisioning a webhook on the
// repositor(ies).
// repository(ies).
func (s *Server) RegisterRepository(ctx context.Context,
in *pb.RegisterRepositoryRequest) (*pb.RegisterRepositoryResponse, error) {
entityCtx := engine.EntityFromContext(ctx)
Expand Down Expand Up @@ -124,7 +125,7 @@ func (s *Server) RegisterRepository(ctx context.Context,
repoDBID := dbRepo.ID.String()
r.Id = &repoDBID

// publish a reconcile event for the registered repositories
// publish a reconciling event for the registered repositories
log.Printf("publishing register event for repository: %s/%s", r.Owner, r.Name)

msg, err := reconcilers.NewRepoReconcilerMessage(provider.Name, r.RepoId, projectID)
Expand All @@ -138,6 +139,11 @@ func (s *Server) RegisterRepository(ctx context.Context,
log.Printf("error publishing reconciler event: %v", err)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = provider.Name
logger.BusinessRecord(ctx).Project = projectID
logger.BusinessRecord(ctx).Repository = dbRepo.ID

return response, nil
}

Expand Down Expand Up @@ -220,6 +226,10 @@ func (s *Server) ListRepositories(ctx context.Context,
resp.Results = results
resp.Cursor = respRepoCursor.String()

// Telemetry logging
logger.BusinessRecord(ctx).Provider = provider.Name
logger.BusinessRecord(ctx).Project = projectID

return &resp, nil
}

Expand Down Expand Up @@ -250,6 +260,12 @@ func (s *Server) GetRepositoryById(ctx context.Context,
Project: &projID,
Provider: &repo.Provider,
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = repo.Provider
logger.BusinessRecord(ctx).Project = repo.ProjectID
logger.BusinessRecord(ctx).Repository = repo.ID

return &pb.GetRepositoryByIdResponse{Repository: r}, nil
}

Expand Down Expand Up @@ -297,6 +313,12 @@ func (s *Server) GetRepositoryByName(ctx context.Context,
Project: &projID,
Provider: &repo.Provider,
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = repo.Provider
logger.BusinessRecord(ctx).Project = repo.ProjectID
logger.BusinessRecord(ctx).Repository = repo.ID

return &pb.GetRepositoryByNameResponse{Repository: r}, nil
}

Expand Down Expand Up @@ -331,6 +353,11 @@ func (s *Server) DeleteRepositoryById(ctx context.Context,
return nil, err
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = repo.Provider
logger.BusinessRecord(ctx).Project = repo.ProjectID
logger.BusinessRecord(ctx).Repository = repo.ID

// return the response with the id of the deleted repository
return &pb.DeleteRepositoryByIdResponse{
RepositoryId: in.RepositoryId,
Expand Down Expand Up @@ -376,6 +403,11 @@ func (s *Server) DeleteRepositoryByName(ctx context.Context,
return nil, err
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = repo.Provider
logger.BusinessRecord(ctx).Project = repo.ProjectID
logger.BusinessRecord(ctx).Repository = repo.ID

// return the response with the name of the deleted repository
return &pb.DeleteRepositoryByNameResponse{
Name: in.Name,
Expand Down Expand Up @@ -474,6 +506,10 @@ func (s *Server) ListRemoteRepositoriesFromProvider(
out.Results = append(out.Results, repo)
}

// Telemetry logging
logger.BusinessRecord(ctx).Provider = provider.Name
logger.BusinessRecord(ctx).Project = projectID

return out, nil
}

Expand Down
Loading

0 comments on commit 4416c7f

Please sign in to comment.