-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
524 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package v1 | ||
|
||
type ( | ||
// ComponentType represents all the types of components that Smithy supports. | ||
// ENUM(unknown, target, scanner, enricher, filter, reporter) | ||
ComponentType string | ||
|
||
// Component is a binary or a script that can be used in the context of a | ||
// workflow to generate some useful result. | ||
Component struct { | ||
// Description describes what the component will do. | ||
Description string | ||
// Name is the component name. | ||
Name string | ||
// Parameters is the list of parameters to be supplied to the component. | ||
Parameters []Parameter | ||
// Steps is the list of steps to be supplied to the component. | ||
Steps []Step | ||
// Type represents the component type. | ||
Type ComponentType | ||
} | ||
|
||
// Step represents an executing step inside a Component. | ||
Step struct { | ||
// Args is the list of arguments supplied to a component. | ||
Args []string | ||
// EnvVars is the set of environment variables key:val supplied to a component. | ||
EnvVars map[string]string | ||
// Name is the step name. | ||
Name string | ||
// Executable is the path to the entrypoint to run the component. | ||
Executable string | ||
// Images is the docker image to be run for this component. | ||
Image string | ||
// Script will be deprecated after rewriting all components. | ||
Script string | ||
} | ||
) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package v1 | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
) | ||
|
||
var ( | ||
// ErrMismatchedExpectedType is returned when the type field of a parameter | ||
// is not the same as the actual type of the value of a parameter. | ||
ErrMismatchedExpectedType = errors.New("stated parameter type different than actual value type") | ||
// ErrUnknownParameterType is returned when the type of field parameter | ||
// is not one of the expected values. | ||
ErrUnknownParameterType = errors.New("unknown parameter type") | ||
) | ||
|
||
type ( | ||
// ParameterType represents the type of parameter that can be parsed by the | ||
// system. | ||
// ENUM(string, const:string, list:string) | ||
ParameterType string | ||
|
||
// Parameter is a struct whose value must be of the type as it's defined in the | ||
// Type field. Due to the fact that this value is expected to be communicated | ||
// to external clients via JSON, which doesn't support rich types, we need to | ||
// communicate the expected value type via an enum string. Given the Golang | ||
// type system, there is no way to enforce the type restrictions via an | ||
// interface, so do all the type checks when marshaling/unmarshalling the JSON | ||
// bytes, since this type will constantly be subject to such transformations. | ||
Parameter struct { | ||
// Name is the name of the parameter. | ||
Name string | ||
// Type is the parameter type. | ||
Type ParameterType | ||
// Value is the JSON encoded/decoded value of the parameter which is decoded based its Type. | ||
Value any | ||
} | ||
) | ||
|
||
// UnmarshalJSON unmarshal JSON bytes into a Parameter object. | ||
func (p *Parameter) UnmarshalJSON(b []byte) error { | ||
partialParameter := &struct { | ||
Name string | ||
Type ParameterType | ||
}{} | ||
|
||
var err error | ||
if err = json.Unmarshal(b, partialParameter); err != nil { | ||
return err | ||
} | ||
|
||
p.Name = partialParameter.Name | ||
p.Type = partialParameter.Type | ||
|
||
switch partialParameter.Type { | ||
case ParameterTypeString, ParameterTypeConststring: | ||
parameterValueStrPtr := &struct{ Value *string }{} | ||
if err = json.Unmarshal(b, parameterValueStrPtr); err == nil { | ||
p.Value = parameterValueStrPtr.Value | ||
break | ||
} | ||
parameterValueStr := &struct{ Value string }{} | ||
err = json.Unmarshal(b, parameterValueStr) | ||
p.Value = parameterValueStr.Value | ||
case ParameterTypeListstring: | ||
parameterValue := &struct{ Value []string }{} | ||
err = json.Unmarshal(b, parameterValue) | ||
p.Value = parameterValue.Value | ||
default: | ||
err = ErrUnknownParameterType | ||
} | ||
if err != nil { | ||
return fmt.Errorf("parameter.Name: %s, parameter.Type: %s: %w", partialParameter.Name, partialParameter.Type, err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// MarshalJSON marshals the Parameter into JSON bytes. | ||
func (p *Parameter) MarshalJSON() ([]byte, error) { | ||
if err := p.Validate(); err != nil { | ||
return nil, err | ||
} | ||
|
||
b, err := json.Marshal(struct { | ||
Name string | ||
Type ParameterType | ||
Value any | ||
}{ | ||
Name: p.Name, | ||
Type: p.Type, | ||
Value: p.Value, | ||
}) | ||
if err != nil { | ||
return nil, fmt.Errorf("could not json marshal value: %w", err) | ||
} | ||
|
||
return b, nil | ||
} | ||
|
||
// Validate checks all the fields of the parameter to make sure that the type | ||
// specified matches the actual type of the value | ||
func (p *Parameter) Validate() error { | ||
_, err := ParseParameterType(string(p.Type)) | ||
if err != nil { | ||
return fmt.Errorf("could not parse parameter '%s' with type: '%s': %w", p.Name, p.Type, err) | ||
} | ||
|
||
if p.Value == nil { | ||
return nil | ||
} | ||
|
||
var correctType bool | ||
switch p.Type { | ||
case ParameterTypeString, ParameterTypeConststring: | ||
_, correctType = p.Value.(*string) | ||
if !correctType { | ||
_, correctType = p.Value.(string) | ||
} | ||
case ParameterTypeListstring: | ||
_, correctType = p.Value.([]string) | ||
default: | ||
err = ErrUnknownParameterType | ||
} | ||
|
||
if !correctType { | ||
err = ErrMismatchedExpectedType | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf( | ||
"invalid parameter '%s' with type '%s' and value '%v': %w", | ||
p.Name, | ||
p.Type, | ||
p.Value, | ||
err, | ||
) | ||
} | ||
|
||
return nil | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.