blob: 1fc01e03bcd5ff2c53fb5c44580fb2ba48ff31db [file] [log] [blame]
Pratik Mallya5fddb2a2015-09-14 14:04:49 -05001package stacks
2
3import (
4 "errors"
5 "fmt"
6 "strings"
7)
8
9// an interface to represent stack environments
10type Environment struct {
11 TE
12}
13
14// allowed sections in a stack environment file
15var EnvironmentSections = map[string]bool{
16 "parameters": true,
17 "parameter_defaults": true,
18 "resource_registry": true,
19}
20
21func (e *Environment) Validate() error {
22 if e.Parsed == nil {
23 if err := e.Parse(); err != nil {
24 return err
25 }
26 }
27 for key, _ := range e.Parsed {
28 if _, ok := EnvironmentSections[key]; !ok {
29 return errors.New(fmt.Sprintf("Environment has wrong section: %s", key))
30 }
31 }
32 return nil
33}
34
Pratik Mallyabfc6eda2015-09-21 15:01:18 -050035// 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.
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050038func GetRRFileContents(e *Environment, ignoreIf igFunc) error {
Pratik Mallyabfc6eda2015-09-21 15:01:18 -050039 // initialize environment if empty
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050040 if e.Files == nil {
41 e.Files = make(map[string]string)
42 }
43 if e.fileMaps == nil {
44 e.fileMaps = make(map[string]string)
45 }
Pratik Mallyabfc6eda2015-09-21 15:01:18 -050046
47 // get the resource registry
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050048 rr := e.Parsed["resource_registry"]
Pratik Mallyabfc6eda2015-09-21 15:01:18 -050049
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050050 // search the resource registry for URLs
51 switch rr.(type) {
Pratik Mallyabfc6eda2015-09-21 15:01:18 -050052 // process further only if the resource registry is a map
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050053 case map[string]interface{}, map[interface{}]interface{}:
54 rr_map, err := toStringKeys(rr)
55 if err != nil {
56 return err
57 }
Pratik Mallyabfc6eda2015-09-21 15:01:18 -050058 // 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.
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050060 var baseURL string
61 if val, ok := rr_map["base_url"]; ok {
62 baseURL = val.(string)
63 } else {
64 baseURL = e.baseURL
65 }
Pratik Mallyabfc6eda2015-09-21 15:01:18 -050066
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.
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050070 tempTemplate := new(Template)
71 tempTemplate.baseURL = baseURL
72 tempTemplate.client = e.client
73
74 if err = GetFileContents(tempTemplate, rr, ignoreIf, false); err != nil {
75 return err
76 }
77 // check the `resources` section (if it exists) for more URLs
78 if val, ok := rr_map["resources"]; ok {
79 switch val.(type) {
Pratik Mallyabfc6eda2015-09-21 15:01:18 -050080 // process further only if the contents are a map
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050081 case map[string]interface{}, map[interface{}]interface{}:
82 resources_map, err := toStringKeys(val)
83 if err != nil {
84 return err
85 }
86 for _, v := range resources_map {
87 switch v.(type) {
88 case map[string]interface{}, map[interface{}]interface{}:
89 resource_map, err := toStringKeys(v)
90 if err != nil {
91 return err
92 }
93 var resourceBaseURL string
94 // if base_url for the resource type is defined, use it
95 if val, ok := resource_map["base_url"]; ok {
96 resourceBaseURL = val.(string)
97 } else {
98 resourceBaseURL = baseURL
99 }
100 tempTemplate.baseURL = resourceBaseURL
101 if err := GetFileContents(tempTemplate, v, ignoreIf, false); err != nil {
102 return err
103 }
104 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500105 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500106 }
107 }
Pratik Mallyabfc6eda2015-09-21 15:01:18 -0500108 // if the resource registry contained any URL's, store them. This can
109 // then be passed as parameter to api calls to Heat api.
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500110 e.Files = tempTemplate.Files
111 return nil
112 default:
113 return nil
114 }
115}
116
117// function to choose keys whose values are other environment files
118func ignoreIfEnvironment(key string, value interface{}) bool {
119 // base_url and hooks refer to components which cannot have urls
120 if key == "base_url" || key == "hooks" {
121 return true
122 }
123 // if value is not string, it cannot be a URL
124 valueString, ok := value.(string)
125 if !ok {
126 return true
127 }
128 // if value contains `::`, it must be a reference to another resource type
129 // e.g. OS::Nova::Server : Rackspace::Cloud::Server
130 if strings.Contains(valueString, "::") {
131 return true
132 }
133 return false
134}