-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Isolate the jobspec package from the rest of Nomad (#8815)
This eases adoption of the jobspec package by other projects (e.g. terraform nomad provider, Lavant). Either by consuming directy as a library (hopefully without having go mod import rest of nomad) or by copying the package without modification. Ideally, this package will be published as an independent module. We aren't ready for that considering we'll be switching to HCLv2 "soon", but eitherway, this seems like a reasonable intermediate step if we choose to.
- Loading branch information
Mahmood Ali
authored
Sep 3, 2020
1 parent
884fe5c
commit 9fe74c9
Showing
10 changed files
with
470 additions
and
330 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,113 @@ | ||
package jobspec | ||
|
||
// These functions are copied from helper/funcs.go | ||
// added here to avoid jobspec depending on any other package | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"strings" | ||
"time" | ||
|
||
multierror "github.com/hashicorp/go-multierror" | ||
"github.com/hashicorp/hcl/hcl/ast" | ||
) | ||
|
||
// stringToPtr returns the pointer to a string | ||
func stringToPtr(str string) *string { | ||
return &str | ||
} | ||
|
||
// timeToPtr returns the pointer to a time.Duration. | ||
func timeToPtr(t time.Duration) *time.Duration { | ||
return &t | ||
} | ||
|
||
// boolToPtr returns the pointer to a boolean | ||
func boolToPtr(b bool) *bool { | ||
return &b | ||
} | ||
|
||
func checkHCLKeys(node ast.Node, valid []string) error { | ||
var list *ast.ObjectList | ||
switch n := node.(type) { | ||
case *ast.ObjectList: | ||
list = n | ||
case *ast.ObjectType: | ||
list = n.List | ||
default: | ||
return fmt.Errorf("cannot check HCL keys of type %T", n) | ||
} | ||
|
||
validMap := make(map[string]struct{}, len(valid)) | ||
for _, v := range valid { | ||
validMap[v] = struct{}{} | ||
} | ||
|
||
var result error | ||
for _, item := range list.Items { | ||
key := item.Keys[0].Token.Value().(string) | ||
if _, ok := validMap[key]; !ok { | ||
result = multierror.Append(result, fmt.Errorf( | ||
"invalid key: %s", key)) | ||
} | ||
} | ||
|
||
return result | ||
} | ||
|
||
// UnusedKeys returns a pretty-printed error if any `hcl:",unusedKeys"` is not empty | ||
func unusedKeys(obj interface{}) error { | ||
val := reflect.ValueOf(obj) | ||
if val.Kind() == reflect.Ptr { | ||
val = reflect.Indirect(val) | ||
} | ||
return unusedKeysImpl([]string{}, val) | ||
} | ||
|
||
func unusedKeysImpl(path []string, val reflect.Value) error { | ||
stype := val.Type() | ||
for i := 0; i < stype.NumField(); i++ { | ||
ftype := stype.Field(i) | ||
fval := val.Field(i) | ||
tags := strings.Split(ftype.Tag.Get("hcl"), ",") | ||
name := tags[0] | ||
tags = tags[1:] | ||
|
||
if fval.Kind() == reflect.Ptr { | ||
fval = reflect.Indirect(fval) | ||
} | ||
|
||
// struct? recurse. Add the struct's key to the path | ||
if fval.Kind() == reflect.Struct { | ||
err := unusedKeysImpl(append([]string{name}, path...), fval) | ||
if err != nil { | ||
return err | ||
} | ||
continue | ||
} | ||
|
||
// Search the hcl tags for "unusedKeys" | ||
unusedKeys := false | ||
for _, p := range tags { | ||
if p == "unusedKeys" { | ||
unusedKeys = true | ||
break | ||
} | ||
} | ||
|
||
if unusedKeys { | ||
ks, ok := fval.Interface().([]string) | ||
if ok && len(ks) != 0 { | ||
ps := "" | ||
if len(path) > 0 { | ||
ps = strings.Join(path, ".") + " " | ||
} | ||
return fmt.Errorf("%sunexpected keys %s", | ||
ps, | ||
strings.Join(ks, ", ")) | ||
} | ||
} | ||
} | ||
return nil | ||
} |
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,24 @@ | ||
package jobspec | ||
|
||
// These functions are copied from helper/funcs.go | ||
// added here to avoid jobspec depending on any other package | ||
|
||
// intToPtr returns the pointer to an int | ||
func intToPtr(i int) *int { | ||
return &i | ||
} | ||
|
||
// int8ToPtr returns the pointer to an int8 | ||
func int8ToPtr(i int8) *int8 { | ||
return &i | ||
} | ||
|
||
// int64ToPtr returns the pointer to an int | ||
func int64ToPtr(i int64) *int64 { | ||
return &i | ||
} | ||
|
||
// Uint64ToPtr returns the pointer to an uint64 | ||
func uint64ToPtr(u uint64) *uint64 { | ||
return &u | ||
} |
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
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
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
Oops, something went wrong.