示例#1
0
// get the basepath of the TE
func getBasePath() (string, error) {
	basePath, err := filepath.Abs(".")
	if err != nil {
		return "", err
	}
	u, err := gophercloud.NormalizePathURL("", basePath)
	if err != nil {
		return "", err
	}
	return u, nil
}
示例#2
0
// Fetch fetches the contents of a TE from its URL. Once a TE structure has a
// URL, call the fetch method to fetch the contents.
func (t *TE) Fetch() error {
	// if the baseURL is not provided, use the current directors as the base URL
	if t.baseURL == "" {
		u, err := getBasePath()
		if err != nil {
			return err
		}
		t.baseURL = u
	}

	// if the contents are already present, do nothing.
	if t.Bin != nil {
		return nil
	}

	// get a fqdn from the URL using the baseURL of the TE. For local files,
	// the URL's will have the `file` scheme.
	u, err := gophercloud.NormalizePathURL(t.baseURL, t.URL)
	if err != nil {
		return err
	}
	t.URL = u

	// get an HTTP client if none present
	if t.client == nil {
		t.client = getHTTPClient()
	}

	// use the client to fetch the contents of the TE
	resp, err := t.client.Get(t.URL)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	t.Bin = body
	return nil
}
示例#3
0
// GetFileContents recursively parses a template to search for urls. These urls
// are assumed to point to other templates (known in OpenStack Heat as child
// templates). The contents of these urls are fetched and stored in the `Files`
// parameter of the template structure. This is the only way that a user can
// use child templates that are located in their filesystem; urls located on the
// web (e.g. on github or swift) can be fetched directly by Heat engine.
func (t *Template) getFileContents(te interface{}, ignoreIf igFunc, recurse bool) error {
	// initialize template if empty
	if t.Files == nil {
		t.Files = make(map[string]string)
	}
	if t.fileMaps == nil {
		t.fileMaps = make(map[string]string)
	}
	switch te.(type) {
	// if te is a map
	case map[string]interface{}, map[interface{}]interface{}:
		teMap, err := toStringKeys(te)
		if err != nil {
			return err
		}
		for k, v := range teMap {
			value, ok := v.(string)
			if !ok {
				// if the value is not a string, recursively parse that value
				if err := t.getFileContents(v, ignoreIf, recurse); err != nil {
					return err
				}
			} else if !ignoreIf(k, value) {
				// at this point, the k, v pair has a reference to an external template.
				// The assumption of heatclient is that value v is a reference
				// to a file in the users environment

				// create a new child template
				childTemplate := new(Template)

				// initialize child template

				// get the base location of the child template
				baseURL, err := gophercloud.NormalizePathURL(t.baseURL, value)
				if err != nil {
					return err
				}
				childTemplate.baseURL = baseURL
				childTemplate.client = t.client

				// fetch the contents of the child template
				if err := childTemplate.Parse(); err != nil {
					return err
				}

				// process child template recursively if required. This is
				// required if the child template itself contains references to
				// other templates
				if recurse {
					if err := childTemplate.getFileContents(childTemplate.Parsed, ignoreIf, recurse); err != nil {
						return err
					}
				}
				// update parent template with current child templates' content.
				// At this point, the child template has been parsed recursively.
				t.fileMaps[value] = childTemplate.URL
				t.Files[childTemplate.URL] = string(childTemplate.Bin)

			}
		}
		return nil
	// if te is a slice, call the function on each element of the slice.
	case []interface{}:
		teSlice := te.([]interface{})
		for i := range teSlice {
			if err := t.getFileContents(teSlice[i], ignoreIf, recurse); err != nil {
				return err
			}
		}
	// if te is anything else, return
	case string, bool, float64, nil, int:
		return nil
	default:
		return fmt.Errorf("%v: Unrecognized type", reflect.TypeOf(te))

	}
	return nil
}