Add template and environment parsing to gophercloud
Openstack Heat expects the client to do some parsing client side,
specifically for nested templates and environments which refer
to local files. This patch adds a recursive parser for both the
template and environment files to gophercloud. The interfaces
are also changed to make use of the new parsing functionality.
diff --git a/openstack/orchestration/v1/stacks/requests.go b/openstack/orchestration/v1/stacks/requests.go
index bd8e59e..9859d4d 100644
--- a/openstack/orchestration/v1/stacks/requests.go
+++ b/openstack/orchestration/v1/stacks/requests.go
@@ -33,9 +33,16 @@
type CreateOpts struct {
// (REQUIRED) The name of the stack. It must start with an alphabetic character.
Name string
+ // (REQUIRED) A structure that contains either the template file or url. Call the
+ // associated methods to extract the information relevant to send in a create request.
+ TemplateOpts *Template
+ // (DEPRECATED): Please use TemplateOpts for providing the template. If
+ // TemplateOpts is provided, TemplateURL will be ignored
// (OPTIONAL; REQUIRED IF Template IS EMPTY) The URL of the template to instantiate.
// This value is ignored if Template is supplied inline.
TemplateURL string
+ // (DEPRECATED): Please use TemplateOpts for providing the template. If
+ // TemplateOpts is provided, Template will be ignored
// (OPTIONAL; REQUIRED IF TemplateURL IS EMPTY) A template to instantiate. The value
// is a stringified version of the JSON/YAML template. Since the template will likely
// be located in a file, one way to set this variable is by using ioutil.ReadFile:
@@ -51,8 +58,14 @@
// creation fails. Default is true, meaning all resources are not deleted when
// stack creation fails.
DisableRollback Rollback
+ // (OPTIONAL) A structure that contains details for the environment of the stack.
+ EnvironmentOpts *Environment
+ // (DEPRECATED): Please use EnvironmentOpts to provide Environment data
// (OPTIONAL) A stringified JSON environment for the stack.
Environment string
+ // (DEPRECATED): Files is automatically determined
+ // by parsing the template and environment passed as TemplateOpts and
+ // EnvironmentOpts respectively.
// (OPTIONAL) A map that maps file names to file contents. It can also be used
// to pass provider template contents. Example:
// Files: `{"myfile": "#!/bin/bash\necho 'Hello world' > /root/testfile.txt"}`
@@ -73,25 +86,60 @@
return s, errors.New("Required field 'Name' not provided.")
}
s["stack_name"] = opts.Name
-
- if opts.Template != "" {
- s["template"] = opts.Template
- } else if opts.TemplateURL != "" {
- s["template_url"] = opts.TemplateURL
+ Files := make(map[string]string)
+ if opts.TemplateOpts == nil {
+ if opts.Template != "" {
+ s["template"] = opts.Template
+ } else if opts.TemplateURL != "" {
+ s["template_url"] = opts.TemplateURL
+ } else {
+ return s, errors.New("Either Template or TemplateURL must be provided.")
+ }
} else {
- return s, errors.New("Either Template or TemplateURL must be provided.")
+ if err := opts.TemplateOpts.Parse(); err != nil {
+ return nil, err
+ }
+
+ if err := GetFileContents(opts.TemplateOpts, opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
+ return nil, err
+ }
+ opts.TemplateOpts.FixFileRefs()
+ s["template"] = string(opts.TemplateOpts.Bin)
+
+ for k, v := range opts.TemplateOpts.Files {
+ Files[k] = v
+ }
+ }
+ if opts.DisableRollback != nil {
+ s["disable_rollback"] = &opts.DisableRollback
+ }
+
+ if opts.EnvironmentOpts != nil {
+ if err := opts.EnvironmentOpts.Parse(); err != nil {
+ return nil, err
+ }
+ if err := GetRRFileContents(opts.EnvironmentOpts, ignoreIfEnvironment); err != nil {
+ return nil, err
+ }
+ opts.EnvironmentOpts.FixFileRefs()
+ for k, v := range opts.EnvironmentOpts.Files {
+ Files[k] = v
+ }
+ s["environment"] = string(opts.EnvironmentOpts.Bin)
+ } else if opts.Environment != "" {
+ s["environment"] = opts.Environment
+ }
+
+ if opts.Files != nil {
+ s["files"] = opts.Files
+ } else {
+ s["files"] = Files
}
if opts.DisableRollback != nil {
s["disable_rollback"] = &opts.DisableRollback
}
- if opts.Environment != "" {
- s["environment"] = opts.Environment
- }
- if opts.Files != nil {
- s["files"] = opts.Files
- }
if opts.Parameters != nil {
s["parameters"] = opts.Parameters
}
@@ -139,9 +187,16 @@
Name string
// (REQUIRED) The timeout for stack creation in minutes.
Timeout int
+ // (REQUIRED) A structure that contains either the template file or url. Call the
+ // associated methods to extract the information relevant to send in a create request.
+ TemplateOpts *Template
+ // (DEPRECATED): Please use TemplateOpts for providing the template. If
+ // TemplateOpts is provided, TemplateURL will be ignored
// (OPTIONAL; REQUIRED IF Template IS EMPTY) The URL of the template to instantiate.
// This value is ignored if Template is supplied inline.
TemplateURL string
+ // (DEPRECATED): Please use TemplateOpts for providing the template. If
+ // TemplateOpts is provided, Template will be ignored
// (OPTIONAL; REQUIRED IF TemplateURL IS EMPTY) A template to instantiate. The value
// is a stringified version of the JSON/YAML template. Since the template will likely
// be located in a file, one way to set this variable is by using ioutil.ReadFile:
@@ -157,8 +212,14 @@
// creation fails. Default is true, meaning all resources are not deleted when
// stack creation fails.
DisableRollback Rollback
+ // (OPTIONAL) A structure that contains details for the environment of the stack.
+ EnvironmentOpts *Environment
+ // (DEPRECATED): Please use EnvironmentOpts to provide Environment data
// (OPTIONAL) A stringified JSON environment for the stack.
Environment string
+ // (DEPRECATED): Files is automatically determined
+ // by parsing the template and environment passed as TemplateOpts and
+ // EnvironmentOpts respectively.
// (OPTIONAL) A map that maps file names to file contents. It can also be used
// to pass provider template contents. Example:
// Files: `{"myfile": "#!/bin/bash\necho 'Hello world' > /root/testfile.txt"}`
@@ -175,15 +236,30 @@
return s, errors.New("Required field 'Name' not provided.")
}
s["stack_name"] = opts.Name
-
- if opts.Template != "" {
- s["template"] = opts.Template
- } else if opts.TemplateURL != "" {
- s["template_url"] = opts.TemplateURL
+ Files := make(map[string]string)
+ if opts.TemplateOpts == nil {
+ if opts.Template != "" {
+ s["template"] = opts.Template
+ } else if opts.TemplateURL != "" {
+ s["template_url"] = opts.TemplateURL
+ } else {
+ return s, errors.New("Either Template or TemplateURL must be provided.")
+ }
} else {
- return s, errors.New("Either Template or TemplateURL must be provided.")
- }
+ if err := opts.TemplateOpts.Parse(); err != nil {
+ return nil, err
+ }
+ if err := GetFileContents(opts.TemplateOpts, opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
+ return nil, err
+ }
+ opts.TemplateOpts.FixFileRefs()
+ s["template"] = string(opts.TemplateOpts.Bin)
+
+ for k, v := range opts.TemplateOpts.Files {
+ Files[k] = v
+ }
+ }
if opts.AdoptStackData == "" {
return s, errors.New("Required field 'AdoptStackData' not provided.")
}
@@ -193,12 +269,28 @@
s["disable_rollback"] = &opts.DisableRollback
}
- if opts.Environment != "" {
+ if opts.EnvironmentOpts != nil {
+ if err := opts.EnvironmentOpts.Parse(); err != nil {
+ return nil, err
+ }
+ if err := GetRRFileContents(opts.EnvironmentOpts, ignoreIfEnvironment); err != nil {
+ return nil, err
+ }
+ opts.EnvironmentOpts.FixFileRefs()
+ for k, v := range opts.EnvironmentOpts.Files {
+ Files[k] = v
+ }
+ s["environment"] = string(opts.EnvironmentOpts.Bin)
+ } else if opts.Environment != "" {
s["environment"] = opts.Environment
}
+
if opts.Files != nil {
s["files"] = opts.Files
+ } else {
+ s["files"] = Files
}
+
if opts.Parameters != nil {
s["parameters"] = opts.Parameters
}
@@ -311,9 +403,16 @@
// UpdateOpts contains the common options struct used in this package's Update
// operation.
type UpdateOpts struct {
+ // (REQUIRED) A structure that contains either the template file or url. Call the
+ // associated methods to extract the information relevant to send in a create request.
+ TemplateOpts *Template
+ // (DEPRECATED): Please use TemplateOpts for providing the template. If
+ // TemplateOpts is provided, TemplateURL will be ignored
// (OPTIONAL; REQUIRED IF Template IS EMPTY) The URL of the template to instantiate.
// This value is ignored if Template is supplied inline.
TemplateURL string
+ // (DEPRECATED): Please use TemplateOpts for providing the template. If
+ // TemplateOpts is provided, Template will be ignored
// (OPTIONAL; REQUIRED IF TemplateURL IS EMPTY) A template to instantiate. The value
// is a stringified version of the JSON/YAML template. Since the template will likely
// be located in a file, one way to set this variable is by using ioutil.ReadFile:
@@ -325,8 +424,14 @@
// }
// opts.Template = string(b)
Template string
+ // (OPTIONAL) A structure that contains details for the environment of the stack.
+ EnvironmentOpts *Environment
+ // (DEPRECATED): Please use EnvironmentOpts to provide Environment data
// (OPTIONAL) A stringified JSON environment for the stack.
Environment string
+ // (DEPRECATED): Files is automatically determined
+ // by parsing the template and environment passed as TemplateOpts and
+ // EnvironmentOpts respectively.
// (OPTIONAL) A map that maps file names to file contents. It can also be used
// to pass provider template contents. Example:
// Files: `{"myfile": "#!/bin/bash\necho 'Hello world' > /root/testfile.txt"}`
@@ -342,21 +447,51 @@
// ToStackUpdateMap casts a CreateOpts struct to a map.
func (opts UpdateOpts) ToStackUpdateMap() (map[string]interface{}, error) {
s := make(map[string]interface{})
-
- if opts.Template != "" {
- s["template"] = opts.Template
- } else if opts.TemplateURL != "" {
- s["template_url"] = opts.TemplateURL
+ Files := make(map[string]string)
+ if opts.TemplateOpts == nil {
+ if opts.Template != "" {
+ s["template"] = opts.Template
+ } else if opts.TemplateURL != "" {
+ s["template_url"] = opts.TemplateURL
+ } else {
+ return s, errors.New("Either Template or TemplateURL must be provided.")
+ }
} else {
- return s, errors.New("Either Template or TemplateURL must be provided.")
+ if err := opts.TemplateOpts.Parse(); err != nil {
+ return nil, err
+ }
+
+ if err := GetFileContents(opts.TemplateOpts, opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
+ return nil, err
+ }
+ opts.TemplateOpts.FixFileRefs()
+ s["template"] = string(opts.TemplateOpts.Bin)
+
+ for k, v := range opts.TemplateOpts.Files {
+ Files[k] = v
+ }
}
- if opts.Environment != "" {
+ if opts.EnvironmentOpts != nil {
+ if err := opts.EnvironmentOpts.Parse(); err != nil {
+ return nil, err
+ }
+ if err := GetRRFileContents(opts.EnvironmentOpts, ignoreIfEnvironment); err != nil {
+ return nil, err
+ }
+ opts.EnvironmentOpts.FixFileRefs()
+ for k, v := range opts.EnvironmentOpts.Files {
+ Files[k] = v
+ }
+ s["environment"] = string(opts.EnvironmentOpts.Bin)
+ } else if opts.Environment != "" {
s["environment"] = opts.Environment
}
if opts.Files != nil {
s["files"] = opts.Files
+ } else {
+ s["files"] = Files
}
if opts.Parameters != nil {
@@ -409,9 +544,16 @@
Name string
// (REQUIRED) The timeout for stack creation in minutes.
Timeout int
+ // (REQUIRED) A structure that contains either the template file or url. Call the
+ // associated methods to extract the information relevant to send in a create request.
+ TemplateOpts *Template
+ // (DEPRECATED): Please use TemplateOpts for providing the template. If
+ // TemplateOpts is provided, TemplateURL will be ignored
// (OPTIONAL; REQUIRED IF Template IS EMPTY) The URL of the template to instantiate.
// This value is ignored if Template is supplied inline.
TemplateURL string
+ // (DEPRECATED): Please use TemplateOpts for providing the template. If
+ // TemplateOpts is provided, Template will be ignored
// (OPTIONAL; REQUIRED IF TemplateURL IS EMPTY) A template to instantiate. The value
// is a stringified version of the JSON/YAML template. Since the template will likely
// be located in a file, one way to set this variable is by using ioutil.ReadFile:
@@ -427,8 +569,14 @@
// creation fails. Default is true, meaning all resources are not deleted when
// stack creation fails.
DisableRollback Rollback
+ // (OPTIONAL) A structure that contains details for the environment of the stack.
+ EnvironmentOpts *Environment
+ // (DEPRECATED): Please use EnvironmentOpts to provide Environment data
// (OPTIONAL) A stringified JSON environment for the stack.
Environment string
+ // (DEPRECATED): Files is automatically determined
+ // by parsing the template and environment passed as TemplateOpts and
+ // EnvironmentOpts respectively.
// (OPTIONAL) A map that maps file names to file contents. It can also be used
// to pass provider template contents. Example:
// Files: `{"myfile": "#!/bin/bash\necho 'Hello world' > /root/testfile.txt"}`
@@ -445,25 +593,56 @@
return s, errors.New("Required field 'Name' not provided.")
}
s["stack_name"] = opts.Name
-
- if opts.Template != "" {
- s["template"] = opts.Template
- } else if opts.TemplateURL != "" {
- s["template_url"] = opts.TemplateURL
+ Files := make(map[string]string)
+ if opts.TemplateOpts == nil {
+ if opts.Template != "" {
+ s["template"] = opts.Template
+ } else if opts.TemplateURL != "" {
+ s["template_url"] = opts.TemplateURL
+ } else {
+ return s, errors.New("Either Template or TemplateURL must be provided.")
+ }
} else {
- return s, errors.New("Either Template or TemplateURL must be provided.")
- }
+ if err := opts.TemplateOpts.Parse(); err != nil {
+ return nil, err
+ }
+ if err := GetFileContents(opts.TemplateOpts, opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
+ return nil, err
+ }
+ opts.TemplateOpts.FixFileRefs()
+ s["template"] = string(opts.TemplateOpts.Bin)
+
+ for k, v := range opts.TemplateOpts.Files {
+ Files[k] = v
+ }
+ }
if opts.DisableRollback != nil {
s["disable_rollback"] = &opts.DisableRollback
}
- if opts.Environment != "" {
+ if opts.EnvironmentOpts != nil {
+ if err := opts.EnvironmentOpts.Parse(); err != nil {
+ return nil, err
+ }
+ if err := GetRRFileContents(opts.EnvironmentOpts, ignoreIfEnvironment); err != nil {
+ return nil, err
+ }
+ opts.EnvironmentOpts.FixFileRefs()
+ for k, v := range opts.EnvironmentOpts.Files {
+ Files[k] = v
+ }
+ s["environment"] = string(opts.EnvironmentOpts.Bin)
+ } else if opts.Environment != "" {
s["environment"] = opts.Environment
}
+
if opts.Files != nil {
s["files"] = opts.Files
+ } else {
+ s["files"] = Files
}
+
if opts.Parameters != nil {
s["parameters"] = opts.Parameters
}