blob: 378eeaf66c9d3af37b71e0d0ed5773f768f4f646 [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
35// Parse environment file to resolve the urls of the resources
36func GetRRFileContents(e *Environment, ignoreIf igFunc) error {
37 if e.Files == nil {
38 e.Files = make(map[string]string)
39 }
40 if e.fileMaps == nil {
41 e.fileMaps = make(map[string]string)
42 }
43 rr := e.Parsed["resource_registry"]
44 // search the resource registry for URLs
45 switch rr.(type) {
46 case map[string]interface{}, map[interface{}]interface{}:
47 rr_map, err := toStringKeys(rr)
48 if err != nil {
49 return err
50 }
51 var baseURL string
52 if val, ok := rr_map["base_url"]; ok {
53 baseURL = val.(string)
54 } else {
55 baseURL = e.baseURL
56 }
57 // use a fake template to fetch contents from URLs
58 tempTemplate := new(Template)
59 tempTemplate.baseURL = baseURL
60 tempTemplate.client = e.client
61
62 if err = GetFileContents(tempTemplate, rr, ignoreIf, false); err != nil {
63 return err
64 }
65 // check the `resources` section (if it exists) for more URLs
66 if val, ok := rr_map["resources"]; ok {
67 switch val.(type) {
68 case map[string]interface{}, map[interface{}]interface{}:
69 resources_map, err := toStringKeys(val)
70 if err != nil {
71 return err
72 }
73 for _, v := range resources_map {
74 switch v.(type) {
75 case map[string]interface{}, map[interface{}]interface{}:
76 resource_map, err := toStringKeys(v)
77 if err != nil {
78 return err
79 }
80 var resourceBaseURL string
81 // if base_url for the resource type is defined, use it
82 if val, ok := resource_map["base_url"]; ok {
83 resourceBaseURL = val.(string)
84 } else {
85 resourceBaseURL = baseURL
86 }
87 tempTemplate.baseURL = resourceBaseURL
88 if err := GetFileContents(tempTemplate, v, ignoreIf, false); err != nil {
89 return err
90 }
91 }
92
93 }
94
95 }
96 }
97 e.Files = tempTemplate.Files
98 return nil
99 default:
100 return nil
101 }
102}
103
104// function to choose keys whose values are other environment files
105func ignoreIfEnvironment(key string, value interface{}) bool {
106 // base_url and hooks refer to components which cannot have urls
107 if key == "base_url" || key == "hooks" {
108 return true
109 }
110 // if value is not string, it cannot be a URL
111 valueString, ok := value.(string)
112 if !ok {
113 return true
114 }
115 // if value contains `::`, it must be a reference to another resource type
116 // e.g. OS::Nova::Server : Rackspace::Cloud::Server
117 if strings.Contains(valueString, "::") {
118 return true
119 }
120 return false
121}