diff --git a/.gitignore b/.gitignore index e69de29..48c26dc 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,3 @@ +*.tf +*.tfstate +*.backup diff --git a/croc/croc_client.go b/croc/croc_client.go new file mode 100644 index 0000000..eb2a6fa --- /dev/null +++ b/croc/croc_client.go @@ -0,0 +1,26 @@ +package croc + +import ( + "net/http" + "time" +) +type Config struct { + client *http.Client + api_url string + project string + access_key string + secret_key string +} + + +func newCrocClient(api_url, access_key, secret_key, project string) *Config{ + return &Config{ + client : &http.Client{ + Timeout: time.Second * 10, + }, + api_url: api_url, + project: project, + access_key: access_key, + secret_key: secret_key, + } +} diff --git a/croc/provider.go b/croc/provider.go index 5e3ad26..8f4d94e 100644 --- a/croc/provider.go +++ b/croc/provider.go @@ -2,56 +2,53 @@ package croc import ( "log" - "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" - ) - - func Provider() terraform.ResourceProvider { - return &schema.Provider{ - Schema: map[string]*schema.Schema{ - "project" : &schema.Schema{ - Type: schema.TypeString, - Required: true, - }, - "storage_url" : &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "https://storage.cloud.croc.ru:443", - }, - "api_url" : &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "https://api.cloud.croc.ru:443/", - }, - "monitoring_url" : &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "https://monitoring.cloud.croc.ru:443/", - }, - "ec2_access_key" : &schema.Schema{ - Type: schema.TypeString, - Required: true, - }, - "ec2_secret_key" : &schema.Schema{ - Type: schema.TypeString, - Required: true, - }, - "aws_access_key" : &schema.Schema{ - Type: schema.TypeString, - Required: true, - }, - "aws_secret_key" : &schema.Schema{ - Type: schema.TypeString, - Required: true, - }, - }, - ResourcesMap: map[string]*schema.Resource{}, - }, - ConfigureFunc: providerConfigure, +) + +func Provider() terraform.ResourceProvider { + return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "project" : &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "storage_url" : &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "https://storage.cloud.croc.ru:443", + }, + "api_url" : &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "https://api.cloud.croc.ru:443/", + }, + "monitoring_url" : &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "https://monitoring.cloud.croc.ru:443/", + }, + "access_key" : &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "secret_key" : &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + ResourcesMap: map[string]*schema.Resource{ + "croc_address" : resourceCrocAddress(), + }, + ConfigureFunc: providerConfigure, + } } func providerConfigure(d * schema.ResourceData) (interface{}, error) { - config := Config{} - log.Println("[INFO], Initializing Croc client") - return config.Client() + config := newCrocClient(d.Get("api_url").(string), + d.Get("access_key").(string), + d.Get("secret_key").(string), + d.Get("project").(string)) + log.Println("[INFO], Initializing Croc client") + return config, nil } diff --git a/croc/resource_croc_address.go b/croc/resource_croc_address.go new file mode 100644 index 0000000..9fa029d --- /dev/null +++ b/croc/resource_croc_address.go @@ -0,0 +1,98 @@ +package croc + +import ( + "github.com/hashicorp/terraform/helper/schema" + "log" + "net/url" + "io/ioutil" + "net/http" + "bytes" + "time" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" +) + +func resourceCrocAddress() *schema.Resource { + return &schema.Resource{ + Create: resourceCrocAddressCreate, + Read: resourceCrocAddressRead, + Update: resourceCrocAddressUpdate, + Delete: resourceCrocAddressDelete, + Exists: resourceCrocAddressExists, + Schema: map[string]*schema.Schema{ + "ipaddress": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "instanceid" : &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "privateaddressid" : &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "pivateaddress" : &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func resourceCrocAddressExists(d *schema.ResourceData, meta interface{}) (b bool, e error) { + log.Println("resourceCrocAddressExists") + return true, nil +} + +func resourceCrocAddressCreate(d *schema.ResourceData, meta interface{}) error { + // http://docs.aws.amazon.com/general/latest/gr/signature-version-2.html + config := meta.(*Config) + var buffer bytes.Buffer + u, _ := url.Parse(config.api_url) + + timestamp := time.Now().UTC().Format(time.RFC3339) + buffer.WriteString("GET\n") + buffer.WriteString(u.Path + "\n") + buffer.WriteString("AWSAccessKeyId=" + url.QueryEscape(config.project + ":" + config.access_key) + "\n") + buffer.WriteString("Action=AllocateAddress\n") + buffer.WriteString("SignatureMethod=HmacSHA256\n") + buffer.WriteString("SignatureVersion=2\n") + buffer.WriteString("Timestamp=" + timestamp + "\n") + buffer.WriteString("Version=2013-02-01\n") + log.Println(buffer.String()) + mac := hmac.New(sha256.New, []byte(config.secret_key)) + mac.Write([]byte(buffer.String())) + log.Println(base64.StdEncoding.EncodeToString(mac.Sum(nil))) + req, err := http.NewRequest("GET", config.api_url + "/?AWSAccessKeyId=" + url.QueryEscape(config.project + ":" + config.access_key) + + "&Action=AllocateAddress&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=" + timestamp + "&Version=2013-02-01&Signature=" + + base64.StdEncoding.EncodeToString(mac.Sum(nil)), nil) + req.Header.Add("User-Agent", "Terraform croc plugin") + resp, err := config.client.Do(req) + if err != nil { + log.Println("Error") + // handle error + } else { + defer resp.Body.Close() + body, _ := ioutil.ReadAll(resp.Body) + log.Printf("%v",body) + } + log.Println("resourceCrocAddressCreate") + return nil +} + +func resourceCrocAddressRead(d *schema.ResourceData, meta interface{}) error { + log.Println("resourceCrocAddressRead") + return nil +} + +func resourceCrocAddressUpdate(d *schema.ResourceData, meta interface{}) error { + log.Println("resourceCrocAddressUpdate") + return nil +} + +func resourceCrocAddressDelete(d *schema.ResourceData, meta interface{}) error { + log.Println("resourceCrocAddressDelete") + return nil +}