From b924e0644320cbeef7b8b7d8d1c45e8d2b9135cc Mon Sep 17 00:00:00 2001 From: Pavel Nosovets <56305887+palson-cf@users.noreply.github.com> Date: Tue, 9 Jun 2020 08:48:43 +0300 Subject: [PATCH] Split client and provider into separate packages (#2) * Add client package * Added project import Fix token defaults * Add pipeline import * Add project tests * Refactoring * Add pipeline tests * Fix pipeline triggers * Added tests for pipeline triggers * Refactoring * Add original_yaml_string and runtime_environment to pipeline * Add pipeline revision * Added a test for pipeline revision * Fix SetVariables methods --- client/client.go | 92 +++++ client/pipeline.go | 198 ++++++++++ client/project.go | 149 ++++++++ client/utils.go | 12 + codefresh/client.go | 10 - codefresh/provider.go | 21 +- codefresh/provider_test.go | 30 ++ codefresh/resource_pipeline.go | 559 +++++++++++++++------------- codefresh/resource_pipeline_test.go | 519 ++++++++++++++++++++++++++ codefresh/resource_project.go | 125 +++---- codefresh/resource_project_test.go | 179 +++++++++ codefresh/utils.go | 266 +------------ go.mod | 5 +- go.sum | 198 ++++++++++ 14 files changed, 1753 insertions(+), 610 deletions(-) create mode 100644 client/client.go create mode 100644 client/pipeline.go create mode 100644 client/project.go create mode 100644 client/utils.go delete mode 100644 codefresh/client.go create mode 100644 codefresh/provider_test.go create mode 100644 codefresh/resource_pipeline_test.go create mode 100644 codefresh/resource_project_test.go diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..e6ed7e2 --- /dev/null +++ b/client/client.go @@ -0,0 +1,92 @@ +package client + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" +) + +// Client token, host, htpp.Client +type Client struct { + Token string + Host string + Client *http.Client +} + +// RequestOptions path, method, etc +type RequestOptions struct { + Path string + Method string + Body []byte + QS map[string]string +} + +// NewClient returns a new client configured to communicate on a server with the +// given hostname and to send an Authorization Header with the value of +// token +func NewClient(hostname string, token string) *Client { + return &Client{ + Host: hostname, + Token: token, + Client: &http.Client{}, + } + +} + +// RequestAPI http request to Codefresh API +func (client *Client) RequestAPI(opt *RequestOptions) ([]byte, error) { + finalURL := fmt.Sprintf("%s%s", client.Host, opt.Path) + if opt.QS != nil { + finalURL += ToQS(opt.QS) + } + request, err := http.NewRequest(opt.Method, finalURL, bytes.NewBuffer(opt.Body)) + if err != nil { + return nil, err + } + + request.Header.Set("Authorization", client.Token) + request.Header.Set("Content-Type", "application/json; charset=utf-8") + + resp, err := client.Client.Do(request) + + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("Failed to read body %v %v", resp.StatusCode, resp.Status) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("%v, %s", resp.Status, string(body)) + } + return body, nil +} + +// ToQS add extra parameters to path +func ToQS(qs map[string]string) string { + var arr = []string{} + for k, v := range qs { + arr = append(arr, fmt.Sprintf("%s=%s", k, v)) + } + return "?" + strings.Join(arr, "&") +} + +// DecodeResponseInto json Unmarshall +func DecodeResponseInto(body []byte, target interface{}) error { + return json.Unmarshal(body, target) +} + +// EncodeToJSON json Marshal +func EncodeToJSON(object interface{}) ([]byte, error) { + body, err := json.Marshal(object) + if err != nil { + return nil, err + } + return body, nil +} diff --git a/client/pipeline.go b/client/pipeline.go new file mode 100644 index 0000000..8495afb --- /dev/null +++ b/client/pipeline.go @@ -0,0 +1,198 @@ +package client + +import ( + "errors" + "fmt" + "strings" +) + +type ErrorResponse struct { + Status int `json:"status,omitempty"` + Message string `json:"message,omitempty"` + Error string `json:"error,omitempty"` +} + +type Labels struct { + Tags []string `json:"tags,omitempty"` +} + +type Metadata struct { + Name string `json:"name,omitempty"` + ID string `json:"id,omitempty"` + Labels Labels `json:"labels,omitempty"` + OriginalYamlString string `json:"originalYamlString,omitempty"` + Project string `json:"project,omitempty"` + ProjectId string `json:"projectId,omitempty"` + Revision int `json:"revision,omitempty"` +} + +type SpecTemplate struct { + Location string `json:"location,omitempty"` + Repo string `json:"repo,omitempty"` + Path string `json:"path,omitempty"` + Revision string `json:"revision,omitempty"` + Context string `json:"context,omitempty"` +} + +type Trigger struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Type string `json:"type,omitempty"` + Repo string `json:"repo,omitempty"` + Events []string `json:"events,omitempty"` + BranchRegex string `json:"branchRegex,omitempty"` + ModifiedFilesGlob string `json:"modifiedFilesGlob,omitempty"` + Provider string `json:"provider,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Context string `json:"context,omitempty"` + Variables []Variable `json:"variables,omitempty"` +} + +type RuntimeEnvironment struct { + Name string `json:"name,omitempty"` + Memory string `json:"memory,omitempty"` + CPU string `json:"cpu,omitempty"` + DindStorage string `json:"dindStorage,omitempty"` +} + +func (t *Trigger) SetVariables(variables map[string]string) { + for key, value := range variables { + t.Variables = append(t.Variables, Variable{Key: key, Value: value}) + } +} + +type Spec struct { + Variables []Variable `json:"variables,omitempty"` + SpecTemplate *SpecTemplate `json:"specTemplate,omitempty"` + Triggers []Trigger `json:"triggers,omitempty"` + Priority int `json:"priority,omitempty"` + Concurrency int `json:"concurrency,omitempty"` + Contexts []interface{} `json:"contexts,omitempty"` + Steps map[string]interface{} `json:"steps,omitempty"` + Stages []interface{} `json:"stages,omitempty"` + Mode string `json:"mode,omitempty"` + RuntimeEnvironment RuntimeEnvironment `json:"runtimeEnvironment,omitempty"` +} + +type Pipeline struct { + Metadata Metadata `json:"metadata,omitempty"` + Spec Spec `json:"spec,omitempty"` + Version string `json:"version,omitempty"` +} + +func (p *Pipeline) SetVariables(variables map[string]string) { + for key, value := range variables { + p.Spec.Variables = append(p.Spec.Variables, Variable{Key: key, Value: value}) + } +} + +func (pipeline *Pipeline) GetID() string { + if pipeline.Metadata.ID != "" { + return pipeline.Metadata.ID + } else { + return pipeline.Metadata.Name + } +} + +func (client *Client) GetPipeline(name string) (*Pipeline, error) { + fullPath := fmt.Sprintf("/pipelines/%s", strings.Replace(name, "/", "%2F", 1)) + opts := RequestOptions{ + Path: fullPath, + Method: "GET", + } + + resp, err := client.RequestAPI(&opts) + + if err != nil { + return nil, err + } + + var pipeline Pipeline + + err = DecodeResponseInto(resp, &pipeline) + if err != nil { + return nil, err + } + + return &pipeline, nil +} + +func (client *Client) CreatePipeline(pipeline *Pipeline) (*Pipeline, error) { + + body, err := EncodeToJSON(pipeline) + + if err != nil { + return nil, err + } + opts := RequestOptions{ + Path: "/pipelines", + Method: "POST", + Body: body, + } + + resp, err := client.RequestAPI(&opts) + + if err != nil { + return nil, err + } + + var respPipeline Pipeline + err = DecodeResponseInto(resp, &respPipeline) + if err != nil { + return nil, err + } + + return &respPipeline, nil + +} + +func (client *Client) UpdatePipeline(pipeline *Pipeline) (*Pipeline, error) { + + body, err := EncodeToJSON(pipeline) + + if err != nil { + return nil, err + } + + id := pipeline.GetID() + if id == "" { + return nil, errors.New("[ERROR] Both Pipeline ID and Name are empty") + } + + fullPath := fmt.Sprintf("/pipelines/%s", strings.Replace(id, "/", "%2F", 1)) + opts := RequestOptions{ + Path: fullPath, + Method: "PUT", + Body: body, + } + + resp, err := client.RequestAPI(&opts) + if err != nil { + return nil, err + } + + var respPipeline Pipeline + err = DecodeResponseInto(resp, &respPipeline) + if err != nil { + return nil, err + } + + return &respPipeline, nil +} + +func (client *Client) DeletePipeline(name string) error { + + fullPath := fmt.Sprintf("/pipelines/%s", strings.Replace(name, "/", "%2F", 1)) + opts := RequestOptions{ + Path: fullPath, + Method: "DELETE", + } + + _, err := client.RequestAPI(&opts) + + if err != nil { + return err + } + + return nil +} diff --git a/client/project.go b/client/project.go new file mode 100644 index 0000000..44fd3aa --- /dev/null +++ b/client/project.go @@ -0,0 +1,149 @@ +package client + +import ( + "errors" + "fmt" +) + +// Project spec +type Project struct { + ID string `json:"id,omitempty"` + ProjectName string `json:"projectName,omitempty"` + Tags []string `json:"tags,omitempty"` + Variables []Variable `json:"variables,omitempty"` +} + +// GetID implement CodefreshObject interface +func (project *Project) GetID() string { + return project.ID +} + +// SetVariables project variables +func (project *Project) SetVariables(variables map[string]string) { + for key, value := range variables { + project.Variables = append(project.Variables, Variable{Key: key, Value: value}) + } +} + +// GetProjectByName get project object by name +func (client *Client) GetProjectByName(name string) (*Project, error) { + fullPath := fmt.Sprintf("/projects/name/%s", name) + opts := RequestOptions{ + Path: fullPath, + Method: "GET", + } + + resp, err := client.RequestAPI(&opts) + + if err != nil { + return nil, err + } + + var project Project + + err = DecodeResponseInto(resp, &project) + if err != nil { + return nil, err + } + + return &project, nil +} + +// GetProjectByID get project object by id +func (client *Client) GetProjectByID(id string) (*Project, error) { + fullPath := fmt.Sprintf("/projects/%s", id) + opts := RequestOptions{ + Path: fullPath, + Method: "GET", + } + + resp, err := client.RequestAPI(&opts) + + if err != nil { + return nil, err + } + + var project Project + + err = DecodeResponseInto(resp, &project) + if err != nil { + return nil, err + } + + return &project, nil +} + +// CreateProject POST project +func (client *Client) CreateProject(project *Project) (*Project, error) { + + body, err := EncodeToJSON(project) + + if err != nil { + return nil, err + } + opts := RequestOptions{ + Path: "/projects", + Method: "POST", + Body: body, + } + + resp, err := client.RequestAPI(&opts) + + if err != nil { + return nil, err + } + + var respProject Project + err = DecodeResponseInto(resp, &respProject) + if err != nil { + return nil, err + } + + return &respProject, nil +} + +// UpdateProject PATCH project +func (client *Client) UpdateProject(project *Project) error { + + body, err := EncodeToJSON(project) + + if err != nil { + return err + } + + id := project.GetID() + if id == "" { + return errors.New("[ERROR] Project ID is empty") + } + + fullPath := fmt.Sprintf("/projects/%s", id) + opts := RequestOptions{ + Path: fullPath, + Method: "PATCH", + Body: body, + } + + _, err = client.RequestAPI(&opts) + if err != nil { + return err + } + + return nil +} + +// DeleteProject DELETE +func (client *Client) DeleteProject(id string) error { + fullPath := fmt.Sprintf("/projects/%s", id) + opts := RequestOptions{ + Path: fullPath, + Method: "DELETE", + } + + _, err := client.RequestAPI(&opts) + + if err != nil { + return err + } + + return nil +} diff --git a/client/utils.go b/client/utils.go new file mode 100644 index 0000000..0ee5e3e --- /dev/null +++ b/client/utils.go @@ -0,0 +1,12 @@ +package client + +// Variable spec +type Variable struct { + Key string `json:"key"` + Value string `json:"value"` +} + +// CodefreshObject codefresh interface +type CodefreshObject interface { + GetID() string +} diff --git a/codefresh/client.go b/codefresh/client.go deleted file mode 100644 index f8124ff..0000000 --- a/codefresh/client.go +++ /dev/null @@ -1,10 +0,0 @@ -package codefresh - -import ( -// "net/http" -) - -type Config struct { - APIServer string - Token string -} diff --git a/codefresh/provider.go b/codefresh/provider.go index 9ba07ac..be640a2 100644 --- a/codefresh/provider.go +++ b/codefresh/provider.go @@ -1,16 +1,24 @@ package codefresh import ( + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "os" ) -func Provider() *schema.Provider { +func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ "api_url": { Type: schema.TypeString, Optional: true, - Default: "https://g.codefresh.io/api", + DefaultFunc: func() (interface{}, error) { + if url := os.Getenv("CODEFRESH_API_URL"); url != "" { + return url, nil + } + return "https://g.codefresh.io/api", nil + }, }, "token": { Type: schema.TypeString, @@ -27,10 +35,9 @@ func Provider() *schema.Provider { } func configureProvider(d *schema.ResourceData) (interface{}, error) { - config := Config{ - APIServer: d.Get("api_url").(string), - Token: d.Get("token").(string), - } - return &config, nil + apiURL := d.Get("api_url").(string) + token := d.Get("token").(string) + + return cfClient.NewClient(apiURL, token), nil } diff --git a/codefresh/provider_test.go b/codefresh/provider_test.go new file mode 100644 index 0000000..0d113f3 --- /dev/null +++ b/codefresh/provider_test.go @@ -0,0 +1,30 @@ +package codefresh + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "os" + "testing" +) + +var testAccProvider *schema.Provider +var testAccProviders map[string]terraform.ResourceProvider + +func init() { + testAccProvider = Provider().(*schema.Provider) + testAccProviders = map[string]terraform.ResourceProvider{ + "codefresh": testAccProvider, + } +} + +func TestProvider(t *testing.T) { + if err := Provider().(*schema.Provider).InternalValidate(); err != nil { + t.Fatalf("err: %s", err) + } +} + +func testAccPreCheck(t *testing.T) { + if v := os.Getenv("CODEFRESH_API_KEY"); v == "" { + t.Fatal("CODEFRESH_API_KEY must be set for acceptance tests") + } +} diff --git a/codefresh/resource_pipeline.go b/codefresh/resource_pipeline.go index 599909f..39def9d 100644 --- a/codefresh/resource_pipeline.go +++ b/codefresh/resource_pipeline.go @@ -1,72 +1,12 @@ package codefresh import ( - "encoding/json" "fmt" + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "strings" ) -type labels struct { - Tags []string `json:"tags,omitempty"` -} - -type metadata struct { - Name string `json:"name,omitempty"` - ID string `json:"id,omitempty"` - Labels labels `json:"labels,omitempty"` -} - -type specTemplate struct { - Location string `json:"location,omitempty"` - Repo string `json:"repo,omitempty"` - Path string `json:"path,omitempty"` - Revision string `json:"revision,omitempty"` - Context string `json:"context,omitempty"` -} - -type trigger struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Type string `json:"type,omitempty"` - Repo string `json:"repo,omitempty"` - Events []string `json:"events,omitempty"` - BranchRegex string `json:"branchRegex,omitempty"` - ModifiedFilesGlob string `json:"modifiedFilesGlob,omitempty"` - Provider string `json:"provider,omitempty"` - Disabled bool `json:"disabled,omitempty"` - Context string `json:"context,omitempty"` - Variables []variable `json:"variables,omitempty"` -} - -func (t *trigger) setVariables(variables map[string]interface{}) { - for key, value := range variables { - t.Variables = append(t.Variables, variable{Key: key, Value: value.(string)}) - } -} - -type spec struct { - Variables []variable `json:"variables,omitempty"` - SpecTemplate *specTemplate `json:"specTemplate,omitempty"` - Triggers []trigger `json:"triggers,omitempty"` - Priority int `json:"priority,omitempty"` - Concurrency int `json:"concurrency,omitempty"` -} - -type pipeline struct { - Metadata metadata `json:"metadata,omitempty"` - Spec *spec `json:"spec,omitempty"` -} - -func (p *pipeline) setVariables(variables map[string]interface{}) { - for key, value := range variables { - p.Spec.Variables = append(p.Spec.Variables, variable{Key: key, Value: value.(string)}) - } -} - -func (p *pipeline) getID() string { - return p.Metadata.ID -} - func resourcePipeline() *schema.Resource { return &schema.Resource{ Create: resourcePipelineCreate, @@ -74,64 +14,24 @@ func resourcePipeline() *schema.Resource { Update: resourcePipelineUpdate, Delete: resourcePipelineDelete, Importer: &schema.ResourceImporter{ - State: resourcePipelineImport, + State: schema.ImportStatePassthrough, }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, }, - "project": { + "original_yaml_string": { Type: schema.TypeString, - Required: true, + Optional: true, }, - "spec": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "location": { - Type: schema.TypeString, - Optional: true, - Default: "git", - }, - "repo": { - Type: schema.TypeString, - Required: true, - }, - "path": { - Type: schema.TypeString, - Required: true, - }, - "revision": { - Type: schema.TypeString, - Required: true, - }, - "context": { - Type: schema.TypeString, - Optional: true, - Default: "github", - }, - "priority": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - }, - "concurrency": { - Type: schema.TypeInt, - Optional: true, - Default: 0, // zero is unlimited - }, - }, - }, + "project_id": { + Type: schema.TypeString, + Optional: true, }, - "variables": { - Type: schema.TypeMap, + "revision": { + Type: schema.TypeInt, Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, }, "tags": { Type: schema.TypeSet, @@ -140,65 +40,145 @@ func resourcePipeline() *schema.Resource { Type: schema.TypeString, }, }, - "trigger": { + "spec": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - }, - "description": { - Type: schema.TypeString, + "priority": { + Type: schema.TypeInt, Optional: true, + Default: 0, }, - "type": { - Type: schema.TypeString, + "concurrency": { + Type: schema.TypeInt, Optional: true, - Default: "git", - }, - "repo": { - Type: schema.TypeString, - Required: true, + Default: 0, // zero is unlimited }, - "branch_regex": { - Type: schema.TypeString, + "spec_template": { + Type: schema.TypeList, Optional: true, - Default: "/.*/gi", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "location": { + Type: schema.TypeString, + Optional: true, + Default: "git", + }, + "repo": { + Type: schema.TypeString, + Required: true, + }, + "path": { + Type: schema.TypeString, + Required: true, + }, + "revision": { + Type: schema.TypeString, + Required: true, + }, + "context": { + Type: schema.TypeString, + Optional: true, + Default: "github", + }, + }, + }, }, - "modified_files_glob": { - Type: schema.TypeString, + "variables": { + Type: schema.TypeMap, Optional: true, - Default: "", - }, - "events": { - Type: schema.TypeList, - Required: true, Elem: &schema.Schema{ Type: schema.TypeString, }, }, - "provider": { - Type: schema.TypeString, - Optional: true, - Default: "github", - }, - "disabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "context": { - Type: schema.TypeString, + "trigger": { + Type: schema.TypeList, Optional: true, - Default: "github", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + Default: "git", + }, + "repo": { + Type: schema.TypeString, + Optional: true, + }, + "branch_regex": { + Type: schema.TypeString, + Optional: true, + Default: "/.*/gi", + }, + "modified_files_glob": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "events": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "provider": { + Type: schema.TypeString, + Optional: true, + Default: "github", + }, + "disabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "context": { + Type: schema.TypeString, + Optional: true, + Default: "github", + }, + "variables": { + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, }, - "variables": { - Type: schema.TypeMap, + "runtime_environment": { + Type: schema.TypeList, Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + }, + "memory": { + Type: schema.TypeString, + Optional: true, + }, + "cpu": { + Type: schema.TypeString, + Optional: true, + }, + "dind_storage": { + Type: schema.TypeString, + Optional: true, + }, + }, }, }, }, @@ -209,79 +189,90 @@ func resourcePipeline() *schema.Resource { } func resourcePipelineCreate(d *schema.ResourceData, meta interface{}) error { - return createCodefreshObject( - meta.(*Config), - "/pipelines", - "POST", - d, - mapResourceToPipeline, - readPipeline, - ) + + client := meta.(*cfClient.Client) + + pipeline := *mapResourceToPipeline(d) + + resp, err := client.CreatePipeline(&pipeline) + if err != nil { + return err + } + + d.SetId(resp.Metadata.ID) + + return resourcePipelineRead(d, meta) } func resourcePipelineRead(d *schema.ResourceData, meta interface{}) error { - return readCodefreshObject( - d, - meta.(*Config), - getPipelineFromCodefresh, - mapPipelineToResource) + + client := meta.(*cfClient.Client) + + pipelineID := d.Id() + + if pipelineID == "" { + d.SetId("") + return nil + } + + pipeline, err := client.GetPipeline(pipelineID) + if err != nil { + return err + } + + err = mapPipelineToResource(*pipeline, d) + if err != nil { + return err + } + + return nil } func resourcePipelineUpdate(d *schema.ResourceData, meta interface{}) error { - path := fmt.Sprintf("/pipelines/%v?disableRevisionCheck=true", d.Id()) - return updateCodefreshObject( - d, - meta.(*Config), - path, - "PUT", - mapResourceToPipeline, - readPipeline, - resourcePipelineRead) + + client := meta.(*cfClient.Client) + + pipeline := *mapResourceToPipeline(d) + pipeline.Metadata.ID = d.Id() + + _, err := client.UpdatePipeline(&pipeline) + if err != nil { + return err + } + + return resourcePipelineRead(d, meta) } func resourcePipelineDelete(d *schema.ResourceData, meta interface{}) error { - path := fmt.Sprintf("/pipelines/%v", d.Id()) - return deleteCodefreshObject(meta.(*Config), path) -} -func resourcePipelineImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - return importCodefreshObject( - d, - meta.(*Config), - getPipelineFromCodefresh, - mapPipelineToResource) -} + client := meta.(*cfClient.Client) -func readPipeline(_ *schema.ResourceData, b []byte) (codefreshObject, error) { - pipeline := &pipeline{} - err := json.Unmarshal(b, pipeline) + err := client.DeletePipeline(d.Id()) if err != nil { - return nil, err + return err } - return pipeline, nil -} -func getPipelineFromCodefresh(d *schema.ResourceData, c *Config) (codefreshObject, error) { - pipelineName := d.Id() - path := fmt.Sprintf("/pipelines/%v", pipelineName) - return getFromCodefresh(d, c, path, readPipeline) + return nil } -func mapPipelineToResource(cfObject codefreshObject, d *schema.ResourceData) error { - pipeline := cfObject.(*pipeline) - d.SetId(pipeline.Metadata.ID) +func mapPipelineToResource(pipeline cfClient.Pipeline, d *schema.ResourceData) error { err := d.Set("name", pipeline.Metadata.Name) if err != nil { return err } - err = d.Set("spec", flattenSpec(pipeline.Spec)) + err = d.Set("revision", pipeline.Metadata.Revision) if err != nil { return err } - err = d.Set("variables", convertVariables(pipeline.Spec.Variables)) + err = d.Set("project_id", pipeline.Metadata.ProjectId) + if err != nil { + return err + } + + err = d.Set("spec", flattenSpec(pipeline.Spec)) if err != nil { return err } @@ -291,7 +282,7 @@ func mapPipelineToResource(cfObject codefreshObject, d *schema.ResourceData) err return err } - err = d.Set("trigger", flattenTriggers(pipeline.Spec.Triggers)) + err = d.Set("original_yaml_string", pipeline.Metadata.OriginalYamlString) if err != nil { return err } @@ -299,85 +290,143 @@ func mapPipelineToResource(cfObject codefreshObject, d *schema.ResourceData) err return nil } -func flattenSpec(spec *spec) []map[string]interface{} { - if spec.SpecTemplate == nil { - return nil +func flattenSpec(spec cfClient.Spec) []interface{} { + + var res = make([]interface{}, 0) + m := make(map[string]interface{}) + + if len(spec.Triggers) > 0 { + m["trigger"] = flattenTriggers(spec.Triggers) + } + + if spec.SpecTemplate != nil { + m["spec_template"] = flattenSpecTemplate(*spec.SpecTemplate) + } + + if len(spec.Variables) != 0 { + m["variables"] = convertVariables(spec.Variables) + } + + if spec.RuntimeEnvironment != (cfClient.RuntimeEnvironment{}) { + m["runtime_environment"] = flattenSpecRuntimeEnvironment(spec.RuntimeEnvironment) + } + + m["concurrency"] = spec.Concurrency + + m["priority"] = spec.Priority + + res = append(res, m) + return res +} + +func flattenSpecTemplate(spec cfClient.SpecTemplate) []map[string]interface{} { + return []map[string]interface{}{ + { + "location": spec.Location, + "repo": spec.Repo, + "context": spec.Context, + "revision": spec.Revision, + "path": spec.Path, + }, } +} + +func flattenSpecRuntimeEnvironment(spec cfClient.RuntimeEnvironment) []map[string]interface{} { return []map[string]interface{}{ { - "location": spec.SpecTemplate.Location, - "repo": spec.SpecTemplate.Repo, - "context": spec.SpecTemplate.Context, - "revision": spec.SpecTemplate.Revision, - "path": spec.SpecTemplate.Path, - "priority": spec.Priority, - "concurrency": spec.Concurrency, + "name": spec.Name, + "memory": spec.Memory, + "cpu": spec.CPU, + "dind_storage": spec.DindStorage, }, } } -func flattenTriggers(triggers []trigger) []map[string]interface{} { - var res []map[string]interface{} - for _, trigger := range triggers { - res = append(res, map[string]interface{}{ - "name": trigger.Name, - "description": trigger.Description, - "context": trigger.Context, - "repo": trigger.Repo, - "branch_regex": trigger.BranchRegex, - "modified_files_glob": trigger.ModifiedFilesGlob, - "disabled": trigger.Disabled, - "provider": trigger.Provider, - "type": trigger.Type, - "events": trigger.Events, - "variables": convertVariables(trigger.Variables), - }) +func flattenTriggers(triggers []cfClient.Trigger) []map[string]interface{} { + var res = make([]map[string]interface{}, len(triggers)) + for i, trigger := range triggers { + m := make(map[string]interface{}) + m["name"] = trigger.Name + m["description"] = trigger.Description + m["context"] = trigger.Context + m["repo"] = trigger.Repo + m["branch_regex"] = trigger.BranchRegex + m["modified_files_glob"] = trigger.ModifiedFilesGlob + m["disabled"] = trigger.Disabled + m["provider"] = trigger.Provider + m["type"] = trigger.Type + m["events"] = trigger.Events + m["variables"] = convertVariables(trigger.Variables) + + res[i] = m } return res } -func mapResourceToPipeline(d *schema.ResourceData) codefreshObject { +func mapResourceToPipeline(d *schema.ResourceData) *cfClient.Pipeline { + tags := d.Get("tags").(*schema.Set).List() - pipeline := &pipeline{ - Metadata: metadata{ - Name: d.Get("name").(string), - Labels: labels{ + + pipeline := &cfClient.Pipeline{ + Metadata: cfClient.Metadata{ + Name: d.Get("name").(string), + Revision: d.Get("revision").(int), + ProjectId: d.Get("project_id").(string), + Labels: cfClient.Labels{ Tags: convertStringArr(tags), }, + OriginalYamlString: strings.Replace( + d.Get("original_yaml_string").(string), + "\n", + "\n", + -1), }, - Spec: &spec{ - SpecTemplate: &specTemplate{ - Location: d.Get("spec.0.location").(string), - Repo: d.Get("spec.0.repo").(string), - Path: d.Get("spec.0.path").(string), - Revision: d.Get("spec.0.revision").(string), - Context: d.Get("spec.0.context").(string), - }, + Spec: cfClient.Spec{ Priority: d.Get("spec.0.priority").(int), Concurrency: d.Get("spec.0.concurrency").(int), }, } - variables := d.Get("variables").(map[string]interface{}) - pipeline.setVariables(variables) - triggers := d.Get("trigger").([]interface{}) + if _, ok := d.GetOk("spec.0.spec_template"); ok { + pipeline.Spec.SpecTemplate = &cfClient.SpecTemplate{ + Location: d.Get("spec.0.spec_template.0.location").(string), + Repo: d.Get("spec.0.spec_template.0.repo").(string), + Path: d.Get("spec.0.spec_template.0.path").(string), + Revision: d.Get("spec.0.spec_template.0.revision").(string), + Context: d.Get("spec.0.spec_template.0.context").(string), + } + } + + if _, ok := d.GetOk("spec.0.runtime_environment"); ok { + pipeline.Spec.RuntimeEnvironment = cfClient.RuntimeEnvironment{ + Name: d.Get("spec.0.runtime_environment.0.name").(string), + Memory: d.Get("spec.0.runtime_environment.0.memory").(string), + CPU: d.Get("spec.0.runtime_environment.0.cpu").(string), + DindStorage: d.Get("spec.0.runtime_environment.0.dind_storage").(string), + } + } + + variables := d.Get("spec.0.variables").(map[string]string) + pipeline.SetVariables(variables) + + triggers := d.Get("spec.0.trigger").([]interface{}) for idx := range triggers { - events := d.Get(fmt.Sprintf("trigger.%v.events", idx)).([]interface{}) - - codefreshTrigger := trigger{ - Name: d.Get(fmt.Sprintf("trigger.%v.name", idx)).(string), - Description: d.Get(fmt.Sprintf("trigger.%v.description", idx)).(string), - Type: d.Get(fmt.Sprintf("trigger.%v.type", idx)).(string), - Repo: d.Get(fmt.Sprintf("trigger.%v.repo", idx)).(string), - BranchRegex: d.Get(fmt.Sprintf("trigger.%v.branch_regex", idx)).(string), - ModifiedFilesGlob: d.Get(fmt.Sprintf("trigger.%v.modified_files_glob", idx)).(string), - Provider: d.Get(fmt.Sprintf("trigger.%v.provider", idx)).(string), - Disabled: d.Get(fmt.Sprintf("trigger.%v.disabled", idx)).(bool), - Context: d.Get(fmt.Sprintf("trigger.%v.context", idx)).(string), + events := d.Get(fmt.Sprintf("spec.0.trigger.%v.events", idx)).([]interface{}) + + codefreshTrigger := cfClient.Trigger{ + Name: d.Get(fmt.Sprintf("spec.0.trigger.%v.name", idx)).(string), + Description: d.Get(fmt.Sprintf("spec.0.trigger.%v.description", idx)).(string), + Type: d.Get(fmt.Sprintf("spec.0.trigger.%v.type", idx)).(string), + Repo: d.Get(fmt.Sprintf("spec.0.trigger.%v.repo", idx)).(string), + BranchRegex: d.Get(fmt.Sprintf("spec.0.trigger.%v.branch_regex", idx)).(string), + ModifiedFilesGlob: d.Get(fmt.Sprintf("spec.0.trigger.%v.modified_files_glob", idx)).(string), + Provider: d.Get(fmt.Sprintf("spec.0.trigger.%v.provider", idx)).(string), + Disabled: d.Get(fmt.Sprintf("spec.0.trigger.%v.disabled", idx)).(bool), + Context: d.Get(fmt.Sprintf("spec.0.trigger.%v.context", idx)).(string), Events: convertStringArr(events), } - variables := d.Get(fmt.Sprintf("trigger.%v.variables", idx)).(map[string]interface{}) - codefreshTrigger.setVariables(variables) + variables := d.Get(fmt.Sprintf("spec.0.trigger.%v.variables", idx)).(map[string]string) + codefreshTrigger.SetVariables(variables) pipeline.Spec.Triggers = append(pipeline.Spec.Triggers, codefreshTrigger) } diff --git a/codefresh/resource_pipeline_test.go b/codefresh/resource_pipeline_test.go new file mode 100644 index 0000000..4f1bdb5 --- /dev/null +++ b/codefresh/resource_pipeline_test.go @@ -0,0 +1,519 @@ +package codefresh + +import ( + "fmt" + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "regexp" + "testing" +) + +var pipelineNamePrefix = "TerraformAccTest_" + +func TestAccCodefreshPipeline_basic(t *testing.T) { + name := pipelineNamePrefix + acctest.RandString(10) + resourceName := "codefresh_pipeline.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshPipelineBasicConfig(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "spec.0.spec_template.0.revision", "master"), + resource.TestCheckResourceAttr(resourceName, "spec.0.spec_template.0.context", "git"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCodefreshPipeline_Tags(t *testing.T) { + name := pipelineNamePrefix + acctest.RandString(10) + resourceName := "codefresh_pipeline.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshPipelineBasicConfigTags(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", "testTag1", "testTag2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.3247715412", "testTag2"), + resource.TestCheckResourceAttr(resourceName, "tags.3938019223", "testTag1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCodefreshPipeline_Variables(t *testing.T) { + name := pipelineNamePrefix + acctest.RandString(10) + resourceName := "codefresh_pipeline.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshPipelineBasicConfigVariables(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", "var1", "val1", "var2", "val2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "spec.0.variables.var1", "val1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.variables.var2", "val2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccCodefreshPipelineBasicConfigVariables(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", "var1", "val1_updated", "var2", "val2_updated"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "spec.0.variables.var1", "val1_updated"), + resource.TestCheckResourceAttr(resourceName, "spec.0.variables.var2", "val2_updated"), + ), + }, + }, + }) +} + +func TestAccCodefreshPipeline_RuntimeEnvironment(t *testing.T) { + name := pipelineNamePrefix + acctest.RandString(10) + resourceName := "codefresh_pipeline.test" + runtimeName := "system/codefresh-inc-default" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshPipelineBasicConfigRuntimeEnvironment(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git", runtimeName), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "spec.0.runtime_environment.0.name", runtimeName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCodefreshPipeline_OriginalYamlString(t *testing.T) { + name := pipelineNamePrefix + acctest.RandString(10) + resourceName := "codefresh_pipeline.test" + originalYamlString := "version: \"1.0\"\nsteps:\n test:\n image: alpine:latest\n commands:\n - echo \"ACC tests\"" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshPipelineBasicConfigOriginalYamlString(name, originalYamlString), + Check: resource.ComposeTestCheckFunc( + + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "original_yaml_string", originalYamlString), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCodefreshPipeline_Triggers(t *testing.T) { + name := pipelineNamePrefix + acctest.RandString(10) + resourceName := "codefresh_pipeline.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshPipelineBasicConfigTriggers( + name, + "codefresh-contrib/react-sample-app", + "./codefresh.yml", + "master", + "git", + "commits", + "git", + "push.heads", + "codefresh-contrib/react-sample-app", + "tags", + "git", + "push.tags", + "codefresh-contrib/react-sample-app", + "triggerTestVar", + "triggerTestValue", + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.#", "2"), + resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.0.name", "commits"), + resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.1.name", "tags"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccCodefreshPipelineBasicConfigTriggers( + name, + "codefresh-contrib/react-sample-app", + "./codefresh.yml", + "master", + "git", + "commits", + "git", + "push.heads", + "codefresh-contrib/react-sample-app", + "tags", + "git", + "push.tags", + "codefresh-contrib/react-sample-app", + "triggerTestVar", + "triggerTestValue", + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "spec.0.trigger.1.variables.triggerTestVar", "triggerTestValue"), + ), + }, + }, + }) +} + +func TestAccCodefreshPipeline_Revision(t *testing.T) { + name := pipelineNamePrefix + acctest.RandString(10) + resourceName := "codefresh_pipeline.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshPipelineDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshPipelineBasicConfig(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "master", "git"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "revision", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccCodefreshPipelineBasicConfig(name, "codefresh-contrib/react-sample-app", "./codefresh.yml", "development", "git"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshPipelineExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "revision", "1"), + ), + }, + }, + }) +} + +func testAccCheckCodefreshPipelineExists(resource string) resource.TestCheckFunc { + return func(state *terraform.State) error { + + rs, ok := state.RootModule().Resources[resource] + if !ok { + return fmt.Errorf("Not found: %s", resource) + } + if rs.Primary.ID == "" { + return fmt.Errorf("No Record ID is set") + } + + pipelineID := rs.Primary.ID + + apiClient := testAccProvider.Meta().(*cfClient.Client) + _, err := apiClient.GetPipeline(pipelineID) + + if err != nil { + return fmt.Errorf("error fetching pipeline with resource %s. %s", resource, err) + } + return nil + } +} + +func testAccCheckCodefreshPipelineDestroy(s *terraform.State) error { + apiClient := testAccProvider.Meta().(*cfClient.Client) + + for _, rs := range s.RootModule().Resources { + + if rs.Type != "codefresh_pipeline" { + continue + } + + _, err := apiClient.GetPipeline(rs.Primary.ID) + + if err == nil { + return fmt.Errorf("Alert still exists") + } + + notFoundErr := "PIPELINE_NOT_FOUND_ERROR" + expectedErr := regexp.MustCompile(notFoundErr) + if !expectedErr.Match([]byte(err.Error())) { + return fmt.Errorf("expected %s, got %s", notFoundErr, err) + } + + } + + return nil +} + +// CONFIGS +func testAccCodefreshPipelineBasicConfig(rName, repo, path, revision, context string) string { + return fmt.Sprintf(` +resource "codefresh_pipeline" "test" { + + lifecycle { + ignore_changes = [ + revision + ] + } + + name = "%s" + + spec { + spec_template { + repo = %q + path = %q + revision = %q + context = %q + } + } +} +`, rName, repo, path, revision, context) +} + +func testAccCodefreshPipelineBasicConfigTags(rName, repo, path, revision, context, tag1, tag2 string) string { + return fmt.Sprintf(` +resource "codefresh_pipeline" "test" { + + lifecycle { + ignore_changes = [ + revision + ] + } + + name = "%s" + + spec { + spec_template { + repo = %q + path = %q + revision = %q + context = %q + } + } + + tags = [ + %q, + %q + ] +} +`, rName, repo, path, revision, context, tag1, tag2) +} + +func testAccCodefreshPipelineBasicConfigVariables(rName, repo, path, revision, context, var1Name, var1Value, var2Name, var2Value string) string { + return fmt.Sprintf(` +resource "codefresh_pipeline" "test" { + + lifecycle { + ignore_changes = [ + revision + ] + } + + name = "%s" + + spec { + spec_template { + repo = %q + path = %q + revision = %q + context = %q + } + + variables = { + %q = %q + %q = %q + } + } +} +`, rName, repo, path, revision, context, var1Name, var1Value, var2Name, var2Value) +} + +func testAccCodefreshPipelineBasicConfigTriggers( + rName, + repo, + path, + revision, + context, + trigger1Name, + trigger1Context, + trigger1Event, + trigger1Repo, + trigger2Name, + trigger2Context, + trigger2Event, + trigger2Repo, + trigger2VarName, + trigger2VarValue string) string { + return fmt.Sprintf(` +resource "codefresh_pipeline" "test" { + + lifecycle { + ignore_changes = [ + revision + ] + } + + name = "%s" + + spec { + spec_template { + repo = %q + path = %q + revision = %q + context = %q + } + + trigger { + name = %q + branch_regex = "/.*/gi" + context = %q + description = "" + disabled = false + events = [ + %q + ] + modified_files_glob = "" + provider = "github" + repo = %q + type = "git" + } + + trigger { + name = %q + branch_regex = "/.*/gi" + context = %q + description = "" + disabled = false + events = [ + %q + ] + modified_files_glob = "" + provider = "github" + repo = %q + type = "git" + + variables = { + %q = %q + } + } + } +} +`, + rName, + repo, + path, + revision, + context, + trigger1Name, + trigger1Context, + trigger1Event, + trigger1Repo, + trigger2Name, + trigger2Context, + trigger2Event, + trigger2Repo, + trigger2VarName, + trigger2VarValue) +} + +func testAccCodefreshPipelineBasicConfigRuntimeEnvironment(rName, repo, path, revision, context, runtimeName string) string { + return fmt.Sprintf(` +resource "codefresh_pipeline" "test" { + + lifecycle { + ignore_changes = [ + revision + ] + } + + name = "%s" + + spec { + spec_template { + repo = %q + path = %q + revision = %q + context = %q + } + + runtime_environment { + name = %q + } + } +} +`, rName, repo, path, revision, context, runtimeName) +} + +func testAccCodefreshPipelineBasicConfigOriginalYamlString(rName, originalYamlString string) string { + return fmt.Sprintf(` +resource "codefresh_pipeline" "test" { + + lifecycle { + ignore_changes = [ + revision + ] + } + + name = "%s" + + original_yaml_string = %#v + + spec {} + +} +`, rName, originalYamlString) +} diff --git a/codefresh/resource_project.go b/codefresh/resource_project.go index bb096ec..0dcf02b 100644 --- a/codefresh/resource_project.go +++ b/codefresh/resource_project.go @@ -1,29 +1,10 @@ package codefresh import ( - "encoding/json" - "fmt" - + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) -type project struct { - ID string `json:"id,omitempty"` - ProjectName string `json:"projectName,omitempty"` - Tags []string `json:"tags,omitempty"` - Variables []variable `json:"variables,omitempty"` -} - -func (p *project) getID() string { - return p.ID -} - -func (p *project) setVariables(variables map[string]interface{}) { - for key, value := range variables { - p.Variables = append(p.Variables, variable{Key: key, Value: value.(string)}) - } -} - func resourceProject() *schema.Resource { return &schema.Resource{ Create: resourceProjectCreate, @@ -31,7 +12,7 @@ func resourceProject() *schema.Resource { Update: resourceProjectUpdate, Delete: resourceProjectDelete, Importer: &schema.ResourceImporter{ - State: resourceProjectImport, + State: schema.ImportStatePassthrough, }, Schema: map[string]*schema.Schema{ "name": { @@ -57,67 +38,68 @@ func resourceProject() *schema.Resource { } func resourceProjectCreate(d *schema.ResourceData, meta interface{}) error { - return createCodefreshObject( - meta.(*Config), - "/projects", - "POST", - d, - mapResourceToProject, - readProject, - ) + client := meta.(*cfClient.Client) + + project := *mapResourceToProject(d) + + resp, err := client.CreateProject(&project) + if err != nil { + return err + } + + d.SetId(resp.ID) + + return nil } func resourceProjectRead(d *schema.ResourceData, meta interface{}) error { - return readCodefreshObject( - d, - meta.(*Config), - getProjectFromCodefresh, - mapProjectToResource) + + client := meta.(*cfClient.Client) + + projectID := d.Id() + if projectID == "" { + d.SetId("") + return nil + } + + project, err := client.GetProjectByID(projectID) + if err != nil { + return err + } + + err = mapProjectToResource(project, d) + if err != nil { + return err + } + + return nil } func resourceProjectUpdate(d *schema.ResourceData, meta interface{}) error { - path := fmt.Sprintf("/projects/%v", d.Id()) - return updateCodefreshObject( - d, - meta.(*Config), - path, - "PATCH", - mapResourceToProject, - readProject, - resourceProjectRead) -} + client := meta.(*cfClient.Client) -func resourceProjectDelete(d *schema.ResourceData, meta interface{}) error { - path := fmt.Sprintf("/projects/%v", d.Id()) - return deleteCodefreshObject(meta.(*Config), path) -} + project := *mapResourceToProject(d) -func resourceProjectImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - return importCodefreshObject( - d, - meta.(*Config), - getProjectFromCodefresh, - mapProjectToResource) + err := client.UpdateProject(&project) + if err != nil { + return err + } + + return nil } -func readProject(_ *schema.ResourceData, b []byte) (codefreshObject, error) { - project := &project{} - err := json.Unmarshal(b, project) +func resourceProjectDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*cfClient.Client) + + err := client.DeleteProject(d.Id()) if err != nil { - return nil, err + return err } - return project, nil -} -func getProjectFromCodefresh(d *schema.ResourceData, c *Config) (codefreshObject, error) { - projectName := d.Id() - path := fmt.Sprintf("/projects/%v", projectName) - return getFromCodefresh(d, c, path, readProject) + return nil } -func mapProjectToResource(cfObject codefreshObject, d *schema.ResourceData) error { - project := cfObject.(*project) - d.SetId(project.ID) +func mapProjectToResource(project *cfClient.Project, d *schema.ResourceData) error { err := d.Set("name", project.ProjectName) if err != nil { @@ -136,13 +118,14 @@ func mapProjectToResource(cfObject codefreshObject, d *schema.ResourceData) erro return nil } -func mapResourceToProject(d *schema.ResourceData) codefreshObject { +func mapResourceToProject(d *schema.ResourceData) *cfClient.Project { tags := d.Get("tags").(*schema.Set).List() - project := &project{ + project := &cfClient.Project{ + ID: d.Id(), ProjectName: d.Get("name").(string), Tags: convertStringArr(tags), } - variables := d.Get("variables").(map[string]interface{}) - project.setVariables(variables) + variables := d.Get("variables").(map[string]string) + project.SetVariables(variables) return project } diff --git a/codefresh/resource_project_test.go b/codefresh/resource_project_test.go new file mode 100644 index 0000000..7908095 --- /dev/null +++ b/codefresh/resource_project_test.go @@ -0,0 +1,179 @@ +package codefresh + +import ( + "fmt" + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "regexp" + "testing" +) + +var projectNamePrefix = "TerraformAccTest_" + +func TestAccCodefreshProject_basic(t *testing.T) { + name := projectNamePrefix + acctest.RandString(10) + resourceName := "codefresh_project.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshProjectBasicConfig(name), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshProjectExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "name", name), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCodefreshProject_Tags(t *testing.T) { + name := projectNamePrefix + acctest.RandString(10) + resourceName := "codefresh_project.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshProjectBasicConfigTags(name, "testTag1", "testTag2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshProjectExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.3247715412", "testTag2"), + resource.TestCheckResourceAttr(resourceName, "tags.3938019223", "testTag1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCodefreshProject_Variables(t *testing.T) { + name := projectNamePrefix + acctest.RandString(10) + resourceName := "codefresh_project.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCodefreshProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCodefreshProjectBasicConfigVariables(name, "var1", "val1", "var2", "val2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshProjectExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "variables.var1", "val1"), + resource.TestCheckResourceAttr(resourceName, "variables.var2", "val2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccCodefreshProjectBasicConfigVariables(name, "var1", "val1_updated", "var2", "val2_updated"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCodefreshProjectExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "variables.var1", "val1_updated"), + resource.TestCheckResourceAttr(resourceName, "variables.var2", "val2_updated"), + // resource.TestCheckResourceAttr(resourceName, "variables.", name), + ), + }, + }, + }) +} + +func testAccCheckCodefreshProjectExists(resource string) resource.TestCheckFunc { + return func(state *terraform.State) error { + rs, ok := state.RootModule().Resources[resource] + if !ok { + return fmt.Errorf("Not found: %s", resource) + } + if rs.Primary.ID == "" { + return fmt.Errorf("No Record ID is set") + } + + projectID := rs.Primary.ID + + apiClient := testAccProvider.Meta().(*cfClient.Client) + _, err := apiClient.GetProjectByID(projectID) + + if err != nil { + return fmt.Errorf("error fetching project with resource %s. %s", resource, err) + } + return nil + } +} + +func testAccCheckCodefreshProjectDestroy(s *terraform.State) error { + apiClient := testAccProvider.Meta().(*cfClient.Client) + + for _, rs := range s.RootModule().Resources { + + if rs.Type != "codefresh_project" { + continue + } + + _, err := apiClient.GetProjectByID(rs.Primary.ID) + + if err == nil { + return fmt.Errorf("Alert still exists") + } + notFoundErr := "not found" + expectedErr := regexp.MustCompile(notFoundErr) + if !expectedErr.Match([]byte(err.Error())) { + return fmt.Errorf("expected %s, got %s", notFoundErr, err) + } + + } + + return nil +} + +// CONFIGS +func testAccCodefreshProjectBasicConfig(rName string) string { + return fmt.Sprintf(` +resource "codefresh_project" "test" { + name = "%s" +} +`, rName) +} + +func testAccCodefreshProjectBasicConfigTags(rName, tag1, tag2 string) string { + return fmt.Sprintf(` +resource "codefresh_project" "test" { + name = "%s" + tags = [ + %q, + %q, + ] +} +`, rName, tag1, tag2) +} + +func testAccCodefreshProjectBasicConfigVariables(rName, var1Name, var1Value, var2Name, var2Value string) string { + return fmt.Sprintf(` +resource "codefresh_project" "test" { + name = "%s" + variables = { + %q = %q + %q = %q + } +} +`, rName, var1Name, var1Value, var2Name, var2Value) +} diff --git a/codefresh/utils.go b/codefresh/utils.go index 3f4d799..c71fb2f 100644 --- a/codefresh/utils.go +++ b/codefresh/utils.go @@ -1,30 +1,9 @@ package codefresh import ( - "encoding/json" - "errors" - "fmt" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "io/ioutil" - "net/http" - "strings" + cfClient "github.com/codefresh-io/terraform-provider-codefresh/client" ) -type codefreshObject interface { - getID() string -} - -type variable struct { - Key string `json:"key"` - Value string `json:"value"` -} - -type errorResponse struct { - Status int `json:"status,omitempty"` - Message string `json:"message,omitempty"` - Error string `json:"error,omitempty"` -} - func convertStringArr(ifaceArr []interface{}) []string { return convertAndMapStringArr(ifaceArr, func(s string) string { return s }) } @@ -40,251 +19,10 @@ func convertAndMapStringArr(ifaceArr []interface{}, f func(string) string) []str return arr } -func convertVariables(vars []variable) map[string]string { +func convertVariables(vars []cfClient.Variable) map[string]string { res := make(map[string]string, len(vars)) for _, v := range vars { res[v.Key] = v.Value } return res } - -func createCodefreshObject( - c *Config, - path string, - httpMethod string, - d *schema.ResourceData, - mapFunc func(data *schema.ResourceData) codefreshObject, - readFunc func(*schema.ResourceData, []byte) (codefreshObject, error), -) error { - body, err := getBody(d, mapFunc) - if err != nil { - return err - } - - url := c.APIServer + path - apiKey := c.Token - - req, err := http.NewRequest(httpMethod, url, body) - if err != nil { - return err - } - req.Header.Add("Authorization", apiKey) - req.Header.Add("Content-Type", "application/json; charset=utf-8") - - client := http.DefaultClient - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := ioutil.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("Failed to read body %v %v", resp.StatusCode, resp.Status) - } - - if resp.StatusCode == 500 { - errorResp, err := readErrorResponse(bodyBytes) - if err != nil { - return fmt.Errorf("%v (%v)", resp.Status, resp.StatusCode) - } - return fmt.Errorf("%v (%v) %v", errorResp.Message, errorResp.Status, errorResp.Error) - } - - if resp.StatusCode != 200 { - return fmt.Errorf("%v, %s", resp.Status, string(bodyBytes)) - } - - cfObject, err := readFunc(d, bodyBytes) - if err != nil { - return err - } - - d.SetId(cfObject.getID()) - return nil -} - -func readErrorResponse(b []byte) (*errorResponse, error) { - errorResponse := &errorResponse{} - err := json.Unmarshal(b, errorResponse) - if err != nil { - return nil, err - } - return errorResponse, nil -} - -func getBody(d *schema.ResourceData, mapFunc func(data *schema.ResourceData) codefreshObject) (*strings.Reader, error) { - cfObject := mapFunc(d) - postBytes, err := json.Marshal(cfObject) - if err != nil { - return nil, err - } - return strings.NewReader(string(postBytes)), nil -} - -func readCodefreshObject( - d *schema.ResourceData, - c *Config, - getFromSource func(d *schema.ResourceData, c *Config) (codefreshObject, error), - mapToResource func(codefreshObject, *schema.ResourceData) error) error { - cfObject, err := getFromSource(d, c) - if err != nil { - return err - } - - if cfObject == nil { - // if object was not found, clear ID, this signals to terraform that the resource does not exist in destination - d.SetId("") - return nil - } - - err = mapToResource(cfObject, d) - if err != nil { - return err - } - - return nil -} - -func getFromCodefresh( - d *schema.ResourceData, - c *Config, - path string, - readFunc func(*schema.ResourceData, []byte) (codefreshObject, error), -) (codefreshObject, error) { - - url := c.APIServer + path - apiKey := c.Token - - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - req.Header.Add("Authorization", apiKey) - - client := http.DefaultClient - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - // if not found, this is not an error, we just need to return nil to signal the thing was not found - if resp.StatusCode == 404 { - return nil, nil - } - - if resp.StatusCode != 200 { - return nil, errors.New(resp.Status) - } - - bodyBytes, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("Failed to read body %v %v", resp.StatusCode, resp.Status) - } - - return readFunc(d, bodyBytes) -} - -func updateCodefreshObject( - d *schema.ResourceData, - c *Config, - path string, - httpMethod string, - mapFunc func(data *schema.ResourceData) codefreshObject, - readFunc func(*schema.ResourceData, []byte) (codefreshObject, error), - resourceRead func(d *schema.ResourceData, m interface{}) error, -) error { - body, err := getBody(d, mapFunc) - if err != nil { - return err - } - - url := c.APIServer + path - apiKey := c.Token - - req, err := http.NewRequest(httpMethod, url, body) - if err != nil { - return err - } - req.Header.Add("Authorization", apiKey) - req.Header.Add("Content-Type", "application/json; charset=utf-8") - - client := http.DefaultClient - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - return errors.New(resp.Status) - } - - bodyBytes, err := ioutil.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("Failed to read body %v %v", resp.StatusCode, resp.Status) - } - - _, err = readFunc(d, bodyBytes) - if err != nil { - return err - } - - return resourceRead(d, c) -} - -func deleteCodefreshObject(c *Config, path string) error { - url := c.APIServer + path - apiKey := c.Token - - req, err := http.NewRequest("DELETE", url, nil) - if err != nil { - return err - } - req.Header.Add("Authorization", apiKey) - - client := http.DefaultClient - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - // it seems like Codefresh should return a 400 error when a pipeline is not found, but it's actually returning - // a 500, so we won't be able to tell the difference between a not found and an issue, we'll just have to - // assume not found - if resp.StatusCode == 500 { - return nil - } - - if resp.StatusCode != 200 { - return errors.New(resp.Status) - } - - return nil -} - -func importCodefreshObject( - d *schema.ResourceData, - c *Config, - getFromCodefresh func(d *schema.ResourceData, c *Config) (codefreshObject, error), - mapToResource func(codefreshObject, *schema.ResourceData) error, -) ([]*schema.ResourceData, error) { - cfObject, err := getFromCodefresh(d, c) - if err != nil { - return nil, err - } - - if cfObject == nil { - // not found - d.SetId("") - return nil, errors.New("Failed to find object with id " + d.Id()) - } - - err = mapToResource(cfObject, d) - if err != nil { - return nil, err - } - return []*schema.ResourceData{d}, nil -} diff --git a/go.mod b/go.mod index a24f189..f8ebfac 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,12 @@ module github.com/codefresh-io/terraform-provider-codefresh require ( + github.com/aws/aws-sdk-go v1.30.12 github.com/bflad/tfproviderdocs v0.6.0 github.com/bflad/tfproviderlint v0.14.0 github.com/client9/misspell v0.3.4 github.com/golangci/golangci-lint v1.27.0 - github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02 // indirect - github.com/hashicorp/hcl/v2 v2.3.0 // indirect - github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 // indirect + github.com/hashicorp/terraform v0.12.25 github.com/hashicorp/terraform-plugin-sdk v1.7.0 ) diff --git a/go.sum b/go.sum index 940df14..4ee7295 100644 --- a/go.sum +++ b/go.sum @@ -7,21 +7,63 @@ cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v36.2.0+incompatible h1:09cv2WoH0g6jl6m2iT+R9qcIPZKhXEL0sbmLhxP895s= +github.com/Azure/azure-sdk-for-go v36.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.2 h1:6AWuh3uWrsZJcNoCHrCF/+g4aKPCU39kaMO6/qrnK/4= +github.com/Azure/go-autorest/autorest v0.9.2/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503 h1:Hxqlh1uAA8aGpa1dFhDNhll7U/rkWtG8ZItFvRMr7l0= +github.com/Azure/go-autorest/autorest/adal v0.8.1-0.20191028180845-3492b2aff503/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/azure/cli v0.2.0 h1:pSwNMF0qotgehbQNllUWwJ4V3vnrLKOzHrwDLEZK904= +github.com/Azure/go-autorest/autorest/azure/cli v0.2.0/go.mod h1:WWTbGPvkAg3I4ms2j2s+Zr5xCGwGqTQh+6M2ZqOczkE= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.2.0 h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 h1:pSm8mp0T2OH2CPmPDPtwHPr3VAQaOwVF/JbllOPP4xA= +github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022 h1:y8Gs8CzNfDF5AZvjr+5UyGQvQEBL7pwo+v+wX6q9JI8= +github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157 h1:hY39LwQHh+1kaovmIjOrlqnXNX6tygSRfLkkK33IkZU= github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/Unknwon/com v0.0.0-20151008135407-28b053d5a292 h1:tuQ7w+my8a8mkwN7x2TSd7OzTjkZ7rAeSyH4xncuAMI= +github.com/Unknwon/com v0.0.0-20151008135407-28b053d5a292/go.mod h1:KYCjqMOeHpNuTOiFQU6WEcTG7poCJrUs0YgyHNtn1no= +github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a h1:APorzFpCcv6wtD5vmRWYqNm4N55kbepL7c7kTq9XI6A= +github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= +github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70 h1:FrF4uxA24DF3ARNXVbUin3wa5fDLaB1Cy8mKks/LRz4= +github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/aliyun-tablestore-go-sdk v4.1.2+incompatible h1:ABQ7FF+IxSFHDMOTtjCfmMDMHiCq6EsAoCV/9sFinaM= +github.com/aliyun/aliyun-tablestore-go-sdk v4.1.2+incompatible/go.mod h1:LDQHRZylxvcg8H7wBIDfvO5g/cy4/sz1iucBlc2l3Jw= +github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk= +github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0/go.mod h1:LzD22aAzDP8/dyiCKFp31He4m2GPjl0AFyzDtZzUu9M= github.com/apparentlymart/go-cidr v1.0.1 h1:NmIwLZ/KdsjIUlhf+/Np40atNXm/+lZ5txfTJ/SpF+U= github.com/apparentlymart/go-cidr v1.0.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= @@ -29,13 +71,20 @@ github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFU github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-versions v0.0.2-0.20180815153302-64b99f7cb171/go.mod h1:JXY95WvQrPJQtudvNARshgWajS7jNNlM90altXIPNyI= +github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 h1:7Ip0wMmLHLRJdrloDxZfhMm0xrLXZS8+COSu2bXmEQs= +github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.25.3 h1:uM16hIw9BotjZKMZlX05SN2EFtaWfi/NonPKIARiBLQ= github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.30.12 h1:KrjyosZvkpJjcwMk0RNxMZewQ47v7+ZkbQDXjWsJMs8= +github.com/aws/aws-sdk-go v1.30.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bflad/gopaniccheck v0.1.0 h1:tJftp+bv42ouERmUMWLoUn/5bi/iQZjHPznM00cP/bU= @@ -48,18 +97,30 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/bmatcuk/doublestar v1.2.1 h1:eetYiv8DDYOZcBADY+pRvRytf3Dlz1FhnpvL2FsClBc= github.com/bmatcuk/doublestar v1.2.1/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bombsimon/wsl/v3 v3.0.0 h1:w9f49xQatuaeTJFaNP4SpiWSR5vfT6IstPtM62JjcqA= github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -67,8 +128,15 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURUI= +github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ= +github.com/dylanmei/winrmtest v0.0.0-20190225150635-99b7fe2fddf1/go.mod h1:lcy9/2gH1jn/VCLouHA6tOEwLoNVd4GW6zhuKLmHC2Y= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -83,7 +151,9 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= @@ -113,10 +183,12 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw= github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -127,6 +199,7 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= @@ -164,6 +237,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -176,6 +251,10 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= +github.com/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968 h1:Pu+HW4kcQozw0QyrTTgLE+3RXNqFhQNNzhbnoLFL83c= +github.com/gophercloud/gophercloud v0.0.0-20190208042652-bc37892e1968/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= +github.com/gophercloud/utils v0.0.0-20190128072930-fbb6ab446f01 h1:OgCNGSnEalfkRpn//WGJHhpo7fkP+LhTpvEITZ7CkK4= +github.com/gophercloud/utils v0.0.0-20190128072930-fbb6ab446f01/go.mod h1:wjDF8z83zTeg5eMLml5EBSlAhbF7G8DobyI1YsMuyzw= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -183,9 +262,18 @@ github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:J github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/aws-sdk-go-base v0.4.0 h1:zH9hNUdsS+2G0zJaU85ul8D59BGnZBaKM+KMNPAHGwk= +github.com/hashicorp/aws-sdk-go-base v0.4.0/go.mod h1:eRhlz3c4nhqxFZJAahJEFL7gh6Jyj5rQmQc7F9eHFyQ= +github.com/hashicorp/consul v0.0.0-20171026175957-610f3c86a089 h1:1eDpXAxTh0iPv+1kc9/gfSI2pxRERDsTk/lNGolwHn8= +github.com/hashicorp/consul v0.0.0-20171026175957-610f3c86a089/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-azure-helpers v0.10.0 h1:KhjDnQhCqEMKlt4yH00MCevJQPJ6LkHFdSveXINO6vE= +github.com/hashicorp/go-azure-helpers v0.10.0/go.mod h1:YuAtHxm2v74s+IjQwUG88dHBJPd5jL+cXr5BGVzSKhE= +github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= +github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -193,16 +281,30 @@ github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUC github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02 h1:l1KB3bHVdvegcIf5upQ5mjcHjs2qsWnKh4Yr9xgIuu8= github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.10.0 h1:b86HUuA126IcSHyC55WjPo7KtCOVeTCKIjr+3lBhPxI= github.com/hashicorp/go-hclog v0.10.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v0.0.0-20180129170900-7f3cd4390caa/go.mod h1:6ij3Z20p+OhOkCSrA0gImAWoHYQRGbnlcuk6XYTiaRw= +github.com/hashicorp/go-msgpack v0.5.4/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.0.1-0.20190610192547-a1bc61569a26/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE= github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.2 h1:AoISa4P4IsW0/m4T6St8Yw38gTl5GtBAgfkhYh1xAz4= +github.com/hashicorp/go-retryablehttp v0.5.2/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= +github.com/hashicorp/go-slug v0.4.1 h1:/jAo8dNuLgSImoLXaX7Od7QB4TfYCVPam+OpAt5bZqc= +github.com/hashicorp/go-slug v0.4.1/go.mod h1:I5tq5Lv0E2xcNXNkmx7BSfzi1PsJ2cNjs3cC3LwyhK8= +github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-tfe v0.3.27 h1:7XZ/ZoPyYoeuNXaWWW0mJOq016y0qb7I4Q0P/cagyu8= +github.com/hashicorp/go-tfe v0.3.27/go.mod h1:DVPSW2ogH+M9W1/i50ASgMht8cHP7NxxK0nrY9aFikQ= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -218,8 +320,15 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= github.com/hashicorp/hcl/v2 v2.3.0 h1:iRly8YaMwTBAKhn1Ybk7VSdzbnopghktCD031P8ggUE= github.com/hashicorp/hcl/v2 v2.3.0/go.mod h1:d+FwDBbOLvpAM3Z6J7gPj/VoAGkNe/gm352ZhjJ/Zv8= +github.com/hashicorp/hil v0.0.0-20190212112733-ab17b08d6590 h1:2yzhWGdgQUWZUCNK+AoO35V+HTsgEmcM4J9IkArh7PI= +github.com/hashicorp/hil v0.0.0-20190212112733-ab17b08d6590/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE= +github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb h1:ZbgmOQt8DOg796figP87/EFCVx2v2h9yRvwHF/zceX4= +github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/hashicorp/terraform v0.12.25 h1:4RCbJeJvBTl+t9SDa3xqEU9G9sH5khqjlabr/89bshk= +github.com/hashicorp/terraform v0.12.25/go.mod h1:B9VZ/cn0j1wpi16bdgLBCw5D5wNOqM8DVP0al92nPXc= github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 h1:Pc5TCv9mbxFN6UVX0LH6CpQrdTM5YjbVI2w15237Pjk= github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= @@ -229,10 +338,12 @@ github.com/hashicorp/terraform-json v0.5.0 h1:7TV3/F3y7QVSuN4r9BEXqnWqrAyeOtON8f github.com/hashicorp/terraform-json v0.5.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= github.com/hashicorp/terraform-plugin-sdk v1.7.0 h1:B//oq0ZORG+EkVrIJy0uPGSonvmXqxSzXe8+GhknoW0= github.com/hashicorp/terraform-plugin-sdk v1.7.0/go.mod h1:OjgQmey5VxnPej/buEhe+YqKm0KNvV3QqU4hkqHqPCY= +github.com/hashicorp/terraform-plugin-sdk v1.13.0 h1:8v2/ZNiI12OHxEn8pzJ3noCHyRc0biKbKj+iFv5ZWKw= github.com/hashicorp/terraform-plugin-test v1.2.0 h1:AWFdqyfnOj04sxTdaAF57QqvW7XXrT8PseUHkbKsE8I= github.com/hashicorp/terraform-plugin-test v1.2.0/go.mod h1:QIJHYz8j+xJtdtLrFTlzQVC0ocr3rf/OjIpgZLK56Hs= github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596 h1:hjyO2JsNZUKT1ym+FAdlBEkGPevazYsmVgIMw7dVELg= github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= +github.com/hashicorp/vault v0.10.4/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= @@ -247,12 +358,21 @@ github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/joyent/triton-go v0.0.0-20180313100802-d8f9c0314926 h1:kie3qOosvRKqwij2HGzXWffwpXvcqfPPXRUw8I4F/mg= +github.com/joyent/triton-go v0.0.0-20180313100802-d8f9c0314926/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= @@ -274,13 +394,28 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/likexian/gokit v0.0.0-20190309162924-0a377eecf7aa/go.mod h1:QdfYv6y6qPA9pbBA2qXtoT8BMKha6UyNbxWGWl/9Jfk= +github.com/likexian/gokit v0.0.0-20190418170008-ace88ad0983b/go.mod h1:KKqSnk/VVSW8kEyO2vVCXoanzEutKdlBAPohmGXkxCk= +github.com/likexian/gokit v0.0.0-20190501133040-e77ea8b19cdc/go.mod h1:3kvONayqCaj+UgrRZGpgfXzHdMYCAO0KAt4/8n0L57Y= +github.com/likexian/gokit v0.20.15 h1:DgtIqqTRFqtbiLJFzuRESwVrxWxfs8OlY6hnPYBa3BM= +github.com/likexian/gokit v0.20.15/go.mod h1:kn+nTv3tqh6yhor9BC4Lfiu58SmH8NmQ2PmEl+uM6nU= +github.com/likexian/simplejson-go v0.0.0-20190409170913-40473a74d76d/go.mod h1:Typ1BfnATYtZ/+/shXfFYLrovhFyuKvzwrdOnIDHlmg= +github.com/likexian/simplejson-go v0.0.0-20190419151922-c1f9f0b4f084/go.mod h1:U4O1vIJvIKwbMZKUJ62lppfdvkCdVd2nfMimHK81eec= +github.com/likexian/simplejson-go v0.0.0-20190502021454-d8787b4bfa0b/go.mod h1:3BWwtmKP9cXWwYCr5bkoVDEfLywacOv0s06OBEDpyt8= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82 h1:wnfcqULT+N2seWf6y4yHzmi7GD2kNx4Ute0qArktD48= +github.com/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82/go.mod h1:y54tfGmO3NKssKveTEFFzH8C/akrSOy/iW9qEAUDV84= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= +github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9 h1:SmVbOZFWAlyQshuMfOkiAx1f5oUTsOGG5IXplAEYeeM= +github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= +github.com/masterzen/winrm v0.0.0-20190223112901-5e5c9a7fe54b h1:/1RFh2SLCJ+tEnT73+Fh5R2AO89sQqs8ba7o+hx1G0Y= +github.com/masterzen/winrm v0.0.0-20190223112901-5e5c9a7fe54b/go.mod h1:wr1VqkwW0AB5JS0QLy5GpVMS9E3VtRoSYXUYyVk46KY= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -296,9 +431,12 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-shellwords v1.0.4 h1:xmZZyxuP+bYKAKkA9ABYXVNJ+G/Wf3R8d8vAP3LDJJk= +github.com/mattn/go-shellwords v1.0.4/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= @@ -308,6 +446,8 @@ github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFW github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-linereader v0.0.0-20190213213312-1b945b3263eb h1:GRiLv4rgyqjqzxbhJke65IYUf4NCOOvrPOJbV/sPxkM= +github.com/mitchellh/go-linereader v0.0.0-20190213213312-1b945b3263eb/go.mod h1:OaY7UOoTkkrX3wRwjpYRKafIkkyeD0UtweSHAWWiqQM= github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= @@ -315,12 +455,24 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= +github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/panicwrap v1.0.0 h1:67zIyVakCIvcs69A0FGfZjBdPleaonSgGlXRSRlb6fE= +github.com/mitchellh/panicwrap v1.0.0/go.mod h1:pKvZHwWrZowLUzftuFq7coarnxbBXU4aQh3N0BJOeeA= +github.com/mitchellh/prefixedio v0.0.0-20190213213902-5733675afd51 h1:eD92Am0Qf3rqhsOeA1zwBHSfRkoHrt4o6uORamdmJP8= +github.com/mitchellh/prefixedio v0.0.0-20190213213902-5733675afd51/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= +github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= +github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= @@ -328,6 +480,8 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1 github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ= +github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -337,26 +491,37 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/packer-community/winrmcp v0.0.0-20180102160824-81144009af58 h1:m3CEgv3ah1Rhy82L+c0QG/U3VyY1UsvsIdkh0/rU97Y= +github.com/packer-community/winrmcp v0.0.0-20180102160824-81144009af58/go.mod h1:f6Izs6JvFTdnRbziASagjZ2vmf55NSIkC/weStxCHqk= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.1 h1:LrvDIY//XNo65Lq84G/akBuMGlawHvGBABv8f/ZN6DI= github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= @@ -365,6 +530,9 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/ryancurrah/gomodguard v1.0.4 h1:oCreMAt9GuFXDe9jW4HBpc3GjdX3R/sUEcLAGh1zPx8= github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/securego/gosec/v2 v2.3.0 h1:y/9mCF2WPDbSDpL3QDWZD3HHGrSYw0QSHnCqTfs4JPE= github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= @@ -380,6 +548,7 @@ github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -387,6 +556,7 @@ github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QC github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= @@ -413,16 +583,28 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d h1:Z4EH+5EffvBEhh37F0C0DnpklTMh00JOkjW5zK3ofBI= +github.com/svanharmelen/jsonapi v0.0.0-20180618144545-0c0828c3f16d/go.mod h1:BSTlc8jOjh0niykqEGVXOLXdi9o0r0kR8tCYiMvjFgw= github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2 h1:Xr9gkxfOP0KQWXKNqmwe8vEeSUiUj4Rlee9CMVX2ZUQ= github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tencentcloud/tencentcloud-sdk-go v3.0.82+incompatible h1:5Td2b0yfaOvw9M9nZ5Oav6Li9bxUNxt4DgxMfIPpsa0= +github.com/tencentcloud/tencentcloud-sdk-go v3.0.82+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= +github.com/tencentyun/cos-go-sdk-v5 v0.0.0-20190808065407-f07404cefc8c h1:iRD1CqtWUjgEVEmjwTMbP1DMzz1HRytOsgx/rlw/vNs= +github.com/tencentyun/cos-go-sdk-v5 v0.0.0-20190808065407-f07404cefc8c/go.mod h1:wk2XFUg6egk4tSDNZtXeKfe2G6690UVyt163PuUxBZk= +github.com/terraform-providers/terraform-provider-openstack v1.15.0 h1:adpjqej+F8BAX9dHmuPF47sUIkgifeqBu6p7iCsyj0Y= +github.com/terraform-providers/terraform-provider-openstack v1.15.0/go.mod h1:2aQ6n/BtChAl1y2S60vebhyJyZXBsuAI5G4+lHrT1Ew= github.com/tetafro/godot v0.3.7 h1:+mecr7RKrUKB5UQ1gwqEMn13sDKTyDR8KNIquB9mm+8= github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa h1:RC4maTWLKKwb7p1cnoygsbKIgNlJqSYBeAFON3Ar8As= github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= +github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= @@ -439,7 +621,12 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.1+incompatible h1:RMF1enSPeKTlXrXdOcqjFUElywVZjjC6pqse21bKbEU= github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557 h1:Jpn2j6wHkC9wJv5iMfJhKqrZJx3TahFx+7sbZ7zQdxs= +github.com/xlab/treeprint v0.0.0-20161029104018-1d6e34225557/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -454,11 +641,15 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -467,6 +658,8 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1X golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -489,6 +682,7 @@ golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -499,6 +693,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191009170851-d66e71096ffb h1:TR699M2v0qoKTOHxeLgp6zPqaQNs74f01a/ob9W0qko= golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -520,6 +715,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -539,6 +735,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -615,6 +812,7 @@ gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=