github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/digitalocean/config.go (about)

     1  package digitalocean
     2  
     3  import (
     4  	"context"
     5  	"log"
     6  	"net/http"
     7  	"net/http/httputil"
     8  	"time"
     9  
    10  	"github.com/digitalocean/godo"
    11  	"github.com/hashicorp/terraform/helper/logging"
    12  	"github.com/hashicorp/terraform/helper/resource"
    13  	"golang.org/x/oauth2"
    14  )
    15  
    16  type Config struct {
    17  	Token string
    18  }
    19  
    20  // Client() returns a new client for accessing digital ocean.
    21  func (c *Config) Client() (*godo.Client, error) {
    22  	tokenSrc := oauth2.StaticTokenSource(&oauth2.Token{
    23  		AccessToken: c.Token,
    24  	})
    25  
    26  	client := godo.NewClient(oauth2.NewClient(oauth2.NoContext, tokenSrc))
    27  
    28  	if logging.IsDebugOrHigher() {
    29  		client.OnRequestCompleted(logRequestAndResponse)
    30  	}
    31  
    32  	log.Printf("[INFO] DigitalOcean Client configured for URL: %s", client.BaseURL.String())
    33  
    34  	return client, nil
    35  }
    36  
    37  func logRequestAndResponse(req *http.Request, resp *http.Response) {
    38  	reqData, err := httputil.DumpRequest(req, true)
    39  	if err == nil {
    40  		log.Printf("[DEBUG] "+logReqMsg, string(reqData))
    41  	} else {
    42  		log.Printf("[ERROR] DigitalOcean API Request error: %#v", err)
    43  	}
    44  
    45  	respData, err := httputil.DumpResponse(resp, true)
    46  	if err == nil {
    47  		log.Printf("[DEBUG] "+logRespMsg, string(respData))
    48  	} else {
    49  		log.Printf("[ERROR] DigitalOcean API Response error: %#v", err)
    50  	}
    51  }
    52  
    53  // waitForAction waits for the action to finish using the resource.StateChangeConf.
    54  func waitForAction(client *godo.Client, action *godo.Action) error {
    55  	var (
    56  		pending   = "in-progress"
    57  		target    = "completed"
    58  		refreshfn = func() (result interface{}, state string, err error) {
    59  			a, _, err := client.Actions.Get(context.Background(), action.ID)
    60  			if err != nil {
    61  				return nil, "", err
    62  			}
    63  			if a.Status == "errored" {
    64  				return a, "errored", nil
    65  			}
    66  			if a.CompletedAt != nil {
    67  				return a, target, nil
    68  			}
    69  			return a, pending, nil
    70  		}
    71  	)
    72  	_, err := (&resource.StateChangeConf{
    73  		Pending: []string{pending},
    74  		Refresh: refreshfn,
    75  		Target:  []string{target},
    76  
    77  		Delay:      10 * time.Second,
    78  		Timeout:    60 * time.Minute,
    79  		MinTimeout: 3 * time.Second,
    80  
    81  		// This is a hack around DO API strangeness.
    82  		// https://github.com/hashicorp/terraform/issues/481
    83  		//
    84  		NotFoundChecks: 60,
    85  	}).WaitForState()
    86  	return err
    87  }
    88  
    89  const logReqMsg = `DigitalOcean API Request Details:
    90  ---[ REQUEST ]---------------------------------------
    91  %s
    92  -----------------------------------------------------`
    93  
    94  const logRespMsg = `DigitalOcean API Response Details:
    95  ---[ RESPONSE ]--------------------------------------
    96  %s
    97  -----------------------------------------------------`