diff --git a/builtin/bins/provider-consul/main.go b/builtin/bins/provider-consul/main.go new file mode 100644 index 000000000..1f0b52a2a --- /dev/null +++ b/builtin/bins/provider-consul/main.go @@ -0,0 +1,10 @@ +package main + +import ( + "github.com/hashicorp/terraform/builtin/providers/consul" + "github.com/hashicorp/terraform/plugin" +) + +func main() { + plugin.Serve(new(consul.ResourceProvider)) +} diff --git a/builtin/providers/consul/config.go b/builtin/providers/consul/config.go new file mode 100644 index 000000000..c5e94a03d --- /dev/null +++ b/builtin/providers/consul/config.go @@ -0,0 +1,32 @@ +package consul + +import ( + "log" + + "github.com/armon/consul-api" +) + +type Config struct { + Datacenter string `mapstructure:"datacenter"` + Address string `mapstructure:"address"` +} + +// Client() returns a new client for accessing digital +// ocean. +// +func (c *Config) Client() (*consulapi.Client, error) { + config := consulapi.DefaultConfig() + if c.Datacenter != "" { + config.Datacenter = c.Datacenter + } + if c.Address != "" { + config.Address = c.Address + } + client, err := consulapi.NewClient(config) + + log.Printf("[INFO] Consul Client configured with: %#v", config) + if err != nil { + return nil, err + } + return client, nil +} diff --git a/builtin/providers/consul/resource_consul_key.go b/builtin/providers/consul/resource_consul_key.go new file mode 100644 index 000000000..047aa055c --- /dev/null +++ b/builtin/providers/consul/resource_consul_key.go @@ -0,0 +1,57 @@ +package consul + +import ( + "github.com/hashicorp/terraform/helper/config" + "github.com/hashicorp/terraform/terraform" +) + +func resource_consul_keys_validation() *config.Validator { + return &config.Validator{ + Optional: []string{ + "datacenter", + "*.key", + "*.value", + "*.default", + "*.delete", + }, + } +} + +func resource_consul_keys_create( + s *terraform.ResourceState, + d *terraform.ResourceDiff, + meta interface{}) (*terraform.ResourceState, error) { + // Merge the diff into the state so that we have all the attributes + // properly. + rs := s.MergeDiff(d) + return rs, nil +} + +func resource_consul_keys_destroy( + s *terraform.ResourceState, + meta interface{}) error { + return nil +} + +func resource_consul_keys_update( + s *terraform.ResourceState, + d *terraform.ResourceDiff, + meta interface{}) (*terraform.ResourceState, error) { + // Merge the diff into the state so that we have all the attributes + // properly. + rs := s.MergeDiff(d) + return rs, nil +} + +func resource_consul_keys_diff( + s *terraform.ResourceState, + c *terraform.ResourceConfig, + meta interface{}) (*terraform.ResourceDiff, error) { + return nil, nil +} + +func resource_consul_keys_refresh( + s *terraform.ResourceState, + meta interface{}) (*terraform.ResourceState, error) { + return s, nil +} diff --git a/builtin/providers/consul/resource_provider.go b/builtin/providers/consul/resource_provider.go new file mode 100644 index 000000000..410b8e6d6 --- /dev/null +++ b/builtin/providers/consul/resource_provider.go @@ -0,0 +1,64 @@ +package consul + +import ( + "log" + + "github.com/armon/consul-api" + "github.com/hashicorp/terraform/helper/config" + "github.com/hashicorp/terraform/terraform" +) + +type ResourceProvider struct { + Config Config + client *consulapi.Client +} + +func (p *ResourceProvider) Validate(c *terraform.ResourceConfig) ([]string, []error) { + v := &config.Validator{ + Optional: []string{ + "datacenter", + "address", + }, + } + return v.Validate(c) +} + +func (p *ResourceProvider) ValidateResource( + t string, c *terraform.ResourceConfig) ([]string, []error) { + return resourceMap.Validate(t, c) +} + +func (p *ResourceProvider) Configure(c *terraform.ResourceConfig) error { + if _, err := config.Decode(&p.Config, c.Config); err != nil { + return err + } + + log.Println("[INFO] Initializing Consul client") + var err error + p.client, err = p.Config.Client() + if err != nil { + return err + } + return nil +} + +func (p *ResourceProvider) Apply( + s *terraform.ResourceState, + d *terraform.ResourceDiff) (*terraform.ResourceState, error) { + return resourceMap.Apply(s, d, p) +} + +func (p *ResourceProvider) Diff( + s *terraform.ResourceState, + c *terraform.ResourceConfig) (*terraform.ResourceDiff, error) { + return resourceMap.Diff(s, c, p) +} + +func (p *ResourceProvider) Refresh( + s *terraform.ResourceState) (*terraform.ResourceState, error) { + return resourceMap.Refresh(s, p) +} + +func (p *ResourceProvider) Resources() []terraform.ResourceType { + return resourceMap.Resources() +} diff --git a/builtin/providers/consul/resources.go b/builtin/providers/consul/resources.go new file mode 100644 index 000000000..5829d059a --- /dev/null +++ b/builtin/providers/consul/resources.go @@ -0,0 +1,24 @@ +package consul + +import ( + "github.com/hashicorp/terraform/helper/resource" +) + +// resourceMap is the mapping of resources we support to their basic +// operations. This makes it easy to implement new resource types. +var resourceMap *resource.Map + +func init() { + resourceMap = &resource.Map{ + Mapping: map[string]resource.Resource{ + "consul_keys": resource.Resource{ + ConfigValidator: resource_consul_keys_validation(), + Create: resource_consul_keys_create, + Destroy: resource_consul_keys_destroy, + Update: resource_consul_keys_update, + Diff: resource_consul_keys_diff, + Refresh: resource_consul_keys_refresh, + }, + }, + } +} diff --git a/config.go b/config.go index b12c7ce64..201fac46f 100644 --- a/config.go +++ b/config.go @@ -37,6 +37,8 @@ func init() { "digitalocean": "terraform-provider-digitalocean", "heroku": "terraform-provider-heroku", "dnsimple": "terraform-provider-dnsimple", + "consul": "terraform-provider-consul", + "cloudflare": "terraform-provider-cloudflare", } BuiltinConfig.Provisioners = map[string]string{ "local-exec": "terraform-provisioner-local-exec",