From caec730248b1d9b2af3edb9817878fedf11fffb0 Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Thu, 10 Sep 2020 00:06:29 +0300 Subject: [PATCH] move out tracers Signed-off-by: Vasiliy Tolstov --- auth/auth.go | 2 +- auth/jwt/jwt.go | 151 ----------------------------- auth/noop.go | 84 ++++++++++++++++ auth/noop/noop.go | 81 ---------------- debug/trace/memory/memory.go | 90 ----------------- go.mod | 4 +- go.sum | 4 +- options.go | 4 +- server/options.go | 6 +- tracer/noop.go | 25 +++++ {debug/trace => tracer}/options.go | 2 +- {debug/trace => tracer}/trace.go | 28 +----- 12 files changed, 125 insertions(+), 356 deletions(-) delete mode 100644 auth/jwt/jwt.go create mode 100644 auth/noop.go delete mode 100644 auth/noop/noop.go delete mode 100644 debug/trace/memory/memory.go create mode 100644 tracer/noop.go rename {debug/trace => tracer}/options.go (97%) rename {debug/trace => tracer}/trace.go (83%) diff --git a/auth/auth.go b/auth/auth.go index c704f9e7..8fa5b77b 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -17,7 +17,7 @@ const ( ) var ( - DefaultAuth Auth + DefaultAuth Auth = newAuth() // ErrInvalidToken is when the token provided is not valid ErrInvalidToken = errors.New("invalid token provided") // ErrForbidden is when a user does not have the necessary scope to access a resource diff --git a/auth/jwt/jwt.go b/auth/jwt/jwt.go deleted file mode 100644 index 5fe77d5c..00000000 --- a/auth/jwt/jwt.go +++ /dev/null @@ -1,151 +0,0 @@ -// Package jwt is a jwt implementation of the auth interface -package jwt - -import ( - "sync" - "time" - - "github.com/unistack-org/micro/v3/auth" - "github.com/unistack-org/micro/v3/util/token" - "github.com/unistack-org/micro/v3/util/token/jwt" -) - -// NewAuth returns a new instance of the Auth service -func NewAuth(opts ...auth.Option) auth.Auth { - j := new(jwtAuth) - j.Init(opts...) - return j -} - -type jwtAuth struct { - options auth.Options - token token.Provider - rules []*auth.Rule - - sync.Mutex -} - -func (j *jwtAuth) String() string { - return "jwt" -} - -func (j *jwtAuth) Init(opts ...auth.Option) { - j.Lock() - defer j.Unlock() - - for _, o := range opts { - o(&j.options) - } - - j.token = jwt.NewTokenProvider( - token.WithPrivateKey(j.options.PrivateKey), - token.WithPublicKey(j.options.PublicKey), - ) -} - -func (j *jwtAuth) Options() auth.Options { - j.Lock() - defer j.Unlock() - return j.options -} - -func (j *jwtAuth) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, error) { - options := auth.NewGenerateOptions(opts...) - if len(options.Issuer) == 0 { - options.Issuer = j.Options().Issuer - } - - account := &auth.Account{ - ID: id, - Type: options.Type, - Scopes: options.Scopes, - Metadata: options.Metadata, - Issuer: options.Issuer, - } - - // generate a JWT secret which can be provided to the Token() method - // and exchanged for an access token - secret, err := j.token.Generate(account, token.WithExpiry(time.Hour*24*365)) - if err != nil { - return nil, err - } - account.Secret = secret.Token - - // return the account - return account, nil -} - -func (j *jwtAuth) Grant(rule *auth.Rule) error { - j.Lock() - defer j.Unlock() - j.rules = append(j.rules, rule) - return nil -} - -func (j *jwtAuth) Revoke(rule *auth.Rule) error { - j.Lock() - defer j.Unlock() - - rules := []*auth.Rule{} - for _, r := range j.rules { - if r.ID != rule.ID { - rules = append(rules, r) - } - } - - j.rules = rules - return nil -} - -func (j *jwtAuth) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error { - j.Lock() - defer j.Unlock() - - var options auth.VerifyOptions - for _, o := range opts { - o(&options) - } - - return auth.VerifyAccess(j.rules, acc, res) -} - -func (j *jwtAuth) Rules(opts ...auth.RulesOption) ([]*auth.Rule, error) { - j.Lock() - defer j.Unlock() - return j.rules, nil -} - -func (j *jwtAuth) Inspect(token string) (*auth.Account, error) { - return j.token.Inspect(token) -} - -func (j *jwtAuth) Token(opts ...auth.TokenOption) (*auth.Token, error) { - options := auth.NewTokenOptions(opts...) - - secret := options.RefreshToken - if len(options.Secret) > 0 { - secret = options.Secret - } - - account, err := j.token.Inspect(secret) - if err != nil { - return nil, err - } - - access, err := j.token.Generate(account, token.WithExpiry(options.Expiry)) - if err != nil { - return nil, err - } - - refresh, err := j.token.Generate(account, token.WithExpiry(options.Expiry+time.Hour)) - if err != nil { - return nil, err - } - - return &auth.Token{ - Created: access.Created, - Expiry: access.Expiry, - AccessToken: access.Token, - RefreshToken: refresh.Token, - }, nil -} diff --git a/auth/noop.go b/auth/noop.go new file mode 100644 index 00000000..e7dbbda2 --- /dev/null +++ b/auth/noop.go @@ -0,0 +1,84 @@ +package auth + +import ( + "github.com/google/uuid" +) + +func newAuth(opts ...Option) Auth { + var options Options + for _, o := range opts { + o(&options) + } + + return &noop{ + opts: options, + } +} + +type noop struct { + opts Options +} + +// String returns the name of the implementation +func (n *noop) String() string { + return "noop" +} + +// Init the auth +func (n *noop) Init(opts ...Option) { + for _, o := range opts { + o(&n.opts) + } +} + +// Options set for auth +func (n *noop) Options() Options { + return n.opts +} + +// Generate a new account +func (n *noop) Generate(id string, opts ...GenerateOption) (*Account, error) { + options := NewGenerateOptions(opts...) + + return &Account{ + ID: id, + Secret: options.Secret, + Metadata: options.Metadata, + Scopes: options.Scopes, + Issuer: n.Options().Issuer, + }, nil +} + +// Grant access to a resource +func (n *noop) Grant(rule *Rule) error { + return nil +} + +// Revoke access to a resource +func (n *noop) Revoke(rule *Rule) error { + return nil +} + +// Rules used to verify requests +func (n *noop) Rules(opts ...RulesOption) ([]*Rule, error) { + return []*Rule{}, nil +} + +// Verify an account has access to a resource +func (n *noop) Verify(acc *Account, res *Resource, opts ...VerifyOption) error { + return nil +} + +// Inspect a token +func (n *noop) Inspect(token string) (*Account, error) { + uid, err := uuid.NewRandom() + if err != nil { + return nil, err + } + return &Account{ID: uid.String(), Issuer: n.Options().Issuer}, nil +} + +// Token generation using an account id and secret +func (n *noop) Token(opts ...TokenOption) (*Token, error) { + return &Token{}, nil +} diff --git a/auth/noop/noop.go b/auth/noop/noop.go deleted file mode 100644 index 4ac670c3..00000000 --- a/auth/noop/noop.go +++ /dev/null @@ -1,81 +0,0 @@ -package noop - -import ( - "github.com/google/uuid" - "github.com/unistack-org/micro/v3/auth" -) - -func NewAuth(opts ...auth.Option) auth.Auth { - var options auth.Options - for _, o := range opts { - o(&options) - } - - return &noop{ - opts: options, - } -} - -type noop struct { - opts auth.Options -} - -// String returns the name of the implementation -func (n *noop) String() string { - return "noop" -} - -// Init the auth -func (n *noop) Init(opts ...auth.Option) { - for _, o := range opts { - o(&n.opts) - } -} - -// Options set for auth -func (n *noop) Options() auth.Options { - return n.opts -} - -// Generate a new account -func (n *noop) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, error) { - options := auth.NewGenerateOptions(opts...) - - return &auth.Account{ - ID: id, - Secret: options.Secret, - Metadata: options.Metadata, - Scopes: options.Scopes, - Issuer: n.Options().Issuer, - }, nil -} - -// Grant access to a resource -func (n *noop) Grant(rule *auth.Rule) error { - return nil -} - -// Revoke access to a resource -func (n *noop) Revoke(rule *auth.Rule) error { - return nil -} - -// Rules used to verify requests -func (n *noop) Rules(opts ...auth.RulesOption) ([]*auth.Rule, error) { - return []*auth.Rule{}, nil -} - -// Verify an account has access to a resource -func (n *noop) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error { - return nil -} - -// Inspect a token -func (n *noop) Inspect(token string) (*auth.Account, error) { - return &auth.Account{ID: uuid.New().String(), Issuer: n.Options().Issuer}, nil -} - -// Token generation using an account id and secret -func (n *noop) Token(opts ...auth.TokenOption) (*auth.Token, error) { - return &auth.Token{}, nil -} diff --git a/debug/trace/memory/memory.go b/debug/trace/memory/memory.go deleted file mode 100644 index 0a8524c0..00000000 --- a/debug/trace/memory/memory.go +++ /dev/null @@ -1,90 +0,0 @@ -package memory - -import ( - "context" - "time" - - "github.com/google/uuid" - "github.com/unistack-org/micro/v3/debug/trace" - "github.com/unistack-org/micro/v3/util/ring" -) - -type Tracer struct { - opts trace.Options - - // ring buffer of traces - buffer *ring.Buffer -} - -func (t *Tracer) Read(opts ...trace.ReadOption) ([]*trace.Span, error) { - var options trace.ReadOptions - for _, o := range opts { - o(&options) - } - - sp := t.buffer.Get(t.buffer.Size()) - - spans := make([]*trace.Span, 0, len(sp)) - - for _, span := range sp { - val := span.Value.(*trace.Span) - // skip if trace id is specified and doesn't match - if len(options.Trace) > 0 && val.Trace != options.Trace { - continue - } - spans = append(spans, val) - } - - return spans, nil -} - -func (t *Tracer) Start(ctx context.Context, name string) (context.Context, *trace.Span) { - span := &trace.Span{ - Name: name, - Trace: uuid.New().String(), - Id: uuid.New().String(), - Started: time.Now(), - Metadata: make(map[string]string), - } - - // return span if no context - if ctx == nil { - return trace.ToContext(context.Background(), span.Trace, span.Id), span - } - traceID, parentSpanID, ok := trace.FromContext(ctx) - // If the trace can not be found in the header, - // that means this is where the trace is created. - if !ok { - return trace.ToContext(ctx, span.Trace, span.Id), span - } - - // set trace id - span.Trace = traceID - // set parent - span.Parent = parentSpanID - - // return the span - return trace.ToContext(ctx, span.Trace, span.Id), span -} - -func (t *Tracer) Finish(s *trace.Span) error { - // set finished time - s.Duration = time.Since(s.Started) - // save the span - t.buffer.Put(s) - - return nil -} - -func NewTracer(opts ...trace.Option) trace.Tracer { - var options trace.Options - for _, o := range opts { - o(&options) - } - - return &Tracer{ - opts: options, - // the last 256 requests - buffer: ring.New(256), - } -} diff --git a/go.mod b/go.mod index cb74220b..44b330f9 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/unistack-org/micro/v3 -go 1.15 +go 1.14 require ( github.com/BurntSushi/toml v0.3.1 @@ -24,7 +24,7 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/stretchr/testify v1.5.1 github.com/unistack-org/micro-codec-bytes v0.0.0-20200828083432-4e49e953d844 - github.com/unistack-org/micro-config-cmd v0.0.0-20200828075439-d859b9d7265b + github.com/unistack-org/micro-config-cmd v0.0.0-20200909210346-ec89783dc46c golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a golang.org/x/net v0.0.0-20200904194848-62affa334b73 google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d diff --git a/go.sum b/go.sum index f3c35d55..9da154f1 100644 --- a/go.sum +++ b/go.sum @@ -283,8 +283,8 @@ github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4 github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/unistack-org/micro-codec-bytes v0.0.0-20200828083432-4e49e953d844 h1:5b1yuSllbsMm/9fUIlIXSr8DbsKT/sAKSCgOx6+SAfI= github.com/unistack-org/micro-codec-bytes v0.0.0-20200828083432-4e49e953d844/go.mod h1:g5sOI8TWgGZiVHe8zoUPdtz7+0oLnqTnfBoai6Qb7jE= -github.com/unistack-org/micro-config-cmd v0.0.0-20200828075439-d859b9d7265b h1:v5Ak+Sr780jZclFDnx82g5biF0N5HRVKphEpJhbnVUs= -github.com/unistack-org/micro-config-cmd v0.0.0-20200828075439-d859b9d7265b/go.mod h1:6pm1cadbwsFcEW1ZbV5Fp0i3goR3TNfROMNSPih3I8k= +github.com/unistack-org/micro-config-cmd v0.0.0-20200909210346-ec89783dc46c h1:GbcjxyOyA9tnNoe4FcnzzLDa8JwEBnQKN/7Bhd8t47I= +github.com/unistack-org/micro-config-cmd v0.0.0-20200909210346-ec89783dc46c/go.mod h1:6pm1cadbwsFcEW1ZbV5Fp0i3goR3TNfROMNSPih3I8k= github.com/unistack-org/micro/v3 v3.0.0-20200827083227-aa99378adc6e/go.mod h1:rPQbnry3nboAnMczj8B1Gzlcyv/HYoMZLgd3/3nttJ4= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA= diff --git a/options.go b/options.go index d07c59ff..73bb6fa7 100644 --- a/options.go +++ b/options.go @@ -11,7 +11,6 @@ import ( "github.com/unistack-org/micro/v3/client" "github.com/unistack-org/micro/v3/config" "github.com/unistack-org/micro/v3/debug/profile" - "github.com/unistack-org/micro/v3/debug/trace" "github.com/unistack-org/micro/v3/logger" "github.com/unistack-org/micro/v3/registry" "github.com/unistack-org/micro/v3/router" @@ -19,6 +18,7 @@ import ( "github.com/unistack-org/micro/v3/selector" "github.com/unistack-org/micro/v3/server" "github.com/unistack-org/micro/v3/store" + "github.com/unistack-org/micro/v3/tracer" "github.com/unistack-org/micro/v3/transport" ) @@ -171,7 +171,7 @@ func Registry(r registry.Registry) Option { } // Tracer sets the tracer for the service -func Tracer(t trace.Tracer) Option { +func Tracer(t tracer.Tracer) Option { return func(o *Options) { if o.Server != nil { //todo client trace diff --git a/server/options.go b/server/options.go index 60c1fcdd..abd6fb84 100644 --- a/server/options.go +++ b/server/options.go @@ -9,9 +9,9 @@ import ( "github.com/unistack-org/micro/v3/auth" "github.com/unistack-org/micro/v3/broker" "github.com/unistack-org/micro/v3/codec" - "github.com/unistack-org/micro/v3/debug/trace" "github.com/unistack-org/micro/v3/logger" "github.com/unistack-org/micro/v3/registry" + "github.com/unistack-org/micro/v3/tracer" "github.com/unistack-org/micro/v3/transport" ) @@ -19,7 +19,7 @@ type Options struct { Codecs map[string]codec.NewCodec Broker broker.Broker Registry registry.Registry - Tracer trace.Tracer + Tracer tracer.Tracer Auth auth.Auth Logger logger.Logger Transport transport.Transport @@ -149,7 +149,7 @@ func Registry(r registry.Registry) Option { } // Tracer mechanism for distributed tracking -func Tracer(t trace.Tracer) Option { +func Tracer(t tracer.Tracer) Option { return func(o *Options) { o.Tracer = t } diff --git a/tracer/noop.go b/tracer/noop.go new file mode 100644 index 00000000..4443dcce --- /dev/null +++ b/tracer/noop.go @@ -0,0 +1,25 @@ +package tracer + +import "context" + +type noop struct{} + +func (n *noop) Init(...Option) error { + return nil +} + +func (n *noop) Start(ctx context.Context, name string) (context.Context, *Span) { + return nil, nil +} + +func (n *noop) Finish(*Span) error { + return nil +} + +func (n *noop) Read(...ReadOption) ([]*Span, error) { + return nil, nil +} + +func newTracer(opts ...Option) Tracer { + return &noop{} +} diff --git a/debug/trace/options.go b/tracer/options.go similarity index 97% rename from debug/trace/options.go rename to tracer/options.go index c7a6285f..11113d6b 100644 --- a/debug/trace/options.go +++ b/tracer/options.go @@ -1,4 +1,4 @@ -package trace +package tracer type Options struct { // Size is the size of ring buffer diff --git a/debug/trace/trace.go b/tracer/trace.go similarity index 83% rename from debug/trace/trace.go rename to tracer/trace.go index 5049bd62..d4a91a89 100644 --- a/debug/trace/trace.go +++ b/tracer/trace.go @@ -1,5 +1,5 @@ // Package trace provides an interface for distributed tracing -package trace +package tracer import ( "context" @@ -8,6 +8,10 @@ import ( "github.com/unistack-org/micro/v3/metadata" ) +var ( + DefaultTracer Tracer = newTracer() +) + // Tracer is an interface for distributed tracing type Tracer interface { // Start a trace @@ -75,25 +79,3 @@ func ToContext(ctx context.Context, traceID, parentSpanID string) context.Contex spanIDKey: parentSpanID, }, true) } - -var ( - DefaultTracer Tracer = new(noop) -) - -type noop struct{} - -func (n *noop) Init(...Option) error { - return nil -} - -func (n *noop) Start(ctx context.Context, name string) (context.Context, *Span) { - return nil, nil -} - -func (n *noop) Finish(*Span) error { - return nil -} - -func (n *noop) Read(...ReadOption) ([]*Span, error) { - return nil, nil -}