forked from docker-archive/deploykit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move terraform options into new terraform types (docker-archive#833)
* Move terraform options into new terraform types Creates a `types.go` that handles the definition of the terraform `Option`s and the associated functions. Signed-off-by: Steven Kaufer <[email protected]> * Rename `ImportResourceOptions` struct to `Resource` Signed-off-by: Steven Kaufer <[email protected]>
- Loading branch information
Showing
8 changed files
with
441 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package types | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"strings" | ||
|
||
logutil "github.com/docker/infrakit/pkg/log" | ||
group_types "github.com/docker/infrakit/pkg/plugin/group/types" | ||
"github.com/docker/infrakit/pkg/run/scope" | ||
"github.com/docker/infrakit/pkg/spi/group" | ||
"github.com/docker/infrakit/pkg/spi/instance" | ||
"github.com/docker/infrakit/pkg/template" | ||
"github.com/docker/infrakit/pkg/types" | ||
"github.com/docker/machine/libmachine/log" | ||
) | ||
|
||
var ( | ||
logger = logutil.New("module", "provider/terraform/instance/types") | ||
) | ||
|
||
// Resource defines a resource to import | ||
type Resource struct { | ||
// Terraform resource type | ||
ResourceType string | ||
|
||
// Resource name in the group spec | ||
ResourceName string | ||
|
||
// ID of the resource to import | ||
ResourceID string | ||
|
||
// IDs of the properties to exclude from the instance spec | ||
ExcludePropIDs []string | ||
} | ||
|
||
// Options capture the options for starting up the plugin. | ||
type Options struct { | ||
// Dir for storing plan files | ||
Dir string | ||
|
||
// PollInterval is the Terraform polling interval | ||
PollInterval types.Duration | ||
|
||
// Standalone - set if running standalone, disables manager leadership verification | ||
Standalone bool | ||
|
||
// ImportGroupSpecURL defines the group spec that the instance is imported into. | ||
ImportGroupSpecURL string | ||
|
||
// ImportResources defines the instances to import | ||
ImportResources []Resource | ||
|
||
// ImportGroupID defines the group ID to import the resource into (optional) | ||
ImportGroupID string | ||
|
||
// NewOption is an example... see the plugins.json file in this directory. | ||
NewOption string | ||
|
||
// Envs are the environment variables to include when invoking terraform | ||
Envs types.Any | ||
} | ||
|
||
// ParseOptionsEnvs processes the data to create a key=value slice of strings | ||
func (o Options) ParseOptionsEnvs() ([]string, error) { | ||
envs := []string{} | ||
if o.Envs == nil || len(o.Envs.Bytes()) == 0 { | ||
return envs, nil | ||
} | ||
err := json.Unmarshal(o.Envs.Bytes(), &envs) | ||
if err != nil { | ||
return envs, fmt.Errorf("Failed to unmarshall Options.Envs data: %v", err) | ||
} | ||
// Must be key=value pairs | ||
for _, val := range envs { | ||
if !strings.Contains(val, "=") { | ||
return []string{}, fmt.Errorf("Env var is missing '=' character: %v", val) | ||
} | ||
} | ||
return envs, err | ||
} | ||
|
||
// ParseInstanceSpecFromGroup parses the instance.Spec from the group.Spec and adds | ||
// in the tags that should be set on the imported instance | ||
func (o Options) ParseInstanceSpecFromGroup(scope scope.Scope) (*instance.Spec, error) { | ||
if o.ImportGroupSpecURL == "" { | ||
log.Info("No group spec URL specified for import") | ||
return nil, nil | ||
} | ||
var groupSpec group.Spec | ||
t, err := scope.TemplateEngine(o.ImportGroupSpecURL, template.Options{MultiPass: false}) | ||
if err != nil { | ||
logger.Error("ParseInstanceSpecFromGroup", | ||
"msg", "Failed to create template", | ||
"spec", o.ImportGroupSpecURL, | ||
"err", err) | ||
return nil, err | ||
} | ||
template, err := t.Render(nil) | ||
if err != nil { | ||
logger.Error("ParseInstanceSpecFromGroup", | ||
"msg", "Failed to render template", | ||
"spec", o.ImportGroupSpecURL, | ||
"err", err) | ||
return nil, err | ||
} | ||
if err = types.AnyString(template).Decode(&groupSpec); err != nil { | ||
logger.Error("ParseInstanceSpecFromGroup", | ||
"msg", "Failed to decode template", | ||
"spec", o.ImportGroupSpecURL, | ||
"err", err) | ||
return nil, err | ||
} | ||
// Get the instance properties we care about | ||
groupProps, err := group_types.ParseProperties(groupSpec) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Add in the bootstrap tag and (if set) the group ID | ||
tags := map[string]string{ | ||
group.ConfigSHATag: "bootstrap", | ||
} | ||
// The group ID should match the spec | ||
if o.ImportGroupID != "" { | ||
if string(groupSpec.ID) != o.ImportGroupID { | ||
return nil, | ||
fmt.Errorf("Given spec ID '%v' does not match given group ID '%v'", string(groupSpec.ID), o.ImportGroupID) | ||
} | ||
tags[group.GroupTag] = o.ImportGroupID | ||
} | ||
// Use the first logical ID if set | ||
if len(groupProps.Allocation.LogicalIDs) > 0 { | ||
tags[instance.LogicalIDTag] = string(groupProps.Allocation.LogicalIDs[0]) | ||
} | ||
|
||
spec := instance.Spec{ | ||
Properties: groupProps.Instance.Properties, | ||
Tags: tags, | ||
} | ||
logger.Info("ParseInstanceSpecFromGroup", | ||
"msg", "Successfully processed instance spec from group", | ||
"group", groupSpec.ID, | ||
"spec", spec) | ||
return &spec, nil | ||
} |
Oops, something went wrong.