Beispiel #1
0
func parseResources(result *structs.Resources, list *ast.ObjectList) error {
	list = list.Elem()
	if len(list.Items) == 0 {
		return nil
	}
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'resource' block allowed per task")
	}

	// Get our resource object
	o := list.Items[0]

	// We need this later
	var listVal *ast.ObjectList
	if ot, ok := o.Val.(*ast.ObjectType); ok {
		listVal = ot.List
	} else {
		return fmt.Errorf("resource: should be an object")
	}

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, o.Val); err != nil {
		return err
	}
	delete(m, "network")

	if err := mapstructure.WeakDecode(m, result); err != nil {
		return err
	}

	// Parse the network resources
	if o := listVal.Filter("network"); len(o.Items) > 0 {
		if len(o.Items) > 1 {
			return fmt.Errorf("only one 'network' resource allowed")
		}

		var r structs.NetworkResource
		var m map[string]interface{}
		if err := hcl.DecodeObject(&m, o.Items[0].Val); err != nil {
			return err
		}
		if err := mapstructure.WeakDecode(m, &r); err != nil {
			return err
		}

		var networkObj *ast.ObjectList
		if ot, ok := o.Items[0].Val.(*ast.ObjectType); ok {
			networkObj = ot.List
		} else {
			return fmt.Errorf("resource: should be an object")
		}
		if err := parsePorts(networkObj, &r); err != nil {
			return err
		}

		result.Networks = []*structs.NetworkResource{&r}
	}

	return nil
}
Beispiel #2
0
func parseTelemetry(result *Config, list *ast.ObjectList) error {
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'telemetry' block is permitted")
	}

	// Get our one item
	item := list.Items[0]

	// Check for invalid keys
	valid := []string{
		"statsite_address",
		"statsd_address",
		"disable_hostname",
	}
	if err := checkHCLKeys(item.Val, valid); err != nil {
		return multierror.Prefix(err, "telemetry:")
	}

	var t Telemetry
	if err := hcl.DecodeObject(&t, item.Val); err != nil {
		return multierror.Prefix(err, "telemetry:")
	}

	if result.Telemetry == nil {
		result.Telemetry = &Telemetry{}
	}

	if err := hcl.DecodeObject(&result.Telemetry, item.Val); err != nil {
		return multierror.Prefix(err, "telemetry:")
	}
	return nil
}
Beispiel #3
0
func parseResources(result *structs.Resources, obj *hclobj.Object) error {
	if obj.Len() > 1 {
		return fmt.Errorf("only one 'resource' block allowed per task")
	}

	for _, o := range obj.Elem(false) {
		var m map[string]interface{}
		if err := hcl.DecodeObject(&m, o); err != nil {
			return err
		}
		delete(m, "network")

		if err := mapstructure.WeakDecode(m, result); err != nil {
			return err
		}

		// Parse the network resources
		if o := o.Get("network", false); o != nil {
			if o.Len() > 1 {
				return fmt.Errorf("only one 'network' resource allowed")
			}

			var r structs.NetworkResource
			var m map[string]interface{}
			if err := hcl.DecodeObject(&m, o); err != nil {
				return err
			}
			if err := mapstructure.WeakDecode(m, &r); err != nil {
				return err
			}

			// Keep track of labels we've already seen so we can ensure there
			// are no collisions when we turn them into environment variables.
			// lowercase:NomalCase so we can get the first for the error message
			seenLabel := map[string]string{}

			for _, label := range r.DynamicPorts {
				if !reDynamicPorts.MatchString(label) {
					return errDynamicPorts
				}
				first, seen := seenLabel[strings.ToLower(label)]
				if seen {
					return fmt.Errorf("Found a port label collision: `%s` overlaps with previous `%s`", label, first)
				} else {
					seenLabel[strings.ToLower(label)] = label
				}

			}

			result.Networks = []*structs.NetworkResource{&r}
		}

	}

	return nil
}
Beispiel #4
0
func loadConfigVariables(hclConfig *ast.ObjectList) ([]*tfcfg.Variable, error) {
	hclConfig = hclConfig.Children()
	result := make([]*tfcfg.Variable, 0, len(hclConfig.Items))

	if len(hclConfig.Items) == 0 {
		return result, nil
	}

	for _, item := range hclConfig.Items {
		n := item.Keys[0].Token.Value().(string)

		var listVal *ast.ObjectList
		if ot, ok := item.Val.(*ast.ObjectType); ok {
			listVal = ot.List
		} else {
			return nil, fmt.Errorf("variable '%s': should be a block", n)
		}

		var config map[string]interface{}
		if err := hcl.DecodeObject(&config, item.Val); err != nil {
			return nil, err
		}

		variable := &tfcfg.Variable{
			Name: n,
		}
		if a := listVal.Filter("default"); len(a.Items) > 0 {
			err := hcl.DecodeObject(&variable.Default, a.Items[0].Val)
			if err != nil {
				return nil, fmt.Errorf(
					"error reading variable %s default: %s", n, err,
				)
			}
		}
		if a := listVal.Filter("description"); len(a.Items) > 0 {
			err := hcl.DecodeObject(&variable.Description, a.Items[0].Val)
			if err != nil {
				return nil, fmt.Errorf(
					"error reading variable %s description: %s", n, err,
				)
			}
		}
		if a := listVal.Filter("type"); len(a.Items) > 0 {
			err := hcl.DecodeObject(&variable.DeclaredType, a.Items[0].Val)
			if err != nil {
				return nil, fmt.Errorf(
					"error reading variable %s type: %s", n, err,
				)
			}
		}

		result = append(result, variable)
	}

	return result, nil
}
Beispiel #5
0
// LoadOutputsHcl recurses into the given HCL object and turns
// it into a mapping of outputs.
func loadOutputsHcl(list *ast.ObjectList) ([]*Output, error) {
	list = list.Children()
	if len(list.Items) == 0 {
		return nil, fmt.Errorf(
			"'output' must be followed by exactly one string: a name")
	}

	// Go through each object and turn it into an actual result.
	result := make([]*Output, 0, len(list.Items))
	for _, item := range list.Items {
		n := item.Keys[0].Token.Value().(string)

		var listVal *ast.ObjectList
		if ot, ok := item.Val.(*ast.ObjectType); ok {
			listVal = ot.List
		} else {
			return nil, fmt.Errorf("output '%s': should be an object", n)
		}

		var config map[string]interface{}
		if err := hcl.DecodeObject(&config, item.Val); err != nil {
			return nil, err
		}

		// Delete special keys
		delete(config, "depends_on")

		rawConfig, err := NewRawConfig(config)
		if err != nil {
			return nil, fmt.Errorf(
				"Error reading config for output %s: %s",
				n,
				err)
		}

		// If we have depends fields, then add those in
		var dependsOn []string
		if o := listVal.Filter("depends_on"); len(o.Items) > 0 {
			err := hcl.DecodeObject(&dependsOn, o.Items[0].Val)
			if err != nil {
				return nil, fmt.Errorf(
					"Error reading depends_on for output %q: %s",
					n,
					err)
			}
		}

		result = append(result, &Output{
			Name:      n,
			RawConfig: rawConfig,
			DependsOn: dependsOn,
		})
	}

	return result, nil
}
Beispiel #6
0
// LoadProvidersHcl recurses into the given HCL object and turns
// it into a mapping of provider configs.
func loadProvidersHcl(os *hclobj.Object) ([]*ProviderConfig, error) {
	var objects []*hclobj.Object

	// Iterate over all the "provider" blocks and get the keys along with
	// their raw configuration objects. We'll parse those later.
	for _, o1 := range os.Elem(false) {
		for _, o2 := range o1.Elem(true) {
			objects = append(objects, o2)
		}
	}

	if len(objects) == 0 {
		return nil, nil
	}

	// Go through each object and turn it into an actual result.
	result := make([]*ProviderConfig, 0, len(objects))
	for _, o := range objects {
		var config map[string]interface{}

		if err := hcl.DecodeObject(&config, o); err != nil {
			return nil, err
		}

		delete(config, "alias")

		rawConfig, err := NewRawConfig(config)
		if err != nil {
			return nil, fmt.Errorf(
				"Error reading config for provider config %s: %s",
				o.Key,
				err)
		}

		// If we have an alias field, then add those in
		var alias string
		if a := o.Get("alias", false); a != nil {
			err := hcl.DecodeObject(&alias, a)
			if err != nil {
				return nil, fmt.Errorf(
					"Error reading alias for provider[%s]: %s",
					o.Key,
					err)
			}
		}

		result = append(result, &ProviderConfig{
			Name:      o.Key,
			Alias:     alias,
			RawConfig: rawConfig,
		})
	}

	return result, nil
}
Beispiel #7
0
// LoadProvidersHcl recurses into the given HCL object and turns
// it into a mapping of provider configs.
func loadProvidersHcl(list *ast.ObjectList) ([]*ProviderConfig, error) {
	list = list.Children()
	if len(list.Items) == 0 {
		return nil, nil
	}

	// Go through each object and turn it into an actual result.
	result := make([]*ProviderConfig, 0, len(list.Items))
	for _, item := range list.Items {
		n := item.Keys[0].Token.Value().(string)

		var listVal *ast.ObjectList
		if ot, ok := item.Val.(*ast.ObjectType); ok {
			listVal = ot.List
		} else {
			return nil, fmt.Errorf("module '%s': should be an object", n)
		}

		var config map[string]interface{}
		if err := hcl.DecodeObject(&config, item.Val); err != nil {
			return nil, err
		}

		delete(config, "alias")

		rawConfig, err := NewRawConfig(config)
		if err != nil {
			return nil, fmt.Errorf(
				"Error reading config for provider config %s: %s",
				n,
				err)
		}

		// If we have an alias field, then add those in
		var alias string
		if a := listVal.Filter("alias"); len(a.Items) > 0 {
			err := hcl.DecodeObject(&alias, a.Items[0].Val)
			if err != nil {
				return nil, fmt.Errorf(
					"Error reading alias for provider[%s]: %s",
					n,
					err)
			}
		}

		result = append(result, &ProviderConfig{
			Name:      n,
			Alias:     alias,
			RawConfig: rawConfig,
		})
	}

	return result, nil
}
Beispiel #8
0
func loadConfigProviders(hclConfig *ast.ObjectList) ([]*tfcfg.ProviderConfig, error) {
	hclConfig = hclConfig.Children()
	result := make([]*tfcfg.ProviderConfig, 0, len(hclConfig.Items))

	if len(hclConfig.Items) == 0 {
		return result, nil
	}

	for _, item := range hclConfig.Items {
		n := item.Keys[0].Token.Value().(string)

		var listVal *ast.ObjectList
		if ot, ok := item.Val.(*ast.ObjectType); ok {
			listVal = ot.List
		} else {
			return nil, fmt.Errorf("provider '%s': should be a block", n)
		}

		var config map[string]interface{}
		if err := hcl.DecodeObject(&config, item.Val); err != nil {
			return nil, err
		}

		delete(config, "alias")

		rawConfig, err := tfcfg.NewRawConfig(config)
		if err != nil {
			return nil, fmt.Errorf(
				"error reading provider config %s: %s", n, err,
			)
		}

		// If we have an alias, add it in
		var alias string
		if a := listVal.Filter("alias"); len(a.Items) > 0 {
			err := hcl.DecodeObject(&alias, a.Items[0].Val)
			if err != nil {
				return nil, fmt.Errorf(
					"error reading provider %s alias: %s", n, err,
				)
			}
		}

		result = append(result, &tfcfg.ProviderConfig{
			Name:      n,
			Alias:     alias,
			RawConfig: rawConfig,
		})
	}

	return result, nil
}
Beispiel #9
0
func loadConfigModules(hclConfig *ast.ObjectList) ([]*tfcfg.Module, error) {
	hclConfig = hclConfig.Children()
	result := make([]*tfcfg.Module, 0, len(hclConfig.Items))

	if len(hclConfig.Items) == 0 {
		return result, nil
	}

	for _, item := range hclConfig.Items {
		n := item.Keys[0].Token.Value().(string)

		var listVal *ast.ObjectList
		if ot, ok := item.Val.(*ast.ObjectType); ok {
			listVal = ot.List
		} else {
			return nil, fmt.Errorf("module '%s': should be a block", n)
		}

		var config map[string]interface{}
		if err := hcl.DecodeObject(&config, item.Val); err != nil {
			return nil, err
		}

		delete(config, "source")

		rawConfig, err := tfcfg.NewRawConfig(config)
		if err != nil {
			return nil, fmt.Errorf(
				"error reading module config %s: %s", n, err,
			)
		}

		var source string
		if a := listVal.Filter("source"); len(a.Items) > 0 {
			err := hcl.DecodeObject(&source, a.Items[0].Val)
			if err != nil {
				return nil, fmt.Errorf(
					"error reading module %s source: %s", n, err,
				)
			}
		}

		result = append(result, &tfcfg.Module{
			Name:      n,
			Source:    source,
			RawConfig: rawConfig,
		})
	}

	return result, nil
}
Beispiel #10
0
func parseUpdate(result *structs.UpdateStrategy, obj *hclobj.Object) error {
	if obj.Len() > 1 {
		return fmt.Errorf("only one 'update' block allowed per job")
	}

	for _, o := range obj.Elem(false) {
		var m map[string]interface{}
		if err := hcl.DecodeObject(&m, o); err != nil {
			return err
		}
		for _, key := range []string{"stagger", "Stagger"} {
			if raw, ok := m[key]; ok {
				switch v := raw.(type) {
				case string:
					dur, err := time.ParseDuration(v)
					if err != nil {
						return fmt.Errorf("invalid stagger time '%s'", raw)
					}
					m[key] = dur
				case int:
					m[key] = time.Duration(v) * time.Second
				default:
					return fmt.Errorf("invalid type for stagger time '%s'",
						raw)
				}
			}
		}

		if err := mapstructure.WeakDecode(m, result); err != nil {
			return err
		}
	}
	return nil
}
Beispiel #11
0
func parseRestartPolicy(final **structs.RestartPolicy, list *ast.ObjectList) error {
	list = list.Elem()
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'restart' block allowed")
	}

	// Get our job object
	obj := list.Items[0]

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, obj.Val); err != nil {
		return err
	}

	var result structs.RestartPolicy
	dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
		DecodeHook:       mapstructure.StringToTimeDurationHookFunc(),
		WeaklyTypedInput: true,
		Result:           &result,
	})
	if err != nil {
		return err
	}
	if err := dec.Decode(m); err != nil {
		return err
	}

	*final = &result
	return nil
}
Beispiel #12
0
func parseConstraints(result *[]*structs.Constraint, obj *hclobj.Object) error {
	for _, o := range obj.Elem(false) {
		var m map[string]interface{}
		if err := hcl.DecodeObject(&m, o); err != nil {
			return err
		}
		m["LTarget"] = m["attribute"]
		m["RTarget"] = m["value"]
		m["Operand"] = m["operator"]

		// Default constraint to being hard
		if _, ok := m["hard"]; !ok {
			m["hard"] = true
		}

		// Build the constraint
		var c structs.Constraint
		if err := mapstructure.WeakDecode(m, &c); err != nil {
			return err
		}
		if c.Operand == "" {
			c.Operand = "="
		}

		*result = append(*result, &c)
	}

	return nil
}
Beispiel #13
0
// 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
}
Beispiel #14
0
func parseProject(result *File, obj *hclobj.Object) error {
	if obj.Len() > 1 {
		return fmt.Errorf("only one 'project' block allowed")
	}

	// Check for invalid keys
	valid := []string{"name", "infrastructure"}
	if err := checkHCLKeys(obj, valid); err != nil {
		return multierror.Prefix(err, "project:")
	}

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, obj); err != nil {
		return err
	}

	// Parse the project
	var proj Project
	result.Project = &proj
	if err := mapstructure.WeakDecode(m, &proj); err != nil {
		return err
	}

	return nil
}
Beispiel #15
0
// 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
}
Beispiel #16
0
func parseProject(result *File, list *ast.ObjectList) error {
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'project' block allowed")
	}

	// Get our one item
	item := list.Items[0]

	// Check for invalid keys
	valid := []string{"name", "infrastructure"}
	if err := checkHCLKeys(item.Val, valid); err != nil {
		return multierror.Prefix(err, "project:")
	}

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, item.Val); err != nil {
		return err
	}

	// Parse the project
	var proj Project
	result.Project = &proj
	if err := mapstructure.WeakDecode(m, &proj); err != nil {
		return err
	}

	return nil
}
Beispiel #17
0
func parseTelemetry(result **Telemetry, list *ast.ObjectList) error {
	list = list.Elem()
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'telemetry' block allowed")
	}

	// Get our telemetry object
	listVal := list.Items[0].Val

	// Check for invalid keys
	valid := []string{
		"statsite_address",
		"statsd_address",
		"disable_hostname",
	}
	if err := checkHCLKeys(listVal, valid); err != nil {
		return err
	}

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, listVal); err != nil {
		return err
	}

	var telemetry Telemetry
	if err := mapstructure.WeakDecode(m, &telemetry); err != nil {
		return err
	}
	*result = &telemetry
	return nil
}
Beispiel #18
0
func parseUpdate(result *structs.UpdateStrategy, list *ast.ObjectList) error {
	list = list.Elem()
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'update' block allowed per job")
	}

	// Get our resource object
	o := list.Items[0]

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, o.Val); err != nil {
		return err
	}

	// Check for invalid keys
	valid := []string{
		"stagger",
		"max_parallel",
	}
	if err := checkHCLKeys(o.Val, valid); err != nil {
		return err
	}

	dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
		DecodeHook:       mapstructure.StringToTimeDurationHookFunc(),
		WeaklyTypedInput: true,
		Result:           result,
	})
	if err != nil {
		return err
	}
	return dec.Decode(m)
}
Beispiel #19
0
// 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
}
Beispiel #20
0
func parsePorts(networkObj *ast.ObjectList, nw *structs.NetworkResource) error {
	portsObjList := networkObj.Filter("port")
	knownPortLabels := make(map[string]bool)
	for _, port := range portsObjList.Items {
		if len(port.Keys) == 0 {
			return fmt.Errorf("ports must be named")
		}
		label := port.Keys[0].Token.Value().(string)
		if !reDynamicPorts.MatchString(label) {
			return errPortLabel
		}
		l := strings.ToLower(label)
		if knownPortLabels[l] {
			return fmt.Errorf("found a port label collision: %s", label)
		}
		var p map[string]interface{}
		var res structs.Port
		if err := hcl.DecodeObject(&p, port.Val); err != nil {
			return err
		}
		if err := mapstructure.WeakDecode(p, &res); err != nil {
			return err
		}
		res.Label = label
		if res.Value > 0 {
			nw.ReservedPorts = append(nw.ReservedPorts, res)
		} else {
			nw.DynamicPorts = append(nw.DynamicPorts, res)
		}
		knownPortLabels[l] = true
	}
	return nil
}
Beispiel #21
0
// LoadOutputsHcl recurses into the given HCL object and turns
// it into a mapping of outputs.
func loadOutputsHcl(list *ast.ObjectList) ([]*Output, error) {
	list = list.Children()
	if len(list.Items) == 0 {
		return nil, nil
	}

	// Go through each object and turn it into an actual result.
	result := make([]*Output, 0, len(list.Items))
	for _, item := range list.Items {
		n := item.Keys[0].Token.Value().(string)

		var config map[string]interface{}
		if err := hcl.DecodeObject(&config, item.Val); err != nil {
			return nil, err
		}

		rawConfig, err := NewRawConfig(config)
		if err != nil {
			return nil, fmt.Errorf(
				"Error reading config for output %s: %s",
				n,
				err)
		}

		result = append(result, &Output{
			Name:      n,
			RawConfig: rawConfig,
		})
	}

	return result, nil
}
Beispiel #22
0
func parseChecks(service *structs.Service, checkObjs *ast.ObjectList) error {
	service.Checks = make([]*structs.ServiceCheck, len(checkObjs.Items))
	for idx, co := range checkObjs.Items {
		var check structs.ServiceCheck
		var cm map[string]interface{}
		if err := hcl.DecodeObject(&cm, co.Val); err != nil {
			return err
		}
		dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
			DecodeHook:       mapstructure.StringToTimeDurationHookFunc(),
			WeaklyTypedInput: true,
			Result:           &check,
		})
		if err != nil {
			return err
		}
		if err := dec.Decode(cm); err != nil {
			return err
		}

		service.Checks[idx] = &check
	}

	return nil
}
Beispiel #23
0
func loadConfigOutputs(hclConfig *ast.ObjectList) ([]*tfcfg.Output, error) {
	hclConfig = hclConfig.Children()
	result := make([]*tfcfg.Output, 0, len(hclConfig.Items))

	if len(hclConfig.Items) == 0 {
		return result, nil
	}

	for _, item := range hclConfig.Items {
		n := item.Keys[0].Token.Value().(string)

		if _, ok := item.Val.(*ast.ObjectType); !ok {
			return nil, fmt.Errorf("output '%s': should be a block", n)
		}

		var config map[string]interface{}
		if err := hcl.DecodeObject(&config, item.Val); err != nil {
			return nil, err
		}

		rawConfig, err := tfcfg.NewRawConfig(config)
		if err != nil {
			return nil, fmt.Errorf(
				"error reading output config %s: %s", n, err,
			)
		}

		result = append(result, &tfcfg.Output{
			Name:      n,
			RawConfig: rawConfig,
		})
	}

	return result, nil
}
Beispiel #24
0
func parseFoundations(result *Infrastructure, list *ast.ObjectList) error {
	list = list.Children()
	if len(list.Items) == 0 {
		return nil
	}

	// Go through each object and turn it into an actual result.
	collection := make([]*Foundation, 0, len(list.Items))
	seen := make(map[string]struct{})
	for _, item := range list.Items {
		n := item.Keys[0].Token.Value().(string)

		// Make sure we haven't already found this
		if _, ok := seen[n]; ok {
			return fmt.Errorf("foundation '%s' defined more than once", n)
		}
		seen[n] = struct{}{}

		var m map[string]interface{}
		if err := hcl.DecodeObject(&m, item.Val); err != nil {
			return err
		}

		var f Foundation
		f.Name = n
		f.Config = m

		collection = append(collection, &f)
	}

	// Set the results
	result.Foundations = collection
	return nil
}
Beispiel #25
0
func parseLocalDisk(result **structs.LocalDisk, list *ast.ObjectList) error {
	list = list.Elem()
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'local_disk' block allowed")
	}

	// Get our local_disk object
	obj := list.Items[0]

	// Check for invalid keys
	valid := []string{
		"sticky",
		"disk",
	}
	if err := checkHCLKeys(obj.Val, valid); err != nil {
		return err
	}

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, obj.Val); err != nil {
		return err
	}

	var localDisk structs.LocalDisk
	if err := mapstructure.WeakDecode(m, &localDisk); err != nil {
		return err
	}
	*result = &localDisk

	return nil
}
Beispiel #26
0
// 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
}
Beispiel #27
0
func parseAdvertise(result **AdvertiseAddrs, list *ast.ObjectList) error {
	list = list.Elem()
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'advertise' block allowed")
	}

	// Get our advertise object
	listVal := list.Items[0].Val

	// Check for invalid keys
	valid := []string{
		"http",
		"rpc",
		"serf",
	}
	if err := checkHCLKeys(listVal, valid); err != nil {
		return err
	}

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, listVal); err != nil {
		return err
	}

	var advertise AdvertiseAddrs
	if err := mapstructure.WeakDecode(m, &advertise); err != nil {
		return err
	}
	*result = &advertise
	return nil
}
Beispiel #28
0
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
}
Beispiel #29
0
func parseAtlas(result **AtlasConfig, list *ast.ObjectList) error {
	list = list.Elem()
	if len(list.Items) > 1 {
		return fmt.Errorf("only one 'atlas' block allowed")
	}

	// Get our atlas object
	listVal := list.Items[0].Val

	// Check for invalid keys
	valid := []string{
		"infrastructure",
		"token",
		"join",
		"endpoint",
	}
	if err := checkHCLKeys(listVal, valid); err != nil {
		return err
	}

	var m map[string]interface{}
	if err := hcl.DecodeObject(&m, listVal); err != nil {
		return err
	}

	var atlas AtlasConfig
	if err := mapstructure.WeakDecode(m, &atlas); err != nil {
		return err
	}
	*result = &atlas
	return nil
}
Beispiel #30
0
func parseDetect(result *Config, obj *hclobj.Object) error {
	// 从map中获取所有实际对象的key值
	objects := make([]*hclobj.Object, 0, 2)
	for _, o1 := range obj.Elem(false) {
		for _, o2 := range o1.Elem(true) {
			objects = append(objects, o2)
		}
	}

	if len(objects) == 0 {
		return nil
	}

	// 检查每个对象,返回实际结果
	collection := make([]*Detector, 0, len(objects))
	for _, o := range objects {
		var m map[string]interface{}
		if err := hcl.DecodeObject(&m, o); err != nil {
			return err
		}

		var d Detector
		if err := mapstructure.WeakDecode(m, &d); err != nil {
			return fmt.Errorf("解析detector错误 '%s' : %s", o.Key, err)
		}

		d.Type = o.Key
		collection = append(collection, &d)
	}
	result.Detectors = collection
	return nil
}