Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit bfc6eda

Browse files
committed
Improve documentation of functions and methods
1 parent 469394d commit bfc6eda

File tree

3 files changed

+67
-14
lines changed

3 files changed

+67
-14
lines changed

openstack/orchestration/v1/stacks/environment.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,41 @@ func (e *Environment) Validate() error {
3232
return nil
3333
}
3434

35-
// Parse environment file to resolve the urls of the resources
35+
// Parse environment file to resolve the URL's of the resources. This is done by
36+
// reading from the `Resource Registry` section, which is why the function is
37+
// named GetRRFileContents.
3638
func GetRRFileContents(e *Environment, ignoreIf igFunc) error {
39+
// initialize environment if empty
3740
if e.Files == nil {
3841
e.Files = make(map[string]string)
3942
}
4043
if e.fileMaps == nil {
4144
e.fileMaps = make(map[string]string)
4245
}
46+
47+
// get the resource registry
4348
rr := e.Parsed["resource_registry"]
49+
4450
// search the resource registry for URLs
4551
switch rr.(type) {
52+
// process further only if the resource registry is a map
4653
case map[string]interface{}, map[interface{}]interface{}:
4754
rr_map, err := toStringKeys(rr)
4855
if err != nil {
4956
return err
5057
}
58+
// the resource registry might contain a base URL for the resource. If
59+
// such a field is present, use it. Otherwise, use the default base URL.
5160
var baseURL string
5261
if val, ok := rr_map["base_url"]; ok {
5362
baseURL = val.(string)
5463
} else {
5564
baseURL = e.baseURL
5665
}
57-
// use a fake template to fetch contents from URLs
66+
67+
// The contents of the resource may be located in a remote file, which
68+
// will be a template. Instantiate a temporary template to manage the
69+
// contents.
5870
tempTemplate := new(Template)
5971
tempTemplate.baseURL = baseURL
6072
tempTemplate.client = e.client
@@ -65,6 +77,7 @@ func GetRRFileContents(e *Environment, ignoreIf igFunc) error {
6577
// check the `resources` section (if it exists) for more URLs
6678
if val, ok := rr_map["resources"]; ok {
6779
switch val.(type) {
80+
// process further only if the contents are a map
6881
case map[string]interface{}, map[interface{}]interface{}:
6982
resources_map, err := toStringKeys(val)
7083
if err != nil {
@@ -89,11 +102,11 @@ func GetRRFileContents(e *Environment, ignoreIf igFunc) error {
89102
return err
90103
}
91104
}
92-
93105
}
94-
95106
}
96107
}
108+
// if the resource registry contained any URL's, store them. This can
109+
// then be passed as parameter to api calls to Heat api.
97110
e.Files = tempTemplate.Files
98111
return nil
99112
default:

openstack/orchestration/v1/stacks/template.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,22 @@ func (t *Template) Validate() error {
3232
return errors.New(fmt.Sprintf("Template format version not found."))
3333
}
3434

35+
// GetFileContents recursively parses a template to search for urls. These urls
36+
// are assumed to point to other templates (known in OpenStack Heat as child
37+
// templates). The contents of these urls are fetched and stored in the `Files`
38+
// parameter of the template structure. This is the only way that a user can
39+
// use child templates that are located in their filesystem; urls located on the
40+
// web (e.g. on github or swift) can be fetched directly by Heat engine.
3541
func GetFileContents(t *Template, te interface{}, ignoreIf igFunc, recurse bool) error {
42+
// initialize template if empty
3643
if t.Files == nil {
3744
t.Files = make(map[string]string)
3845
}
3946
if t.fileMaps == nil {
4047
t.fileMaps = make(map[string]string)
4148
}
4249
switch te.(type) {
50+
// if te is a map
4351
case map[string]interface{}, map[interface{}]interface{}:
4452
te_map, err := toStringKeys(te)
4553
if err != nil {
@@ -48,43 +56,58 @@ func GetFileContents(t *Template, te interface{}, ignoreIf igFunc, recurse bool)
4856
for k, v := range te_map {
4957
value, ok := v.(string)
5058
if !ok {
59+
// if the value is not a string, recursively parse that value
5160
if err := GetFileContents(t, v, ignoreIf, recurse); err != nil {
5261
return err
5362
}
5463
} else if !ignoreIf(k, value) {
5564
// at this point, the k, v pair has a reference to an external template.
56-
// The assumption of heatclient is that value v is a relative reference
65+
// The assumption of heatclient is that value v is a reference
5766
// to a file in the users environment
67+
68+
// create a new child template
5869
childTemplate := new(Template)
70+
71+
// initialize child template
72+
73+
// get the base location of the child template
5974
baseURL, err := gophercloud.NormalizePathURL(t.baseURL, value)
6075
if err != nil {
6176
return err
6277
}
6378
childTemplate.baseURL = baseURL
6479
childTemplate.client = t.client
80+
81+
// fetch the contents of the child template
6582
if err := childTemplate.Parse(); err != nil {
6683
return err
6784
}
68-
// process child template recursively if required
85+
86+
// process child template recursively if required. This is
87+
// required if the child template itself contains references to
88+
// other templates
6989
if recurse {
7090
if err := GetFileContents(childTemplate, childTemplate.Parsed, ignoreIf, recurse); err != nil {
7191
return err
7292
}
7393
}
74-
// update parent template with current child templates' content
94+
// update parent template with current child templates' content.
95+
// At this point, the child template has been parsed recursively.
7596
t.fileMaps[value] = childTemplate.URL
7697
t.Files[childTemplate.URL] = string(childTemplate.Bin)
7798

7899
}
79100
}
80101
return nil
102+
// if te is a slice, call the function on each element of the slice.
81103
case []interface{}:
82104
te_slice := te.([]interface{})
83105
for i := range te_slice {
84106
if err := GetFileContents(t, te_slice[i], ignoreIf, recurse); err != nil {
85107
return err
86108
}
87109
}
110+
// if te is anything else, return
88111
case string, bool, float64, nil, int:
89112
return nil
90113
default:

openstack/orchestration/v1/stacks/utils.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ import (
1414
"gopkg.in/yaml.v2"
1515
)
1616

17+
// Client is an interface that expects a Get method similar to http.Get. This
18+
// is needed for unit testing, since we can mock an http client. Thus, the
19+
// client will usually be an http.Client EXCEPT in unit tests.
1720
type Client interface {
1821
Get(string) (*http.Response, error)
1922
}
2023

24+
// Base structure for both Template and Environment
2125
type TE struct {
2226
// Bin stores the contents of the template or environment.
2327
Bin []byte
@@ -38,28 +42,37 @@ type TE struct {
3842
client Client
3943
}
4044

45+
// Fetch fetches the contents of a TE from its URL. Once a TE structure has a
46+
// URL, call the fetch method to fetch the contents.
4147
func (t *TE) Fetch() error {
42-
// get baseURL if not already defined
48+
// if the baseURL is not provided, use the current directors as the base URL
4349
if t.baseURL == "" {
4450
u, err := getBasePath()
4551
if err != nil {
4652
return err
4753
}
4854
t.baseURL = u
4955
}
56+
57+
// if the contents are already present, do nothing.
5058
if t.Bin != nil {
51-
// already have contents
5259
return nil
5360
}
61+
62+
// get a fqdn from the URL using the baseURL of the template. For local files,
63+
// the URL's will have the `file` scheme.
5464
u, err := gophercloud.NormalizePathURL(t.baseURL, t.URL)
5565
if err != nil {
5666
return err
5767
}
5868
t.URL = u
69+
5970
// get an HTTP client if none present
6071
if t.client == nil {
6172
t.client = getHTTPClient()
6273
}
74+
75+
// use the client to fetch the contents of the template
6376
resp, err := t.client.Get(t.URL)
6477
if err != nil {
6578
return err
@@ -73,7 +86,7 @@ func (t *TE) Fetch() error {
7386
return nil
7487
}
7588

76-
// get the basepath of the template
89+
// get the basepath of the template.
7790
func getBasePath() (string, error) {
7891
basePath, err := filepath.Abs(".")
7992
if err != nil {
@@ -86,14 +99,15 @@ func getBasePath() (string, error) {
8699
return u, nil
87100
}
88101

89-
// get a an HTTP client to retrieve URLs
102+
// get a an HTTP client to retrieve URL's. This client allows the use of `file`
103+
// scheme since we may need to fetch templates from users filesystem
90104
func getHTTPClient() Client {
91105
transport := &http.Transport{}
92106
transport.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
93107
return &http.Client{Transport: transport}
94108
}
95109

96-
// parse the contents and validate
110+
// Parse will parse the contents and then validate. The contents MUST be either JSON or YAML.
97111
func (t *TE) Parse() error {
98112
if err := t.Fetch(); err != nil {
99113
return err
@@ -106,11 +120,13 @@ func (t *TE) Parse() error {
106120
return t.Validate()
107121
}
108122

109-
// base Validate method, always returns true
123+
// base Validate method, always returns nil
110124
func (t *TE) Validate() error {
111125
return nil
112126
}
113127

128+
// igfunc is a parameter used by GetFileContents and GetRRFileContents to check
129+
// for valid template URL's.
114130
type igFunc func(string, interface{}) bool
115131

116132
// convert map[interface{}]interface{} to map[string]interface{}
@@ -132,7 +148,8 @@ func toStringKeys(m interface{}) (map[string]interface{}, error) {
132148
}
133149
}
134150

135-
// fix the template reference to files
151+
// fix the template reference to files by replacing relative URL's by absolute
152+
// URL's
136153
func (t *TE) FixFileRefs() {
137154
t_str := string(t.Bin)
138155
if t.fileMaps == nil {

0 commit comments

Comments
 (0)