Allow artifacts checksum interpolation

Fixes https://github.com/hashicorp/nomad/issues/4814
This commit is contained in:
Mahmood Ali
2018-10-30 13:24:30 -04:00
parent 4b08ef0534
commit e9fa36f9ef
4 changed files with 94 additions and 40 deletions

View File

@@ -26,3 +26,8 @@ func ReplaceEnv(arg string, environments ...map[string]string) string {
func ReplaceEnvWithPlaceHolder(arg string, placeholder string) string {
return envRe.ReplaceAllString(arg, placeholder)
}
// ContainsEnv takes an arg and returns true if if contains an environment variable reference
func ContainsEnv(arg string) bool {
return envRe.MatchString(arg)
}

View File

@@ -75,3 +75,30 @@ func TestArgs_ReplaceEnv_Chained(t *testing.T) {
t.Fatalf("ReplaceEnv(%v, %v) returned %#v; want %#v", input, envVars, act, exp)
}
}
func TestArgs_ContainsEnv(t *testing.T) {
positiveCases := []string{
"test-${env_var}",
}
for _, c := range positiveCases {
t.Run(fmt.Sprintf("positive case: %v", c), func(t *testing.T) {
if !ContainsEnv(c) {
t.Fatalf("ContainsEnv(%v) returned false; want true", c)
}
})
}
negativeCases := []string{
"test",
"test-$",
"test-${asdf",
}
for _, c := range negativeCases {
t.Run(fmt.Sprintf("positive case: %v", c), func(t *testing.T) {
if ContainsEnv(c) {
t.Fatalf("ContainsEnv(%v) returned true; want false", c)
}
})
}
}

View File

@@ -6155,51 +6155,64 @@ func (ta *TaskArtifact) Validate() error {
}
// Verify the checksum
if check, ok := ta.GetterOptions["checksum"]; ok {
check = strings.TrimSpace(check)
if check == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("checksum value cannot be empty"))
return mErr.ErrorOrNil()
}
parts := strings.Split(check, ":")
if l := len(parts); l != 2 {
mErr.Errors = append(mErr.Errors, fmt.Errorf(`checksum must be given as "type:value"; got %q`, check))
return mErr.ErrorOrNil()
}
checksumVal := parts[1]
checksumBytes, err := hex.DecodeString(checksumVal)
if err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("invalid checksum: %v", err))
return mErr.ErrorOrNil()
}
checksumType := parts[0]
expectedLength := 0
switch checksumType {
case "md5":
expectedLength = md5.Size
case "sha1":
expectedLength = sha1.Size
case "sha256":
expectedLength = sha256.Size
case "sha512":
expectedLength = sha512.Size
default:
mErr.Errors = append(mErr.Errors, fmt.Errorf("unsupported checksum type: %s", checksumType))
return mErr.ErrorOrNil()
}
if len(checksumBytes) != expectedLength {
mErr.Errors = append(mErr.Errors, fmt.Errorf("invalid %s checksum: %v", checksumType, checksumVal))
return mErr.ErrorOrNil()
}
if err := ta.validateChecksum(); err != nil {
mErr.Errors = append(mErr.Errors, err)
}
return mErr.ErrorOrNil()
}
func (ta *TaskArtifact) validateChecksum() error {
check, ok := ta.GetterOptions["checksum"]
if !ok {
return nil
}
// job struct validation occurs before interpolation resolution can be effective
// skip checking if checksum contain variable reference, and artifacts fetching will
// eventually fail at pick up time if checksum is indeed invalid
if args.ContainsEnv(check) {
return nil
}
check = strings.TrimSpace(check)
if check == "" {
return fmt.Errorf("checksum value cannot be empty")
}
parts := strings.Split(check, ":")
if l := len(parts); l != 2 {
return fmt.Errorf(`checksum must be given as "type:value"; got %q`, check)
}
checksumVal := parts[1]
checksumBytes, err := hex.DecodeString(checksumVal)
if err != nil {
return fmt.Errorf("invalid checksum: %v", err)
}
checksumType := parts[0]
expectedLength := 0
switch checksumType {
case "md5":
expectedLength = md5.Size
case "sha1":
expectedLength = sha1.Size
case "sha256":
expectedLength = sha256.Size
case "sha512":
expectedLength = sha512.Size
default:
return fmt.Errorf("unsupported checksum type: %s", checksumType)
}
if len(checksumBytes) != expectedLength {
return fmt.Errorf("invalid %s checksum: %v", checksumType, checksumVal)
}
return nil
}
const (
ConstraintDistinctProperty = "distinct_property"
ConstraintDistinctHosts = "distinct_hosts"

View File

@@ -2672,6 +2672,15 @@ func TestTaskArtifact_Validate_Checksum(t *testing.T) {
},
true,
},
{
&TaskArtifact{
GetterSource: "foo.com",
GetterOptions: map[string]string{
"checksum": "md5:${ARTIFACT_CHECKSUM}",
},
},
false,
},
}
for i, tc := range cases {