Example #1
0
func TestNormalizePathURL(t *testing.T) {
	baseDir, _ := os.Getwd()

	rawPath := "template.yaml"
	basePath, _ := filepath.Abs(".")
	result, _ := gophercloud.NormalizePathURL(basePath, rawPath)
	expected := strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "template.yaml"}, "/")
	th.CheckEquals(t, expected, result)

	rawPath = "http://www.google.com"
	basePath, _ = filepath.Abs(".")
	result, _ = gophercloud.NormalizePathURL(basePath, rawPath)
	expected = "http://www.google.com"
	th.CheckEquals(t, expected, result)

	rawPath = "very/nested/file.yaml"
	basePath, _ = filepath.Abs(".")
	result, _ = gophercloud.NormalizePathURL(basePath, rawPath)
	expected = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "very/nested/file.yaml"}, "/")
	th.CheckEquals(t, expected, result)

	rawPath = "very/nested/file.yaml"
	basePath = "http://www.google.com"
	result, _ = gophercloud.NormalizePathURL(basePath, rawPath)
	expected = "http://www.google.com/very/nested/file.yaml"
	th.CheckEquals(t, expected, result)

	rawPath = "very/nested/file.yaml/"
	basePath = "http://www.google.com/"
	result, _ = gophercloud.NormalizePathURL(basePath, rawPath)
	expected = "http://www.google.com/very/nested/file.yaml"
	th.CheckEquals(t, expected, result)

	rawPath = "very/nested/file.yaml"
	basePath = "http://www.google.com/even/more"
	result, _ = gophercloud.NormalizePathURL(basePath, rawPath)
	expected = "http://www.google.com/even/more/very/nested/file.yaml"
	th.CheckEquals(t, expected, result)

	rawPath = "very/nested/file.yaml"
	basePath = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "only/file/even/more"}, "/")
	result, _ = gophercloud.NormalizePathURL(basePath, rawPath)
	expected = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "only/file/even/more/very/nested/file.yaml"}, "/")
	th.CheckEquals(t, expected, result)

	rawPath = "very/nested/file.yaml/"
	basePath = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "only/file/even/more"}, "/")
	result, _ = gophercloud.NormalizePathURL(basePath, rawPath)
	expected = strings.Join([]string{"file:/", filepath.ToSlash(baseDir), "only/file/even/more/very/nested/file.yaml"}, "/")
	th.CheckEquals(t, expected, result)

}
Example #2
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
}
Example #3
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
}
Example #4
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 gophercloud.ErrUnexpectedType{Actual: fmt.Sprintf("%v", reflect.TypeOf(te))}
	}
	return nil
}