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: createdBy and updatedBy in resource & revision #49

Merged
merged 2 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
NAME=github.com/goto/entropy
VERSION=$(shell git describe --tags --always --first-parent 2>/dev/null)
COMMIT=$(shell git rev-parse --short HEAD)
PROTON_COMMIT="1d611a9efbfecfa54945906214b19b72e6fbb841"
PROTON_COMMIT="ec066344b8597f9238dbbfe3cd05532a49df59ca"
BUILD_TIME=$(shell date)
COVERAGE_DIR=coverage
BUILD_DIR=dist
Expand Down
15 changes: 8 additions & 7 deletions buf.gen.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
version: v1
plugins:
- remote: "buf.build/library/plugins/go:v1.27.1-1"
- plugin: buf.build/protocolbuffers/go:v1.30.0
out: proto
opt: paths=source_relative
- remote: "buf.build/library/plugins/go-grpc:v1.1.0-2"
- plugin: buf.build/grpc/go:v1.3.0
out: proto
opt: paths=source_relative,require_unimplemented_servers=true
- remote: buf.build/odpf/plugins/validate
out: "proto"
opt: "paths=source_relative,lang=go"
- remote: "buf.build/grpc-ecosystem/plugins/grpc-gateway:v2.11.3-1"
- plugin: buf.build/bufbuild/validate-go:v1.0.1
out: proto
opt:
- paths=source_relative
- plugin: buf.build/grpc-ecosystem/gateway:v2.15.2
out: proto
opt:
- paths=source_relative
- allow_repeated_fields_in_body=true
- remote: "buf.build/grpc-ecosystem/plugins/openapiv2:v2.11.3-1"
- plugin: buf.build/grpc-ecosystem/openapiv2:v2.15.2
out: proto
opt:
- allow_repeated_fields_in_body=true
Expand Down
1 change: 1 addition & 0 deletions core/module/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type ActionRequest struct {
Name string `json:"name"`
Params json.RawMessage `json:"params"`
Labels map[string]string `json:"labels"`
UserID string
}

