func loadVarFile(rawPath string) (map[string]string, error) { path, err := homedir.Expand(rawPath) if err != nil { return nil, fmt.Errorf( "Error expanding path: %s", err) } // Read the HCL file and prepare for parsing d, err := ioutil.ReadFile(path) if err != nil { return nil, fmt.Errorf( "Error reading %s: %s", path, err) } // Parse it obj, err := hcl.Parse(string(d)) if err != nil { return nil, fmt.Errorf( "Error parsing %s: %s", path, err) } var result map[string]string if err := hcl.DecodeObject(&result, obj); err != nil { return nil, err } return result, nil }
// LoadSSHHelperConfig loads ssh-helper's configuration from the file and populates the corresponding // in-memory structure. // // Vault address is a required parameter. // Mount point defaults to "ssh". func LoadSSHHelperConfig(path string) (*SSHHelperConfig, error) { var config SSHHelperConfig contents, err := ioutil.ReadFile(path) if !os.IsNotExist(err) { obj, err := hcl.Parse(string(contents)) if err != nil { return nil, err } if err := hcl.DecodeObject(&config, obj); err != nil { return nil, err } } else { return nil, err } if config.VaultAddr == "" { return nil, fmt.Errorf("config missing vault_addr") } if config.SSHMountPoint == "" { config.SSHMountPoint = SSHHelperDefaultMountPoint } return &config, nil }
// Parse parses the detector config from the given io.Reader. // // Due to current internal limitations, the entire contents of the // io.Reader will be copied into memory first before parsing. func Parse(r io.Reader) (*Config, error) { // Copy the reader into an in-memory buffer first since HCL requires it. var buf bytes.Buffer if _, err := io.Copy(&buf, r); err != nil { return nil, err } // Parse the buffer obj, err := hcl.Parse(buf.String()) if err != nil { return nil, fmt.Errorf("error parsing: %s", err) } buf.Reset() var result Config // Parse the detects if o := obj.Get("detect", false); o != nil { if err := parseDetect(&result, o); err != nil { return nil, fmt.Errorf("error parsing 'import': %s", err) } } return &result, nil }
// ParseConfig parses the config from the given io.Reader. // // Due to current internal limitations, the entire contents of the // io.Reader will be copied into memory first before parsing. func ParseConfig(r io.Reader) (*Config, error) { // Copy the reader into an in-memory buffer first since HCL requires it. var buf bytes.Buffer if _, err := io.Copy(&buf, r); err != nil { return nil, err } // Parse the buffer root, err := hcl.Parse(buf.String()) if err != nil { return nil, fmt.Errorf("error parsing: %s", err) } buf.Reset() // Top-level item should be a list list, ok := root.Node.(*ast.ObjectList) if !ok { return nil, fmt.Errorf("error parsing: root should be an object") } var config Config if err := parseConfig(&config, list); err != nil { return nil, fmt.Errorf("error parsing 'config': %v", err) } return &config, nil }
// Parse parses the job spec from the given io.Reader. // // Due to current internal limitations, the entire contents of the // io.Reader will be copied into memory first before parsing. func Parse(r io.Reader) (*structs.Job, error) { // Copy the reader into an in-memory buffer first since HCL requires it. var buf bytes.Buffer if _, err := io.Copy(&buf, r); err != nil { return nil, err } // Parse the buffer root, err := hcl.Parse(buf.String()) if err != nil { return nil, fmt.Errorf("error parsing: %s", err) } buf.Reset() // Top-level item should be a list list, ok := root.Node.(*ast.ObjectList) if !ok { return nil, fmt.Errorf("error parsing: root should be an object") } var job structs.Job // Parse the job out matches := list.Filter("job") if len(matches.Items) == 0 { return nil, fmt.Errorf("'job' stanza not found") } if err := parseJob(&job, matches); err != nil { return nil, fmt.Errorf("error parsing 'job': %s", err) } return &job, nil }
func loadKVFile(rawPath string) (map[string]interface{}, error) { path, err := homedir.Expand(rawPath) if err != nil { return nil, fmt.Errorf( "Error expanding path: %s", err) } // Read the HCL file and prepare for parsing d, err := ioutil.ReadFile(path) if err != nil { return nil, fmt.Errorf( "Error reading %s: %s", path, err) } // Parse it obj, err := hcl.Parse(string(d)) if err != nil { return nil, fmt.Errorf( "Error parsing %s: %s", path, err) } var result map[string]interface{} if err := hcl.DecodeObject(&result, obj); err != nil { return nil, fmt.Errorf( "Error decoding Terraform vars file: %s\n\n"+ "The vars file should be in the format of `key = \"value\"`.\n"+ "Decoding errors are usually caused by an invalid format.", err) } return result, nil }
// Parse parses the job spec from the given io.Reader. // // Due to current internal limitations, the entire contents of the // io.Reader will be copied into memory first before parsing. func Parse(r io.Reader) (*structs.Job, error) { // Copy the reader into an in-memory buffer first since HCL requires it. var buf bytes.Buffer if _, err := io.Copy(&buf, r); err != nil { return nil, err } // Parse the buffer obj, err := hcl.Parse(buf.String()) if err != nil { return nil, fmt.Errorf("error parsing: %s", err) } buf.Reset() var job structs.Job // Parse the job out jobO := obj.Get("job", false) if jobO == nil { return nil, fmt.Errorf("'job' stanza not found") } if err := parseJob(&job, jobO); err != nil { return nil, fmt.Errorf("error parsing 'job': %s", err) } return &job, nil }
// LoadConfig reads the configuration from the given path. If path is // empty, then the default path will be used, or the environment variable // if set. func LoadConfig(path string) (*Config, error) { if path == "" { path = DefaultConfigPath } if v := os.Getenv(ConfigPathEnv); v != "" { path = v } path, err := homedir.Expand(path) if err != nil { return nil, fmt.Errorf("Error expanding config path: %s", err) } var config Config contents, err := ioutil.ReadFile(path) if !os.IsNotExist(err) { if err != nil { return nil, err } obj, err := hcl.Parse(string(contents)) if err != nil { return nil, err } if err := hcl.DecodeObject(&config, obj); err != nil { return nil, err } } return &config, nil }
// ParseSSHHelperConfig parses the given contents as a string for the SSHHelper // configuration. func ParseSSHHelperConfig(contents string) (*SSHHelperConfig, error) { root, err := hcl.Parse(string(contents)) if err != nil { return nil, fmt.Errorf("ssh_helper: error parsing config: %s", err) } list, ok := root.Node.(*ast.ObjectList) if !ok { return nil, fmt.Errorf("ssh_helper: error parsing config: file doesn't contain a root object") } valid := []string{ "vault_addr", "ssh_mount_point", "ca_cert", "ca_path", "allowed_cidr_list", "allowed_roles", "tls_skip_verify", } if err := checkHCLKeys(list, valid); err != nil { return nil, multierror.Prefix(err, "ssh_helper:") } var c SSHHelperConfig c.SSHMountPoint = SSHHelperDefaultMountPoint if err := hcl.DecodeObject(&c, list); err != nil { return nil, multierror.Prefix(err, "ssh_helper:") } if c.VaultAddr == "" { return nil, fmt.Errorf("ssh_helper: missing config 'vault_addr'") } return &c, nil }
// ParseClusterFromFile reads a cluster from file func ParseClusterFromFile(path string) (*Cluster, error) { data, err := ioutil.ReadFile(path) if err != nil { return nil, maskAny(err) } // Parse the input root, err := hcl.Parse(string(data)) if err != nil { return nil, maskAny(err) } // Top-level item should be a list list, ok := root.Node.(*ast.ObjectList) if !ok { return nil, errgo.New("error parsing: root should be an object") } matches := list.Filter("cluster") if len(matches.Items) == 0 { return nil, errgo.New("'cluster' stanza not found") } // Parse hcl into Cluster cluster := &Cluster{} if err := cluster.parse(matches); err != nil { return nil, maskAny(err) } cluster.setDefaults() // Validate the cluster if err := cluster.validate(); err != nil { return nil, maskAny(err) } return cluster, nil }
func main() { for i, arg := range os.Args { if i == 0 { continue } search := arg if info, err := os.Stat(arg); err == nil && info.IsDir() { search = fmt.Sprintf("%s/*.tf", arg) } files, err := filepath.Glob(search) if err != nil { colorstring.Printf("[red]Error finding files: %s", err) } for _, filename := range files { fmt.Printf("Checking %s ... ", filename) file, err := ioutil.ReadFile(filename) if err != nil { colorstring.Printf("[red]Error reading file: %s\n", err) break } _, err = hcl.Parse(string(file)) if err != nil { colorstring.Printf("[red]Error parsing file: %s\n", err) break } colorstring.Printf("[green]OK!\n") } } }
// ParseConfig parses the given configuration as a string. func ParseConfig(contents string) (*DefaultConfig, error) { root, err := hcl.Parse(contents) if err != nil { return nil, err } // Top-level item should be the object list list, ok := root.Node.(*ast.ObjectList) if !ok { return nil, fmt.Errorf("Failed to parse config: does not contain a root object") } valid := []string{ "token_helper", } if err := checkHCLKeys(list, valid); err != nil { return nil, err } var c DefaultConfig if err := hcl.DecodeObject(&c, list); err != nil { return nil, err } return &c, nil }
// Parse parses the detector config from the given io.Reader. // // Due to current internal limitations, the entire contents of the // io.Reader will be copied into memory first before parsing. func Parse(r io.Reader) (*Config, error) { // Copy the reader into an in-memory buffer first since HCL requires it. var buf bytes.Buffer if _, err := io.Copy(&buf, r); err != nil { return nil, err } // Parse the buffer root, err := hcl.Parse(buf.String()) if err != nil { return nil, fmt.Errorf("error parsing: %s", err) } buf.Reset() // Top-level item should be the object list list, ok := root.Node.(*ast.ObjectList) if !ok { return nil, fmt.Errorf("error parsing: file doesn't contain a root object") } var result Config // Parse the detects if o := list.Filter("detect"); len(o.Items) > 0 { if err := parseDetect(&result, o); err != nil { return nil, fmt.Errorf("error parsing 'import': %s", err) } } return &result, nil }
// LoadConfigFile loads the configuration from the given file. func LoadConfigFile(path string) (*Config, error) { // Read the file d, err := ioutil.ReadFile(path) if err != nil { return nil, err } // Parse! obj, err := hcl.Parse(string(d)) if err != nil { return nil, err } // Start building the result var result Config if err := hcl.DecodeObject(&result, obj); err != nil { return nil, err } if objs := obj.Get("listener", false); objs != nil { result.Listeners, err = loadListeners(objs) if err != nil { return nil, err } } if objs := obj.Get("backend", false); objs != nil { result.Backend, err = loadBackend(objs) if err != nil { return nil, err } } return &result, nil }
// ParseJob takes input from a given reader and parses it into a Job. func parseJob(input []byte, jf *jobFunctions) (*Job, error) { // Create a template, add the function map, and parse the text. tmpl, err := template.New("job").Funcs(jf.Functions()).Parse(string(input)) if err != nil { return nil, maskAny(err) } // Run the template to verify the output. buffer := &bytes.Buffer{} err = tmpl.Execute(buffer, jf.Options()) if err != nil { return nil, maskAny(err) } // Parse the input root, err := hcl.Parse(buffer.String()) if err != nil { return nil, maskAny(err) } // Top-level item should be a list list, ok := root.Node.(*ast.ObjectList) if !ok { return nil, errgo.New("error parsing: root should be an object") } // Parse hcl into Job job := &Job{} matches := list.Filter("job") if len(matches.Items) == 0 { return nil, maskAny(errgo.WithCausef(nil, ValidationError, "'job' stanza not found")) } if err := job.parse(matches); err != nil { return nil, maskAny(err) } // Link internal structures job.prelink() // Set defaults job.setDefaults(jf.cluster) // Replace variables if err := job.replaceVariables(); err != nil { return nil, maskAny(err) } // Sort internal structures and make final links job.link() // Optimize job for cluster job.optimizeFor(jf.cluster) // Validate the job if err := job.Validate(); err != nil { return nil, maskAny(err) } return job, nil }
// LoadConfigFile loads the configuration from the given file. func LoadConfigFile(path string) (*Config, error) { // Read the file d, err := ioutil.ReadFile(path) if err != nil { return nil, err } // Parse! obj, err := hcl.Parse(string(d)) if err != nil { return nil, err } // Start building the result var result Config if err := hcl.DecodeObject(&result, obj); err != nil { return nil, err } if result.MaxLeaseDurationRaw != "" { if result.MaxLeaseDuration, err = time.ParseDuration(result.MaxLeaseDurationRaw); err != nil { return nil, err } } if result.DefaultLeaseDurationRaw != "" { if result.DefaultLeaseDuration, err = time.ParseDuration(result.DefaultLeaseDurationRaw); err != nil { return nil, err } } if objs := obj.Get("listener", false); objs != nil { result.Listeners, err = loadListeners(objs) if err != nil { return nil, err } } if objs := obj.Get("backend", false); objs != nil { result.Backend, err = loadBackend(objs) if err != nil { return nil, err } } // A little hacky but upgrades the old stats config directives to the new way if result.Telemetry == nil { statsdAddr := obj.Get("statsd_addr", false) statsiteAddr := obj.Get("statsite_addr", false) if statsdAddr != nil || statsiteAddr != nil { result.Telemetry = &Telemetry{ StatsdAddr: getString(statsdAddr), StatsiteAddr: getString(statsiteAddr), } } } return &result, nil }
func ParseConfig(configBytes []byte, filename string) (*Config, error) { rawConfigFile, err := hcl.Parse(string(configBytes)) if err != nil { return nil, err } rawConfig := rawConfigFile.Node return NewConfigFromHCL(rawConfig.(*ast.ObjectList), filename) }
func unmarshallConfigReader(in io.Reader, c map[string]interface{}, configType string) error { buf := new(bytes.Buffer) buf.ReadFrom(in) switch strings.ToLower(configType) { case "yaml", "yml": if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil { return ConfigParseError{err} } case "json": if err := json.Unmarshal(buf.Bytes(), &c); err != nil { return ConfigParseError{err} } case "hcl": obj, err := hcl.Parse(string(buf.Bytes())) if err != nil { return ConfigParseError{err} } if err = hcl.DecodeObject(&c, obj); err != nil { return ConfigParseError{err} } case "toml": tree, err := toml.LoadReader(buf) if err != nil { return ConfigParseError{err} } tmap := tree.ToMap() for k, v := range tmap { c[k] = v } case "properties", "props", "prop": var p *properties.Properties var err error if p, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil { return ConfigParseError{err} } for _, key := range p.Keys() { value, _ := p.Get(key) // recursively build nested maps path := strings.Split(key, ".") lastKey := strings.ToLower(path[len(path)-1]) deepestMap := deepSearch(c, path[0:len(path)-1]) // set innermost value deepestMap[lastKey] = value } } insensitiviseMap(c) return nil }
// parseVarFlagAsHCL parses the value of a single variable as would have been specified // on the command line via -var or in an environment variable named TF_VAR_x, where x is // the name of the variable. In order to get around the restriction of HCL requiring a // top level object, we prepend a sentinel key, decode the user-specified value as its // value and pull the value back out of the resulting map. func parseVarFlagAsHCL(input string) (string, interface{}, error) { idx := strings.Index(input, "=") if idx == -1 { return "", nil, fmt.Errorf("No '=' value in variable: %s", input) } probablyName := input[0:idx] parsed, err := hcl.Parse(input) if err != nil { value := input[idx+1:] // If it didn't parse as HCL, we check if it doesn't match our // whitelist of TF-accepted HCL types for inputs. If not, then // we let it through as a raw string. trimmed := strings.TrimSpace(value) if !varFlagHCLRe.MatchString(trimmed) { return probablyName, value, nil } // This covers flags of the form `foo=bar` which is not valid HCL // At this point, probablyName is actually the name, and the remainder // of the expression after the equals sign is the value. if regexp.MustCompile(`Unknown token: \d+:\d+ IDENT`).Match([]byte(err.Error())) { return probablyName, value, nil } return "", nil, fmt.Errorf("Cannot parse value for variable %s (%q) as valid HCL: %s", probablyName, input, err) } var decoded map[string]interface{} if hcl.DecodeObject(&decoded, parsed); err != nil { return "", nil, fmt.Errorf("Cannot parse value for variable %s (%q) as valid HCL: %s", probablyName, input, err) } // Cover cases such as key= if len(decoded) == 0 { return probablyName, "", nil } if len(decoded) > 1 { return "", nil, fmt.Errorf("Cannot parse value for variable %s (%q) as valid HCL. Only one value may be specified.", probablyName, input) } for k, v := range decoded { return k, v, nil } // Should be unreachable return "", nil, fmt.Errorf("No value for variable: %s", input) }
// LoadJSON loads a single Terraform configuration from a given JSON document. // // The document must be a complete Terraform configuration. This function will // NOT try to load any additional modules so only the given document is loaded. func LoadJSON(raw json.RawMessage) (*Config, error) { obj, err := hcl.Parse(string(raw)) if err != nil { return nil, fmt.Errorf( "Error parsing JSON document as HCL: %s", err) } // Start building the result hclConfig := &hclConfigurable{ Object: obj, } return hclConfig.Config() }
func unmarshallConfigReader(in io.Reader, c map[string]interface{}, configType string) error { buf := new(bytes.Buffer) buf.ReadFrom(in) switch strings.ToLower(configType) { case "yaml", "yml": if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil { return ConfigParseError{err} } case "json": if err := json.Unmarshal(buf.Bytes(), &c); err != nil { return ConfigParseError{err} } case "hcl": obj, err := hcl.Parse(string(buf.Bytes())) if err != nil { return ConfigParseError{err} } if err = hcl.DecodeObject(&c, obj); err != nil { return ConfigParseError{err} } case "toml": tree, err := toml.LoadReader(buf) if err != nil { return ConfigParseError{err} } tmap := tree.ToMap() for k, v := range tmap { c[k] = v } case "properties", "props", "prop": var p *properties.Properties var err error if p, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil { return ConfigParseError{err} } for _, key := range p.Keys() { value, _ := p.Get(key) c[key] = value } } insensitiviseMap(c) return nil }
// LoadConfigString is used to parse a config string func LoadConfigString(s string) (*Config, error) { // Parse! obj, err := hcl.Parse(s) if err != nil { return nil, err } // Start building the result var result Config if err := hcl.DecodeObject(&result, obj); err != nil { return nil, err } return &result, nil }
func LoadConfig(path string) (*Config, error) { d, err := ioutil.ReadFile(path) if err != nil { return nil, fmt.Errorf("Error reading %s: %s", path, err) } obj, err := hcl.Parse(string(d)) if err != nil { return nil, fmt.Errorf("Error parsing %s: %s", path, err) } var result Config if err := hcl.DecodeObject(&result, obj); err != nil { return nil, err } if result.Addr == "" { return nil, fmt.Errorf("addr config is required") } if result.SessionKey == "" { return nil, fmt.Errorf("session_key config is required") } if result.Auth.Service == "" { return nil, fmt.Errorf("auth.serviresult. result.nfig is required") } if result.Auth.ClientID == "" { return nil, fmt.Errorf("auth.result.ient_id result.nfig is required") } if result.Auth.ClientSecret == "" { return nil, fmt.Errorf("auth.result.ient_seresult.et result.nfig is required") } if result.Auth.RedirectUrl == "" { return nil, fmt.Errorf("auth.redireresult._url result.nfig is required") } if result.Auth.Service == "github" && result.Auth.Endpoint == "" { result.Auth.Endpoint = "https://github.com" } if result.Auth.Service == "github" && result.Auth.ApiEndpoint == "" { result.Auth.ApiEndpoint = "https://api.github.com" } return &result, nil }
// NewConfig reads configuration from path. The format is deduced from the file extension // * .json - is decoded as json // * .yml - is decoded as yaml // * .toml - is decoded as toml // * .hcl - is decoded as hcl func NewConfig(path string) (*Config, error) { _, err := os.Stat(path) if err != nil { return nil, err } data, err := ioutil.ReadFile(path) if err != nil { return nil, err } cfg := &Config{} switch filepath.Ext(path) { case ".json": jerr := json.Unmarshal(data, cfg) if jerr != nil { return nil, jerr } case ".toml": _, terr := toml.Decode(string(data), cfg) if terr != nil { return nil, terr } case ".yml": yerr := yaml.Unmarshal(data, cfg) if yerr != nil { return nil, yerr } case ".hcl": obj, herr := hcl.Parse(string(data)) if herr != nil { return nil, herr } if herr = hcl.DecodeObject(&cfg, obj); herr != nil { return nil, herr } default: return nil, errCfgUnsupported } err = cfg.SyncEnv() if err != nil { return nil, err } return cfg, nil }
// LoadRoutesFile loads routes from a json file. Example of the routes file. // { // "routes": [ // "get,post;/hello;Sample.Hello", // "get,post;/about;Hello.About" // ] // } // // supported formats are json, toml, yaml and hcl with extension .json, .toml, .yml and .hcl respectively. // //TODO refactor the decoding part to a separate function? This part shares the same logic as the // one found in NewConfig() func (r *Router) LoadRoutesFile(file string) error { rFile := &routeFile{} data, err := ioutil.ReadFile(file) if err != nil { return err } switch filepath.Ext(file) { case ".json": err = json.Unmarshal(data, rFile) if err != nil { return err } case ".toml": _, err = toml.Decode(string(data), rFile) if err != nil { return err } case ".yml": err = yaml.Unmarshal(data, rFile) if err != nil { return err } case ".hcl": obj, err := hcl.Parse(string(data)) if err != nil { return err } if err = hcl.DecodeObject(&rFile, obj); err != nil { return err } default: return errors.New("utron: unsupported file format") } for _, v := range rFile.Routes { parsedRoute, perr := splitRoutes(v) if perr != nil { // TODO: log error? continue } r.routes = append(r.routes, parsedRoute) } return nil }
func unmarshallConfigReader(in io.Reader, c map[string]interface{}, configType string) error { buf := new(bytes.Buffer) buf.ReadFrom(in) switch strings.ToLower(configType) { case "yaml", "yml": if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil { return ConfigParseError{err} } case "json": if err := json.Unmarshal(buf.Bytes(), &c); err != nil { return ConfigParseError{err} } case "hcl": obj, err := hcl.Parse(string(buf.Bytes())) if err != nil { return ConfigParseError{err} } if err = hcl.DecodeObject(&c, obj); err != nil { return ConfigParseError{err} } case "toml": if _, err := toml.Decode(buf.String(), &c); err != nil { return ConfigParseError{err} } case "properties", "props", "prop": var p *properties.Properties var err error if p, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil { return ConfigParseError{err} } if err = p.Decode(&c); err != nil { return ConfigParseError{err} } } insensitiviseMap(c) return nil }
func ParseConfig(hclText string) (*Config, error) { config := &Config{} var errors *multierror.Error hclParseTree, err := hcl.Parse(hclText) //log.Println(spew.Sdump(hclParseTree)) if err != nil { return nil, err } config.Version = parseVersion(hclParseTree, errors) config.JobStore = parseJobStore(hclParseTree, errors) config.Jobs = parseJobs(hclParseTree, errors) //log.Println(spew.Sdump(config.Jobs)) return config, nil }
// Load loads the configuration from ".qubotrc" files. func Load(path string) (*qubot.Config, error) { // Read the HCL file and prepare for parsing d, err := ioutil.ReadFile(path) if err != nil { return nil, fmt.Errorf("Error reading %s: %s", path, err) } // Parse it obj, err := hcl.Parse(string(d)) if err != nil { return nil, fmt.Errorf( "Error parsing %s: %s", path, err) } // Build up the result var result qubot.Config if err := hcl.DecodeObject(&result, obj); err != nil { return nil, err } return &result, nil }
// Parse is used to parse the specified ACL rules into an // intermediary set of policies, before being compiled into // the ACL func Parse(rules string) (*Policy, error) { // Parse the rules root, err := hcl.Parse(rules) if err != nil { return nil, fmt.Errorf("Failed to parse policy: %s", err) } // Top-level item should be the object list list, ok := root.Node.(*ast.ObjectList) if !ok { return nil, fmt.Errorf("Failed to parse policy: does not contain a root object") } // Check for invalid top-level keys valid := []string{ "name", "path", } if err := checkHCLKeys(list, valid); err != nil { return nil, fmt.Errorf("Failed to parse policy: %s", err) } // Create the initial policy and store the raw text of the rules var p Policy p.Raw = rules if err := hcl.DecodeObject(&p, list); err != nil { return nil, fmt.Errorf("Failed to parse policy: %s", err) } if o := list.Filter("path"); len(o.Items) > 0 { if err := parsePaths(&p, o); err != nil { return nil, fmt.Errorf("Failed to parse policy: %s", err) } } return &p, nil }
// Parse 解析发现的配置 // // 由于当前内部限制,配置文件的实体内容在解析前会先 // 拷贝到内存 func Parse(r io.Reader) (*Config, error) { // 在使用HCL进行解析之前,首先拷贝文件内容到内存缓冲 var buf bytes.Buffer if _, err := io.Copy(&buf, r); err != nil { return nil, err } // 解析Buffer obj, err := hcl.Parse(buf.String()) if err != nil { return nil, fmt.Errorf("解析错误:%s", err) } buf.Reset() var result Config // 解析 if o := obj.Get("detect", false); o != nil { if err := parseDetect(&result, o); err != nil { return nil, fmt.Errorf("解析'import'错误: %s", err) } } return &result, nil }