From 95b49e7061a32f007dbc096293cdcdb22bc68aa4 Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Tue, 24 Dec 2019 10:04:59 +0100 Subject: [PATCH] Add new corredor service --- pkg/app/options/corredor.go | 11 +- pkg/corredor/README.adoc | 8 + pkg/corredor/authtoken.go | 25 + pkg/corredor/conn.go | 38 + pkg/corredor/deferred.go | 1 + pkg/corredor/scripts.go | 17 + pkg/corredor/service-corredor.pb.go | 1052 +++++++++++++++++++++++++++ pkg/corredor/service.go | 335 +++++++++ 8 files changed, 1483 insertions(+), 4 deletions(-) create mode 100644 pkg/corredor/README.adoc create mode 100644 pkg/corredor/authtoken.go create mode 100644 pkg/corredor/conn.go create mode 100644 pkg/corredor/deferred.go create mode 100644 pkg/corredor/scripts.go create mode 100644 pkg/corredor/service-corredor.pb.go create mode 100644 pkg/corredor/service.go diff --git a/pkg/app/options/corredor.go b/pkg/app/options/corredor.go index ac6aaffc2..788bb14aa 100644 --- a/pkg/app/options/corredor.go +++ b/pkg/app/options/corredor.go @@ -15,15 +15,18 @@ type ( Log bool `env:"CORREDOR_LOG_ENABLED"` MaxBackoffDelay time.Duration `env:"CORREDOR_MAX_BACKOFF_DELAY"` + + DefaultExecTimeout time.Duration `env:"CORREDOR_DEFAULT_EXEC_TIMEOUT"` } ) func Corredor(pfix string) (o *CorredorOpt) { o = &CorredorOpt{ - Enabled: true, - Addr: "corredor:80", - MaxBackoffDelay: time.Minute, - Log: false, + Enabled: true, + Addr: "corredor:80", + MaxBackoffDelay: time.Minute, + DefaultExecTimeout: time.Minute, + Log: false, } fill(o, pfix) diff --git a/pkg/corredor/README.adoc b/pkg/corredor/README.adoc new file mode 100644 index 000000000..471a6b420 --- /dev/null +++ b/pkg/corredor/README.adoc @@ -0,0 +1,8 @@ +# pkg/corredor + +This package is an interface to Corredor script runner service. + +.It provides: + - Connection to Corredor service + - Subscriber service to handle events raised from Corteza services + - Scheduling service for deferred events (scheduled, interval) diff --git a/pkg/corredor/authtoken.go b/pkg/corredor/authtoken.go new file mode 100644 index 000000000..3e410515a --- /dev/null +++ b/pkg/corredor/authtoken.go @@ -0,0 +1,25 @@ +package corredor + +// Authentication token maker must be able to convert user's handle or email +// into valid authentication token with short expiration + +// Used by non-system services +func CrossServiceAuthTokenMaker() AuthTokenMaker { + return func(user string) (s string, err error) { + panic("not implemented") + return "", nil + } +} + +// InternalAuthTokenMaker used by system or by all services when running in monolith mode +func InternalAuthTokenMaker() AuthTokenMaker { + return func(user string) (s string, err error) { + panic("not implemented") + // @todo implementation + // + // DefaultUser.FindByAny(user) + // auth.TokenEncoder + + return "", nil + } +} diff --git a/pkg/corredor/conn.go b/pkg/corredor/conn.go new file mode 100644 index 000000000..2364f3d3c --- /dev/null +++ b/pkg/corredor/conn.go @@ -0,0 +1,38 @@ +package corredor + +import ( + "context" + + "go.uber.org/zap" + "go.uber.org/zap/zapgrpc" + "google.golang.org/grpc" + "google.golang.org/grpc/grpclog" + + "github.com/cortezaproject/corteza-server/pkg/app/options" +) + +// Corredor standard connector to Corredor service via gRPC +func NewConnection(ctx context.Context, opt options.CorredorOpt, logger *zap.Logger) (c *grpc.ClientConn, err error) { + if !opt.Enabled { + // Do not connect when script runner is not enabled + return + } + + if opt.Log { + // Send logs to zap + // + // waiting for https://github.com/uber-go/zap/pull/538 + grpclog.SetLogger(zapgrpc.NewLogger(logger.Named("grpc"))) + } + + var dialOpts = []grpc.DialOption{ + // @todo insecure? + grpc.WithInsecure(), + } + + if opt.MaxBackoffDelay > 0 { + dialOpts = append(dialOpts, grpc.WithBackoffMaxDelay(opt.MaxBackoffDelay)) + } + + return grpc.DialContext(ctx, opt.Addr, dialOpts...) +} diff --git a/pkg/corredor/deferred.go b/pkg/corredor/deferred.go new file mode 100644 index 000000000..3f28d564e --- /dev/null +++ b/pkg/corredor/deferred.go @@ -0,0 +1 @@ +package corredor diff --git a/pkg/corredor/scripts.go b/pkg/corredor/scripts.go new file mode 100644 index 000000000..d5bafcd2a --- /dev/null +++ b/pkg/corredor/scripts.go @@ -0,0 +1,17 @@ +package corredor + +type ( + Script struct { + Name string + Label string + Description string + Errors []string + } + + ScriptSet []*Script + + MatchedScriptSet []MatchedScript + MatchedScript struct { + script *Script + } +) diff --git a/pkg/corredor/service-corredor.pb.go b/pkg/corredor/service-corredor.pb.go new file mode 100644 index 000000000..ca58a168a --- /dev/null +++ b/pkg/corredor/service-corredor.pb.go @@ -0,0 +1,1052 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: service-corredor.proto + +package corredor + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type ExecRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Args map[string]string `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExecRequest) Reset() { *m = ExecRequest{} } +func (m *ExecRequest) String() string { return proto.CompactTextString(m) } +func (*ExecRequest) ProtoMessage() {} +func (*ExecRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{0} +} + +func (m *ExecRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExecRequest.Unmarshal(m, b) +} +func (m *ExecRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExecRequest.Marshal(b, m, deterministic) +} +func (m *ExecRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecRequest.Merge(m, src) +} +func (m *ExecRequest) XXX_Size() int { + return xxx_messageInfo_ExecRequest.Size(m) +} +func (m *ExecRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ExecRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ExecRequest proto.InternalMessageInfo + +func (m *ExecRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ExecRequest) GetArgs() map[string]string { + if m != nil { + return m.Args + } + return nil +} + +type ExecResponse struct { + Result map[string]string `protobuf:"bytes,2,rep,name=result,proto3" json:"result,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExecResponse) Reset() { *m = ExecResponse{} } +func (m *ExecResponse) String() string { return proto.CompactTextString(m) } +func (*ExecResponse) ProtoMessage() {} +func (*ExecResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{1} +} + +func (m *ExecResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExecResponse.Unmarshal(m, b) +} +func (m *ExecResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExecResponse.Marshal(b, m, deterministic) +} +func (m *ExecResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecResponse.Merge(m, src) +} +func (m *ExecResponse) XXX_Size() int { + return xxx_messageInfo_ExecResponse.Size(m) +} +func (m *ExecResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ExecResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ExecResponse proto.InternalMessageInfo + +func (m *ExecResponse) GetResult() map[string]string { + if m != nil { + return m.Result + } + return nil +} + +type ServerScriptListRequest struct { + // query by name, label, description + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + // filter by resource - exact match + Resource string `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"` + // filter by events - script must contain all specified events + Events []string `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServerScriptListRequest) Reset() { *m = ServerScriptListRequest{} } +func (m *ServerScriptListRequest) String() string { return proto.CompactTextString(m) } +func (*ServerScriptListRequest) ProtoMessage() {} +func (*ServerScriptListRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{2} +} + +func (m *ServerScriptListRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServerScriptListRequest.Unmarshal(m, b) +} +func (m *ServerScriptListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServerScriptListRequest.Marshal(b, m, deterministic) +} +func (m *ServerScriptListRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServerScriptListRequest.Merge(m, src) +} +func (m *ServerScriptListRequest) XXX_Size() int { + return xxx_messageInfo_ServerScriptListRequest.Size(m) +} +func (m *ServerScriptListRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ServerScriptListRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ServerScriptListRequest proto.InternalMessageInfo + +func (m *ServerScriptListRequest) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +func (m *ServerScriptListRequest) GetResource() string { + if m != nil { + return m.Resource + } + return "" +} + +func (m *ServerScriptListRequest) GetEvents() []string { + if m != nil { + return m.Events + } + return nil +} + +type ServerScriptListResponse struct { + Scripts []*ServerScript `protobuf:"bytes,1,rep,name=scripts,proto3" json:"scripts,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServerScriptListResponse) Reset() { *m = ServerScriptListResponse{} } +func (m *ServerScriptListResponse) String() string { return proto.CompactTextString(m) } +func (*ServerScriptListResponse) ProtoMessage() {} +func (*ServerScriptListResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{3} +} + +func (m *ServerScriptListResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServerScriptListResponse.Unmarshal(m, b) +} +func (m *ServerScriptListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServerScriptListResponse.Marshal(b, m, deterministic) +} +func (m *ServerScriptListResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServerScriptListResponse.Merge(m, src) +} +func (m *ServerScriptListResponse) XXX_Size() int { + return xxx_messageInfo_ServerScriptListResponse.Size(m) +} +func (m *ServerScriptListResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ServerScriptListResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ServerScriptListResponse proto.InternalMessageInfo + +func (m *ServerScriptListResponse) GetScripts() []*ServerScript { + if m != nil { + return m.Scripts + } + return nil +} + +type ClientScriptListRequest struct { + // query by name, label, description + Query string `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + // filter by resource - exact match + Resource string `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"` + // filter by events - script must contain all specified events + Events []string `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"` + // filter by bundle - exact match + Bundle string `protobuf:"bytes,4,opt,name=bundle,proto3" json:"bundle,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ClientScriptListRequest) Reset() { *m = ClientScriptListRequest{} } +func (m *ClientScriptListRequest) String() string { return proto.CompactTextString(m) } +func (*ClientScriptListRequest) ProtoMessage() {} +func (*ClientScriptListRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{4} +} + +func (m *ClientScriptListRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ClientScriptListRequest.Unmarshal(m, b) +} +func (m *ClientScriptListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ClientScriptListRequest.Marshal(b, m, deterministic) +} +func (m *ClientScriptListRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientScriptListRequest.Merge(m, src) +} +func (m *ClientScriptListRequest) XXX_Size() int { + return xxx_messageInfo_ClientScriptListRequest.Size(m) +} +func (m *ClientScriptListRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ClientScriptListRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ClientScriptListRequest proto.InternalMessageInfo + +func (m *ClientScriptListRequest) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +func (m *ClientScriptListRequest) GetResource() string { + if m != nil { + return m.Resource + } + return "" +} + +func (m *ClientScriptListRequest) GetEvents() []string { + if m != nil { + return m.Events + } + return nil +} + +func (m *ClientScriptListRequest) GetBundle() string { + if m != nil { + return m.Bundle + } + return "" +} + +type ClientScriptListResponse struct { + Scripts []*ClientScript `protobuf:"bytes,1,rep,name=scripts,proto3" json:"scripts,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ClientScriptListResponse) Reset() { *m = ClientScriptListResponse{} } +func (m *ClientScriptListResponse) String() string { return proto.CompactTextString(m) } +func (*ClientScriptListResponse) ProtoMessage() {} +func (*ClientScriptListResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{5} +} + +func (m *ClientScriptListResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ClientScriptListResponse.Unmarshal(m, b) +} +func (m *ClientScriptListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ClientScriptListResponse.Marshal(b, m, deterministic) +} +func (m *ClientScriptListResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientScriptListResponse.Merge(m, src) +} +func (m *ClientScriptListResponse) XXX_Size() int { + return xxx_messageInfo_ClientScriptListResponse.Size(m) +} +func (m *ClientScriptListResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ClientScriptListResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ClientScriptListResponse proto.InternalMessageInfo + +func (m *ClientScriptListResponse) GetScripts() []*ClientScript { + if m != nil { + return m.Scripts + } + return nil +} + +type BundleRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BundleRequest) Reset() { *m = BundleRequest{} } +func (m *BundleRequest) String() string { return proto.CompactTextString(m) } +func (*BundleRequest) ProtoMessage() {} +func (*BundleRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{6} +} + +func (m *BundleRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BundleRequest.Unmarshal(m, b) +} +func (m *BundleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BundleRequest.Marshal(b, m, deterministic) +} +func (m *BundleRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BundleRequest.Merge(m, src) +} +func (m *BundleRequest) XXX_Size() int { + return xxx_messageInfo_BundleRequest.Size(m) +} +func (m *BundleRequest) XXX_DiscardUnknown() { + xxx_messageInfo_BundleRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_BundleRequest proto.InternalMessageInfo + +func (m *BundleRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type BundleResponse struct { + Bundles []*Bundle `protobuf:"bytes,1,rep,name=bundles,proto3" json:"bundles,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BundleResponse) Reset() { *m = BundleResponse{} } +func (m *BundleResponse) String() string { return proto.CompactTextString(m) } +func (*BundleResponse) ProtoMessage() {} +func (*BundleResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{7} +} + +func (m *BundleResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BundleResponse.Unmarshal(m, b) +} +func (m *BundleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BundleResponse.Marshal(b, m, deterministic) +} +func (m *BundleResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BundleResponse.Merge(m, src) +} +func (m *BundleResponse) XXX_Size() int { + return xxx_messageInfo_BundleResponse.Size(m) +} +func (m *BundleResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BundleResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BundleResponse proto.InternalMessageInfo + +func (m *BundleResponse) GetBundles() []*Bundle { + if m != nil { + return m.Bundles + } + return nil +} + +type ServerScript struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Triggers []*Trigger `protobuf:"bytes,14,rep,name=triggers,proto3" json:"triggers,omitempty"` + Errors []string `protobuf:"bytes,15,rep,name=errors,proto3" json:"errors,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServerScript) Reset() { *m = ServerScript{} } +func (m *ServerScript) String() string { return proto.CompactTextString(m) } +func (*ServerScript) ProtoMessage() {} +func (*ServerScript) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{8} +} + +func (m *ServerScript) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServerScript.Unmarshal(m, b) +} +func (m *ServerScript) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServerScript.Marshal(b, m, deterministic) +} +func (m *ServerScript) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServerScript.Merge(m, src) +} +func (m *ServerScript) XXX_Size() int { + return xxx_messageInfo_ServerScript.Size(m) +} +func (m *ServerScript) XXX_DiscardUnknown() { + xxx_messageInfo_ServerScript.DiscardUnknown(m) +} + +var xxx_messageInfo_ServerScript proto.InternalMessageInfo + +func (m *ServerScript) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ServerScript) GetLabel() string { + if m != nil { + return m.Label + } + return "" +} + +func (m *ServerScript) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *ServerScript) GetTriggers() []*Trigger { + if m != nil { + return m.Triggers + } + return nil +} + +func (m *ServerScript) GetErrors() []string { + if m != nil { + return m.Errors + } + return nil +} + +type ClientScript struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Bundle string `protobuf:"bytes,4,opt,name=bundle,proto3" json:"bundle,omitempty"` + Type string `protobuf:"bytes,6,opt,name=type,proto3" json:"type,omitempty"` + Triggers []*Trigger `protobuf:"bytes,14,rep,name=triggers,proto3" json:"triggers,omitempty"` + Errors []string `protobuf:"bytes,15,rep,name=errors,proto3" json:"errors,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ClientScript) Reset() { *m = ClientScript{} } +func (m *ClientScript) String() string { return proto.CompactTextString(m) } +func (*ClientScript) ProtoMessage() {} +func (*ClientScript) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{9} +} + +func (m *ClientScript) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ClientScript.Unmarshal(m, b) +} +func (m *ClientScript) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ClientScript.Marshal(b, m, deterministic) +} +func (m *ClientScript) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientScript.Merge(m, src) +} +func (m *ClientScript) XXX_Size() int { + return xxx_messageInfo_ClientScript.Size(m) +} +func (m *ClientScript) XXX_DiscardUnknown() { + xxx_messageInfo_ClientScript.DiscardUnknown(m) +} + +var xxx_messageInfo_ClientScript proto.InternalMessageInfo + +func (m *ClientScript) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ClientScript) GetLabel() string { + if m != nil { + return m.Label + } + return "" +} + +func (m *ClientScript) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *ClientScript) GetBundle() string { + if m != nil { + return m.Bundle + } + return "" +} + +func (m *ClientScript) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *ClientScript) GetTriggers() []*Trigger { + if m != nil { + return m.Triggers + } + return nil +} + +func (m *ClientScript) GetErrors() []string { + if m != nil { + return m.Errors + } + return nil +} + +type Trigger struct { + Events []string `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` + Resources []string `protobuf:"bytes,2,rep,name=resources,proto3" json:"resources,omitempty"` + RunAs string `protobuf:"bytes,3,opt,name=runAs,proto3" json:"runAs,omitempty"` + Constraints []*TConstraint `protobuf:"bytes,4,rep,name=constraints,proto3" json:"constraints,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Trigger) Reset() { *m = Trigger{} } +func (m *Trigger) String() string { return proto.CompactTextString(m) } +func (*Trigger) ProtoMessage() {} +func (*Trigger) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{10} +} + +func (m *Trigger) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Trigger.Unmarshal(m, b) +} +func (m *Trigger) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Trigger.Marshal(b, m, deterministic) +} +func (m *Trigger) XXX_Merge(src proto.Message) { + xxx_messageInfo_Trigger.Merge(m, src) +} +func (m *Trigger) XXX_Size() int { + return xxx_messageInfo_Trigger.Size(m) +} +func (m *Trigger) XXX_DiscardUnknown() { + xxx_messageInfo_Trigger.DiscardUnknown(m) +} + +var xxx_messageInfo_Trigger proto.InternalMessageInfo + +func (m *Trigger) GetEvents() []string { + if m != nil { + return m.Events + } + return nil +} + +func (m *Trigger) GetResources() []string { + if m != nil { + return m.Resources + } + return nil +} + +func (m *Trigger) GetRunAs() string { + if m != nil { + return m.RunAs + } + return "" +} + +func (m *Trigger) GetConstraints() []*TConstraint { + if m != nil { + return m.Constraints + } + return nil +} + +type TConstraint struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Op string `protobuf:"bytes,2,opt,name=op,proto3" json:"op,omitempty"` + Value []string `protobuf:"bytes,3,rep,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TConstraint) Reset() { *m = TConstraint{} } +func (m *TConstraint) String() string { return proto.CompactTextString(m) } +func (*TConstraint) ProtoMessage() {} +func (*TConstraint) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{11} +} + +func (m *TConstraint) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TConstraint.Unmarshal(m, b) +} +func (m *TConstraint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TConstraint.Marshal(b, m, deterministic) +} +func (m *TConstraint) XXX_Merge(src proto.Message) { + xxx_messageInfo_TConstraint.Merge(m, src) +} +func (m *TConstraint) XXX_Size() int { + return xxx_messageInfo_TConstraint.Size(m) +} +func (m *TConstraint) XXX_DiscardUnknown() { + xxx_messageInfo_TConstraint.DiscardUnknown(m) +} + +var xxx_messageInfo_TConstraint proto.InternalMessageInfo + +func (m *TConstraint) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *TConstraint) GetOp() string { + if m != nil { + return m.Op + } + return "" +} + +func (m *TConstraint) GetValue() []string { + if m != nil { + return m.Value + } + return nil +} + +type Bundle struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Code string `protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Bundle) Reset() { *m = Bundle{} } +func (m *Bundle) String() string { return proto.CompactTextString(m) } +func (*Bundle) ProtoMessage() {} +func (*Bundle) Descriptor() ([]byte, []int) { + return fileDescriptor_c06bb92bf45e37e2, []int{12} +} + +func (m *Bundle) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Bundle.Unmarshal(m, b) +} +func (m *Bundle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Bundle.Marshal(b, m, deterministic) +} +func (m *Bundle) XXX_Merge(src proto.Message) { + xxx_messageInfo_Bundle.Merge(m, src) +} +func (m *Bundle) XXX_Size() int { + return xxx_messageInfo_Bundle.Size(m) +} +func (m *Bundle) XXX_DiscardUnknown() { + xxx_messageInfo_Bundle.DiscardUnknown(m) +} + +var xxx_messageInfo_Bundle proto.InternalMessageInfo + +func (m *Bundle) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Bundle) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *Bundle) GetCode() string { + if m != nil { + return m.Code + } + return "" +} + +func init() { + proto.RegisterType((*ExecRequest)(nil), "corredor.ExecRequest") + proto.RegisterMapType((map[string]string)(nil), "corredor.ExecRequest.ArgsEntry") + proto.RegisterType((*ExecResponse)(nil), "corredor.ExecResponse") + proto.RegisterMapType((map[string]string)(nil), "corredor.ExecResponse.ResultEntry") + proto.RegisterType((*ServerScriptListRequest)(nil), "corredor.ServerScriptListRequest") + proto.RegisterType((*ServerScriptListResponse)(nil), "corredor.ServerScriptListResponse") + proto.RegisterType((*ClientScriptListRequest)(nil), "corredor.ClientScriptListRequest") + proto.RegisterType((*ClientScriptListResponse)(nil), "corredor.ClientScriptListResponse") + proto.RegisterType((*BundleRequest)(nil), "corredor.BundleRequest") + proto.RegisterType((*BundleResponse)(nil), "corredor.BundleResponse") + proto.RegisterType((*ServerScript)(nil), "corredor.ServerScript") + proto.RegisterType((*ClientScript)(nil), "corredor.ClientScript") + proto.RegisterType((*Trigger)(nil), "corredor.Trigger") + proto.RegisterType((*TConstraint)(nil), "corredor.TConstraint") + proto.RegisterType((*Bundle)(nil), "corredor.Bundle") +} + +func init() { proto.RegisterFile("service-corredor.proto", fileDescriptor_c06bb92bf45e37e2) } + +var fileDescriptor_c06bb92bf45e37e2 = []byte{ + // 622 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0xd5, 0x26, 0x6e, 0x52, 0x8f, 0xdb, 0x52, 0x56, 0x6d, 0xba, 0x8a, 0x90, 0x08, 0xe6, 0x52, + 0x21, 0x35, 0x42, 0xa9, 0x50, 0xa1, 0x70, 0x69, 0x4b, 0xc5, 0xa5, 0x5c, 0x5c, 0x7e, 0xc0, 0x75, + 0x46, 0x91, 0x85, 0xf1, 0xba, 0xbb, 0xeb, 0x88, 0x8a, 0x33, 0x57, 0x38, 0x71, 0xe2, 0xc4, 0x07, + 0xf1, 0x4f, 0xc8, 0xbb, 0x6b, 0x7b, 0x21, 0x49, 0x05, 0x52, 0xb9, 0xed, 0xcc, 0xbe, 0x9d, 0x79, + 0xef, 0x65, 0x3c, 0x81, 0x81, 0x44, 0x31, 0x4f, 0x13, 0x3c, 0x48, 0xb8, 0x10, 0x38, 0xe5, 0x62, + 0x5c, 0x08, 0xae, 0x38, 0x5d, 0xaf, 0xe3, 0xf0, 0x2b, 0x81, 0xe0, 0xfc, 0x23, 0x26, 0x11, 0x5e, + 0x97, 0x28, 0x15, 0xa5, 0xe0, 0xe5, 0xf1, 0x07, 0x64, 0x64, 0x44, 0xf6, 0xfd, 0x48, 0x9f, 0xe9, + 0x21, 0x78, 0xb1, 0x98, 0x49, 0xd6, 0x19, 0x75, 0xf7, 0x83, 0xc9, 0xc3, 0x71, 0x53, 0xcc, 0x79, + 0x38, 0x3e, 0x11, 0x33, 0x79, 0x9e, 0x2b, 0x71, 0x13, 0x69, 0xf0, 0xf0, 0x08, 0xfc, 0x26, 0x45, + 0xb7, 0xa1, 0xfb, 0x1e, 0x6f, 0x6c, 0xd1, 0xea, 0x48, 0x77, 0x60, 0x6d, 0x1e, 0x67, 0x25, 0xb2, + 0x8e, 0xce, 0x99, 0xe0, 0xb8, 0xf3, 0x9c, 0x84, 0x9f, 0x09, 0x6c, 0x98, 0xc2, 0xb2, 0xe0, 0xb9, + 0x44, 0x7a, 0x0c, 0x3d, 0x81, 0xb2, 0xcc, 0x94, 0x25, 0x10, 0xfe, 0x49, 0xc0, 0xe0, 0xc6, 0x91, + 0x06, 0x19, 0x0e, 0xf6, 0xc5, 0xf0, 0x05, 0x04, 0x4e, 0xfa, 0x9f, 0x78, 0x24, 0xb0, 0x77, 0x89, + 0x62, 0x8e, 0xe2, 0x32, 0x11, 0x69, 0xa1, 0x2e, 0x52, 0xa9, 0x6a, 0x93, 0x76, 0x60, 0xed, 0xba, + 0x44, 0x51, 0x17, 0x32, 0x01, 0x1d, 0xc2, 0xba, 0x40, 0xc9, 0x4b, 0x91, 0xd4, 0xd5, 0x9a, 0x98, + 0x0e, 0xa0, 0x87, 0x73, 0xcc, 0x95, 0x64, 0xdd, 0x51, 0x77, 0xdf, 0x8f, 0x6c, 0x14, 0x5e, 0x00, + 0x5b, 0x6c, 0x62, 0x75, 0x3f, 0x85, 0xbe, 0xd4, 0x59, 0xc9, 0x88, 0x16, 0x3e, 0x68, 0x85, 0xbb, + 0x8f, 0xa2, 0x1a, 0x16, 0x7e, 0x82, 0xbd, 0xb3, 0x2c, 0xc5, 0x5c, 0xfd, 0x47, 0xca, 0x55, 0xfe, + 0xaa, 0xcc, 0xa7, 0x19, 0x32, 0x4f, 0xbf, 0xb0, 0x51, 0x25, 0x65, 0xb1, 0xf9, 0x5f, 0x48, 0x71, + 0x1f, 0xb5, 0x52, 0x1e, 0xc3, 0xe6, 0xa9, 0xae, 0x7b, 0xcb, 0x60, 0x86, 0xaf, 0x60, 0xab, 0x06, + 0xd9, 0x46, 0x4f, 0xa0, 0x6f, 0xe8, 0xd4, 0x8d, 0xb6, 0xdb, 0x46, 0x16, 0x5a, 0x03, 0xc2, 0x1f, + 0x04, 0x36, 0x5c, 0x1f, 0x97, 0xce, 0xfe, 0x0e, 0xac, 0x65, 0xf1, 0x15, 0x66, 0xf5, 0x7c, 0xe8, + 0x80, 0x8e, 0x20, 0x98, 0xa2, 0xa1, 0x9a, 0xf2, 0x9c, 0x75, 0xf5, 0x9d, 0x9b, 0xa2, 0x07, 0xb0, + 0xae, 0x44, 0x3a, 0x9b, 0xa1, 0x90, 0x6c, 0x4b, 0x33, 0xb9, 0xdf, 0x32, 0x79, 0x67, 0x6e, 0xa2, + 0x06, 0xa2, 0xcd, 0x16, 0x82, 0x0b, 0xc9, 0xee, 0x59, 0xb3, 0x75, 0x14, 0xfe, 0x24, 0xb0, 0xe1, + 0x1a, 0x74, 0xa7, 0x1c, 0x57, 0xfc, 0x92, 0x55, 0x0f, 0x75, 0x53, 0x20, 0xeb, 0x99, 0x1e, 0xd5, + 0xf9, 0xae, 0xf4, 0x7c, 0x21, 0xd0, 0xb7, 0x68, 0x67, 0xc0, 0xc8, 0x6f, 0x03, 0xf6, 0x00, 0xfc, + 0x7a, 0x08, 0xcd, 0xce, 0xf1, 0xa3, 0x36, 0x51, 0x89, 0x15, 0x65, 0x7e, 0x22, 0xad, 0x20, 0x13, + 0xd0, 0x23, 0x08, 0x12, 0x9e, 0x4b, 0x25, 0xe2, 0xb4, 0x2a, 0xe8, 0x69, 0x86, 0xbb, 0x0e, 0xc3, + 0xb3, 0xe6, 0x36, 0x72, 0x91, 0xe1, 0x1b, 0x08, 0x9c, 0xbb, 0xa5, 0xf6, 0x6e, 0x41, 0x87, 0x17, + 0xd6, 0xdb, 0x0e, 0x2f, 0xda, 0x95, 0x61, 0xbe, 0x0b, 0x13, 0x84, 0xaf, 0xa1, 0x77, 0xda, 0xd8, + 0xb7, 0x50, 0xa3, 0xb6, 0xb4, 0xe3, 0x58, 0x4a, 0xc1, 0x4b, 0xf8, 0x14, 0xad, 0x10, 0x7d, 0x9e, + 0x7c, 0x23, 0xb0, 0xe9, 0xce, 0xa4, 0xa4, 0xcf, 0xc0, 0xab, 0xb6, 0x1c, 0xdd, 0x5d, 0xba, 0x76, + 0x87, 0x83, 0xe5, 0xcb, 0x90, 0xbe, 0x05, 0xaf, 0xfa, 0x02, 0xe9, 0xa3, 0xe5, 0x3b, 0xc3, 0x59, + 0x0d, 0xc3, 0xf0, 0x36, 0x88, 0x29, 0x37, 0xf9, 0x4e, 0x60, 0xd3, 0x9d, 0x43, 0x49, 0x5f, 0x36, + 0x7a, 0xf7, 0x16, 0x3e, 0x31, 0x5b, 0x98, 0x2d, 0x5e, 0xac, 0x66, 0xb7, 0x62, 0x71, 0xb9, 0xec, + 0x56, 0xad, 0x97, 0x89, 0x0f, 0xfd, 0x4b, 0xc5, 0x45, 0x3c, 0xc3, 0xab, 0x9e, 0xfe, 0x83, 0x3b, + 0xfc, 0x15, 0x00, 0x00, 0xff, 0xff, 0xe5, 0x77, 0x9e, 0xee, 0xfa, 0x06, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// ServerScriptsClient is the client API for ServerScripts service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ServerScriptsClient interface { + // Executes server script + Exec(ctx context.Context, in *ExecRequest, opts ...grpc.CallOption) (*ExecResponse, error) + // List of server scripts + List(ctx context.Context, in *ServerScriptListRequest, opts ...grpc.CallOption) (*ServerScriptListResponse, error) +} + +type serverScriptsClient struct { + cc *grpc.ClientConn +} + +func NewServerScriptsClient(cc *grpc.ClientConn) ServerScriptsClient { + return &serverScriptsClient{cc} +} + +func (c *serverScriptsClient) Exec(ctx context.Context, in *ExecRequest, opts ...grpc.CallOption) (*ExecResponse, error) { + out := new(ExecResponse) + err := c.cc.Invoke(ctx, "/corredor.ServerScripts/Exec", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serverScriptsClient) List(ctx context.Context, in *ServerScriptListRequest, opts ...grpc.CallOption) (*ServerScriptListResponse, error) { + out := new(ServerScriptListResponse) + err := c.cc.Invoke(ctx, "/corredor.ServerScripts/List", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ServerScriptsServer is the server API for ServerScripts service. +type ServerScriptsServer interface { + // Executes server script + Exec(context.Context, *ExecRequest) (*ExecResponse, error) + // List of server scripts + List(context.Context, *ServerScriptListRequest) (*ServerScriptListResponse, error) +} + +// UnimplementedServerScriptsServer can be embedded to have forward compatible implementations. +type UnimplementedServerScriptsServer struct { +} + +func (*UnimplementedServerScriptsServer) Exec(ctx context.Context, req *ExecRequest) (*ExecResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Exec not implemented") +} +func (*UnimplementedServerScriptsServer) List(ctx context.Context, req *ServerScriptListRequest) (*ServerScriptListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method List not implemented") +} + +func RegisterServerScriptsServer(s *grpc.Server, srv ServerScriptsServer) { + s.RegisterService(&_ServerScripts_serviceDesc, srv) +} + +func _ServerScripts_Exec_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExecRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServerScriptsServer).Exec(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/corredor.ServerScripts/Exec", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServerScriptsServer).Exec(ctx, req.(*ExecRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ServerScripts_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ServerScriptListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServerScriptsServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/corredor.ServerScripts/List", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServerScriptsServer).List(ctx, req.(*ServerScriptListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _ServerScripts_serviceDesc = grpc.ServiceDesc{ + ServiceName: "corredor.ServerScripts", + HandlerType: (*ServerScriptsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Exec", + Handler: _ServerScripts_Exec_Handler, + }, + { + MethodName: "List", + Handler: _ServerScripts_List_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service-corredor.proto", +} + +// ClientScriptsClient is the client API for ClientScripts service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ClientScriptsClient interface { + // Bundles + Bundle(ctx context.Context, in *BundleRequest, opts ...grpc.CallOption) (*BundleResponse, error) + // List of client scripts + List(ctx context.Context, in *ClientScriptListRequest, opts ...grpc.CallOption) (*ClientScriptListResponse, error) +} + +type clientScriptsClient struct { + cc *grpc.ClientConn +} + +func NewClientScriptsClient(cc *grpc.ClientConn) ClientScriptsClient { + return &clientScriptsClient{cc} +} + +func (c *clientScriptsClient) Bundle(ctx context.Context, in *BundleRequest, opts ...grpc.CallOption) (*BundleResponse, error) { + out := new(BundleResponse) + err := c.cc.Invoke(ctx, "/corredor.ClientScripts/Bundle", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *clientScriptsClient) List(ctx context.Context, in *ClientScriptListRequest, opts ...grpc.CallOption) (*ClientScriptListResponse, error) { + out := new(ClientScriptListResponse) + err := c.cc.Invoke(ctx, "/corredor.ClientScripts/List", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ClientScriptsServer is the server API for ClientScripts service. +type ClientScriptsServer interface { + // Bundles + Bundle(context.Context, *BundleRequest) (*BundleResponse, error) + // List of client scripts + List(context.Context, *ClientScriptListRequest) (*ClientScriptListResponse, error) +} + +// UnimplementedClientScriptsServer can be embedded to have forward compatible implementations. +type UnimplementedClientScriptsServer struct { +} + +func (*UnimplementedClientScriptsServer) Bundle(ctx context.Context, req *BundleRequest) (*BundleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Bundle not implemented") +} +func (*UnimplementedClientScriptsServer) List(ctx context.Context, req *ClientScriptListRequest) (*ClientScriptListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method List not implemented") +} + +func RegisterClientScriptsServer(s *grpc.Server, srv ClientScriptsServer) { + s.RegisterService(&_ClientScripts_serviceDesc, srv) +} + +func _ClientScripts_Bundle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BundleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClientScriptsServer).Bundle(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/corredor.ClientScripts/Bundle", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClientScriptsServer).Bundle(ctx, req.(*BundleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ClientScripts_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClientScriptListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClientScriptsServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/corredor.ClientScripts/List", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClientScriptsServer).List(ctx, req.(*ClientScriptListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _ClientScripts_serviceDesc = grpc.ServiceDesc{ + ServiceName: "corredor.ClientScripts", + HandlerType: (*ClientScriptsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Bundle", + Handler: _ClientScripts_Bundle_Handler, + }, + { + MethodName: "List", + Handler: _ClientScripts_List_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "service-corredor.proto", +} + +// StorageClient is the client API for Storage service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type StorageClient interface { +} + +type storageClient struct { + cc *grpc.ClientConn +} + +func NewStorageClient(cc *grpc.ClientConn) StorageClient { + return &storageClient{cc} +} + +// StorageServer is the server API for Storage service. +type StorageServer interface { +} + +// UnimplementedStorageServer can be embedded to have forward compatible implementations. +type UnimplementedStorageServer struct { +} + +func RegisterStorageServer(s *grpc.Server, srv StorageServer) { + s.RegisterService(&_Storage_serviceDesc, srv) +} + +var _Storage_serviceDesc = grpc.ServiceDesc{ + ServiceName: "corredor.Storage", + HandlerType: (*StorageServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "service-corredor.proto", +} diff --git a/pkg/corredor/service.go b/pkg/corredor/service.go new file mode 100644 index 000000000..8b5d4aca0 --- /dev/null +++ b/pkg/corredor/service.go @@ -0,0 +1,335 @@ +package corredor + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/davecgh/go-spew/spew" + "github.com/pkg/errors" + "go.uber.org/zap" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + + "github.com/cortezaproject/corteza-server/pkg/app/options" + "github.com/cortezaproject/corteza-server/pkg/auth" + "github.com/cortezaproject/corteza-server/pkg/eventbus" +) + +type ( + service struct { + // stores corredor connection options + // for when we're doing lazy setup + corredorOpt options.CorredorOpt + + // list of all registered triggers + // + registered map[string][]uintptr + + ssClient ServerScriptsClient + log *zap.Logger + + eventbus eventRegistrator + jwtMaker AuthTokenMaker + } + + Event interface { + // ResourceType from resource that fired the event + ResourceType() string + + // Event that was fired + EventType() string + + // Match tests if given constraints match + // event's internal values + Match(name string, op string, values ...string) bool + + // Encode (event) to arguments passed to + // event handlers ([automation ]script runner) + Encode() (map[string][]byte, error) + + // Decodes received data back to event + Decode(map[string][]byte) error + } + + eventRegistrator interface { + Register(h eventbus.Handler, ops ...eventbus.TriggerRegOp) uintptr + Unregister(ptrs ...uintptr) + } + + AuthTokenMaker func(user string) (string, error) +) + +var ( + // Global corredor service + gService *service +) + +func Service() *service { + return gService +} + +// Start connects to Corredor & initialize service +func Start(ctx context.Context, logger *zap.Logger, opt options.CorredorOpt) (err error) { + if gService != nil { + // Prevent multiple initializations + return + } + + var ( + conn *grpc.ClientConn + ) + + if conn, err = NewConnection(ctx, opt, logger); err != nil { + return + } + + gService = NewService(conn, logger) + return +} + +func NewService(conn *grpc.ClientConn, logger *zap.Logger) *service { + return &service{ + ssClient: NewServerScriptsClient(conn), + log: logger.Named("corredor"), + registered: make(map[string][]uintptr), + eventbus: eventbus.Default(), + } +} + +func (svc *service) SetJwtMaker(fn AuthTokenMaker) { + svc.jwtMaker = fn +} + +func (svc *service) Load(ctx context.Context) (err error) { + var ( + rsp *ServerScriptListResponse + ss ScriptSet + ) + + if svc.jwtMaker == nil { + // @todo + // return errors.New("can not load corredor scripts without jwt maker") + } + + svc.log.Debug("reloading server scripts") + rsp, err = svc.ssClient.List(ctx, &ServerScriptListRequest{}, grpc.WaitForReady(true)) + if err != nil { + return errors.Wrap(err, "could not load corredor scripts") + } + + for _, script := range rsp.Scripts { + if len(script.Errors) > 0 { + continue + } + + s := &Script{ + Name: script.Name, + Label: script.Label, + Description: script.Description, + Errors: script.Errors, + } + + svc.registerTriggers(script.Name, script.Triggers...) + + svc.log.Debug( + "loaded server script", + zap.String("name", s.Name), + zap.Int("triggers", len(script.Triggers)), + ) + + ss = append(ss, s) + } + + svc.log.Info("server scripts reloaded", zap.Int("count", len(ss))) + + return +} + +func (svc service) registerTriggers(script string, tt ...*Trigger) { + var ( + ops []eventbus.TriggerRegOp + handler eventbus.Handler + err error + + log = svc.log.With(zap.String("script", script)) + ) + + if ptrs, has := svc.registered[script]; has && len(ptrs) > 0 { + // Unregister previously registered triggers + svc.eventbus.Unregister(ptrs...) + log.Debug( + "triggers unregistered", + zap.Uintptrs("triggers", ptrs), + ) + } + + // Make room for new + svc.registered[script] = make([]uintptr, 0) + + for i := range tt { + if ops, err = svc.makeTriggerRegOpts(tt[i]); err != nil { + log.Warn( + "trigger could not be registered", + zap.Error(err), + ) + + continue + } + + var runAs = tt[i].RunAs + + handler = func(ctx context.Context, ev eventbus.Event) error { + // Is this compatible event? + + if ce, ok := ev.(Event); ok { + if len(runAs) > 0 { + jwt, err := svc.jwtMaker(runAs) + if err != nil { + return err + } + + ctx = auth.SetJwtToContext(ctx, jwt) + } + + return svc.Exec(ctx, script, ce) + } + + return nil + } + + ptr := svc.eventbus.Register(handler, ops...) + + log.Debug( + "trigger registered", + zap.Uintptr("triggers", ptr), + ) + } +} + +// Exec finds and runs specific script with given event +// +// It does not do any (trigger, constraints) checking +// +// For consistency, +func (svc service) Exec(ctx context.Context, script string, event Event) (err error) { + var ( + rsp *ExecResponse + + encArgs map[string][]byte + encResults = make(map[string][]byte) + + log = svc.log.With( + zap.String("script", script), + zap.Stringer("runAs", auth.GetIdentityFromContext(ctx)), + zap.String("event", event.EventType()), + zap.String("resource", event.ResourceType()), + ) + ) + + log.Debug("triggered") + + if encArgs, err = event.Encode(); err != nil { + return + } + + // //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// + // Additional ([]byte) arguments + + req := &ExecRequest{ + Name: script, + Args: make(map[string]string), + } + + if encArgs["authUser"], err = json.Marshal(auth.GetIdentityFromContext(ctx)); err != nil { + return + } + + // Cast arguments from map[string]json.RawMessage to map[string]string + if encArgs != nil { + for key := range encArgs { + req.Args[key] = string(encArgs[key]) + } + } + + // //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// + // Additional (string) arguments + + // pass security credentials + req.Args["jwt"] = auth.GetJwtFromContext(ctx) + + // basic event/event info + req.Args["event"] = event.EventType() + req.Args["resource"] = event.ResourceType() + + // //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// + + ctx, cancel := context.WithTimeout(ctx, svc.corredorOpt.DefaultExecTimeout) + defer cancel() + + // //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// + + var header, trailer metadata.MD + rsp, err = svc.ssClient.Exec( + ctx, + req, + grpc.WaitForReady(true), + grpc.Header(&header), + grpc.Trailer(&trailer), + ) + + if err != nil { + log.Debug("corredor responded with error", zap.Error(err)) + return + } + + log.Debug("corredor responded", zap.Any("result", rsp.Result)) + + // //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// //// + + // @todo process metadata (log, errors, stacktrace) + spew.Dump("grpc exec header", header) + spew.Dump("grpc exec trailer", trailer) + + if rsp.Result == nil { + // No results + return + } + + // Cast map[string]json.RawMessage to map[string]string + for key := range rsp.Result { + encResults[key] = []byte(rsp.Result[key]) + } + + // Send results back to the event for decoding + err = event.Decode(encResults) + if err != nil { + log.Debug("could not decode results", zap.Error(err)) + return + } + + // Everything ok + return +} + +func (svc service) makeTriggerRegOpts(t *Trigger) (oo []eventbus.TriggerRegOp, err error) { + if len(t.Events) == 0 { + return nil, fmt.Errorf("can not generate trigger without at least one events") + } + if len(t.Resources) == 0 { + return nil, fmt.Errorf("can not generate trigger without at least one resource") + } + + oo = append(oo, eventbus.On(t.Events...)) + oo = append(oo, eventbus.For(t.Resources...)) + + for i := range t.Constraints { + oo = append(oo, eventbus.Constraint( + t.Constraints[i].Name, + t.Constraints[i].Op, + t.Constraints[i].Value..., + )) + } + + return +}