// ActionDesc is a descriptor for an action supported by a module.
Expand Down
4 changes: 4 additions & 0 deletions core/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type Resource struct {
Labels map[string]string `json:"labels"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
UpdatedBy string `json:"updated_by"`
CreatedBy string `json:"created_by"`
Spec Spec `json:"spec"`
State State `json:"state"`
}
Expand All @@ -63,6 +65,7 @@ type Filter struct {
type UpdateRequest struct {
Spec Spec `json:"spec"`
Labels map[string]string `json:"labels"`
UserID string
}

type RevisionsSelector struct {
Expand All @@ -75,6 +78,7 @@ type Revision struct {
Reason string `json:"reason"`
Labels map[string]string `json:"labels"`
CreatedAt time.Time `json:"created_at"`
CreatedBy string `json:"created_by"`

Spec Spec `json:"spec"`
}
Expand Down
5 changes: 5 additions & 0 deletions core/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func (svc *Service) CreateResource(ctx context.Context, res resource.Resource) (
Name: module.CreateAction,
Params: res.Spec.Configs,
Labels: res.Labels,
UserID: res.CreatedBy,
}
res.Spec.Configs = nil

Expand All @@ -35,6 +36,7 @@ func (svc *Service) UpdateResource(ctx context.Context, urn string, req resource
Name: module.UpdateAction,
Params: req.Spec.Configs,
Labels: req.Labels,
UserID: req.UserID,
})
}

Expand Down Expand Up @@ -66,9 +68,12 @@ func (svc *Service) execAction(ctx context.Context, res resource.Resource, act m
if isCreate(act.Name) {
planned.CreatedAt = svc.clock()
planned.UpdatedAt = planned.CreatedAt
planned.CreatedBy = act.UserID
planned.UpdatedBy = act.UserID
} else {
planned.CreatedAt = res.CreatedAt
planned.UpdatedAt = svc.clock()
planned.UpdatedBy = act.UserID
}

reason := fmt.Sprintf("action:%s", act.Name)
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ require (
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/briandowns/spinner v1.18.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
github.com/charmbracelet/glamour v0.3.0 // indirect
github.com/containerd/containerd v1.6.6 // indirect
Expand Down Expand Up @@ -162,12 +162,12 @@ require (
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/term v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
golang.org/x/time v0.1.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.66.6 // indirect
Expand Down
9 changes: 6 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,9 @@ github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6
github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/charmbracelet/glamour v0.3.0 h1:3H+ZrKlSg8s+WU6V7eF2eRVYt8lCueffbi7r2+ffGkc=
Expand Down Expand Up @@ -1719,8 +1720,9 @@ golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA=
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -1909,8 +1911,9 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
22 changes: 13 additions & 9 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"google.golang.org/grpc/reflection"
"google.golang.org/protobuf/encoding/protojson"

"github.com/goto/entropy/internal/server/serverutils"
modulesv1 "github.com/goto/entropy/internal/server/v1/modules"
resourcesv1 "github.com/goto/entropy/internal/server/v1/resources"
"github.com/goto/entropy/pkg/common"
Expand Down Expand Up @@ -52,15 +53,18 @@ func Serve(ctx context.Context, httpAddr, grpcAddr string, nrApp *newrelic.Appli
grpc.StatsHandler(&ocgrpc.ServerHandler{}),
}
grpcServer := grpc.NewServer(grpcOpts...)
rpcHTTPGateway := runtime.NewServeMux(runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
MarshalOptions: protojson.MarshalOptions{
UseProtoNames: true,
EmitUnpopulated: true,
},
UnmarshalOptions: protojson.UnmarshalOptions{
DiscardUnknown: true,
},
}))
rpcHTTPGateway := runtime.NewServeMux(
runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
MarshalOptions: protojson.MarshalOptions{
UseProtoNames: true,
EmitUnpopulated: true,
},
UnmarshalOptions: protojson.UnmarshalOptions{
DiscardUnknown: true,
},
}),
runtime.WithMetadata(serverutils.ExtractRequestMetadata),
)

reflection.Register(grpcServer)

Expand Down
38 changes: 38 additions & 0 deletions internal/server/serverutils/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package serverutils

import (
"context"
"net/http"
"strings"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)

const userIDHeader = "user-id"
mabdh marked this conversation as resolved.
Show resolved Hide resolved

func GetUserIdentifier(ctx context.Context) (string, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return "", status.Errorf(codes.DataLoss, "failed to get metadata")
}

xrid := md[userIDHeader]
if len(xrid) == 0 {
return "", status.Errorf(codes.InvalidArgument, "missing '%s' header", userIDHeader)
}

userID := strings.TrimSpace(xrid[0])
if userID == "" {
return "", status.Errorf(codes.InvalidArgument, "empty '%s' header", userIDHeader)
}

return userID, nil
}

func ExtractRequestMetadata(_ context.Context, request *http.Request) metadata.MD {
header := request.Header.Get(userIDHeader)
md := metadata.Pairs(userIDHeader, header)
return md
}
3 changes: 3 additions & 0 deletions internal/server/v1/resources/mappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func resourceToProto(res resource.Resource) (*entropyv1beta1.Resource, error) {
UpdatedAt: timestamppb.New(res.UpdatedAt),
Spec: spec,
State: protoState,
CreatedBy: res.CreatedBy,
UpdatedBy: res.UpdatedBy,
}, nil
}

Expand Down Expand Up @@ -155,6 +157,7 @@ func revisionToProto(revision resource.Revision) (*entropyv1beta1.ResourceRevisi
Reason: revision.Reason,
Labels: revision.Labels,
CreatedAt: timestamppb.New(revision.CreatedAt),
CreatedBy: revision.CreatedBy,
Spec: spec,
}, nil
}
19 changes: 19 additions & 0 deletions internal/server/v1/resources/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ func (server APIServer) CreateResource(ctx context.Context, request *entropyv1be
return nil, serverutils.ToRPCError(err)
}

userIdentifier, err := serverutils.GetUserIdentifier(ctx)
if err != nil {
return nil, serverutils.ToRPCError(err)
}
res.CreatedBy = userIdentifier
res.UpdatedBy = userIdentifier

result, err := server.resourceSvc.CreateResource(ctx, *res)
if err != nil {
return nil, serverutils.ToRPCError(err)
Expand All @@ -62,9 +69,15 @@ func (server APIServer) UpdateResource(ctx context.Context, request *entropyv1be
return nil, serverutils.ToRPCError(err)
}

userIdentifier, err := serverutils.GetUserIdentifier(ctx)
if err != nil {
return nil, serverutils.ToRPCError(err)
}

updateRequest := resource.UpdateRequest{
Spec: *newSpec,
Labels: request.Labels,
UserID: userIdentifier,
}

res, err := server.resourceSvc.UpdateResource(ctx, request.GetUrn(), updateRequest)
Expand Down Expand Up @@ -139,10 +152,16 @@ func (server APIServer) ApplyAction(ctx context.Context, request *entropyv1beta1
return nil, err
}

userIdentifier, err := serverutils.GetUserIdentifier(ctx)
if err != nil {
return nil, serverutils.ToRPCError(err)
}

action := module.ActionRequest{
Name: request.GetAction(),
Params: paramsJSON,
Labels: request.Labels,
UserID: userIdentifier,
}

updatedRes, err := server.resourceSvc.ApplyAction(ctx, request.GetUrn(), action)
Expand Down
19 changes: 16 additions & 3 deletions internal/server/v1/resources/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/structpb"
Expand Down Expand Up @@ -148,7 +149,11 @@ func TestAPIServer_CreateResource(t *testing.T) {
t.Parallel()
srv := tt.setup(t)

got, err := srv.CreateResource(context.Background(), tt.request)
ctx := context.Background()
md := metadata.New(map[string]string{"user-id": "john.doe@goto.com"})
ctx = metadata.NewIncomingContext(ctx, md)

got, err := srv.CreateResource(ctx, tt.request)
if tt.wantErr != nil {
assert.Error(t, err)
assert.Truef(t, errors.Is(err, tt.wantErr), "'%s' != '%s'", tt.wantErr, err)
Expand Down Expand Up @@ -273,7 +278,11 @@ func TestAPIServer_UpdateResource(t *testing.T) {
t.Parallel()
srv := tt.setup(t)

got, err := srv.UpdateResource(context.Background(), tt.request)
ctx := context.Background()
md := metadata.New(map[string]string{"user-id": "john.doe@goto.com"})
ctx = metadata.NewIncomingContext(ctx, md)

got, err := srv.UpdateResource(ctx, tt.request)
if tt.wantErr != nil {
assert.Error(t, err)
assert.True(t, errors.Is(err, tt.wantErr))
Expand Down Expand Up @@ -647,7 +656,11 @@ func TestAPIServer_ApplyAction(t *testing.T) {
t.Parallel()
srv := tt.setup(t)

got, err := srv.ApplyAction(context.Background(), tt.request)
ctx := context.Background()
md := metadata.New(map[string]string{"user-id": "john.doe@goto.com"})
ctx = metadata.NewIncomingContext(ctx, md)

got, err := srv.ApplyAction(ctx, tt.request)
if tt.wantErr != nil {
assert.Error(t, err)
assert.True(t, errors.Is(err, tt.wantErr))
Expand Down
4 changes: 3 additions & 1 deletion internal/store/postgres/resource_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type resourceModel struct {
Project string `db:"project"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
CreatedBy string `db:"created_by"`
UpdatedBy string `db:"updated_by"`
SpecConfigs []byte `db:"spec_configs"`
StateStatus string `db:"state_status"`
StateOutput []byte `db:"state_output"`
Expand All @@ -30,7 +32,7 @@ type resourceModel struct {

func readResourceRecord(ctx context.Context, r sqlx.QueryerContext, urn string, into *resourceModel) error {
cols := []string{
"id", "urn", "kind", "project", "name", "created_at", "updated_at",
"id", "urn", "kind", "project", "name", "created_at", "updated_at", "created_by", "updated_by",
"spec_configs", "state_status", "state_output", "state_module_data",
"state_next_sync", "state_sync_result",
}
Expand Down
Loading
Loading