func ParseFile(path, targetname, packageroot string) Target { source, err := ioutil.ReadFile(path) if err != nil { log.Error(err.Error(), util.Exiter) } yaml, err := simpleyaml.NewYaml(source) if err != nil { log.Error(fmt.Sprintf("cannot parse file %s (not a valid YAML)", path), util.Exiter) } filedir := filepath.Dir(path) rel_targetname := filepath.Base(targetname) targetdata := yaml.Get(rel_targetname) targettype, err := targetdata.Get("type").String() if err != nil { log.Error(fmt.Sprintf("target %s does not exist", targetname), util.Exiter) } var target Target switch targettype { case "lib_c": target = MakeLibCTarget(targetname, targetdata, packageroot, filedir) case "app_c": target = MakeAppCTarget(targetname, targetdata, packageroot, filedir) } return target }
// ParseConfig takes the data from a file and parses the config. func ParseConfig(data []byte) *simpleyaml.Yaml { config, err := simpleyaml.NewYaml(data) if err != nil { Log("Could not parse the configuration.", "info") } return config }
func NewYamlConfig(filename string) Configer { content, err := ioutil.ReadFile(filename) if err != nil { panic(err) } yaml, err := simpleyaml.NewYaml(content) if err != nil { panic(err) } yamlConfig := &YamlConfig{ Yaml: yaml, } return yamlConfig }
func LoadTargets(filename string) ([]Target, error) { data, error := ioutil.ReadFile(filename) if error != nil { panic(error) } yaml, error := simpleyaml.NewYaml(data) if error != nil { panic(error) } m, err := yaml.Map() if err != nil { panic(err) } var targets []Target for key, value := range m { value := value.([]interface{}) commands := make([]Runnable, len(value)) targetName := simplifyTargetName(key.(string)) targetParams, targetParamErr := findParametersInTargetName(key.(string)) if targetParamErr != nil { panic(targetParamErr) } for i := range value { commandString := value[i].(string) if commandString[0] == "="[0] { panic("Subtargets not implemented yet!") } commands[i] = Command{commandString} // commands[i] = Command{value[i].(string)} } targets = append(targets, Target{targetName, commands, targetParams}) } // for targetIndex := range targets { // for commandIndex := range targets[targetIndex].Commands { // currentCommand := targets[targetIndex].Commands[commandIndex].(string) // if currentCommand[0] != "="[0] { // continue // } // subTargetName := currentCommand[1:] // subTarget, err := FindTargetByTargetName(subTargetName, targets) // if err != nil { // fmt.Printf("Error: Using non-existent target \"%v\" as subtarget.\n", subTargetName) // fmt.Println("Valid targets are:") // for tIndex := range targets { // fmt.Println(" -", targets[tIndex].Name) // } // return nil, err // } // targets[targetIndex].Commands[commandIndex] = subTarget // } // } return targets, nil }
func TestVault(t *testing.T) { YAML := func(s string) map[interface{}]interface{} { y, err := simpleyaml.NewYaml([]byte(s)) So(err, ShouldBeNil) data, err := y.Map() So(err, ShouldBeNil) return data } ToYAML := func(tree map[interface{}]interface{}) string { y, err := yaml.Marshal(tree) So(err, ShouldBeNil) return string(y) } ReYAML := func(s string) string { return ToYAML(YAML(s)) } RunTests := func(src string) { var test, input, output string var current *string testPat := regexp.MustCompile(`^##+\s+(.*)\s*$`) convey := func() { if test != "" { Convey(test, func() { ev := &Evaluator{Tree: YAML(input)} err := ev.RunPhase(EvalPhase) So(err, ShouldBeNil) So(ToYAML(ev.Tree), ShouldEqual, ReYAML(output)) }) } } s := bufio.NewScanner(strings.NewReader(src)) for s.Scan() { if testPat.MatchString(s.Text()) { m := testPat.FindStringSubmatch(s.Text()) convey() test, input, output = m[1], "", "" continue } if s.Text() == "---" { if input == "" { current = &input } else { current = &output } continue } if current != nil { *current = *current + s.Text() + "\n" } } convey() } RunErrorTests := func(src string) { var test, input, errors string var current *string testPat := regexp.MustCompile(`^##+\s+(.*)\s*$`) convey := func() { if test != "" { Convey(test, func() { ev := &Evaluator{Tree: YAML(input)} err := ev.RunPhase(EvalPhase) So(err, ShouldNotBeNil) So(strings.Trim(err.Error(), " \t"), ShouldEqual, errors) }) } } s := bufio.NewScanner(strings.NewReader(src)) for s.Scan() { if testPat.MatchString(s.Text()) { m := testPat.FindStringSubmatch(s.Text()) convey() test, input, errors = m[1], "", "" continue } if s.Text() == "---" { if input == "" { current = &input } else { current = &errors } continue } if current != nil { *current = *current + s.Text() + "\n" } } convey() } Convey("Disconnected Vault", t, func() { os.Setenv("REDACT", "yes") RunTests(` ################################################## emits REDACTED when asked to --- secret: (( vault "secret/hand:shake" )) --- secret: REDACTED `) }) Convey("Connected Vault", t, func() { mock := httptest.NewServer( http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { if r.Header.Get("X-Vault-Token") != "sekrit-toekin" { w.WriteHeader(403) fmt.Fprintf(w, `{"errors":["missing client token"]}`) return } switch r.URL.Path { case "/v1/secret/hand": w.WriteHeader(200) fmt.Fprintf(w, `{"data":{"shake":"knock, knock"}}`) case "/v1/secret/admin": w.WriteHeader(200) fmt.Fprintf(w, `{"data":{"username":"******","password":"******"}}`) case "/v1/secret/key": w.WriteHeader(200) fmt.Fprintf(w, `{"data":{"test":"testing"}}`) case "/v1/secret/malformed": w.WriteHeader(200) fmt.Fprintf(w, `wait, this isn't JSON`) case "/v1/secret/structure": w.WriteHeader(200) fmt.Fprintf(w, `{"data":{"data":[1,2,3]}}`) default: w.WriteHeader(404) fmt.Fprintf(w, `{"errors":[]}`) } }, ), ) defer mock.Close() os.Setenv("REDACT", "") os.Setenv("VAULT_ADDR", mock.URL) os.Setenv("VAULT_TOKEN", "sekrit-toekin") RunTests(` ################################################ emits sensitive credentials --- meta: prefix: secret key: secret/key:test secret: (( vault "secret/hand:shake" )) username: (( vault "secret/admin:username" )) password: (( vault "secret/admin:password" )) prefixed: (( vault meta.prefix "/admin:password" )) key: (( vault $.meta.key )) --- meta: key: secret/key:test prefix: secret secret: knock, knock username: admin password: x12345 prefixed: x12345 key: testing `) os.Setenv("VAULT_ADDR", mock.URL) oldhome := os.Getenv("HOME") os.Setenv("HOME", "assets/home/auth") os.Setenv("VAULT_TOKEN", "") RunTests(` ########################## retrieves token transparently from ~/.vault-token --- secret: (( vault "secret/hand:shake" )) --- secret: knock, knock `) os.Setenv("VAULT_ADDR", "garbage") os.Setenv("VAULT_TOKEN", "") os.Setenv("HOME", "assets/home/svtoken") ioutil.WriteFile("assets/home/svtoken/.svtoken", []byte("vault: "+mock.URL+"\n"+ "token: sekrit-toekin\n"), 0644) RunTests(` ############################## retrieves token transparently from ~/.svtoken --- secret: (( vault "secret/hand:shake" )) --- secret: knock, knock `) /* RESET TO A VALID, AUTHENTICATED STATE */ os.Setenv("VAULT_ADDR", mock.URL) os.Setenv("HOME", "assets/home/auth") RunErrorTests(` ######################################### fails when missing its argument --- secret: (( vault )) --- 1 error(s) detected: - $.secret: vault operator requires at least one argument ######################################### fails on non-existent reference --- meta: {} secret: (( vault $.meta.key )) --- 1 error(s) detected: - $.secret: Unable to resolve ` + "`" + `meta.key` + "`" + `: ` + "`" + `$.meta.key` + "`" + ` could not be found in the datastructure #################################################### fails on map reference --- meta: key: secret/hand:shake secret: (( vault $.meta )) --- 1 error(s) detected: - $.secret: tried to look up $.meta, which is not a string scalar ################################################## fails on list reference --- meta: - first secret: (( vault $.meta )) --- 1 error(s) detected: - $.secret: tried to look up $.meta, which is not a string scalar ######################################### fails on non-existent credentials --- secret: (( vault "secret/e:noent" )) --- 1 error(s) detected: - $.secret: secret secret/e:noent not found ############################################## fails on non-string argument --- secret: (( vault 42 )) --- 1 error(s) detected: - $.secret: invalid argument 42; must be in the form path/to/secret:key ################################################# fails on non-JSON response --- secret: (( vault "secret/malformed:key" )) --- 1 error(s) detected: - $.secret: bad JSON response received from Vault: "wait, this isn't JSON" ################################################# fails on non-string data --- secret: (( vault "secret/structure:data" )) --- 1 error(s) detected: - $.secret: secret secret/structure:data is not a string `) os.Setenv("VAULT_TOKEN", "incorrect") RunErrorTests(` ##################################################### fails on a bad token --- secret: (( vault "secret/hand:shake" )) --- 1 error(s) detected: - $.secret: failed to retrieve secret/hand:shake from Vault (` + os.Getenv("VAULT_ADDR") + `): missing client token `) oldhome = os.Getenv("HOME") os.Setenv("HOME", "assets/home/unauth") os.Setenv("REDACT", "") os.Setenv("VAULT_TOKEN", "") RunErrorTests(` ################################################ fails on a missing token --- secret: (( vault "secret/hand:shake" )) --- 1 error(s) detected: - $.secret: Failed to determine Vault URL / token, and the $REDACT environment variable is not set. `) os.Setenv("HOME", oldhome) }) }