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

fix(code): do NOT compile single code protocol w/o request.SelfContained #5757

Open
wants to merge 7 commits into
base: dev
Choose a base branch
from
10 changes: 9 additions & 1 deletion pkg/protocols/code/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ var (
ErrCodeExecutionDeadline = errkit.New("code execution deadline exceeded").SetKind(errkit.ErrKindDeadline).Build()
)

// Request is a request for the SSL protocol
// Request is a request for the code protocol
type Request struct {
// Operators for the current request go here.
operators.Operators `yaml:",inline,omitempty"`
Expand All @@ -70,6 +70,9 @@ type Request struct {
// description: |
// Source File/Snippet
Source string `yaml:"source,omitempty" json:"source,omitempty" jsonschema:"title=source file/snippet,description=Source snippet"`
// description: |
// SelfContained specifies if the request is self-contained.
SelfContained bool `yaml:"-" json:"-"`

options *protocols.ExecutorOptions `yaml:"-" json:"-"`
preConditionCompiled *goja.Program `yaml:"-" json:"-"`
Expand Down Expand Up @@ -130,6 +133,11 @@ func (request *Request) Compile(options *protocols.ExecutorOptions) error {
}
request.preConditionCompiled = preConditionCompiled
}

if !request.options.IsMultiProtocol && !request.SelfContained {
return errorutil.NewWithTag(request.TemplateID, "could not compile single %q protocol without enabling self-contained", request.Type())
}

return nil
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/protocols/code/code_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ func TestCodeProtocol(t *testing.T) {
testutils.Init(options)
templateID := "testing-code"
request := &Request{
Engine: []string{"sh"},
Source: "echo test",
SelfContained: true,
Engine: []string{"sh"},
Source: "echo test",
}
executerOpts := testutils.NewMockExecuterOptions(options, &testutils.TemplateInfo{
ID: templateID,
Expand Down
15 changes: 10 additions & 5 deletions pkg/templates/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ func (template *Template) parseSelfContainedRequests() {
for _, request := range template.RequestsHeadless {
request.SelfContained = true
}
for _, request := range template.RequestsCode {
request.SelfContained = true
}
}

// Requests returns the total request count for the template
Expand Down Expand Up @@ -178,11 +181,12 @@ func (template *Template) compileProtocolRequests(options *protocols.ExecutorOpt

var requests []protocols.Request

if template.hasMultipleRequests() {
// when multiple requests are present preserve the order of requests and protocols
// which is already done during unmarshalling
// when multiple requests or protocols are present, preserve the
// order of requests and protocols which already done during the
// unmarshalling process or else.
if template.hasMultipleRequests() || template.hasMultipleProtocols() {
requests = template.RequestsQueue
if options.Flow == "" {
if template.hasMultipleProtocols() && options.Flow == "" {
options.IsMultiProtocol = true
}
} else {
Expand Down Expand Up @@ -430,6 +434,8 @@ func parseTemplate(data []byte, options protocols.ExecutorOptions) (*Template, e
return nil, err
}

template.parseSelfContainedRequests()

if template.Executer != nil {
if err := template.Executer.Compile(); err != nil {
return nil, errors.Wrap(err, "could not compile request")
Expand All @@ -439,7 +445,6 @@ func parseTemplate(data []byte, options protocols.ExecutorOptions) (*Template, e
if template.Executer == nil && template.CompiledWorkflow == nil {
return nil, ErrCreateTemplateExecutor
}
template.parseSelfContainedRequests()

// check if the template is verified
// only valid templates can be verified or signed
Expand Down
44 changes: 44 additions & 0 deletions pkg/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,50 @@ func (template *Template) addRequestsToQueue(keys ...string) {
}
}

// hasMultipleProtocols checks if the template has multiple protocols
func (template *Template) hasMultipleProtocols() bool {
// TODO(dwisiswant0): This should be done using something like
// `Template.GetAllProtocolRequests` method, which returns
// a slice of anything that starts off with "Requests" for
// currently supported protocols - to avoid redundancy and
// keeps it future-proof.
protocolRequests := []int{
len(template.RequestsCode),
len(template.RequestsDNS),
len(template.RequestsFile),
len(template.RequestsHeadless),
len(template.RequestsHTTP),
len(template.RequestsJavascript),
len(template.RequestsNetwork),
len(template.RequestsSSL),
len(template.RequestsWebsocket),
len(template.RequestsWHOIS),
}

var hasSingleProtocolRequests bool
dwisiswant0 marked this conversation as resolved.
Show resolved Hide resolved
for i, count := range protocolRequests {
if count > 0 {
hasSingleProtocolRequests = true
// NOTE(dwisiswant0): Take out the current index from the slice.
// This is just to check the counter below (other protocols) to
// mark that the template has multiple protocols.
protocolRequests = append(protocolRequests[:i], protocolRequests[i+1:]...)
break
}
}

// check for other protocols
if hasSingleProtocolRequests {
for _, count := range protocolRequests {
if count > 0 && hasSingleProtocolRequests {
return true
}
}
}

return false
}

// hasMultipleRequests checks if the template has multiple requests
// if so it preserves the order of the request during compile and execution
func (template *Template) hasMultipleRequests() bool {
Expand Down
Loading